Discord
Discord bot support status, capabilities, and configuration.
Status: Available for DMs and server (guild) text channels, based on official Discord bot gateway.
Quick Setup
1. Create a Discord bot and copy the bot token.
2. Enable <strong>Message Content Intent</strong> in the Discord Developer Portal (if you want to use allowlist or nickname resolution, also enable <strong>Server Members Intent</strong>).
3. Configure the token for OpenClaw:
- Environment variable: <code>DISCORD_BOT_TOKEN=...</code>
- Or config: <code>channels.discord.token: "..."</code>.
- When both are set, config takes precedence (env is only a fallback for the default account).
4. Invite the bot to your server and grant read/write message permissions (if you only want to use DMs, you can also create a private server for testing).
5. Start the Gateway.
6. DMs default to pairing: first contact sends a pairing code, messages are only processed after approval.
Minimum configuration:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}Goals
- Chat with OpenClaw via Discord DMs or server channels.
- DMs default to folding into the agent's main session (default '<code>'agent:main:main'</code>'); server channels are isolated to '<code>'agent:'<agentId>':discord:channel:'<channelId>''</code>' (display name uses '<code>'discord:'<guildSlug>'#'<channelSlug>''</code>').
- Group DMs are ignored by default; enable with <code>channels.discord.dm.groupEnabled</code> and further restrict with <code>channels.discord.dm.groupChannels</code>.
- Maintain deterministic routing: replies always go back to the source channel.
How It Works
1. Create Discord Application β Bot, enable required intents (DMs/server messages/message content), get bot token.
2. Invite the bot to your server and grant it read/send message permissions in target channels.
3. Configure <code>channels.discord.token</code> in OpenClaw (or use <code>DISCORD_BOT_TOKEN</code> as fallback).
4. Start Gateway: when token is available and <code>channels.discord.enabled</code> is not <code>false</code>, the Discord channel starts automatically.
- Using env only works too: set <code>DISCORD_BOT_TOKEN</code> (no need to write config block).
5. DM delivery target uses '<code>'user:'<id>''</code>' (or '<code>''<@id>''</code>' mention). Bare numeric IDs are ambiguous and will be rejected.
6. Server channel delivery uses '<code>'channel:'<channelId>''</code>'. Mentions are required by default, configurable per guild or channel.
7. DMs default to security gatekeeper: '<code>'channels.discord.dm.policy'</code>' (default '<code>'"pairing"'</code>'). Unknown senders get a pairing code (1 hour expiry), approve with: '<code>'openclaw pairing approve discord '<code>''</code>'.
- To allow anyone to DM: <code>channels.discord.dm.policy="open"</code> and <code>channels.discord.dm.allowFrom=["*"]</code>.
- For strict allowlist: <code>channels.discord.dm.policy="allowlist"</code> and list allowed senders in <code>channels.discord.dm.allowFrom</code>.
- To completely ignore DMs: <code>channels.discord.dm.enabled=false</code> or <code>channels.discord.dm.policy="disabled"</code>.
8. Group DMs are ignored by default; enable with <code>channels.discord.dm.groupEnabled</code>.
9. Optional: use <code>channels.discord.guilds</code> (prioritized by guild id) to configure server rules and channel rules.
10. Optional: native commands. <code>commands.native</code> defaults to <code>"auto"</code> (Discord/Telegram default on, Slack default off). Override with <code>channels.discord.commands.native: true|false|"auto"</code>; <code>false</code> clears registered commands. Text commands are controlled by <code>commands.text</code> and must be sent as separate <code>/...</code> messages. <code>commands.useAccessGroups: false</code> bypasses command access-group checks.
- Command list and configuration: '<a href="/tools/slash-commands">'/tools/slash-commands'</a>'
11. Optional: server channel context. <code>channels.discord.historyLimit</code> (default 20, fallback to <code>messages.groupChat.historyLimit</code>) injects the last N messages as context when the bot is mentioned; set to <code>0</code> to disable.
12. Reactions: agents can trigger via '<code>'discord'</code>' tool (controlled by '<code>'channels.discord.actions.*'</code>' switches). See '<a href="/tools/reactions">'/tools/reactions'</a>' for reaction cancellation semantics.
13. Native commands use isolated session key: '<code>'agent:'<agentId>':discord:slash:'<userId>''</code>' (doesn't write to shared '<code>'main'</code>' session).
Additional notes:
- Nickname/username β id resolution depends on guild member search, requires <strong>Server Members Intent</strong>; if member search fails, use id or <code><@id></code> mention directly.
- slug: all lowercase, spaces replaced with <code>-</code>; channel name slug doesn't include <code>#</code>.
- Group message <code>[from:]</code> line includes <code>author.tag</code> + <code>id</code> for easy pinging.
Config Writes
By default, Discord is allowed to write updates triggered by <code>/config set|unset</code> back to the config file (requires <code>commands.config: true</code>).
To disable:
{
channels: { discord: { configWrites: false } },
}How to Create Your Own Bot (Developer Portal)
This is a typical configuration workflow for using OpenClaw in server channels (like <code>#help</code>).
#
1) Create App + Bot User
1. Discord Developer Portal β <strong>Applications</strong> β <strong>New Application</strong>
2. In your application:
- <strong>Bot</strong> β <strong>Add Bot</strong>
- Copy <strong>Bot Token</strong> (for <code>DISCORD_BOT_TOKEN</code>)
#
2) Enable Required Intents
Discord's "privileged intents" must be explicitly enabled:
Enable in <strong>Bot</strong> β <strong>Privileged Gateway Intents</strong>:
- <strong>Message Content Intent</strong> (required; otherwise you'll see "Used disallowed intents", or bot connects but doesn't process messages)
- <strong>Server Members Intent</strong> (recommended; for member/user lookup and allowlist matching)
<strong>Presence Intent</strong> is generally not needed.
#
3) Generate Invite Link (OAuth2 URL Generator)
In the application: <strong>OAuth2</strong> β <strong>URL Generator</strong>
<strong>Scopes</strong>
- β <code>bot</code>
- β <code>applications.commands</code> (required for native commands)
<strong>Bot Permissions (minimum recommended)</strong>
- β View Channels
- β Send Messages
- β Read Message History
- β Embed Links
- β Attach Files
- β Add Reactions (optional but recommended)
- β Use External Emojis / Stickers (optional)
Unless you're debugging and fully trust the bot, don't select <strong>Administrator</strong>.
Copy the generated URL, open it, and select a server to complete installation.
#
4) Get IDs (guild/user/channel)
Discord uses numeric IDs extensively; OpenClaw configuration also recommends using IDs:
1. Discord (desktop/Web) β <strong>User Settings</strong> β <strong>Advanced</strong> β Enable <strong>Developer Mode</strong>
2. Right-click to copy:
- Server name β <strong>Copy Server ID</strong>
- Channel β <strong>Copy Channel ID</strong>
- User β <strong>Copy User ID</strong>
#
5) Configure OpenClaw
##
Token
Recommended to use environment variable on server:
- <code>DISCORD_BOT_TOKEN=...</code>
Or config file:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}Multiple accounts: use '<code>'channels.discord.accounts'</code>' to configure each account's token (optional '<code>'name'</code>'). See shared structure at '<a href="/gateway/configuration#telegramaccounts--discordaccounts--slackaccounts--signalaccounts--imessageaccounts">'/gateway/configuration'</a>'.
##
Allowlist + Routing
Example: "Only in one server, only allow me, only allow #help":
{
channels: {
discord: {
enabled: true,
dm: { enabled: false },
guilds: {
YOUR_GUILD_ID: {
users: ["YOUR_USER_ID"],
requireMention: true,
channels: {
help: { allow: true, requireMention: true },
},
},
},
retry: {
attempts: 3,
minDelayMs: 500,
maxDelayMs: 30000,
jitter: 0.1,
},
},
},
}Explanation:
- <code>requireMention: true</code> means reply only when mentioned (recommended for shared channels to avoid noise).
- <code>agents.list[].groupChat.mentionPatterns</code> (or <code>messages.groupChat.mentionPatterns</code>) are also treated as mentions.
- If <code>channels</code> exists, unlisted channels are denied by default.
- Threads inherit parent channel configuration (allowlist, requireMention, skills, prompts, etc.) unless you explicitly add the thread's channel id to the config.
- Bot-sent messages are ignored by default; set <code>channels.discord.allowBots=true</code> to allow (but still filters own messages).
- If allowing replies to other bots (<code>allowBots=true</code>), use <code>requireMention</code>, user allowlist, and clear prompts to prevent bot-to-bot loops.
#
6) Verify
1. Start gateway.
2. Send in server channel: <code>@YourBot hello</code>.
3. If no response, see troubleshooting below.
#
Troubleshooting
- First run <code>openclaw doctor</code> and <code>openclaw channels status --probe</code>.
- <strong>"Used disallowed intents"</strong>: Enable <strong>Message Content Intent</strong> (and usually <strong>Server Members Intent</strong>) in Developer Portal, then restart gateway.
- <strong>Connects but doesn't reply in server channels</strong>:
- Missing Message Content Intent, or
- Bot lacks channel permissions (View/Send/Read History), or
- Config requires mention but you didn't @, or
- Allowlist denied the channel/user.
- <strong><code>requireMention: false</code> still doesn't reply</strong>:
- <code>channels.discord.groupPolicy</code> defaults to <strong>allowlist</strong>; set it to <code>"open"</code>, or configure allowed guild/channel in <code>channels.discord.guilds</code>.
- If you only set <code>DISCORD_BOT_TOKEN</code> without creating <code>channels.discord</code> config block, runtime default <code>groupPolicy</code> is <code>open</code>. Once you explicitly configure <code>channels.discord.groupPolicy</code>/<code>channels.defaults.groupPolicy</code> or guild/channel allowlist, it gets tightened.
- <code>requireMention</code> must be placed under <code>channels.discord.guilds</code> (or specific channel); top-level <code>channels.discord.requireMention</code> is ignored.