> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wednesdayai.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Discord

> Connect a Discord bot to WednesdayAI: bot setup, server allowlists, native commands, and voice.

# Discord

WednesdayAI connects to Discord via the Discord Bot API. Setup requires creating a Discord application, adding a bot to your server, and configuring the bot token.

## Quick setup

**1. Create a Discord application and bot:**

1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)
2. Click **New Application** → give it a name
3. In the sidebar, click **Bot** → **Add Bot**
4. Copy the bot token (click **Reset Token** to reveal it)

**2. Enable required intents:**

In the Bot page, scroll to **Privileged Gateway Intents** and enable:

* **Message Content Intent** (`MESSAGE_CONTENT`) — required for reading message content
* **Server Members Intent** — recommended for user lookup

<Note>
  The Server Members intent also requires opting in via config: `channels.discord.intents.guildMembers: true`. Without this, the gateway does not request the GuildMembers intent even when enabled in the Portal.
</Note>

Also ensure these standard (non-privileged) intents are active:

* `GUILD_MESSAGE_REACTIONS` — required for reaction-based interactions

<Warning>MESSAGE\_CONTENT is a privileged intent. It must be enabled in the Discord Developer Portal for bots in 100+ servers.</Warning>

**3. Generate an invite URL and add the bot to your server:**

1. Go to **OAuth2 → URL Generator**
2. Scopes: `bot`, `applications.commands`
3. Bot Permissions: View Channels, Send Messages, Read Message History, Embed Links, Attach Files, Add Reactions
4. Copy the URL and open it in your browser to add the bot

**4. Configure the bot token:**

```bash theme={"dark"}
# Set token securely via CLI (avoids putting it in the config file in plaintext)
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
```

Or in `~/.openclaw/openclaw.json`:

```json5 theme={"dark"}
{
  channels: {
    discord: {
      enabled: true,
      token: "YOUR_BOT_TOKEN",   // or DISCORD_BOT_TOKEN env var
      dmPolicy: "pairing",
    },
  },
}
```

**5. Configure server allowlist and start gateway:**

```json5 theme={"dark"}
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        "YOUR_SERVER_ID": {
          requireMention: true,
          users: ["YOUR_USER_ID"],
        },
      },
    },
  },
}
```

Get your server ID: **Server Settings → right-click server icon → Copy Server ID** (requires Developer Mode: User Settings → Advanced → Developer Mode).

```bash theme={"dark"}
openclaw gateway run
openclaw pairing list discord
openclaw pairing approve discord <CODE>
```

## Access control

### DM policy

```json5 theme={"dark"}
{
  channels: {
    discord: {
      dmPolicy: "pairing",     // pairing | allowlist | open | disabled
      allowFrom: ["user:987654321098765432"],  // Discord user IDs with user: prefix
    },
  },
}
```

Use `user:<id>` or `<@id>` format. Unquoted numeric literals are rejected by schema validation — IDs must be JSON strings. Bare quoted strings (`"987654321098765432"`) are accepted, but the `user:` prefix is preferred for clarity.

### Server (guild) policy

```json5 theme={"dark"}
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        "123456789012345678": {
          requireMention: true,                          // bot must be @mentioned
          users: ["987654321098765432"],                 // allowed user IDs
          roles: ["111222333444555666"],                 // allowed role IDs
          channels: {                                   // optional channel allowlist
            "555666777888999000": { allow: true },
            "111222333444000999": { allow: true, requireMention: false },
          },
        },
      },
    },
  },
}
```

`requireMention: false` lets the bot respond to all messages in allowed channels without needing an @mention.

## Native slash commands

```json5 theme={"dark"}
{
  commands: {
    native: "auto",   // enables native commands for Discord and Telegram
  },
}
```

Discord slash commands register at startup. If you change `native: false`, the gateway clears previously registered commands on next startup.

Default slash command behavior: responses are ephemeral (only visible to the invoking user). Configure per command if needed.

## Live streaming

```json5 theme={"dark"}
{
  channels: {
    discord: {
      streaming: "partial",   // off | partial | block | progress
    },
  },
}
```

`partial` edits a single message in-place as tokens arrive. `off` disables streaming — bot shows typing then sends the complete response.

## Thread support

```yaml theme={"dark"}
channels:
  discord:
    threadBindings:
      enabled: true
      idleHours: 24
      maxAgeHours: 0
      spawnSubagentSessions: false
      spawnAcpSessions: false
```

| Key                                    | Type    | Default | Description                                            |
| -------------------------------------- | ------- | ------- | ------------------------------------------------------ |
| `threadBindings.enabled`               | boolean | `true`  | Participate in threads                                 |
| `threadBindings.idleHours`             | integer | `24`    | Hours of inactivity before a thread is considered idle |
| `threadBindings.maxAgeHours`           | integer | `0`     | Maximum thread age in hours (0 = disabled by default)  |
| `threadBindings.spawnSubagentSessions` | boolean | `false` | Spawn a subagent session per thread                    |
| `threadBindings.spawnAcpSessions`      | boolean | `false` | Spawn an ACP session per thread                        |

## Delivery settings

| Key              | Type    | Default    | Description                                                                  |
| ---------------- | ------- | ---------- | ---------------------------------------------------------------------------- |
| `textChunkLimit` | integer | `2000`     | Maximum characters per outbound chunk (Discord's per-message limit is 2000)  |
| `chunkMode`      | string  | `"length"` | `length` splits at character count; `newline` splits at paragraph boundaries |

```json5 theme={"dark"}
{ channels: { discord: { textChunkLimit: 2000, chunkMode: "length" } } }
```

## Voice channels

Requires:

* Native commands enabled (`commands.native: "auto"`)
* Bot permissions: Connect, Speak in voice channels

```json5 theme={"dark"}
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        autoJoin: [{ guildId: "123...", channelId: "456..." }],
        tts: { enabled: true },
        daveEncryption: true,              // enable DAVE E2E voice encryption (default: true)
        decryptionFailureTolerance: 24,    // hours before treating decryption failures as an error (default: 24)
      },
    },
  },
}
```

<Warning>
  If you see `DecryptionFailed(UnencryptedWhenPassthroughDisabled)` errors in logs, this is a known upstream Discord/DAVE bug triggered when clients that don't support DAVE encryption join the channel. If voice becomes unusable, set `daveEncryption: false` as a workaround. `decryptionFailureTolerance` (default 24 hours) controls how long transient failures are tolerated before being treated as a hard error.
</Warning>

Users join voice channels via `/vc join` (Discord native command only).

## Forum channels

The bot can post to Discord forum channels. Send a message to the forum parent channel ID — the bot automatically creates a thread:

```bash theme={"dark"}
openclaw message send --channel discord --target "channel:<forumId>" --message "Title\n\nBody"
```

Or via the `message thread create` tool action in an agent.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Bot not receiving messages / 'Missing Access'">
    1. Verify **Message Content Intent** is enabled in the Developer Portal
    2. Verify the bot has "View Channels" and "Read Message History" permissions in the server
    3. Restart the gateway after enabling intents
  </Accordion>

  <Accordion title="Guild messages blocked despite requireMention: false">
    Check the `groupPolicy` — if it is `"allowlist"`, the guild must be in `guilds` map AND the sender must be in `users` or have an allowed `roles` entry. `requireMention: false` only removes the mention requirement; allowlist enforcement is separate.
  </Accordion>

  <Accordion title="Slash commands not appearing in Discord">
    Commands can take up to 1 hour to propagate globally. For testing, use guild-specific command registration (contact maintainer for config). Check `openclaw logs --follow | grep "discord.*command"` for registration errors.
  </Accordion>

  <Accordion title="Long-running handlers time out">
    Discord has a 3-second timeout on interaction acknowledgment. For slow tools, increase the event queue timeout:

    ```json5 theme={"dark"}
    { channels: { discord: { accounts: { default: { eventQueue: { listenerTimeout: 300000 } } } } } }
    ```

    The default is already 120 000 ms — use a value higher than that, e.g., 300 000 ms (5 min).
  </Accordion>
</AccordionGroup>

## Related

* [Gateway configuration — Discord](/reference/config#discord)
* [Channel troubleshooting](/admin/troubleshooting)
