Atelier devlog
Every release
one stitch
Two parts: the long diaries of building each project (where I tripped and how I fixed it), and the full change history, 47 releases.
Build diaries
Read like a notebook
mistakes included
Changelog
Every release
open one to read it
buildDISCORD11 changes
Economy
- Economy. A virtual currency ("xu" by default; name and emoji are settings) kept in a ledger.
/vi(balance, rank, job, badges, daily xu, history),/lamviec(shifts with a stored cooldown and five jobs unlocked by total earned),/cuahang(browse; administrators add, edit and remove items),/muahang(buy),/tuido(inventory, use items),/tang(transfers with a tax and a daily cap),/doi(trades with Accept and Decline buttons),/danhcuoc(coin flip, slots, blackjack) and/bangvang(the richest)./kinhteis the admin tool: settings, add or take xu with a ledger reason, and a reset behind a confirm button. The buy command is/muahangbecause/muaalready buys a server plan. - One safe path for every balance change.
eco_accountsandeco_ledger; every change runs in aBEGIN IMMEDIATEtransaction, cannot go below zero, writes its ledger row, and can carry an idempotencyref. Purchases, transfers, trades and gambling rounds are single transactions. Whole numbers only. - Check-in.
/diemdanhalso pays the daily xu with the same streak. Its own points, streak and leaderboard are unchanged, and no existing data is migrated or changed. - Shop. Role rewards (only when the bot can manage the role, with a full refund if the grant fails), consumables (an xp boost that doubles activity xp for a while, a lucky coin that refunds part of the next lost bet) and badges, with price, optional stock and a per-person limit.
- Gambling is virtual only. Off until an admin turns it on. Minimum and maximum bet, a cooldown, and the real odds in
/danhcuoc luat: coin flip keeps 5% for the house, the slot table returns 93.3% (computed from the table), blackjack pays 3:2 and the dealer stands on 17. Nothing can be bought with real money and nothing converts out;/trogiupand the README say so. - Plans. Free: 5 shop items and bets up to 200. Pro: 25 items, bets up to 5,000. Plus: 100 items, bets up to 50,000.
/trogiupmarks the larger forms as locked on free servers. - Anti-abuse. One economy action per person at a time, cooldowns kept in the database, validated inputs and no pings anywhere.
- Dashboard. A "Kinh tế xu" tab with the economy settings.
- Jobs. A new background job closes trade offers nobody answered and blackjack rounds nobody finished.
- Data. New tables
eco_accounts,eco_ledger,eco_items,eco_inventory,eco_tradesandeco_games;/xoadulieuerases them with the rest of the server's data. No new intents, no dependencies. - 958 tests.
- Economy. A virtual currency ("xu" by default; name and emoji are settings) kept in a ledger.
buildDISCORD12 changes
Temporary voice rooms
- Temporary voice rooms.
/phongtammakes a voice channel a "join to create" lobby. Joining it makes a room named after the member, with a few rights on that one room only (see, join, rename, move people out), and moves them in. An empty room is deleted, and a sweep removes leftovers after a restart. 1 lobby free, 3 on Pro, 5 on Plus. - Stats channels.
/kenhthongkeshows members, boosts, channels or roles in the name of a voice channel, updated every 10 minutes to stay inside Discord's rename limit. The bot can build a locked channel for it. 1 free, 4 on Pro and Plus. - Scheduled messages.
/hengioposts a message every day or every week at a set time and never pings anyone. 5 on Pro, 15 on Plus. - Personal reminders.
/nhacviecreminds a member by direct message after a delay or at a clock time. Everyone, free. - Suggestion box.
/gopytakes suggestions from anyone, posts them with vote buttons, and lets staff approve, reject or mark them done with a note. Free. - New-account filter.
/khoakhan caidat tuoitaikhoan hanhdongmoiflags accounts younger than a chosen number of days when they join, and can kick them. Free. - Custom blocked words.
/automod tukhoa them, xoa, danhsach, xoahetwrites the server's own words into Discord's native keyword rule, so the bot still never reads a message. 20 words free, 200 on Pro, 500 on Plus. - Dashboard. New tabs for Giveaways, Role menus, Voice rooms (temporary rooms and stats channels) and Suggestions, a custom words card in AutoMod, an account age card in Security, and open suggestions on the overview.
- Help.
/trogiuplists the new commands with the plan flags of their limits. - Data. New tables
temp_voice,scheduled_messages,reminders,suggestionsandsuggestion_votes./xoadulieunow erases them with the rest of the server's data. No new intents. - Website and handbook. New feature cards, command list, privacy text for the new stored data, and a new section in the handbook for each feature.
- 801 tests.
- Temporary voice rooms.
buildDISCORD14 changes
Guided setup
- Guided setup.
/batdaubuilds and configures a server from three menus and one button, with the health score before and after and a card to share. The bot also posts a Start button when it joins a server./trogiuplists every command by group and marks what the plan locks. - Protection. Anti-raid counts joins and alerts, raises the verification level or locks the text channels; every lockdown records what it changed, unlocks itself after a set time and can be lifted early (
/khoakhan, or the button on the alert). Anti-nuke guard (Pro) takes dangerous roles from someone who deletes channels or roles in a burst. Mod log records bans, unbans, timeouts made through the bot, role permission changes and AutoMod blocks, never the blocked text. - Moderation.
/canhcao,/timeout,/kick,/bancheck role positions, message the member, store a numbered case and log it./hososhows a member's last ten cases. - Activity. Xp for chatting and for time in voice rooms with a cooldown and a daily cap,
/hangfor level and rank (Pro). Role menus with buttons (/vaitro), giveaways (/quatang, Pro) and anonymous polls (/binhchon). - Reports. A weekly digest of numbers and a weekly health check that alerts when the score falls by ten points or more. Reminders three days before a paid plan ends and when it ends.
- AI writing helper.
/vietgiupdrafts rules, a welcome, an announcement or an explanation of the health check (Pro). - Dashboard tabs for security, activity points, the weekly report and the mod log, and a new overview. A public
GET /statusJSON route for the website's status page. - Prices. Pro $3.99 and Plus $7.99 per 30 days, a year costs ten months, and a one-off "Dựng giúp" for $4.99 grants seven days of Pro. The free plan now builds twice.
/dungthustays one 7 day trial per server./muatakes 30, 90, 180 or 365 days. - Funnel.
/admin thongkeshows invited, setup finished, built, trial and paid servers for the last 30 days. - New intents GuildVoiceStates, GuildModeration and AutoModerationExecution, none of them privileged. New tables: events_log, xp, giveaways, giveaway_entries, polls, poll_votes, mod_cases and role_menus.
- Website. New feature cards, prices, a full command list, FAQ entries, privacy and terms for the new features, a page for every theme with its roles, categories and channels, and a status page.
- End-to-end tests.
test/e2eholds a fake gateway (client, guilds, members, roles, channels, interactions, an injectable clock) that drives the real command router, event modules and jobs, with flows for setup, anti-raid, anti-nuke, activity, giveaways and polls, role menus, moderation, tickets, payments,/xoadulieu, command validity, component routing and the no-privileged-intent rules. - Fix.
/xoadulieuleft xp that had not been written yet and the cached activity settings in memory, so a purged server could get its xp rows back. - 586 tests.
- Guided setup.
buildDISCORD8 changes
Welcome flow with an optional verify button and starter role
- Welcome flow with an optional verify button and starter role.
/chaomung. - Server health check with a score, explanations and safe fixes.
/khamsuckhoe. - AutoMod through Discord's native rules, three levels.
/automod. - Tickets as private channels with automatic closing.
/ticket. - Web dashboard with Discord sign-in, running inside the bot.
- Card payments through Stripe next to payOS.
/mua cach:stripe|payos; Stripe orders are checked by polling, with the order reference, amount and currency verified. - Trial:
/dungthugives a server seven days of Pro, once. Free-plan welcomes carry a small credit line. - Unlocked servers:
UNLOCKED_GUILD_IDSgives chosen servers every feature without a license.
- Welcome flow with an optional verify button and starter role.
buildDISCORD10 changes
Humor levels (gentle, troll, absurd) for every built-in theme and for saved themes, in…
- Humor levels (gentle, troll, absurd) for every built-in theme and for saved themes, in
/buildand/theme dung. The level changes words, never structure. - Saved themes: save a blueprint from the editor, reuse it, export it and import it.
/theme. - Backup and restore of a server's layout with safe, create-only restore and strict import validation.
/backup. - Check-in, levels, leaderboard and mini-games (guess the number, rock paper scissors, trivia).
/diemdanh,/bangxephang,/doanso,/thachdau,/cauhoi. - Recurring events with Discord scheduled events and announcements.
/sukien. - Automatic payments through payOS:
/muacreates a payment link, a job polls open orders and switches the plan on when the money arrives./admin donhanglists recent orders. - A job registry (
src/jobs.js) and a router that lets a command own its buttons, menus, modals and autocomplete. - Plan limits for the new features and an updated
/goi. - Fixed
/buildcrashing because a variable shadowed the lines module; handlers are now driven in tests with fake interactions (128 tests). - The website: an after-the-build section, the full command list, payment steps, a privacy page that lists what the new features store, and deployment from Git.
- Humor levels (gentle, troll, absurd) for every built-in theme and for saved themes, in
buildDISCORD5 changes
Seven new themes, eleven in total
- Seven new themes, eleven in total: Booking Bạn Chơi (a server for booking a friend to play or talk, with a booking guide, price list, player profiles, free slots, feedback, anti-scam and complaints channels), anime fans, coders, content creators, cinema and music, an office team, and pet lovers.
- Trust roles in the booking theme (verified player, popular player, regular customer) are handed out by staff and are not in the self-assign picker.
- Tests for every mix of up to four themes (561): Discord limits, no role key or name shared between themes, no permissions on self-assignable roles.
- The website shows all eleven themes, caps a mix at four like
/build, and merges themes in the browser with a port of the bot's merge that a test checks against the bot for every mix. - Fixed the command list scrolling sideways on phones.
buildDISCORD6 changes
Interactive website
- Interactive website: a drafting table in the hero that shows the bot's real output for every mix of themes, a working miniature of the blueprint editor, three real AI answers, plan cards, copyable commands, a drafting crosshair and a scroll ruler, in a brighter blueprint style. Reduced motion, touch and no-script all have plain fallbacks.
- The devlog page renders
docs/devlog.md, with contents, copy buttons and figure cards. The devlog itself is now a full technical write-up. - Website data comes from the bot (
scripts/export-web-data.js,scripts/sample-designs.js) and a test fails when it goes stale. - Build pacing is configurable (
BUILD_STEP_DELAY_MS) and the test suite went from about 38 seconds to about 2.5. - A build that fails halfway now saves what it created, so
/nukecan clean it up. - A Google 5xx answer is retried with a pause and reported as "unavailable" instead of "unusable".
buildDISCORD2 changes
Website live at builddiscord.vercel.app, with plan prices in US dollars ($9.99 and…
- Website live at builddiscord.vercel.app, with plan prices in US dollars ($9.99 and $19.99 per 30 days), Instagram and website contact links, and a refund rule in the terms.
- Website finished: sections for the AI designer (with a real example answer) and the editable blueprint, a plans section with how to buy a code, all seven customer commands, an updated FAQ, a devlog page in both languages, and a working invite button.
buildDISCORD7 changes
/build with one to four mixed themes (late-night gamers, studying without studying,…
/buildwith one to four mixed themes (late-night gamers, studying without studying, general-store community, chill with the crew), an editable blueprint (remove or rename a category, add a channel) and a confirmation before anything is created./thietke: a server designed by Google Gemini from a short description, with three humor levels. The answer is cleaned and always shown as an editable blueprint first./nuke,/roast,/goi,/kichhoat,/xoadulieuand the owner-only/admin.- Plans per server (free, Pro, Plus) activated with one-time codes;
npm run licensemakes and lists codes. - SQLite storage with an automatic import of the first version's JSON files, and a daily database copy.
- Health check, error alerts to a webhook, and a Raspberry Pi installer with a daily self-update that rolls back when the new version is not healthy.
- A bilingual landing page (Next.js) with privacy and terms pages.
companionsDISCORD3 changes
Mention a bot in the companions channel and ask it the time ("mấy giờ rồi?", "what time…
- Mention a bot in the companions channel and ask it the time ("mấy giờ rồi?", "what time is it in Tokyo?"), the date, or the weather and temperature ("thời tiết hôm nay", "weather in Hanoi tomorrow"): it answers from live data. The time and date need no network and follow the bots' time zone or the city named; the weather comes from Open-Meteo (free, no key), which only receives a place name, never the message. This works without the AI; when AI replies are on, the bot words the facts in its own personality. Temperatures are shown in °F and °C.
COMPANION_LOCATIONsets the home city for "here" (default Los Angeles) andLOOKUPS=offturns this off. - AI replies now know the current date and time. Optional
AI_SEARCH=onlets Gemini use Google Search for questions about news, prices and results (a paid Gemini feature; if it is refused the bot falls back to a normal answer). - The daily AI answer limit now resets at midnight in the bots' time zone instead of UTC.
- Mention a bot in the companions channel and ask it the time ("mấy giờ rồi?", "what time is it in Tokyo?"), the date, or the weather and temperature ("thời tiết hôm nay", "weather in Hanoi tomorrow"): it answers from live data. The time and date need no network and follow the bots' time zone or the city named; the weather comes from Open-Meteo (free, no key), which only receives a place name, never the message. This works without the AI; when AI replies are on, the bot words the facts in its own personality. Temperatures are shown in °F and °C.
companionsDISCORD1 change
The bots are called by their Discord names, read live while the program runs (Developer…
- The bots are called by their Discord names, read live while the program runs (Developer Portal, application name), so renaming a bot needs no change in the code. The personalities keep their working names (Pip, Chamy...) only inside the files. A line that names a bot, whether the bot names itself ("Maple gives up") or another bot ("Chamy teased me"), shows the current Discord name; the gossip scenes, the mood board, the notes under the names and the Gemini answers do the same. Only the names that really appear inside lines are swapped, as whole words, so ordinary words like dog or cow are never touched.
companionsDISCORD5 changes
Every bot has a mood for the whole day (happy, grumpy, sleepy, excited, dreamy, lazy),…
- Every bot has a mood for the whole day (happy, grumpy, sleepy, excited, dreamy, lazy), worked out from the date and the bot's number, so it is the same all day and after a restart; Grumble leans grumpy, Pip and Rocket lean cheerful. One status note in six shows the mood (184 new notes), and
/tamtrangshows everyone's mood. /companions chaohoi enabled: every day two or three bots say good morning (when the quiet hours end) and good night (the hour before they start) as a little chain of threaded replies, the first bot in its mood of the day. The moment is fixed per server and day, 312 new lines./companions reactions enabled: now and then one bot leaves a warm reaction on a member's message in the chat channel (at most one in about eight messages, once every two minutes). It needs Add Reactions; an owner still gets the shy reactions./lamsong [emoji]: a stadium wave of emoji across up to nine bots, with a chant from the one in the middle (and the player's name when given)./sinhnhat set,removeandlistwith/companions sinhnhat enabled: a member saves their own birthday (day and month, never a year); on the day six to eight bots sing in the chat channel, the first one pinging the person, from 9:00 and outside quiet hours. 29 February is celebrated on the 28th in a year without a 29th. The date is erased with/sinhnhat removeor with the rest of the server's data.birthdays.jsonis the fourth file that holds user ids, and the privacy page says so.
- Every bot has a mood for the whole day (happy, grumpy, sleepy, excited, dreamy, lazy), worked out from the date and the bot's number, so it is the same all day and after a restart; Grumble leans grumpy, Pip and Rocket lean cheerful. One status note in six shows the mood (184 new notes), and
companionsDISCORD1 change
More than a thousand new lines for /khen, /hype and the cheering on Go Live, funny and…
- More than a thousand new lines for
/khen,/hypeand the cheering on Go Live, funny and affectionate at once: skill hype, fake news bulletins and world records, tender and proud ones ("drink some water, we are proud of you"), absurd everyday comparisons, dramatic threats and bargaining, about a hundred sweet fangirl lines for the girls, lines with the player's name, lines in the voice of the two boys (Lai Bâng doting, Trường Giang the show host) and about 250 English lines. The bots now pick from about five hundred Vietnamese lines per girl instead of thirty-eight, so a long/hypesession does not repeat itself for a very long time. Tests check that no line appears twice, not even in the/che,/clutchand/failbanks.
- More than a thousand new lines for
companionsDISCORD6 changes
/tamchuyen [chude] and /companions tamchuyen enabled
/tamchuyen [chude]and/companions tamchuyen enabled: the companions chat among themselves like friends in a group chat. 56 scenes in both languages (generic topics for any girl bots, the relationship web of bots 22 to 27, the clash of the older personalities, and scenes about the owner). Each scene has 3 to 5 bots, 6 to 10 lines, real threaded replies, human pauses, and bots that name and tease each other. Boys only appear in scenes written for them. A server remembers the last 60 scenes it saw and does not repeat one until it has seen the rest. On their own, group chats start 1, 2 or 4 times a day (calm, normal, lively) between 10:00 and 22:00, outside quiet hours, at least 90 minutes apart and at a random moment./dudoan startand/dudoan result: members bet with Thắng or Thua buttons on the player's next round, some companions bet out loud, the counts update live, and the result lists who was right (names only) while the bets get their reactions. Kept in memory only./companions autohype enabled: when someone starts a Go Live stream in voice, the companions cheer in the chat channel by themselves until the stream ends (at most an hour, never in quiet hours).- Shy reactions: when the bots have the Add Reactions permission (the invite links ask for it now), now and then one of them reacts to an owner's message in the chat channel and takes it back a few seconds later. Nothing happens without the permission.
- About one note in three under a bot's name now follows the time of day (morning, noon, afternoon, evening, night, late night and the weekend), and the notes of the first nine bots were rewritten to sound like a real person.
- The bots' time zone on the Raspberry Pi is now Vietnam time (
COMPANION_TIMEZONE=Asia/Ho_Chi_Minh), so quiet hours, the evening scene and the Monday recap follow Vietnamese hours.
companionsDISCORD8 changes
The note under a bot's name no longer says "Sitting in voice with N people" (every bot…
- The note under a bot's name no longer says "Sitting in voice with N people" (every bot showed the same line whenever someone was in the room). Bots now always show their own funny notes, one new one every 15 minutes; only a running focus session (or the camera sign) replaces them.
/clutch(every companion goes wild for a clutch play) and/fail(comfort, with a little teasing, after a fail): the same options as/khen, with their own lines in both languages./hype start [minutes] [mood]and/hype stop: the companions keep cheering on their own for 5 to 60 minutes (default 15), one bot every 20 to 45 seconds, with praise, teasing or a mix. One session per channel, at most 60 messages./tranhluan a b: the companions split into two camps and argue playfully about a or b, then one gives a verdict./drama [couple]and/companions drama enabled: short scenes between Lai Bâng and Six, Trường Giang and Nhã Phương, and furyZ and Chamy, on demand or once every evening (19:00 and later, outside quiet hours)./khen-top: the most cheered and most teased names of the week. Only names are kept (never IDs), only for the current week, inpraise.json, and they are erased with the rest of the server's data.OWNER_IDScan carry a shyness level per owner (id:1,id:2,id:3). Level 2, the default, softens the goodbye after 45 minutes in the voice room; level 3 is soft from the start; level 1 never softens. The soft lines still half deny it.- The new commands share the 20 second wait per channel with
/khen.
companionsDISCORD3 changes
/khen and /che have a nguoi option to pick the player from the server
/khenand/chehave anguoioption to pick the player from the server: the bots say that member's name. Typing an @mention intenalso turns into the member's name; before, only the numeric ID was left.
/che: the same options as/khen, but every companion teases the player a little instead (a friendly roast about the play, never about looks or anything personal). A channel can use/khenor/cheonce every 20 seconds.OWNER_IDSin.env(comma separated Discord user IDs): to an owner the companions act shy. They pretend not to care and secretly like them, in the welcome, voice greetings, goodbyes and reminders (about 85 percent of the time, so it never becomes a script) and, with Gemini on, in the answers. Everyone else gets the normal warm lines, and the Gemini answers are told to be delighted. Girls say em, the two boys say tui. Nothing changes while the list is empty.
companionsDISCORD1 change
/khen
/khen: every companion cheers on the player in the channel where the command is typed, one different line each, a few seconds apart ("anh hay quá", "anh giỏi quá" and more). Options:goi(anh, chị or bạn),ten(a name to say) andlanguage(Tiếng Việt by default, or English). The girls call themselves em and the two boys say tui; it works in any channel the bots can write in, wherever they sit in voice. Once every 20 seconds per channel.
companionsDISCORD5 changes
Four new personalities for bots 24 to 27, replacing Sizzle, Gizmo, Anchor and Jinx: Lai…
- Four new personalities for bots 24 to 27, replacing Sizzle, Gizmo, Anchor and Jinx: Lai Bâng, Six, Trường Giang and Nhã Phương, each with its own lines and 25 notes in both languages. Lai Bâng and Six are a couple; Trường Giang adores Nhã Phương, who is comically annoyed by him.
- Genders settled: every bot is a girl except Lai Bâng and Trường Giang. furyZ and Chamy are no longer a couple but close best friends, and their notes were rewritten to match.
- Lines shared by all bots (welcomes, goodbyes, reminders, Pomodoro steps) no longer use gendered address such as sir, he or she, and say "you" or "everyone" instead of assuming who is listening.
- README, the cast table and the website list all 30 personalities.
/assembleand/randomare much faster with 30 bots: they start at once instead of waiting for the next 15 second round, and the bots connect six at a time instead of one after another (the first bot of a room still goes alone, so a join-to-create channel is learned first). A crowd now arrives in well under a minute, and voice rounds can no longer overlap.
companionsDISCORD2 changes
Devlog (website in both languages, and docs/devlog.md) rewritten with the Raspberry Pi…
- Devlog (website in both languages, and
docs/devlog.md) rewritten with the Raspberry Pi 5 deployment, the difficulties and how they were solved, the later additions and a lessons section. /assemble [bots]calls the companions to the voice channel you are in, and/random [bots]sends them to random voice channels they can connect to. Both replace the saved voice rooms (the bots stay where they were sent), empty the old rooms, need the Move Members permission by default and are limited to once a minute per server. Tests for both.
- Devlog (website in both languages, and
companionsDISCORD1 change
Optional Gemini features, off by default and only when GEMINI_API_KEY is set:…
- Optional Gemini features, off by default and only when
GEMINI_API_KEYis set:/companions ai replies(a companion answers, in its own personality and still as a bot, when someone mentions it or replies to it in the companions channel) and/companions ai daily(a riddle with a hidden answer, a question or a would-you-rather written once a day). A cooldown per member, a daily cap and a per-minute cap keep it polite, the model output is cleaned (no mentions, no links), and nothing about the member is sent except the message text. README, docs, privacy page and website say plainly that this mode sends that one message to Google.
- Optional Gemini features, off by default and only when
companionsDISCORD1 change
/companions voice camera enabled
/companions voice camera enabled: the companions sitting in a voice room show a "camera on" sign under their name and one of them announces it in the chat. It is only a sign, bots cannot send real video. English and Vietnamese lines, a test, and the website's voice section updated.
companionsDISCORD2 changes
A devlog page on the website in both languages, and a longer devlog in the docs.
- A devlog page on the website in both languages, and a longer devlog in the docs.
- Wording and counts brought in line with 30 bots; project marked finished.
companionsDISCORD2 changes
Each personality speaks its own lines when it welcomes a new member, greets or says…
- Each personality speaks its own lines when it welcomes a new member, greets or says goodbye to someone in the voice room, and delivers a reminder: 20 lines per purpose per language for each of the 30 personalities. The bot that speaks is one of those sitting in the room.
- About 960 more trivia questions per language (geography, animals, nature, space, the body, science, history, inventions, computers and games, movies, music and art, food, sports, language, math, Vietnam, mythology, everyday facts), each checked by a second reader. Trivia now has about 1,250 questions per language.
companionsDISCORD2 changes
About 1,000 spoken lines per language for each purpose
- About 1,000 spoken lines per language for each purpose: welcome, voice greeting, voice goodbye (new: when someone who stayed 20 minutes or more leaves), reminders, and 500 each for the start, break, work and done steps of a focus session.
- furyZ (Valorant gamer) and Chamy (her close best friend) for bots 22 and 23, with matching notes about their friendship.
companionsDISCORD3 changes
Up to 30 bots instead of 10
- Up to 30 bots instead of 10. 21 new personalities (Rex, Maple, Rocket, Zip, Clue, Mochi, Waffle, Tofu, Ziggy, Echo, Misty, Byte, furyZ, Chamy, Sizzle, Gizmo, Anchor, Jinx, Quill, Blip, Sparky), each with its own lines and 25 notes in both languages.
- Logging in a few bots at a time, and lighter caches per bot, so 30 bots stay small.
- Each companion has a funny note under its name from the moment it starts.
companionsDISCORD8 changes
Each companion shows a note under its name from the moment it starts
- Each companion shows a note under its name from the moment it starts: 25 funny notes per personality in both languages, rotating every 15 minutes; people in the voice room and focus sessions take over when they happen.
- Seasonal packs: Halloween, Christmas, New Year, Tet, Valentine, in English and Vietnamese.
- Weekly recap on Monday mornings, trivia streaks with milestone shout-outs, voice regular announcements.
- Adaptive tuning of the kinds of conversation per server, and the best hour in
/companions stats. - Optional webhook alerts and a daily backup of the data files.
- Per-server data export and delete, automatic clean-up a day after every companion left a server.
- Ticks never overlap; a test covers 300 servers.
- CI, a multi-architecture image on GitHub Container Registry, issue templates.
companionsDISCORD4 changes
Companions sit in voice rooms 24/7
- Companions sit in voice rooms 24/7: several rooms, bots that keep their room, "join to create" channels, no mute icon.
- Pomodoro focus sessions, greetings in voice, voice time board.
- Welcome messages with an icebreaker, reminders and event countdowns.
- Optional status endpoint, architecture notes, cinematic bilingual website.
companionsDISCORD2 changes
Question of the day, polls, trivia with answer buttons and a weekly board.
- Question of the day, polls, trivia with answer buttons and a weekly board.
/companions stats, custom content, nine personalities, about 1,250 fun facts per language.
companionsDISCORD1 change
Two to ten small bots that chat, joke and share facts, and step back when people talk.
- Two to ten small bots that chat, joke and share facts, and step back when people talk.
aimDISCORD13 changes
Home tab, the first thing a player sees
- Home tab, the first thing a player sees: one line on what the app is, one big Play now button (the last mode played, Gridshot the first time), and three cards: Peek, today's challenge with its countdown, and the quiz. A 5-minute warm-up and the full list of modes are one click away; open duels show as a strip on top. The mode list, rank card and room board moved to a Modes tab.
- The quiz is now hard to the point of nearly impossible, and every question has a clock: · Tiny corner: a sixth of an in-map screenshot, name the map out of twelve. · Where is this?: a whole in-map screenshot, click the spot on the minimap. · Callouts: the callout's name alone (the site only when the name is ambiguous); full marks within 1.5% of the minimap. · Whose ability: the icon only, among eight agents, most of them the same role. · Gun stats: one exact number (damage to head, body or leg at a given range, fire rate, reload, equip time, magazine, price) among four close ones. The in-map screenshots (357, one per callout, 12 maps) come from the Valorant wiki through the server, listed in
src/data/mapshots.jsonbyscripts/build-mapshots.js; the pictures are not stored in the repo. - Your Valorant: with a HenrikDev API key (
HENRIKDEV_KEY), the Career tab shows the player's real account: card, level, current rank with RR and its last change, peak rank, and the last five matches (agent, map, K/D/A, headshot %, score), with a link to tracker.gg. The Riot ID comes from the Riot account linked on Discord (the Activity now asks for the connections scope, and signs in without it if that is refused) or is typed in. Home shows the real rank next to the one earned here. - The first visit asks for the player's Valorant sensitivity; the app uses the game's own scale, so the number carries over as it is.
- 5-minute warm-up: Gridshot, Peek, Tracking and Microshot back to back, each counted as usual, then one summary with the RR each moved.
- Sounds: a bright ring on every hit, a fuller chime on every fifth hit in a row and on each broken Switching target, and a dull thud for a shot into cover in Peek. All synthesized; no game audio.
- Share to channel: the result screen can post a result card (mode, score, accuracy, hits, rank) in the channel the round was played from, once per run.
- Removed: the map art on the range's back wall from 0.11.0; it was a picture of the whole map, not a place in it.
aimDISCORD4 changes
New ranked mode, Peek (Giữ góc)
- New ranked mode, Peek (Giữ góc): heads come out from behind cover (a crate, two door-frame pillars, a stacked crate and a wall edge), hold for 0.45 to 0.9 s and pull back, never from the same corner twice in a row. A shot into the cover is a miss even right next to the head; a hit is worth 60 to 200 points, more the sooner it lands, times accuracy. Faint ticks on the cover mark the corners at head height. The rules are shared with the server's replay like every other mode, and
/bxh,/thachdauand/hosoinclude it (the profile card is now four tiles to a row). - Range backdrop: the back wall of the 3D room can show a competitive Valorant map's art, darkened so targets and cover stand out, chosen at random or picked in Settings (or turned off). The map's name sits next to the mode in the corner. It is one texture drawn once, so frame rate is unchanged.
- Quiz tab with four games of ten questions, not ranked, best scores kept on the device: Callouts (click where a callout is on the real minimap, scored by distance, then see it and the callouts nearby), Name the map (a close-up of its art), Whose ability (an ability's icon and description with the names hidden, pick from four agents) and Which gun (two guns and a question about their stats). A run of right answers earns a bonus. Number keys pick an answer.
- The API passes through maps (with callouts placed on the minimap), agents (role and abilities), weapon stats, and their pictures; map art is shrunk to 1280 px WebP on the server, and only real PNG, JPEG or WebP bytes are decoded.
- New ranked mode, Peek (Giữ góc): heads come out from behind cover (a crate, two door-frame pillars, a stacked crate and a wall edge), hold for 0.45 to 0.9 s and pull back, never from the same corner twice in a row. A shot into the cover is a miss even right next to the head; a hit is worth 60 to 200 points, more the sooner it lands, times accuracy. Faint ticks on the cover mark the corners at head height. The rules are shared with the server's replay like every other mode, and
aimDISCORD8 changes
New look, "Tactical"
- New look, "Tactical": the game dressed as an FPS client. Navy slate panels with cut corners and scope brackets, Chakra Petch (with Vietnamese) in spaced capitals for titles, names and buttons, one teal accent, a faint scanline. The fashion-magazine theme and Playfair Display are gone.
- The result is a dark after-action report instead of a cream page; the 3D room, the lobby backdrop and the reaction screen take the same colours.
- A round is one WebGL canvas: the picture rifles are drawn into it (a texture of at most 1024 px) instead of a separate image layer, and the crosshair is a 96 px canvas in the middle instead of a full-screen one; the points that floated up after a hit are gone. The room is unlit (no fog, no tone mapping) with all its lines in one draw, targets share two materials, shards and bullet holes come from small pools, the 3D rifles use the standard material merged into three meshes, and nothing is allocated per frame. Raw mouse reports are summed and applied once per frame and on each click; the run result and the HUD are updated only when they change; automatic resolution is chosen once during the countdown. The lobby backdrop is display:none during a round, the countdown is plain text, and a late lobby request can no longer leave a timer running in a round.
- Fixed: in the tactical look, the lobby headline in capitals spilled into the side column on wide windows; it now sizes itself to its column.
- Settings has a 3D resolution (automatic, 100%, 75% or 50%) and an FPS readout for rounds, both kept on the device only. Shaders run at medium precision.
- Smoother rounds, with every effect kept outside them: the view turns on pointerrawupdate where the browser has it (mouse movement as soon as it is reported), the crosshair layer is a low-latency canvas redrawn only while something on it changes, the rifle picture is moved only when it moves, and the 3D room renders without multisampling at one pixel per CSS pixel (lower still on its own when frames run long), with Lambert and Phong materials, a reflection map only for the 3D rifles, fewer shards and no per-frame allocations. During a round the scanline and vignette are off and the HUD does not animate; the lobby, wipes, intro and splash are unchanged.
- The default target colour is teal; players still on an earlier default (red or pink) move to it.
- Fixed: with Settings open on the Crosshair tab, Save & close did nothing (the rifle-picture controls of the General tab were wired first and failed there).
aimDISCORD9 changes
Valorant skins for the rifle
- Valorant skins for the rifle: Settings has a picker with every weapon's skins (about 1,400) and their colour variants, with a weapon list and a search box. In a round the chosen skin is its real picture, set at an angle in the lower right, with the same kick, muzzle flash and sway as the game's own rifles.
- The pictures and the catalog come from valorant-api.com through the bot's API (an Activity in Discord may only load from its own origin). The catalog is kept for a day, pictures are cached in memory, and browsers may keep them for a week.
- The default rifle is now a first-person picture of a rifle in hand (assets/viewmodels/default.webp, 99 KB), at 54% of the view's height; the 3D rifles and Valorant skins stay in Settings.
- Held skins: twenty-one first-person renders of a rifle in hand (Champions 2021, Kuronami, Prelude to Chaos, Mystbloom, Magepunk, Blackthorn, Golden Lion, Celestial, Ivory, Arctic, Ember, Golden Crystal, Bone Fang, Junkyard, Violet Spike, Blaze, Frostbite, Desert, Amethyst, Shadow, Stoneheart) in a section of their own in Settings, with picture swatches, drawn like the default at 54% of the view's height. The default is now a sharper render of the same Neptune rifle.
- Settings panels that should start hidden (the Valorant skin picker) no longer show before they are opened.
- Smoother: no live blur behind panels over the moving backdrop or the 3D room, the lobby backdrop draws at 30 frames a second without canvas shadows, the 3D room has fewer lights and lighter target materials and renders at most 1.25 pixels per CSS pixel, and the HUD only rewrites numbers that changed.
- Your own rifle picture: a first-person PNG with a clear background (a skin in hand, the way the game shows it) can be loaded in Settings and is laid over the lower right of the view, sized with a slider (60% by default), kicking when fired and trailing the view. It stays in that browser (IndexedDB) and is never sent to the server.
- A Valorant skin's picture is now held the way the game holds a rifle: muzzle just right of and below the crosshair, stock leaving the lower right corner.
- Large API answers are gzipped when the browser accepts it.
aimDISCORD8 changes
Rounds are played in first person in a 3D room
- Rounds are played in first person in a 3D room. The crosshair stays in the middle and the mouse turns the view, exactly like Valorant: 0.07° per mouse count times the sensitivity, over a 103° horizontal view. Targets are pearls floating in a studio with gridded walls; hits shatter them and misses mark the back wall. Reaction stays a flat screen.
- The rules and the server's replay are unchanged: the targets float on a plane in front of the eye, and the point where the aim ray meets it is what gets scored.
- A rifle in the lower right of the view, an original design: it kicks back when fired, flashes at the muzzle and trails the view as it turns. Seven skins to pick freely in Settings (Ink, Chrome, Pearl, Carbon, Aurora, Gold, Neon glass), or hide it.
- Two new modes: Timing (one target at a time that swells and fades in under a second; early hits are worth more) and Switching (three drifting targets that break after 0.7 s under the crosshair). Nine modes now cover flicking, clicking, tracking, strafing, switching and reaction.
- Season 2: ranks, leaderboards, personal bests, daily streaks and duel records start over. Season 1 runs stay in the database but no longer count. The season shows in the lobby, on profile cards and under /bxh.
- The profile card lays out nine modes five to a row.
- Without a locked pointer, a jump from the pointer leaving the frame and coming back no longer swings the view.
- The 3D code (three.js) is fetched in the background from the lobby, so the first page stays as light as before.
aimDISCORD9 changes
New look, "Cover Issue"
- New look, "Cover Issue": the game is laid out like a fashion magazine. No more red: ink pages, powder pink as the one accent, chrome silver for metal, hairline rules and square corners.
- New display typeface, Playfair Display (with Vietnamese), alongside Inter Tight. Big Shoulders Display is gone.
- Lobby in three columns read left to right: the contents (each mode with its best score), the chosen mode as a two-line cover line with its rank card and the start button, and a side column with today's challenge, open duels and who is in this room. On a phone the contents become a row of mode names that scrolls sideways.
- Career opens with the player's name as a headline; the leaderboard is "the list" with italic places and chrome for the top three.
- The result is printed on cream paper: a huge score, the rank and the stats in ruled columns.
- In game: an after-hours photo studio with crop marks and pink pearl targets. The reaction test turns pink on "go" instead of green, plum while waiting.
- Mouse sensitivity: the pointer is locked during a round (raw input where the browser allows it) and moves the crosshair on Valorant's scale: the same sensitivity (0.01 to 5) and mouse DPI travel as far as in Valorant across its 103° view. The value can be typed in a box next to the slider (up to three decimals, 0.175 or 0,175). It can be switched off; where the frame does not allow a locked pointer (Discord can refuse it) the hidden pointer's movement still steers the crosshair at that sensitivity. Press Esc to leave a locked round.
- The default target colour is now powder pink; players still on the old red default move to it automatically.
- Image cards in chat use the same magazine look and fonts.
aimDISCORD6 changes
New look, "Radianite Night"
- New look, "Radianite Night": deep ink background with slow aurora light and a fine dot field, frosted glass panels with a cut corner, a red signal kept for the main action and a radianite mint for anything live.
- New typefaces: Big Shoulders Display for titles and numbers, Inter Tight for text. The mode title is polished metal that warms to red near the pointer.
- The lobby range has radianite dust, glowing targets with rim light, and stays quieter behind the career and leaderboard pages.
- In game: a night range with a perspective floor and emissive targets.
- Result screen: the rank stands on a lit glass plinth.
- Image cards in chat use the same look and fonts.
aimDISCORD7 changes
New modes
- New modes: Spidershot, Headshot (head-height line, accuracy counts double) and Strafe (ADAD tracking). Their rank thresholds are first estimates and may be tuned.
- Daily challenge: one mode and seed for everyone each day, its own server and global board, day streaks, a featured card in the lobby,
/thuthach, and an optional daily post with yesterday's winner (/caidat kenh-thu-thach). - 1v1 duels:
/thachdau, accept in chat or in the game, same seed for both, the result card is posted when both have played; expires after 24 hours. /hosoand/bxhanswer with image cards (profile with every mode, podium leaderboard); rank icons as the app's own emoji in chat.- Rank roles:
/caidat role-rankcreates a role per tier and keeps each player in the role of their top rank. - Career page: progress chart of the last 30 scores per mode, duel record, daily streak. Leaderboard: today's challenge board. Modes grouped in the lobby.
- Daily and duel runs never count for ranks or the normal boards.
aimDISCORD6 changes
Lobby backdrop is a live training range
- Lobby backdrop is a live training range: perspective floor, sweeping scan line, floating targets you can shoot between rounds.
- The floor and lighting take the colour of your rank in the selected mode and glide when it changes.
- Your own crosshair is the mouse pointer in the lobby.
- Turning ring of text with rank and RR around the large emblems.
- Tab and mode names decode on hover; headline letters lean and heat up near the pointer; section titles ink in from outlines.
- RR gain is stamped onto the result screen.
aimDISCORD6 changes
Official Valorant competitive tier icons for every rank, used under Riot Games' fan…
- Official Valorant competitive tier icons for every rank, used under Riot Games' fan content policy (disclaimer in Settings).
- Opening sequence, slash wipes between tabs, living background, lock-in start button and match splash.
- In game: targets spring in, floating points, hit streak counter, shake on miss, red warning in the last 5 seconds.
- Result ceremony: emblem lands with rays and shockwaves, score and RR count up, the old emblem shatters on promotion, shard burst.
- Career cards tilt with the pointer; leaderboard rows slide in, top rows and Radiant shine.
- Everything falls back to still screens with reduced motion.
aimDISCORD4 changes
Ranks from Iron 1 to Immortal 3 with Rank Rating, and Radiant for the global top 10 at…
- Ranks from Iron 1 to Immortal 3 with Rank Rating, and Radiant for the global top 10 at Immortal 3; rank-up and RR gain on the result screen.
- New interface: lobby with mode select, career page with every mode's rank and the rank ladder, full leaderboard with rank emblems.
- Crosshair editor that reads and writes Valorant-format profile codes, with real-size and zoomed preview; firing error bloom in game.
- Rank names and RR in
/bxhand/hoso.
aimDISCORD6 changes
Aim trainer as a Discord Activity
- Aim trainer as a Discord Activity: Gridshot, Microshot, Tracking and Reaction.
- Server-side replay of every run from a seeded event log; malformed runs rejected, implausible runs flagged and kept off leaderboards.
- Room, server and global leaderboards in the Activity;
/bxh,/hoso,/aim,/trogiup,/caidat kenh-ky-lucin chat. - Per-player crosshair, target color, sound and language settings.
- Vietnamese and English.
- Docker image with health check, daily database backup, self-update script.
bookingDISCORD8 changes
Quiet-hour discounts (/admin cai-dat, "Giảm giá giờ vắng")
Revenue
- Quiet-hour discounts (
/admin cai-dat, "Giảm giá giờ vắng"): a percent off, at most 50, in windows like the peak ones. - Membership plans (
/thanhvien): bought from the wallet, a percent off every booking for a number of days; renewing early adds days. - Every automatic discount, with any coupon, is taken out of the fee only, so a player's share never changes.
- Tips after a session (up to 2.000.000 đ, once per booking, from the wallet): the whole amount goes to the player as a
TIPledger row, payable at once. The ledger table is rebuilt once on upgrade to allow the new kind. - Referral codes (
/gioithieu): both sides get wallet credit after the newcomer's first session worth enough. - Gift cards (
/quatang) between wallets, and player suggestions (/goiy) with the reason for each pick.
Payments
- Bank transfer straight to the owner's account (
/admin nhan-tien,/admin cho-xac-nhan): a VietQR image with the amount and note, an owner confirmation button, late confirmations refunded; also on the web booking page. Used when no gateway has keys.
Trust and safety
- A Verified badge set by staff (
/staff xac-minh), an Emergency button in every room that alerts staff and owners and freezes a running session like a complaint, ratings of customers by players (staff only), and a risk level in/staff xem-khachwith every reason listed.
- Quiet-hour discounts (
bookingDISCORD25 changes
Stripe as a second gateway behind one interface (src/pay/gateway.js), chosen with…
Feature complete; waiting for a first run against a real server and real payment keys (see the README).
Money
- Stripe as a second gateway behind one interface (
src/pay/gateway.js), chosen withPAYMENT_PROVIDER; Stripe refunds are sent back to the card automatically, with an idempotency key per ledger row and order (refundsjob). Money that arrives late through Stripe is refunded the same way. - payOS webhook (signed, only a nudge: the payment is always confirmed from payOS's own answer) and a
cancelPaymentLinkcall. - Prepaid wallet: top-up packages with a bonus, pay a booking from the wallet or by link (never both), refunds of wallet-paid bookings go back into the wallet, owner corrections, wallet credit and bonus cost in the owner's numbers.
- Loyalty points: earned on completed sessions, turned into wallet credit.
/chuyentien: bank details per row, VietQR images with the amount and note filled in, CSV export of the queue, the whole ledger and all bookings. Customers and players save their account with/nganhang.- Discount codes (
/magiamgia): percent or fixed, uses, per person, minimum price, expiry; paid out of the platform fee so the player's share never changes; held by an unpaid booking and given back when it expires or is cancelled. - A price per game and peak-hour surcharges (priced per half hour);
quoteBookingis the one place a price is made. - Duplicate payments, paid extensions that the session can no longer take, and half-paid links are reported for a manual refund instead of being swallowed.
Booking
- Extend a running session from the room (30 minute steps, as far as the player is free, minutes held while the link is open).
- Waiting list with a hold for the first person in line; weekly repeats with one confirmation button three days before each week; book again from the rating thanks and from
/lichcuatoi. /timplayer: filter by game, price, rating, language and "free now"; five sorts; next free slot.- Hours picker with menus (
/lichranh chon:true); photos and a voice sample as links; per-game prices; profile cards with badges, hours and reliability. - Leaderboards (
/bangxephang, a monthly post), badges (top of the month, 50 and 100 hours, punctual, loyal customers). - A session starts the moment the second person joins the voice room (voice event), not at the next tick; the two paths never overlap.
- A player who left the server is found (Unknown Member), paused, and their upcoming bookings are refunded.
People and safety
- Internal notes and a staff card per customer, a flag for customers who keep losing disputes, anonymous reports with a hashed reporter.
- Audit trail of every staff and owner action in the database (
/admin nhat-ky).
Platform
- Web server (optional): owner dashboard with charts, JSON and CSV,
/metrics,/healthz, the payOS webhook; token auth with per-address rate limiting. - Many servers in one bot: a database per server, licenses (
/kichhoat,npm run license), per-server payment keys, private-message buttons that carry their server. - English and Vietnamese: a translation layer on everything a person is sent privately,
/ngonngu, automatic from the Discord app language; a test fails when any Vietnamese is left in the English journeys. - Structured logs,
npm run restore,npm run smoke,npm run check(syntax, unused imports, version), old databases upgraded in place, release workflow that builds a GitHub release from this file.
Changed
OWNER_IDSapply to single-server installs only.- The booking form has two more optional fields (discount code, weekly repeat); the room welcome has an Extend button;
/lichcuatoihas book-again buttons. - The reminder message reads "Nhắc lịch #N, buổi hẹn với X: ..." so it can be translated.
- Payments job: one confirmed payment can buy a booking, an extension or a top-up.
- Stripe as a second gateway behind one interface (
bookingDISCORD12 changes
/setup
/setup: idempotent builder for the roles (Khách, Người chơi, Trusted, Khách quen, Staff), categories and channels, with permission overwrites rewritten on every run, panels edited in place, a role safety check (powerful permissions, hierarchy, bot permissions) and a report in Vietnamese. Nothing is deleted.- Age gate: button, modal with the confirmation phrase,
attest(), Khách role. Rules and guide posted by the bot; the guide shows the live cancellation tiers. - Players: apply modal, staff queue with approve and reject (reason by modal), profile cards edited in place,
/lichranhwith Vietnamese parse errors,/playerfor profile, pause and resume,/thunhap. - Booking:
/datlich, the book button on cards and a menu of players, modal, quote, payOS link, cancel with a refund preview per tier, the payment notifier (confirmation, late payment refund, partial payment alert), private text and voice rooms, ratings by modal (also from DMs),/lichcuatoi. - Scheduler job: reminders, rooms, start on voice presence, no-show with one extra tick, auto end, rating prompt, rating buttons removed, rooms closed; flag actions are marked only after the Discord side worked.
- Disputes: report by modal, ticket with three resolution buttons and a confirmation step (strike or clear strikes), split by modal, rooms kept during a dispute and closed after,
SETTLED_ALREADYleaves the case open. - Staff tools:
/staff(queue, disputes, cancel, strike, lift suspension, blacklist, summary); suspension on the third strike removes the role, marks the card and offers a cancel-upcoming button. - Money:
/chuyentienqueue with a button per row, held payouts apart with a force button behind a second confirmation, every step logged to the owner-only money channel; daily or weekly owner digest;/adminfor settings, backup and recent orders. - Daily jobs: Trusted and Khách quen roles (members fetched one at a time), card and guide refresh, backup.
- Safety: one access gate (blacklist, 18+, permissions) in every handler, rate limits,
sanitizeTexton every user text,allowedMentionson every send, private replies for personal data, role allowlist, no privileged intents. - Stage 1 additions: more channel settings keys, a
kvtable,getLedgerRow, and the payments job now reports a link that closed with only part paid. - 106 new tests with a fake guild, client and interactions.
bookingDISCORD13 changes
Project scaffold
- Project scaffold: ESM, Node 22.13 or newer,
discord.jsanddotenvonly, Dockerfile and compose file with a heartbeat health check, CI for tests and the image build, Raspberry Pi installer and self-update scripts. - Data layer: SQLite tables for settings, players, availability, bookings, ledger, strikes, blacklist, disputes, attestations and orders, created idempotently with CHECK constraints and unique indexes that back the idempotency rules.
- Availability parsing and formatting (
T2 19:00-23:00; CN 09:00-12:00, spelled-out days,19h30), time-zone awareisWithinwith midnight-crossing bookings split at midnight. - Pricing in exact integer dong with a fee rounded to 1,000, and parsing of booking dates and durations typed in a modal.
- Cancellation policy with tiers from settings; player cancellations always refund in full and earn a strike.
- Booking creation rules and the booking state machine as an explicit transition table, with money written in the same transaction as the status change.
- The ledger: exact splits for completed, cancelled, no-show and disputed bookings, payout hold during the review window, idempotent
markPaid, late-payment refunds. - Ratings once per booking inside a window, sanitized reviews, trusted player and regular customer role rules.
- Strikes with automatic suspension, lifting, blacklist.
dueActionsscheduler decision function andmarkActionDone.- payOS client and order handling copied and adapted from the sibling project, with
checkPaymentsthat settles each order exactly once. - Owner summary and player earnings.
docs/design.md: the specification for the Discord layer.
- Project scaffold: ESM, Node 22.13 or newer,
brainDISCORD10 changes
Chatbot
First version.
- Chatbot. Answers when mentioned, replied to, or messaged directly, only in channels an admin allowed. Per-server persona (
/ai nhanvat: name, personality, language, reply length, emoji, five presets). No Message Content intent. - Models. Anthropic Messages API, Google Gemini and any OpenAI-compatible endpoint (Ollama, LM Studio), all through
fetchwith timeouts, retries with backoff on 429/5xx and normalised tool calling. - Memory. Short-term turns per conversation with token-budget trimming and a retention window; long-term facts saved through a
remembertool, viewable and deletable with/ai trinhnho,/quenroifor a full self-service forget, a purge job. - Knowledge base.
/kienthuc them|danhsach|xoawith text from a form, a.txt/.mdattachment or a link; chunked and ranked with BM25 built into the bot; answers say when they do not know. - Safety and cost. Input length cap, cooldown, per-member and per-server rate limits, daily token budgets and plans stored in the database, kill switch (
/ai tat), owner-only/admin, no pings, output split to 2000 characters,/xoadulieu, data wiped when the bot is removed from a server. - Agent. Tool loop with hard caps on steps, tokens, time and tool calls, abort support, progress shown on one edited message, a queue with concurrency limits per server and globally, and a cancel button. Tools:
web_search(Brave, Tavily or SearXNG),fetch_pagewith an SSRF guard and an HTML extractor,calculate, read-onlygithub_readwith a per-server allowlist,remember. - Commands.
/hoi,/research(structured report with sources built from the pages actually read) and/phantich-issue(diagnosis and suggested patch as text only). - Prompt-injection defence. Tool output is delimited, tagged untrusted data; no side-effecting tools beyond the member-scoped
remember; tool calls audited without page content (/ai nhatky). - Operations. SQLite with WAL,
DATA_DIRvolume,/statusroute, heartbeat health check, Docker Compose on a loopback port, Raspberry Pi install and self-update scripts. - 226 tests.
- Chatbot. Answers when mentioned, replied to, or messaged directly, only in channels an admin allowed. Per-server persona (
feedDISCORD11 changes
Sources
First release.
- Sources.
/theodoifollows a YouTube channel (public channel feed; a channel URL, an@handleor aUC...id), a Twitch channel (Helix API, only whenTWITCH_CLIENT_IDandTWITCH_CLIENT_SECRETare set), any RSS 2.0 or Atom feed, or a web page (the visible text is hashed and a short notice is posted when it changes, at most every 15 minutes)./huytheodoi,/danhsach,/thuand/capnhatremove, list, test and edit them: role ping, message template with{title} {url} {author} {source}, keyword include and exclude filters. - No repeats. Every source remembers what it has seen. The first read when a source is added is silent, so the backlog is never posted. A Twitch stream is announced once per stream start.
- Failures. Each source backs off after errors (doubling, at most six hours) and is paused after
MAX_FAILURESfailures in a row, with a notice in the channel./capnhat tieptuc:trueresumes it. - Outgoing queue. All posts leave through a small queue: one message per channel per second, a few per tick, failed sends retried and then dropped.
- GitHub. An HTTP receiver at
POST /github/<token>checksX-Hub-Signature-256with a secret per subscription (constant-time compare). Push (commits collapsed to five lines), pull request, issues, issue comment, CI (workflow run and check suite, green or red), release, deployment status and ping./github ketnoi,ngat,danhsach,sukien. - Deploys and errors.
POST /deploy/<token>announces a deploy from a script.POST /errlog/<token>takes application errors and groups them by a fingerprint of the message and the first stack frame: the first occurrence is posted at once, later ones as a count update at most every 10 minutes, at once when the error returns after a quiet hour or after being marked resolved./webhookcreates and removes the tokens,/errloglists the top groups and resolves one. - Uptime.
/monitor them,xoa,danhsach: an HTTP check every few minutes, DOWN after two failures in a row, UP with the length of the downtime, uptime percentage from the last 24 hours. - Address safety. Every address a user types goes through one guard: http and https only, no credentials, DNS resolved and loopback, private, link-local, CGNAT, multicast, reserved and metadata ranges refused (IPv4, IPv6, IPv4-mapped and decimal, hex or octal spellings), re-checked after every redirect, with a redirect cap, a size cap and a timeout.
- Limits. Free servers get 3 sources, 1 repo and 2 monitors (
FREE_LIMITS)./admin gioihanraises them for one server,/admin xemshows usage. OnlyOWNER_IDSmay use/admin. - Operations.
/statuswith version and uptime, a heartbeat health check, a Docker image and compose file with the receiver on127.0.0.1:8790, anddeploy/piwith an install script and a daily self-update with rollback. - Only the Guilds intent. 154 tests.
- Sources.