Discord (Bot API)

状态:已就绪,支持通过官方 Discord Gateway 进行私信和服务器频道通信。

快速设置

你需要创建一个带有 Bot 的应用,将 Bot 添加到服务器,然后与 OpenClaw 配对。建议将 Bot 添加到自己的私人服务器。如果你还没有,请先创建一个(选择 Create My Own > For me and my friends)。

步骤 1:创建 Discord 应用和 Bot

前往 [Discord Developer Portal](https://discord.com/developers/applications),点击 **New Application**。为其命名,例如 "OpenClaw"。

在侧栏点击 **Bot**。将 **Username** 设置为你 OpenClaw Agent 的名称。

步骤 2:启用特权意图

仍在 **Bot** 页面,向下滚动到 **Privileged Gateway Intents**,启用:

- **Message Content Intent**(必需)
- **Server Members Intent**(推荐;角色白名单和名称到 ID 匹配所需)
- **Presence Intent**(可选;仅在需要在线状态更新时启用)

步骤 3:复制 Bot Token

在 **Bot** 页面向上滚动,点击 **Reset Token**。

> **注意:** 尽管名称是 "Reset",但这实际上是生成你的第一个 Token——并不会"重置"什么。

复制 Token 并保存。这就是你的 **Bot Token**,稍后需要用到。

步骤 4:生成邀请 URL 并将 Bot 添加到服务器

在侧栏点击 **OAuth2**。你将生成一个带有正确权限的邀请 URL,用于将 Bot 添加到服务器。

向下滚动到 **OAuth2 URL Generator**,勾选:

- `bot`
- `applications.commands`

下方会出现 **Bot Permissions** 部分。勾选:

- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(可选)

复制底部生成的 URL,粘贴到浏览器中,选择你的服务器,点击 **Continue** 进行连接。你现在应该能在 Discord 服务器中看到你的 Bot。

步骤 5:启用开发者模式并收集 ID

回到 Discord 应用,你需要启用开发者模式来复制内部 ID。

1. 点击 **User Settings**(头像旁边的齿轮图标) → **Advanced** → 开启 **Developer Mode**
2. 右键点击侧栏中的**服务器图标** → **Copy Server ID**
3. 右键点击**自己的头像** → **Copy User ID**

将你的 **Server ID** 和 **User ID** 与 Bot Token 一起保存——在下一步中会全部用到。

步骤 6:允许服务器成员发私信

为了使配对正常工作,Discord 需要允许 Bot 给你发私信。右键点击**服务器图标** → **Privacy Settings** → 开启 **Direct Messages**。

这允许服务器成员(包括 Bot)向你发送私信。如果你要使用 Discord 私信与 OpenClaw 互动,请保持此选项开启。如果你只打算使用服务器频道,可以在配对后关闭私信。

步骤 7:安全设置 Bot Token(不要在聊天中发送)

Discord Bot Token 是机密信息(类似密码)。在给 Agent 发消息之前,请在运行 OpenClaw 的机器上设置它。
openclaw config set channels.discord.token '"YOUR_BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
openclaw gateway
如果 OpenClaw 已作为后台服务运行,请改用 `openclaw gateway restart`。

步骤 8:配置 OpenClaw 并配对

  #### 让 Agent 帮你配置
    在任何已有频道(如 Telegram)上与 OpenClaw Agent 对话并告诉它。如果 Discord 是你的第一个频道,请使用 CLI / 配置方式。

    > "我已在配置中设置了 Discord Bot Token。请用 User ID `<user_id>` 和 Server ID `<server_id>` 完成 Discord 设置。"

  #### CLI / 配置
    如果你偏好基于文件的配置,设置如下:
{
  channels: {
    discord: {
      enabled: true,
      token: "YOUR_BOT_TOKEN",
    },
  },
}
    默认账户的环境变量备选:
DISCORD_BOT_TOKEN=...
    `channels.discord.token` 也支持 SecretRef 值(env/file/exec provider)。参见[密钥管理](/docs/gateway/secrets)。

步骤 9:批准首次私信配对

等 Gateway 运行后,在 Discord 中私信你的 Bot。它会回复一个配对码。


  #### 让 Agent 帮你批准
    将配对码发送到你已有频道上的 Agent:

    > "批准这个 Discord 配对码:`<CODE>`"

  #### CLI
openclaw pairing list discord
openclaw pairing approve discord <CODE>
配对码在 1 小时后过期。

你现在应该可以通过 Discord 私信与 Agent 聊天了。

注意: Token 解析具有账户感知能力。配置中的 Token 值优先于环境变量。DISCORD_BOT_TOKEN 仅用于默认账户。 对于高级出站调用(消息工具/频道操作),会使用该调用专用的 token。账户策略/重试设置仍来自活动运行时快照中的所选账户。

推荐:设置服务器工作区

私信正常工作后,你可以将 Discord 服务器设置为完整的工作区,每个频道都有自己独立的 Agent 会话和上下文。这对于只有你和 Bot 的私人服务器尤其推荐。

步骤 1:将服务器添加到服务器白名单

这将使你的 Agent 能在服务器的任何频道中回复,而不仅限于私信。


  #### 让 Agent 帮你配置
    > "将我的 Discord Server ID `<server_id>` 添加到服务器白名单"

  #### 配置
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: true,
          users: ["YOUR_USER_ID"],
        },
      },
    },
  },
}

步骤 2:允许无需 @提及即可回复

默认情况下,Agent 只在被 @提及时才会在服务器频道中回复。对于私人服务器,你可能希望它回复每条消息。


  #### 让 Agent 帮你配置
    > "允许我的 Agent 在此服务器上无需 @提及即可回复"

  #### 配置
    在服务器配置中设置 `requireMention: false`:
{
  channels: {
    discord: {
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: false,
        },
      },
    },
  },
}

步骤 3:规划服务器频道中的记忆

默认情况下,长期记忆(MEMORY.md)仅在私信会话中加载。服务器频道不会自动加载 MEMORY.md。


  #### 让 Agent 帮你配置
    > "当我在 Discord 频道中提问时,如果需要 MEMORY.md 中的长期上下文,请使用 memory_search 或 memory_get。"

  #### 手动配置
    如果你需要在每个频道中都有共享上下文,请将稳定的指令放在 `AGENTS.md` 或 `USER.md` 中(它们会在每个会话中注入)。将长期笔记保存在 `MEMORY.md` 中,按需使用 memory 工具访问。

现在在 Discord 服务器上创建一些频道并开始聊天。你的 Agent 能看到频道名称,每个频道都有自己隔离的会话——因此你可以设置 #coding#home#research 或任何适合你工作流的频道。

运行时模型

  • Gateway 拥有 Discord 连接。
  • 回复路由是确定性的:Discord 入站消息回复到 Discord。
  • 默认情况下(session.dmScope=main),私信共享 Agent 主会话(agent:main:main)。
  • 服务器频道使用隔离的会话键(agent:<agentId>:discord:channel:<channelId>)。
  • 群组私信默认被忽略(channels.discord.dm.groupEnabled=false)。
  • 原生斜杠命令运行在隔离的命令会话中(agent:<agentId>:discord:slash:<userId>),同时仍携带 CommandTargetSessionKey 到路由的对话会话。

论坛频道

Discord 论坛和媒体频道只接受帖子。OpenClaw 支持两种创建方式:

  • 向论坛父级(channel:<forumId>)发送消息以自动创建帖子。帖子标题使用消息的第一行非空文本。
  • 使用 openclaw message thread create 直接创建帖子。论坛频道不需要传 --message-id

示例:向论坛父级发送消息以创建帖子

openclaw message send --channel discord --target channel:<forumId> \
  --message "Topic title\nBody of the post"

示例:显式创建论坛帖子

openclaw message thread create --channel discord --target channel:<forumId> \
  --thread-name "Topic title" --message "Body of the post"

论坛父级不接受 Discord 组件。如果需要组件,请发送到帖子本身(channel:<threadId>)。

交互式组件

OpenClaw 支持在 Agent 消息中使用 Discord components v2 容器。使用消息工具并传入 components payload。交互结果会作为普通入站消息路由回 Agent,并遵循现有的 Discord replyToMode 设置。

支持的区块:

  • textsectionseparatoractionsmedia-galleryfile
  • 操作行最多允许 5 个按钮或一个选择菜单
  • 选择类型:stringuserrolementionablechannel

默认情况下,组件为一次性使用。设置 components.reusable=true 允许按钮、选择器和表单在过期前多次使用。

要限制谁可以点击按钮,请在按钮上设置 allowedUsers(Discord 用户 ID、标签或 *)。配置后,不匹配的用户会收到临时拒绝提示。

/model/models 斜杠命令会打开一个交互式模型选择器,包含提供商和模型下拉菜单以及提交步骤。选择器回复是临时的,仅调用者可使用。

文件附件:

  • file 区块必须指向附件引用(attachment://<filename>
  • 通过 media/path/filePath 提供附件(单文件);多文件使用 media-gallery
  • 使用 filename 覆盖上传名称以匹配附件引用

模态表单:

  • 添加 components.modal,最多 5 个字段
  • 字段类型:textcheckboxradioselectrole-selectuser-select
  • OpenClaw 自动添加触发按钮

示例:

{
  channel: "discord",
  action: "send",
  to: "channel:123456789012345678",
  message: "Optional fallback text",
  components: {
    reusable: true,
    text: "Choose a path",
    blocks: [
      {
        type: "actions",
        buttons: [
          {
            label: "Approve",
            style: "success",
            allowedUsers: ["123456789012345678"],
          },
          { label: "Decline", style: "danger" },
        ],
      },
      {
        type: "actions",
        select: {
          type: "string",
          placeholder: "Pick an option",
          options: [
            { label: "Option A", value: "a" },
            { label: "Option B", value: "b" },
          ],
        },
      },
    ],
    modal: {
      title: "Details",
      triggerLabel: "Open form",
      fields: [
        { type: "text", label: "Requester" },
        {
          type: "select",
          label: "Priority",
          options: [
            { label: "Low", value: "low" },
            { label: "High", value: "high" },
          ],
        },
      ],
    },
  },
}

访问控制与路由

私信策略

`channels.discord.dmPolicy` 控制私信访问(旧版:`channels.discord.dm.policy`):

- `pairing`(默认)
- `allowlist`
- `open`(需要 `channels.discord.allowFrom` 包含 `"*"`;旧版:`channels.discord.dm.allowFrom`)
- `disabled`

非开放模式下,未知用户会被阻止(或在 `pairing` 模式下提示配对)。

多账户优先级:

- `channels.discord.accounts.default.allowFrom` 仅适用于 `default` 账户。
- 命名账户在其自身 `allowFrom` 未设置时继承 `channels.discord.allowFrom`。
- 命名账户不继承 `channels.discord.accounts.default.allowFrom`。

私信投递目标格式:

- `user:<id>`
- `<@id>` 提及

纯数字 ID 存在歧义,除非提供了明确的 user/channel 目标类型,否则会被拒绝。

服务器策略

服务器处理由 `channels.discord.groupPolicy` 控制:

- `open`
- `allowlist`
- `disabled`

当 `channels.discord` 存在时,安全基线为 `allowlist`。

`allowlist` 行为:

- 服务器必须匹配 `channels.discord.guilds`(推荐使用 `id`,也接受 slug)
- 可选的发送者白名单:`users`(推荐使用稳定 ID)和 `roles`(仅限角色 ID);如果配置了任一项,发送者匹配 `users` 或 `roles` 即可通过
- 直接名称/标签匹配默认禁用;仅在紧急兼容模式下启用 `channels.discord.dangerouslyAllowNameMatching: true`
- `users` 支持名称/标签,但 ID 更安全;`openclaw security audit` 会在使用名称/标签条目时发出警告
- 如果服务器配置了 `channels`,未列出的频道会被拒绝
- 如果服务器没有 `channels` 区块,该白名单服务器中的所有频道都被允许

示例:
{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        "123456789012345678": {
          requireMention: true,
          ignoreOtherMentions: true,
          users: ["987654321098765432"],
          roles: ["123456789012345678"],
          channels: {
            general: { allow: true },
            help: { allow: true, requireMention: true },
          },
        },
      },
    },
  },
}
如果你只设置了 `DISCORD_BOT_TOKEN` 而没有创建 `channels.discord` 区块,运行时回退为 `groupPolicy="allowlist"`(日志中有警告),即使 `channels.defaults.groupPolicy` 是 `open`。

提及和群组私信

服务器消息默认需要提及。

提及检测包括:

- 显式的 Bot 提及
- 配置的提及模式(`agents.list[].groupChat.mentionPatterns`,备选 `messages.groupChat.mentionPatterns`)
- 支持的场景下的隐式回复 Bot 行为

`requireMention` 在服务器/频道级别配置(`channels.discord.guilds...`)。
`ignoreOtherMentions` 可选地丢弃提及了其他用户/角色但未提及 Bot 的消息(不包括 @everyone/@here)。

群组私信:

- 默认:忽略(`dm.groupEnabled=false`)
- 可选白名单:`dm.groupChannels`(频道 ID 或 slug)

基于角色的 Agent 路由

使用 bindings[].match.roles 按角色 ID 将 Discord 服务器成员路由到不同的 Agent。基于角色的 binding 仅接受角色 ID,在对等方或父对等方 binding 之后、仅服务器 binding 之前进行评估。如果 binding 同时设置了其他匹配字段(例如 peer + guildId + roles),所有配置的字段都必须匹配。

{
  bindings: [
    {
      agentId: "opus",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
        roles: ["111111111111111111"],
      },
    },
    {
      agentId: "sonnet",
      match: {
        channel: "discord",
        guildId: "123456789012345678",
      },
    },
  ],
}

Developer Portal 设置

创建应用和 Bot
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
3. 复制 Bot Token
特权意图
在 **Bot -> Privileged Gateway Intents** 中启用:

- Message Content Intent
- Server Members Intent(推荐)

Presence Intent 是可选的,仅在你需要接收成员在线状态更新时才需要。设置 Bot 在线状态(`setPresence`)不需要启用成员在线状态更新。
OAuth 范围和基本权限
OAuth URL 生成器:

- scopes:`bot`、`applications.commands`

典型的基本权限:

- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions(可选)

除非明确需要,否则避免使用 `Administrator`。
复制 ID
启用 Discord 开发者模式,然后复制:

- 服务器 ID
- 频道 ID
- 用户 ID

在 OpenClaw 配置中优先使用数字 ID,以确保审计和探测的可靠性。

原生命令和命令授权

  • commands.native 默认为 "auto",对 Discord 已启用。
  • 按频道覆盖:channels.discord.commands.native
  • commands.native=false 会显式清除之前注册的 Discord 原生命令。
  • 原生命令授权使用与普通消息处理相同的 Discord 白名单/策略。
  • 未授权用户在 Discord UI 中仍可能看到命令;执行时仍会强制执行 OpenClaw 授权并返回”未授权”。

参见斜杠命令了解命令目录和行为。

默认斜杠命令设置:

  • ephemeral: true

功能详情

回复标签和原生回复
Discord 支持 Agent 输出中的回复标签:

- `[[reply_to_current]]`
- `[[reply_to:<id>]]`

由 `channels.discord.replyToMode` 控制:

- `off`(默认)
- `first`
- `all`

注意:`off` 会禁用隐式回复线程。显式的 `[[reply_to_*]]` 标签仍然有效。

消息 ID 在上下文/历史中暴露,Agent 可以定位特定消息。
实时流式预览
OpenClaw 可以通过发送临时消息并随文本到达而编辑它来流式传输回复草稿。

- `channels.discord.streaming` 控制预览流式传输(`off` | `partial` | `block` | `progress`,默认:`off`)。
- `progress` 为跨频道一致性而接受,在 Discord 上映射为 `partial`。
- `channels.discord.streamMode` 是旧版别名,会自动迁移。
- `partial` 在 Token 到达时编辑单条预览消息。
- `block` 发送草稿大小的区块(使用 `draftChunk` 调整大小和断点)。

示例:
{
  channels: {
    discord: {
      streaming: "partial",
    },
  },
}
`block` 模式分块默认值(受 `channels.discord.textChunkLimit` 约束):
{
  channels: {
    discord: {
      streaming: "block",
      draftChunk: {
        minChars: 200,
        maxChars: 800,
        breakPreference: "paragraph",
      },
    },
  },
}
预览流式传输仅支持文本;媒体回复回退到正常投递。

注意:预览流式传输与分块流式传输是独立的。当 Discord 显式启用分块流式传输时,OpenClaw 会跳过预览流式传输以避免重复。
历史、上下文和线程行为
服务器历史上下文:

- `channels.discord.historyLimit` 默认 `20`
- 备选:`messages.groupChat.historyLimit`
- `0` 禁用

私信历史控制:

- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`

线程行为:

- Discord 线程作为频道会话路由
- 父线程元数据可用于父会话关联
- 线程配置继承父频道配置,除非存在线程特定条目

频道主题作为**不受信任**的上下文注入(而非系统提示)。
子 Agent 的线程绑定会话
Discord 可以将线程绑定到会话目标,使该线程中的后续消息继续路由到同一会话(包括子 Agent 会话)。

命令:

- `/focus <target>` 将当前/新线程绑定到子 Agent/会话目标
- `/unfocus` 移除当前线程绑定
- `/agents` 显示活跃的运行和绑定状态
- `/session idle <duration|off>` 查看/更新聚焦绑定的空闲自动解除时间
- `/session max-age <duration|off>` 查看/更新聚焦绑定的硬性最大生命周期

配置:
{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
      maxAgeHours: 0,
    },
  },
  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        idleHours: 24,
        maxAgeHours: 0,
        spawnSubagentSessions: false, // 需主动开启
      },
    },
  },
}
说明:

- `session.threadBindings.*` 设置全局默认值。
- `channels.discord.threadBindings.*` 覆盖 Discord 行为。
- `spawnSubagentSessions` 必须为 true 才能为 `sessions_spawn({ thread: true })` 自动创建/绑定线程。
- `spawnAcpSessions` 必须为 true 才能为 ACP(`/acp spawn ... --thread ...` 或 `sessions_spawn({ runtime: "acp", thread: true })`)自动创建/绑定线程。
- 如果账户禁用了线程绑定,`/focus` 及相关线程绑定操作不可用。

参见[子 Agent](/docs/tools/subagents)、[ACP Agent](/docs/tools/acp-agents) 和[配置参考](/docs/gateway/configuration-reference)。
持久化 ACP 频道绑定
对于稳定的 "始终在线" ACP 工作区,配置顶层类型化 ACP 绑定以定位 Discord 对话。

配置路径:

- `bindings[]`,`type: "acp"` 且 `match.channel: "discord"`

示例:
{
  agents: {
    list: [
      {
        id: "codex",
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/workspace/openclaw",
          },
        },
      },
    ],
  },
  bindings: [
    {
      type: "acp",
      agentId: "codex",
      match: {
        channel: "discord",
        accountId: "default",
        peer: { kind: "channel", id: "222222222222222222" },
      },
      acp: { label: "codex-main" },
    },
  ],
  channels: {
    discord: {
      guilds: {
        "111111111111111111": {
          channels: {
            "222222222222222222": {
              requireMention: false,
            },
          },
        },
      },
    },
  },
}
说明:

- 线程消息可以继承父频道的 ACP 绑定。
- 在已绑定的频道或线程中,`/new` 和 `/reset` 会就地重置同一 ACP 会话。
- 临时线程绑定仍然有效,可以在活跃期间覆盖目标解析。

参见 [ACP Agent](/docs/tools/acp-agents) 了解绑定行为详情。
表情回应通知
按服务器的回应通知模式:

- `off`
- `own`(默认)
- `all`
- `allowlist`(使用 `guilds.<id>.users`)

回应事件会转换为系统事件并附加到路由的 Discord 会话中。
确认回应
`ackReaction` 在 OpenClaw 处理入站消息时发送确认 emoji。

解析顺序:

- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- Agent 身份 emoji 备选(`agents.list[].identity.emoji`,否则 "👀")

说明:

- Discord 接受 unicode emoji 或自定义 emoji 名称。
- 使用 `""` 禁用特定频道或账户的回应。
配置写入
频道触发的配置写入默认启用。

这影响 `/config set|unset` 流程(当命令功能已启用时)。

禁用:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
Gateway 代理
通过 `channels.discord.proxy` 将 Discord Gateway WebSocket 流量和启动时的 REST 查询(应用 ID + 白名单解析)路由到 HTTP(S) 代理。
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
按账户覆盖:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
PluralKit 支持
启用 PluralKit 解析以将代理消息映射到系统成员身份:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // 可选;私有系统需要
      },
    },
  },
}
说明:

- 白名单可以使用 `pk:<memberId>`
- 成员显示名称仅在 `channels.discord.dangerouslyAllowNameMatching: true` 时通过名称/slug 匹配
- 查询使用原始消息 ID 且受时间窗口约束
- 如果查询失败,代理消息被视为 Bot 消息并丢弃,除非 `allowBots=true`
在线状态配置
当你设置状态或活动字段或启用自动在线状态时,在线状态更新会被应用。

仅设置状态示例:
{
  channels: {
    discord: {
      status: "idle",
    },
  },
}
活动示例(自定义状态是默认活动类型):
{
  channels: {
    discord: {
      activity: "Focus time",
      activityType: 4,
    },
  },
}
直播示例:
{
  channels: {
    discord: {
      activity: "Live coding",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
活动类型映射:

- 0: Playing
- 1: Streaming(需要 `activityUrl`)
- 2: Listening
- 3: Watching
- 4: Custom(使用活动文本作为状态;emoji 可选)
- 5: Competing

自动在线状态示例(运行时健康信号):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "token exhausted",
      },
    },
  },
}
自动在线状态将运行时可用性映射到 Discord 状态:healthy => online,degraded 或 unknown => idle,exhausted 或 unavailable => dnd。可选文本覆盖:

- `autoPresence.healthyText`
- `autoPresence.degradedText`
- `autoPresence.exhaustedText`(支持 `{reason}` 占位符)
Discord 中的执行审批
Discord 支持在私信中基于按钮的执行审批,也可选择在源频道中发布审批提示。

配置路径:

- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers`
- `channels.discord.execApprovals.target`(`dm` | `channel` | `both`,默认:`dm`)
- `agentFilter`、`sessionFilter`、`cleanupAfterResolve`

当 `target` 为 `channel` 或 `both` 时,审批提示在频道中可见。只有配置的审批者可以使用按钮;其他用户会收到临时拒绝。审批提示包含命令文本,因此仅在可信频道中启用频道投递。如果无法从会话键推导频道 ID,OpenClaw 会回退到私信投递。

此处理器的 Gateway 认证使用与其他 Gateway 客户端相同的共享凭据解析约定:

- 环境变量优先的本地认证(`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD` 然后 `gateway.auth.*`)
- 本地模式下,`gateway.remote.*` 仅在 `gateway.auth.*` 未设置时可用作备选;配置但未解析的本地 SecretRef 会安全失败
- 适用时通过 `gateway.remote.*` 支持远程模式
- URL 覆盖具有覆盖安全性:CLI 覆盖不会复用隐式凭据,环境覆盖仅使用环境凭据

如果审批因未知审批 ID 而失败,请验证审批者列表和功能启用状态。

相关文档:[执行审批](/docs/tools/exec-approvals)

工具和操作门控

Discord 消息操作包括消息、频道管理、管理、在线状态和元数据操作。

核心示例:

  • 消息:sendMessagereadMessageseditMessagedeleteMessagethreadReply
  • 回应:reactreactionsemojiList
  • 管理:timeoutkickban
  • 在线状态:setPresence

操作门控位于 channels.discord.actions.*

默认门控行为:

操作组默认
reactions、messages、threads、pins、polls、search、memberInfo、roleInfo、channelInfo、channels、voiceStatus、events、stickers、emojiUploads、stickerUploads、permissions启用
roles禁用
moderation禁用
presence禁用

Components v2 UI

OpenClaw 使用 Discord components v2 进行执行审批和跨上下文标记。Discord 消息操作也可以接受 components 用于自定义 UI(高级功能;需要 Carbon 组件实例),旧版 embeds 仍然可用但不推荐使用。

  • channels.discord.ui.components.accentColor 设置 Discord 组件容器使用的强调色(十六进制)。
  • 按账户设置:channels.discord.accounts.<id>.ui.components.accentColor
  • 当 components v2 存在时,embeds 会被忽略。

示例:

{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

语音频道

OpenClaw 可以加入 Discord 语音频道进行实时连续对话。这与语音消息附件是分开的。

要求:

  • 启用原生命令(commands.nativechannels.discord.commands.native)。
  • 配置 channels.discord.voice
  • Bot 需要在目标语音频道中拥有 Connect + Speak 权限。

使用 Discord 专有的原生命令 /vc join|leave|status 来控制会话。该命令使用账户默认 Agent,并遵循与其他 Discord 命令相同的白名单和群组策略规则。

自动加入示例:

{
  channels: {
    discord: {
      voice: {
        enabled: true,
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        tts: {
          provider: "openai",
          openai: { voice: "alloy" },
        },
      },
    },
  },
}

说明:

  • voice.tts 仅覆盖语音播放的 messages.tts
  • 语音转录轮次根据 Discord allowFrom(或 dm.allowFrom)派生所有者状态;非所有者发言者无法访问仅限所有者的工具(例如 gatewaycron)。
  • 语音默认启用;设置 channels.discord.voice.enabled=false 禁用。
  • voice.daveEncryptionvoice.decryptionFailureTolerance 透传到 @discordjs/voice 加入选项。
  • 如果未设置,@discordjs/voice 默认值为 daveEncryption=truedecryptionFailureTolerance=24
  • OpenClaw 还会监视接收解密失败,并在短时间内反复失败后自动通过离开/重新加入语音频道来恢复。
  • 如果接收日志反复显示 DecryptionFailed(UnencryptedWhenPassthroughDisabled),这可能是上游 @discordjs/voice 接收 bug,跟踪于 discord.js #11419

语音消息

Discord 语音消息显示波形预览,需要 OGG/Opus 音频和元数据。OpenClaw 自动生成波形,但需要 Gateway 主机上有 ffmpegffprobe 来检查和转换音频文件。

要求和限制:

  • 提供本地文件路径(URL 会被拒绝)。
  • 省略文本内容(Discord 不允许同一 payload 中同时包含文本和语音消息)。
  • 接受任何音频格式;OpenClaw 在需要时转换为 OGG/Opus。

示例:

message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

故障排查

使用了未允许的意图或 Bot 看不到服务器消息
- 启用 Message Content Intent
- 当你依赖用户/成员解析时启用 Server Members Intent
- 更改意图后重启 Gateway
服务器消息被意外阻止
- 验证 `groupPolicy`
- 验证 `channels.discord.guilds` 下的服务器白名单
- 如果服务器的 `channels` 映射存在,只有列出的频道被允许
- 验证 `requireMention` 行为和提及模式

有用的检查命令:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
设置了 requireMention false 但仍被阻止
常见原因:

- `groupPolicy="allowlist"` 但没有匹配的服务器/频道白名单
- `requireMention` 配置位置不对(必须在 `channels.discord.guilds` 或频道条目下)
- 发送者被服务器/频道的 `users` 白名单阻止
长时间运行的处理器超时或重复回复
典型日志:

- `Listener DiscordMessageListener timed out after 30000ms for event MESSAGE_CREATE`
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`

监听器预算调节:

- 单账户:`channels.discord.eventQueue.listenerTimeout`
- 多账户:`channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`

Worker 运行超时调节:

- 单账户:`channels.discord.inboundWorker.runTimeoutMs`
- 多账户:`channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- 默认:`1800000`(30 分钟);设为 `0` 禁用

推荐基线:
{
  channels: {
    discord: {
      accounts: {
        default: {
          eventQueue: {
            listenerTimeout: 120000,
          },
          inboundWorker: {
            runTimeoutMs: 1800000,
          },
        },
      },
    },
  },
}
使用 `eventQueue.listenerTimeout` 处理慢监听器设置,仅在需要队列化 Agent 轮次的单独安全阀时使用 `inboundWorker.runTimeoutMs`。
权限审计不匹配
`channels status --probe` 权限检查仅适用于数字频道 ID。

如果使用 slug 键,运行时匹配仍然有效,但探测无法完全验证权限。
私信和配对问题
- 私信已禁用:`channels.discord.dm.enabled=false`
- 私信策略已禁用:`channels.discord.dmPolicy="disabled"`(旧版:`channels.discord.dm.policy`)
- 在 `pairing` 模式下等待配对批准
Bot 之间的循环
默认情况下,Bot 发送的消息会被忽略。

如果你设置了 `channels.discord.allowBots=true`,请使用严格的提及和白名单规则以避免循环行为。
优先使用 `channels.discord.allowBots="mentions"` 以仅接受提及了 Bot 的 Bot 消息。
语音 STT 因 DecryptionFailed(...) 丢失
- 保持 OpenClaw 最新(`openclaw update`)以确保 Discord 语音接收恢复逻辑存在
- 确认 `channels.discord.voice.daveEncryption=true`(默认)
- 从 `channels.discord.voice.decryptionFailureTolerance=24`(上游默认值)开始,仅在必要时调整
- 关注日志中的:
  - `discord voice: DAVE decrypt failures detected`
  - `discord voice: repeated decrypt failures; attempting rejoin`
- 如果自动重新加入后故障仍然存在,收集日志并对照 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)

配置参考指引

主要参考:

Discord 重要字段:

  • 启动/认证:enabledtokenaccounts.*allowBots
  • 策略:groupPolicydm.*guilds.*guilds.*.channels.*
  • 命令:commands.nativecommands.useAccessGroupsconfigWritesslashCommand.*
  • 事件队列:eventQueue.listenerTimeout(监听器预算)、eventQueue.maxQueueSizeeventQueue.maxConcurrency
  • 入站 Worker:inboundWorker.runTimeoutMs
  • 回复/历史:replyToModehistoryLimitdmHistoryLimitdms.*.historyLimit
  • 投递:textChunkLimitchunkModemaxLinesPerMessage
  • 流式传输:streaming(旧版别名:streamMode)、draftChunkblockStreamingblockStreamingCoalesce
  • 媒体/重试:mediaMaxMbretry
    • mediaMaxMb 限制出站 Discord 上传(默认:8MB
  • 操作:actions.*
  • 在线状态:activitystatusactivityTypeactivityUrl
  • UI:ui.components.accentColor
  • 功能:threadBindings、顶层 bindings[]type: "acp")、pluralkitexecApprovalsintentsagentComponentsheartbeatresponsePrefix

安全与运维

  • 将 Bot Token 视为机密信息(在受监管环境中优先使用 DISCORD_BOT_TOKEN)。
  • 授予最小权限的 Discord 权限。
  • 如果命令部署/状态过时,重启 Gateway 并使用 openclaw channels status --probe 重新检查。

相关