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 设置。
支持的区块:
text、section、separator、actions、media-gallery、file- 操作行最多允许 5 个按钮或一个选择菜单
- 选择类型:
string、user、role、mentionable、channel
默认情况下,组件为一次性使用。设置 components.reusable=true 允许按钮、选择器和表单在过期前多次使用。
要限制谁可以点击按钮,请在按钮上设置 allowedUsers(Discord 用户 ID、标签或 *)。配置后,不匹配的用户会收到临时拒绝提示。
/model 和 /models 斜杠命令会打开一个交互式模型选择器,包含提供商和模型下拉菜单以及提交步骤。选择器回复是临时的,仅调用者可使用。
文件附件:
file区块必须指向附件引用(attachment://<filename>)- 通过
media/path/filePath提供附件(单文件);多文件使用media-gallery - 使用
filename覆盖上传名称以匹配附件引用
模态表单:
- 添加
components.modal,最多 5 个字段 - 字段类型:
text、checkbox、radio、select、role-select、user-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 消息操作包括消息、频道管理、管理、在线状态和元数据操作。
核心示例:
- 消息:
sendMessage、readMessages、editMessage、deleteMessage、threadReply - 回应:
react、reactions、emojiList - 管理:
timeout、kick、ban - 在线状态:
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.native或channels.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)派生所有者状态;非所有者发言者无法访问仅限所有者的工具(例如gateway和cron)。 - 语音默认启用;设置
channels.discord.voice.enabled=false禁用。 voice.daveEncryption和voice.decryptionFailureTolerance透传到@discordjs/voice加入选项。- 如果未设置,
@discordjs/voice默认值为daveEncryption=true和decryptionFailureTolerance=24。 - OpenClaw 还会监视接收解密失败,并在短时间内反复失败后自动通过离开/重新加入语音频道来恢复。
- 如果接收日志反复显示
DecryptionFailed(UnencryptedWhenPassthroughDisabled),这可能是上游@discordjs/voice接收 bug,跟踪于 discord.js #11419。
语音消息
Discord 语音消息显示波形预览,需要 OGG/Opus 音频和元数据。OpenClaw 自动生成波形,但需要 Gateway 主机上有 ffmpeg 和 ffprobe 来检查和转换音频文件。
要求和限制:
- 提供本地文件路径(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 重要字段:
- 启动/认证:
enabled、token、accounts.*、allowBots - 策略:
groupPolicy、dm.*、guilds.*、guilds.*.channels.* - 命令:
commands.native、commands.useAccessGroups、configWrites、slashCommand.* - 事件队列:
eventQueue.listenerTimeout(监听器预算)、eventQueue.maxQueueSize、eventQueue.maxConcurrency - 入站 Worker:
inboundWorker.runTimeoutMs - 回复/历史:
replyToMode、historyLimit、dmHistoryLimit、dms.*.historyLimit - 投递:
textChunkLimit、chunkMode、maxLinesPerMessage - 流式传输:
streaming(旧版别名:streamMode)、draftChunk、blockStreaming、blockStreamingCoalesce - 媒体/重试:
mediaMaxMb、retrymediaMaxMb限制出站 Discord 上传(默认:8MB)
- 操作:
actions.* - 在线状态:
activity、status、activityType、activityUrl - UI:
ui.components.accentColor - 功能:
threadBindings、顶层bindings[](type: "acp")、pluralkit、execApprovals、intents、agentComponents、heartbeat、responsePrefix
安全与运维
- 将 Bot Token 视为机密信息(在受监管环境中优先使用
DISCORD_BOT_TOKEN)。 - 授予最小权限的 Discord 权限。
- 如果命令部署/状态过时,重启 Gateway 并使用
openclaw channels status --probe重新检查。