OpenClawSkills
GitHub
Channels β€’ TutorialHeader.readTime

Discord

Discord bot support status, capabilities, and configuration.

Status: Available for DMs and server (guild) text channels, based on official Discord bot gateway.

Tutorial.step

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:

Json5
{
  channels: {
    discord: {
      enabled: true,
      token: "YOUR_BOT_TOKEN",
    },
  },
}
Tutorial.step

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.

Tutorial.step

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.

Tutorial.step

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:

Json5
{
  channels: { discord: { configWrites: false } },
}
Tutorial.step

How to Create Your Own Bot (Developer Portal)

This is a typical configuration workflow for using OpenClaw in server channels (like <code>#help</code>).

#

Tutorial.step

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>)

#

Tutorial.step

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.

#

Tutorial.step

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.

#

Tutorial.step

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>

#

Tutorial.step

5) Configure OpenClaw

##

Tutorial.step

Token

Recommended to use environment variable on server:

- <code>DISCORD_BOT_TOKEN=...</code>

Or config file:

Json5
{
  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>'.

##

Tutorial.step

Allowlist + Routing

Example: "Only in one server, only allow me, only allow #help":

Json5
{
  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.

#

Tutorial.step

6) Verify

1. Start gateway.

2. Send in server channel: <code>@YourBot hello</code>.

3. If no response, see troubleshooting below.

#

Tutorial.step

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.