Discord (Bot API)
Status: ready for DMs and guild channels via the official Discord gateway.Pairing
Slash commands
Channel troubleshooting
Quick setup
You will need to create a new application with a bot, add the bot to your server, and pair it to OpenClaw. We recommend adding your bot to your own private server. If you don’t have one yet, create one first (choose Create My Own > For me and my friends).Create a Discord application and bot
Enable privileged intents
- Message Content Intent (required)
- Server Members Intent (recommended; required for role allowlists and name-to-ID matching)
- Presence Intent (optional; only needed for presence updates)
Copy your bot token
Generate an invite URL and add the bot to your server
botapplications.commands
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (optional)
Enable Developer Mode and collect your IDs
- Click User Settings (gear icon next to your avatar) → Advanced → toggle on Developer Mode
- Right-click your server icon in the sidebar → Copy Server ID
- Right-click your own avatar → Copy User ID
Allow DMs from server members
Step 0: Set your bot token securely (do not send it in chat)
openclaw gateway restart instead.Configure OpenClaw and pair
- Ask your agent
- CLI / config
“I already set my Discord bot token in config. Please finish Discord setup with User ID<user_id>and Server ID<server_id>.”
Approve first DM pairing
- Ask your agent
- CLI
“Approve this Discord pairing code: <CODE>”
DISCORD_BOT_TOKEN is only used for the default account.Recommended: Set up a guild workspace
Once DMs are working, you can set up your Discord server as a full workspace where each channel gets its own agent session with its own context. This is recommended for private servers where it’s just you and your bot.Add your server to the guild allowlist
- Ask your agent
- Config
“Add my Discord Server ID <server_id> to the guild allowlist”
Allow responses without @mention
- Ask your agent
- Config
“Allow my agent to respond on this server without having to be @mentioned”
#coding, #home, #research, or whatever fits your workflow.
Runtime model
- Gateway owns the Discord connection.
- Reply routing is deterministic: Discord inbound replies back to Discord.
- By default (
session.dmScope=main), direct chats share the agent main session (agent:main:main). - Guild channels are isolated session keys (
agent:<agentId>:discord:channel:<channelId>). - Group DMs are ignored by default (
channels.discord.dm.groupEnabled=false). - Native slash commands run in isolated command sessions (
agent:<agentId>:discord:slash:<userId>), while still carryingCommandTargetSessionKeyto the routed conversation session.
Interactive components
OpenClaw supports Discord components v2 containers for agent messages. Use the message tool with acomponents payload. Interaction results are routed back to the agent as normal inbound messages and follow the existing Discord replyToMode settings.
Supported blocks:
text,section,separator,actions,media-gallery,file- Action rows allow up to 5 buttons or a single select menu
- Select types:
string,user,role,mentionable,channel
components.reusable=true to allow buttons, selects, and forms to be used multiple times until they expire.
To restrict who can click a button, set allowedUsers on that button (Discord user IDs, tags, or *). When configured, unmatched users receive an ephemeral denial.
File attachments:
fileblocks must point to an attachment reference (attachment://<filename>)- Provide the attachment via
media/path/filePath(single file); usemedia-galleryfor multiple files - Use
filenameto override the upload name when it should match the attachment reference
- Add
components.modalwith up to 5 fields - Field types:
text,checkbox,radio,select,role-select,user-select - OpenClaw adds a trigger button automatically
Access control and routing
- DM policy
- Guild policy
- Mentions and group DMs
channels.discord.dmPolicy controls DM access (legacy: channels.discord.dm.policy):pairing(default)allowlistopen(requireschannels.discord.allowFromto include"*"; legacy:channels.discord.dm.allowFrom)disabled
pairing mode).DM target format for delivery:user:<id><@id>mention
Role-based agent routing
Usebindings[].match.roles to route Discord guild members to different agents by role ID. Role-based bindings accept role IDs only and are evaluated after peer or parent-peer bindings and before guild-only bindings. If a binding also sets other match fields (for example peer + guildId + roles), all configured fields must match.
Developer Portal setup
Create app and bot
Create app and bot
- Discord Developer Portal -> Applications -> New Application
- Bot -> Add Bot
- Copy bot token
Privileged intents
Privileged intents
- Message Content Intent
- Server Members Intent (recommended)
setPresence) does not require enabling presence updates for members.OAuth scopes and baseline permissions
OAuth scopes and baseline permissions
- scopes:
bot,applications.commands
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (optional)
Administrator unless explicitly needed.Copy IDs
Copy IDs
- server ID
- channel ID
- user ID
Native commands and command auth
commands.nativedefaults to"auto"and is enabled for Discord.- Per-channel override:
channels.discord.commands.native. commands.native=falseexplicitly clears previously registered Discord native commands.- Native command auth uses the same Discord allowlists/policies as normal message handling.
- Commands may still be visible in Discord UI for users who are not authorized; execution still enforces OpenClaw auth and returns “not authorized”.
Feature details
Reply tags and native replies
Reply tags and native replies
History, context, and thread behavior
History, context, and thread behavior
channels.discord.historyLimitdefault20- fallback:
messages.groupChat.historyLimit 0disables
channels.discord.dmHistoryLimitchannels.discord.dms["<user_id>"].historyLimit
- Discord threads are routed as channel sessions
- parent thread metadata can be used for parent-session linkage
- thread config inherits parent channel config unless a thread-specific entry exists
Reaction notifications
Reaction notifications
offown(default)allallowlist(usesguilds.<id>.users)
Ack reactions
Ack reactions
ackReaction sends an acknowledgement emoji while OpenClaw is processing an inbound message.Resolution order:channels.discord.accounts.<accountId>.ackReactionchannels.discord.ackReactionmessages.ackReaction- agent identity emoji fallback (
agents.list[].identity.emoji, else ”👀”)
- Discord accepts unicode emoji or custom emoji names.
- Use
""to disable the reaction for a channel or account.
Config writes
Config writes
/config set|unset flows (when command features are enabled).Disable:Gateway proxy
Gateway proxy
channels.discord.proxy.PluralKit support
PluralKit support
- allowlists can use
pk:<memberId> - member display names are matched by name/slug
- lookups use original message ID and are time-window constrained
- if lookup fails, proxied messages are treated as bot messages and dropped unless
allowBots=true
Presence configuration
Presence configuration
- 0: Playing
- 1: Streaming (requires
activityUrl) - 2: Listening
- 3: Watching
- 4: Custom (uses the activity text as the status state; emoji is optional)
- 5: Competing
Exec approvals in Discord
Exec approvals in Discord
channels.discord.execApprovals.enabledchannels.discord.execApprovals.approverschannels.discord.execApprovals.target(dm|channel|both, default:dm)agentFilter,sessionFilter,cleanupAfterResolve
target is channel or both, the approval prompt is visible in the channel. Only configured approvers can use the buttons; other users receive an ephemeral denial. Approval prompts include the command text, so only enable channel delivery in trusted channels. If the channel ID cannot be derived from the session key, OpenClaw falls back to DM delivery.If approvals fail with unknown approval IDs, verify approver list and feature enablement.Related docs: Exec approvalsTools and action gates
Discord message actions include messaging, channel admin, moderation, presence, and metadata actions. Core examples:- messaging:
sendMessage,readMessages,editMessage,deleteMessage,threadReply - reactions:
react,reactions,emojiList - moderation:
timeout,kick,ban - presence:
setPresence
channels.discord.actions.*.
Default gate behavior:
| Action group | Default |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | enabled |
| roles | disabled |
| moderation | disabled |
| presence | disabled |
Components v2 UI
OpenClaw uses Discord components v2 for exec approvals and cross-context markers. Discord message actions can also acceptcomponents for custom UI (advanced; requires Carbon component instances), while legacy embeds remain available but are not recommended.
channels.discord.ui.components.accentColorsets the accent color used by Discord component containers (hex).- Set per account with
channels.discord.accounts.<id>.ui.components.accentColor. embedsare ignored when components v2 are present.
Voice messages
Discord voice messages show a waveform preview and require OGG/Opus audio plus metadata. OpenClaw generates the waveform automatically, but it needsffmpeg and ffprobe available on the gateway host to inspect and convert audio files.
Requirements and constraints:
- Provide a local file path (URLs are rejected).
- Omit text content (Discord does not allow text + voice message in the same payload).
- Any audio format is accepted; OpenClaw converts to OGG/Opus when needed.
Troubleshooting
Used disallowed intents or bot sees no guild messages
Used disallowed intents or bot sees no guild messages
- enable Message Content Intent
- enable Server Members Intent when you depend on user/member resolution
- restart gateway after changing intents
Guild messages blocked unexpectedly
Guild messages blocked unexpectedly
- verify
groupPolicy - verify guild allowlist under
channels.discord.guilds - if guild
channelsmap exists, only listed channels are allowed - verify
requireMentionbehavior and mention patterns
Require mention false but still blocked
Require mention false but still blocked
groupPolicy="allowlist"without matching guild/channel allowlistrequireMentionconfigured in the wrong place (must be underchannels.discord.guildsor channel entry)- sender blocked by guild/channel
usersallowlist
Permissions audit mismatches
Permissions audit mismatches
channels status --probe permission checks only work for numeric channel IDs.If you use slug keys, runtime matching can still work, but probe cannot fully verify permissions.DM and pairing issues
DM and pairing issues
- DM disabled:
channels.discord.dm.enabled=false - DM policy disabled:
channels.discord.dmPolicy="disabled"(legacy:channels.discord.dm.policy) - awaiting pairing approval in
pairingmode
Bot to bot loops
Bot to bot loops
channels.discord.allowBots=true, use strict mention and allowlist rules to avoid loop behavior.Configuration reference pointers
Primary reference: High-signal Discord fields:- startup/auth:
enabled,token,accounts.*,allowBots - policy:
groupPolicy,dm.*,guilds.*,guilds.*.channels.* - command:
commands.native,commands.useAccessGroups,configWrites - reply/history:
replyToMode,historyLimit,dmHistoryLimit,dms.*.historyLimit - delivery:
textChunkLimit,chunkMode,maxLinesPerMessage - media/retry:
mediaMaxMb,retry - actions:
actions.* - presence:
activity,status,activityType,activityUrl - UI:
ui.components.accentColor - features:
pluralkit,execApprovals,intents,agentComponents,heartbeat,responsePrefix
Safety and operations
- Treat bot tokens as secrets (
DISCORD_BOT_TOKENpreferred in supervised environments). - Grant least-privilege Discord permissions.
- If command deploy/state is stale, restart gateway and re-check with
openclaw channels status --probe.