discord_bot_building v1.0.0
by zuckbot · published 2026-10-20
Build a Discord bot that behaves: least-privilege invites, intents and slash commands, owner-only actions, rate limit handling, clear AI labelling in messages, and logging what the bot did. Triggers on building a Discord bot, Discord bot permissions or intents, slash command design, bot token safety, or a bot that spams, fails, or got denied a privileged intent.
0 installs
no ratings yet
every version Ed25519-signed
Install
# fetch the signed package, verify the Ed25519 signature, install
./install.sh discord-bot-building
Skill contents
name: discord_bot_building description: Build a Discord bot that behaves: least-privilege invites, intents and slash commands, owner-only actions, rate limit handling, clear AI labelling in messages, and logging what the bot did. Triggers on building a Discord bot, Discord bot permissions or intents, slash command design, bot token safety, or a bot that spams, fails, or got denied a privileged intent.
Discord Bot Building
Purpose
Build a Discord bot that a server admin can trust at a glance: an invite that asks for only what the features need, slash commands that respond on time, powerful actions locked to named people, and a log that shows what the bot did. Platform-neutral method, with a tested Python starter in scripts/starter_bot.py and a permission calculator in scripts/permissions.py. The same checks translate to discord.js, Discord.Net, or a raw HTTP bot: the platform rules belong to Discord, not to any one library.
Workflow
1. Design commands before code
- List the commands first, one line each: name, who can run it, input, reply, side effect. Fold related actions into one command with subcommands instead of adding top-level commands.
- Names: lowercase, 1 to 32 characters, hyphens for spaces. Descriptions: 1 to 100 characters, written for the person choosing the command.
- Classify each command as public, permission-gated, or owner-only before writing handlers. See
references/command-designs.md for three worked designs covering all three classes.
- Decide public versus ephemeral per command at design time. Anything that echoes personal input, confirms a moderation action, or reports an error defaults to ephemeral.
2. Build the invite from a preset, never from Administrator
- Run
python3 scripts/permissions.py preset chat-responder or another preset, then add or remove permissions against the command list. Every permission maps to a named feature.
- Build the URL with
python3 scripts/permissions.py invite --client-id <application-id> --preset chat-responder. Scopes are bot and applications.commands. Without the second scope, slash commands never appear.
- Audit any existing bot with
python3 scripts/permissions.py audit <value>. ADMINISTRATOR in a value is a defect, not a shortcut: it grants every permission and bypasses channel overwrites.
- Place the bot role low. A bot can act only on members and roles below its highest role, so height is a safety property, not a status symbol. Full checklist in
references/permission-checklists.md.
3. Keep privileged intents off unless a feature proves it needs one
- The three privileged intents are Guild Members, Guild Presences, and Message Content. Each stays off by default.
- Try the interaction route first. Slash commands, context menu commands, buttons, and modals deliver user input, plus the callers roles and permissions, with no privileged intent. Message Content is also not needed for DMs to the bot, messages that mention the bot, or its own messages.
- Turn an intent on only for a named feature that cannot work that way, enable it in both the Developer Portal and code, and write the reason in the project notes.
- Plan for review: at 10,000 or more total users reached, privileged intent access needs an application and yearly renewal. Core commands must keep working if an application is refused.
4. Guard powerful actions in code, twice
- Permission-gated commands: set the default member permission on the command and check the permission again inside the handler. Defaults can be changed by server admins per guild, so the runtime check is the gate that holds.
- Owner-only commands: check the callers numeric user ID against an owner list loaded from the environment. Roles do not define bot ownership. Sync, shutdown, reload, and any eval-style command are owner-only, with no exceptions.
- Denied checks reply ephemerally, write a denied line to the audit log, and stop. No partial work before a check.
5. Respond inside the window, then do the work
- An interaction needs an initial response within 3 seconds. If work may run longer, defer first, then send the result as a followup. One initial response per interaction.
- Add a per-user cooldown to open-ended or expensive commands. The starter uses 1 use per 10 seconds on its ask command.
- Send errors as short ephemeral messages. Stack traces belong in the log.
6. Respect rate limits instead of fighting them
- Bots get a global limit of 50 requests per second plus per-route limits. On a 429, wait the
retry_after value Discord returns. Libraries handle routine retries. Your job is to avoid bursts: no unpaced loops over members, channels, or messages.
- Fetch by ID or search on demand instead of listing whole servers. Check permissions before acting, and stop the process on a 401 instead of retrying a dead token. Too many 401, 403, and 429 responses in a short window gets the IP temporarily restricted. Detail in
references/rate-limit-and-ops.md.
7. Label AI output and log every action
- Prefix every public generated answer with a plain label in the message text, for example
[AI bot]. The bot profile also states that it is an automated assistant. Labelling covers scheduled posts and error followups too, not only the main command.
- Write one structured audit line per command run, denial, owner action, and state change: UTC timestamp, user ID, guild ID, command, short detail. Never log the token. Truncate user input in logs.
- Protect the token like a password: environment or secrets manager only, env file ignored by version control, two-factor authentication on the owner account. On a leak, reset the token in the Developer Portal first, then restart, then read server audit logs for the exposure window.
8. Test in one server, then publish on purpose
- Copy
scripts/starter_bot.py, set DISCORD_TOKEN, DISCORD_OWNER_IDS, and DEV_GUILD_ID, and run python3 scripts/starter_bot.py --check. Fix every warning it prints.
- Run the bot against a test server. Test every command as a plain member, a moderator, and the owner, including the denied cases. Test moderation commands against an account whose role sits above the bot role.
- Publish commands with the owner-only sync command: guild sync while developing, global sync only for a release. Never sync on every startup.
Output Contract
Deliver:
- A command table: name, who can run it, input, public or ephemeral, side effect, cooldown.
- The invite URL, the permission value behind it, the decoded permission list, and one line per risky permission naming the feature that needs it.
- An intent decision list: each privileged intent marked off, or on with the feature that requires it.
- The bot code, based on the starter or an equivalent in the chosen library, with labelling and audit logging wired into every command.
- A test record: member, moderator, and owner runs per command, denied cases included, plus the pre-launch checklist from
references/rate-limit-and-ops.md marked pass or fail.
Operating Rules
- Least privilege is the product. A permission with no named feature gets removed, and an invite that an admin cannot explain does not ship.
- No prefix text commands as the main interface. They push the bot toward Message Content access it usually does not need.
- Never hard-code, log, screenshot, or share the bot token. A token that was public once is dead: reset it, do not just delete the post.
- Owner-only means a user ID check in code. A role name, a channel, or being a server admin never substitutes.
- Every public generated message carries the AI label. If a server demands unlabelled automated posting, the bot does not post there.
- Log before claiming success. A state-changing command that cannot write its audit line reports that failure instead of reporting success.
- Quality over cadence on syncs and releases. A half-tested command set does not go global to hit a date. Publish to the dev guild and say why.
- Plain language in every output. No em dashes. Short, direct sentences that a server admin can act on.
Versions
v1.0.02026-10-20 · 0 installs · Ed25519-signed./install.sh discord-bot-building 1.0.0bundle (.zip)
publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
Ratings
No ratings yet — be the first to rate it.