2025-12-15 10:11:18 -06:00
---
summary: "Discord bot support status, capabilities, and configuration"
read_when:
- Working on Discord surface features
---
# Discord (Bot API)
Updated: 2025-12-07
Status: ready for DM and guild text channels via the official Discord bot gateway.
## Goals
- Talk to Clawdis via Discord DMs or guild channels.
2026-01-02 11:15:52 +01:00
- Share the same `main` session used by WhatsApp/Telegram/WebChat; guild channels stay isolated as `discord:group:<channelId>` (display names use `discord:<guildSlug>#<channelSlug>` ).
- Group DMs are ignored by default; enable via `discord.dm.groupEnabled` and optionally restrict by `discord.dm.groupChannels` .
2025-12-15 10:11:18 -06:00
- Keep routing deterministic: replies always go back to the surface they arrived on.
## How it works
1. Create a Discord application → Bot, enable the intents you need (DMs + guild messages + message content), and grab the bot token.
2. Invite the bot to your server with the permissions required to read/send messages where you want to use it.
3. Configure Clawdis with `DISCORD_BOT_TOKEN` (or `discord.token` in `~/.clawdis/clawdis.json` ).
2026-01-02 11:41:08 +00:00
4. Run the gateway; it auto-starts the Discord provider only when a `discord` config section exists **and** the token is set (unless `discord.enabled = false` ).
- If you prefer env vars, still add `discord: { enabled: true }` to `~/.clawdis/clawdis.json` and set `DISCORD_BOT_TOKEN` .
2025-12-15 10:11:18 -06:00
5. Direct chats: use `user:<id>` (or a `<@id>` mention) when delivering; all turns land in the shared `main` session.
2026-01-02 11:15:52 +01:00
6. Guild channels: use `channel:<channelId>` for delivery. Mentions are required by default and can be set per guild or per channel.
7. Optional DM control: set `discord.dm.enabled = false` to ignore all DMs, or `discord.dm.allowFrom` to allow specific users (ids or names). Use `discord.dm.groupEnabled` + `discord.dm.groupChannels` to allow group DMs.
8. Optional guild rules: set `discord.guilds` keyed by guild id (preferred) or slug, with per-channel rules.
2026-01-02 00:11:03 -06:00
9. Optional slash commands: enable `discord.slashCommand` to accept user-installed app commands (ephemeral replies). Slash invocations respect the same DM/guild allowlists.
10. Optional guild context history: set `discord.historyLimit` (default 20) to include the last N guild messages as context when replying to a mention. Set `0` to disable.
2026-01-02 17:47:09 -06:00
11. Reactions: the agent can trigger reactions via the `discord` tool (gated by `discord.actions.*` ).
2026-01-03 12:33:42 +01:00
- The `discord` tool is only exposed when the current surface is Discord.
2026-01-02 15:21:13 -06:00
12. Slash commands use isolated session keys (`${sessionPrefix}:${userId}` ) rather than the shared `main` session.
2025-12-15 10:11:18 -06:00
Note: Discord does not provide a simple username → id lookup without extra guild context, so prefer ids or `<@id>` mentions for DM delivery targets.
2026-01-02 11:15:52 +01:00
Note: Slugs are lowercase with spaces replaced by `-` . Channel names are slugged without the leading `#` .
2026-01-02 11:32:59 +01:00
Note: Guild context `[from:]` lines include `author.tag` + `id` to make ping-ready replies easy.
2025-12-15 10:11:18 -06:00
## Capabilities & limits
- DMs and guild text channels (threads are treated as separate channels; voice not supported).
- Typing indicators sent best-effort; message chunking honors Discord’ s 2k character limit.
- File uploads supported up to the configured `discord.mediaMaxMb` (default 8 MB).
- Mention-gated guild replies by default to avoid noisy bots.
2026-01-02 15:21:13 -06:00
- Reply context is injected when a message references another message (quoted content + ids).
2026-01-02 23:18:41 +01:00
- Native reply threading is **off by default** ; enable with `discord.replyToMode` and reply tags.
2025-12-15 10:11:18 -06:00
## Config
```json5
{
discord: {
2025-12-26 16:54:53 +00:00
enabled: true,
2025-12-15 10:11:18 -06:00
token: "abc.123",
2026-01-01 23:58:35 +01:00
mediaMaxMb: 8,
2026-01-02 17:41:47 -06:00
actions: {
reactions: true,
stickers: true,
polls: true,
permissions: true,
messages: true,
threads: true,
pins: true,
search: true,
memberInfo: true,
roleInfo: true,
roles: false,
channelInfo: true,
voiceStatus: true,
events: true,
moderation: false
},
2026-01-02 23:18:41 +01:00
replyToMode: "off",
2026-01-02 00:11:03 -06:00
slashCommand: {
enabled: true,
name: "clawd",
sessionPrefix: "discord:slash",
ephemeral: true
},
2026-01-02 10:32:21 +01:00
dm: {
enabled: true,
2026-01-02 11:15:52 +01:00
allowFrom: ["123456789012345678", "steipete"],
groupEnabled: false,
groupChannels: ["clawd-dm"]
2026-01-02 10:32:21 +01:00
},
2026-01-02 11:15:52 +01:00
guilds: {
2026-01-02 22:33:26 +01:00
"*": { requireMention: true },
2026-01-02 11:15:52 +01:00
"123456789012345678": {
slug: "friends-of-clawd",
requireMention: false,
2026-01-03 18:48:10 +00:00
reactionNotifications: "own",
2026-01-02 11:15:52 +01:00
users: ["987654321098765432", "steipete"],
channels: {
general: { allow: true },
help: { allow: true, requireMention: true }
}
}
2026-01-02 10:32:21 +01:00
}
2025-12-15 10:11:18 -06:00
}
}
```
2026-01-02 10:32:21 +01:00
- `dm.enabled` : set `false` to ignore all DMs (default `true` ).
- `dm.allowFrom` : DM allowlist (user ids or names). Omit or set to `["*"]` to allow any DM sender.
2026-01-02 11:15:52 +01:00
- `dm.groupEnabled` : enable group DMs (default `false` ).
- `dm.groupChannels` : optional allowlist for group DM channel ids or slugs.
- `guilds` : per-guild rules keyed by guild id (preferred) or slug.
2026-01-02 22:33:26 +01:00
- `guilds."*"` : default per-guild settings applied when no explicit entry exists.
2026-01-02 11:15:52 +01:00
- `guilds.<id>.slug` : optional friendly slug used for display names.
- `guilds.<id>.users` : optional per-guild user allowlist (ids or names).
- `guilds.<id>.channels` : channel rules (keys are channel slugs or ids).
- `guilds.<id>.requireMention` : per-guild mention requirement (overridable per channel).
2026-01-03 12:29:39 -06:00
- `guilds.<id>.reactionNotifications` : reaction system event mode (`off` , `own` , `all` , `allowlist` ).
2026-01-02 00:11:03 -06:00
- `slashCommand` : optional config for user-installed slash commands (ephemeral responses).
2025-12-15 10:11:18 -06:00
- `mediaMaxMb` : clamp inbound media saved to disk.
2026-01-02 11:15:52 +01:00
- `historyLimit` : number of recent guild messages to include as context when replying to a mention (default 20, `0` disables).
2026-01-02 17:41:47 -06:00
- `actions` : per-action tool gates; omit to allow all (set `false` to disable).
- `reactions` (covers react + read reactions)
- `stickers` , `polls` , `permissions` , `messages` , `threads` , `pins` , `search`
- `memberInfo` , `roleInfo` , `channelInfo` , `voiceStatus` , `events`
- `roles` (role add/remove, default `false` )
- `moderation` (timeout/kick/ban, default `false` )
2026-01-03 12:31:50 -06:00
Reaction notifications use `guilds.<id>.reactionNotifications` :
- `off` : no reaction events.
2026-01-03 18:48:10 +00:00
- `own` : reactions on the bot's own messages (default).
2026-01-03 12:31:50 -06:00
- `all` : all reactions on all messages.
2026-01-03 18:48:10 +00:00
- `allowlist` : reactions from `guilds.<id>.users` on all messages (empty list disables).
2026-01-03 12:29:39 -06:00
2026-01-02 17:41:47 -06:00
### Tool action defaults
| Action group | Default | Notes |
| --- | --- | --- |
| reactions | enabled | React + list reactions + emojiList |
| stickers | enabled | Send stickers |
| polls | enabled | Create polls |
| permissions | enabled | Channel permission snapshot |
| messages | enabled | Read/send/edit/delete |
| threads | enabled | Create/list/reply |
| pins | enabled | Pin/unpin/list |
| search | enabled | Message search (preview spec) |
| memberInfo | enabled | Member info |
| roleInfo | enabled | Role list |
| channelInfo | enabled | Channel info + list |
| voiceStatus | enabled | Voice state lookup |
| events | enabled | List/create scheduled events |
| roles | disabled | Role add/remove |
| moderation | disabled | Timeout/kick/ban |
2026-01-02 23:18:41 +01:00
- `replyToMode` : `off` (default), `first` , or `all` . Applies only when the model includes a reply tag.
## Reply tags
To request a threaded reply, the model can include one tag in its output:
- `[[reply_to_current]]` — reply to the triggering Discord message.
- `[[reply_to:<id>]]` — reply to a specific message id from context/history.
Current message ids are appended to prompts as `[message_id: …]` ; history entries already include ids.
Behavior is controlled by `discord.replyToMode` :
- `off` : ignore tags.
- `first` : only the first outbound chunk/attachment is a reply.
- `all` : every outbound chunk/attachment is a reply.
2026-01-02 00:29:32 +01:00
2026-01-02 15:21:13 -06:00
Allowlist matching notes:
- `allowFrom` /`users` /`groupChannels` accept ids, names, tags, or mentions like `<@id>` .
- Prefixes like `discord:` /`user:` (users) and `channel:` (group DMs) are supported.
- Use `*` to allow any sender/channel.
- When `guilds.<id>.channels` is present, channels not listed are denied by default.
2026-01-02 00:11:03 -06:00
Slash command notes:
- Register a chat input command in Discord with at least one string option (e.g., `prompt` ).
- The first non-empty string option is treated as the prompt.
- Slash commands honor the same allowlists as DMs/guild messages (`discord.dm.allowFrom` , `discord.guilds` , per-channel rules).
- Clawdis will auto-register `/clawd` (or the configured name) if it doesn't already exist.
2026-01-02 17:41:47 -06:00
## Tool actions
The agent can call `discord` with actions like:
- `react` / `reactions` (add or list reactions)
- `sticker` , `poll` , `permissions`
- `readMessages` , `sendMessage` , `editMessage` , `deleteMessage`
- `threadCreate` , `threadList` , `threadReply`
- `pinMessage` , `unpinMessage` , `listPins`
- `searchMessages` , `memberInfo` , `roleInfo` , `roleAdd` , `roleRemove` , `emojiList`
- `channelInfo` , `channelList` , `voiceStatus` , `eventList` , `eventCreate`
- `timeout` , `kick` , `ban`
2026-01-02 00:29:32 +01:00
Discord message ids are surfaced in the injected context (`[discord message id: …]` and history lines) so the agent can target them.
2026-01-02 15:21:13 -06:00
Emoji can be unicode (e.g., `✅` ) or custom emoji syntax like `<:party_blob:1234567890>` .
2025-12-15 10:11:18 -06:00
## Safety & ops
- Treat the bot token like a password; prefer the `DISCORD_BOT_TOKEN` env var on supervised hosts or lock down the config file permissions.
- Only grant the bot permissions it needs (typically Read/Send Messages).
- If the bot is stuck or rate limited, restart the gateway (`clawdis gateway --force` ) after confirming no other processes own the Discord session.