Discord (Bot API)
状态:已支持通过官方 Discord bot gateway 使用 DM 和服务器文字 Channel。
快速设置(新手向)
- 创建一个 Discord bot 并复制 bot token。
- 在 Discord 应用设置中,启用 Message Content Intent(如果你要用白名单或名称查找,还需要启用 Server Members Intent)。
- 为 OpenClaw 设置 token:
- 环境变量:
DISCORD_BOT_TOKEN=... - 或配置文件:
channels.discord.token: "..." - 如果两者都设置了,配置文件优先(环境变量仅作为默认账号的备用)。
- 环境变量:
- 邀请 bot 到你的服务器,给它消息权限(如果只想用 DM,可以创建一个私人服务器)。
- 启动 Gateway。
- DM 访问默认需要 Pairing;首次联系时批准 Pairing 代码即可。
最小配置:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
设计目标
- 通过 Discord DM 或服务器 Channel 与 OpenClaw 对话。
- 私聊会合并到 Agent 的主 Session(默认
agent:main:main);服务器 Channel 保持隔离,使用agent:<agentId>:discord:channel:<channelId>(显示名称使用discord:<guildSlug>#<channelSlug>)。 - 群组 DM 默认被忽略;通过
channels.discord.dm.groupEnabled启用,可选用channels.discord.dm.groupChannels限制。 - 保持 Routing 确定性:回复始终返回到消息来源的 Channel。
工作原理
- 创建 Discord 应用 → Bot,启用你需要的 intents(DM + 服务器消息 + 消息内容),获取 bot token。
- 邀请 bot 到你的服务器,给它在你想使用的地方读取/发送消息的权限。
- 用
channels.discord.token(或DISCORD_BOT_TOKEN作为备用)配置 OpenClaw。 - 运行 Gateway;当 token 可用时(配置优先,环境变量备用)且
channels.discord.enabled不是false,会自动启动 Discord Channel。- 如果你偏好环境变量,设置
DISCORD_BOT_TOKEN(配置块是可选的)。
- 如果你偏好环境变量,设置
- 私聊:发送时使用
user:<id>(或<@id>提及);所有对话都进入共享的mainSession。纯数字 ID 有歧义会被拒绝。 - 服务器 Channel:发送时使用
channel:<channelId>。默认需要提及,可以按服务器或按 Channel 设置。 - 私聊:默认通过
channels.discord.dm.policy(默认:"pairing")保护。未知发送者会收到 Pairing 代码(1 小时后过期);通过openclaw pairing approve discord <code>批准。- 要保持旧的”对所有人开放”行为:设置
channels.discord.dm.policy="open"和channels.discord.dm.allowFrom=["*"]。 - 要硬性白名单:设置
channels.discord.dm.policy="allowlist"并在channels.discord.dm.allowFrom中列出发送者。 - 要忽略所有 DM:设置
channels.discord.dm.enabled=false或channels.discord.dm.policy="disabled"。
- 要保持旧的”对所有人开放”行为:设置
- 群组 DM 默认被忽略;通过
channels.discord.dm.groupEnabled启用,可选用channels.discord.dm.groupChannels限制。 - 可选的服务器规则:设置
channels.discord.guilds,用服务器 id(推荐)或 slug 作为键,配置每个 Channel 的规则。 - 可选的原生命令:
commands.native默认为"auto"(Discord/Telegram 开启,Slack 关闭)。用channels.discord.commands.native: true|false|"auto"覆盖;false会清除之前注册的命令。文本命令由commands.text控制,必须作为独立的/...消息发送。使用commands.useAccessGroups: false可以绕过命令的访问组检查。- 完整命令列表 + 配置:Slash commands
- 可选的服务器上下文历史:设置
channels.discord.historyLimit(默认 20,回退到messages.groupChat.historyLimit)以在回复提及时包含最近 N 条服务器消息作为上下文。设置0禁用。 - 表情回应:Agent 可以通过
discord工具触发表情回应(由channels.discord.actions.*控制)。- 表情移除语义:见 /tools/reactions。
discord工具仅在当前 Channel 是 Discord 时暴露。
- 原生命令使用隔离的 Session 键(
agent:<agentId>:discord:slash:<userId>)而不是共享的mainSession。
注意:名称 → id 解析使用服务器成员搜索,需要 Server Members Intent;如果 bot 无法搜索成员,使用 id 或 <@id> 提及。
注意:Slug 是小写的,空格替换为 -。Channel 名称 slug 化时不带前导 #。
注意:服务器上下文的 [from:] 行包含 author.tag + id,方便生成可 ping 的回复。
配置写入
默认情况下,Discord 允许通过 /config set|unset 触发配置更新(需要 commands.config: true)。
禁用方式:
{
channels: { discord: { configWrites: false } },
}
如何创建你自己的 bot
这是在服务器(guild)Channel(如 #help)中运行 OpenClaw 的”Discord Developer Portal”设置流程。
1) 创建 Discord 应用 + bot 用户
- Discord Developer Portal → Applications → New Application
- 在你的应用中:
- Bot → Add Bot
- 复制 Bot Token(这就是你要放到
DISCORD_BOT_TOKEN的内容)
2) 启用 OpenClaw 需要的 gateway intents
Discord 会阻止”特权 intents”,除非你明确启用它们。
在 Bot → Privileged Gateway Intents 中,启用:
- Message Content Intent(必需,用于读取大多数服务器中的消息文本;没有它你会看到”Used disallowed intents”或 bot 连接后不响应消息)
- Server Members Intent(推荐;某些成员/用户查找和服务器白名单匹配需要)
通常不需要 Presence Intent。
3) 生成邀请 URL(OAuth2 URL Generator)
在你的应用中:OAuth2 → URL Generator
Scopes
- ✅
bot - ✅
applications.commands(原生命令需要)
Bot Permissions(最小基线)
- ✅ View Channels
- ✅ Send Messages
- ✅ Read Message History
- ✅ Embed Links
- ✅ Attach Files
- ✅ Add Reactions(可选但推荐)
- ✅ Use External Emojis / Stickers(可选;只在你想用时需要)
避免使用 Administrator,除非你在调试且完全信任这个 bot。
复制生成的 URL,打开它,选择你的服务器,安装 bot。
4) 获取 id(服务器/用户/Channel)
Discord 到处都用数字 id;OpenClaw 配置优先使用 id。
- Discord(桌面/网页)→ User Settings → Advanced → 启用 Developer Mode
- 右键点击:
- 服务器名称 → Copy Server ID(服务器 id)
- Channel(如
#help)→ Copy Channel ID - 你的用户 → Copy User ID
5) 配置 OpenClaw
Token
通过环境变量设置 bot token(服务器上推荐):
DISCORD_BOT_TOKEN=...
或通过配置文件:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN",
},
},
}
多账号支持:使用 channels.discord.accounts,每个账号配置 token 和可选的 name。参见 gateway/configuration 了解共享模式。
白名单 + Channel Routing
示例”单个服务器,只允许我,只允许 #help”:
{
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,
},
},
},
}
注意:
requireMention: true表示 bot 只在被提及时回复(共享 Channel 推荐)。agents.list[].groupChat.mentionPatterns(或messages.groupChat.mentionPatterns)也算作服务器消息的提及。- 多 Agent 覆盖:在
agents.list[].groupChat.mentionPatterns上设置每个 Agent 的模式。 - 如果存在
channels,任何未列出的 Channel 默认被拒绝。 - 使用
"*"Channel 条目在所有 Channel 上应用默认值;显式的 Channel 条目会覆盖通配符。 - 线程继承父 Channel 配置(白名单、
requireMention、Skill、Prompt 等),除非你显式添加线程 Channel id。 - Bot 自己发的消息默认被忽略;设置
channels.discord.allowBots=true允许它们(自己的消息仍然被过滤)。 - 警告:如果你允许回复其他 bot(
channels.discord.allowBots=true),用requireMention、channels.discord.guilds.*.channels.<id>.users白名单和/或在AGENTS.md和SOUL.md中清晰的防护措施来防止 bot 之间的回复循环。
6) 验证是否工作
- 启动 Gateway。
- 在你的服务器 Channel 中发送:
@Krill hello(或你的 bot 名称)。 - 如果没反应:查看下面的故障排除。
故障排除
- 首先:运行
openclaw doctor和openclaw channels status --probe(可操作的警告 + 快速审计)。 - “Used disallowed intents”:在 Developer Portal 中启用 Message Content Intent(可能还需要 Server Members Intent),然后重启 Gateway。
- Bot 连接了但从不在服务器 Channel 回复:
- 缺少 Message Content Intent,或
- Bot 缺少 Channel 权限(View/Send/Read History),或
- 你的配置需要提及但你没有提及它,或
- 你的服务器/Channel 白名单拒绝了该 Channel/用户。
requireMention: false但仍然没有回复:channels.discord.groupPolicy默认为 allowlist;设置为"open"或在channels.discord.guilds下添加服务器条目(可选在channels.discord.guilds.<id>.channels下列出 Channel 以限制)。- 如果你只设置了
DISCORD_BOT_TOKEN且从未创建channels.discord部分,运行时会将groupPolicy默认为open。添加channels.discord.groupPolicy、channels.defaults.groupPolicy或服务器/Channel 白名单来锁定它。
requireMention必须在channels.discord.guilds(或特定 Channel)下。顶层的channels.discord.requireMention会被忽略。- 权限审计(
channels status --probe)只检查数字 Channel ID。如果你使用 slug/名称作为channels.discord.guilds.*.channels键,审计无法验证权限。 - DM 不工作:
channels.discord.dm.enabled=false、channels.discord.dm.policy="disabled",或你还没被批准(channels.discord.dm.policy="pairing")。 - Discord 中的执行批准:Discord 支持 DM 中执行批准的按钮 UI(Allow once / Always allow / Deny)。
/approve <id> ...仅用于转发的批准,不会解决 Discord 的按钮提示。如果你看到❌ Failed to submit approval: Error: unknown approval id或 UI 从未显示,检查:- 配置中的
channels.discord.execApprovals.enabled: true。 - 你的 Discord 用户 ID 列在
channels.discord.execApprovals.approvers中(UI 只发送给批准者)。 - 使用 DM 提示中的按钮(Allow once、Always allow、Deny)。
- 参见 Exec approvals 和 Slash commands 了解更广泛的批准和命令流程。
- 配置中的
功能和限制
- 支持 DM 和服务器文字 Channel(线程被视为独立 Channel;不支持语音)。
- 尽力发送输入指示器;消息分块使用
channels.discord.textChunkLimit(默认 2000)并按行数拆分长回复(channels.discord.maxLinesPerMessage,默认 17)。 - 可选的换行分块:设置
channels.discord.chunkMode="newline"在长度分块前按空行(段落边界)拆分。 - 支持文件上传,最大到配置的
channels.discord.mediaMaxMb(默认 8 MB)。 - 默认通过提及控制服务器回复,避免吵闹的 bot。
- 当消息引用另一条消息时注入回复上下文(引用内容 + id)。
- 原生回复线程默认关闭;通过
channels.discord.replyToMode和回复标签启用。
重试策略
出站 Discord API 调用在速率限制(429)时重试,使用 Discord 的 retry_after(如果可用),配合指数退避和抖动。通过 channels.discord.retry 配置。参见 Retry policy。
配置
{
channels: {
discord: {
enabled: true,
token: "abc.123",
groupPolicy: "allowlist",
guilds: {
"*": {
channels: {
general: { allow: true },
},
},
},
mediaMaxMb: 8,
actions: {
reactions: true,
stickers: true,
emojiUploads: true,
stickerUploads: true,
polls: true,
permissions: true,
messages: true,
threads: true,
pins: true,
search: true,
memberInfo: true,
roleInfo: true,
roles: false,
channelInfo: true,
channels: true,
voiceStatus: true,
events: true,
moderation: false,
},
replyToMode: "off",
dm: {
enabled: true,
policy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["123456789012345678", "steipete"],
groupEnabled: false,
groupChannels: ["openclaw-dm"],
},
guilds: {
"*": { requireMention: true },
"123456789012345678": {
slug: "friends-of-openclaw",
requireMention: false,
reactionNotifications: "own",
users: ["987654321098765432", "steipete"],
channels: {
general: { allow: true },
help: {
allow: true,
requireMention: true,
users: ["987654321098765432"],
skills: ["search", "docs"],
systemPrompt: "Keep answers short.",
},
},
},
},
},
},
}
确认表情由 messages.ackReaction + messages.ackReactionScope 全局控制。使用 messages.removeAckAfterReply 在 bot 回复后清除确认表情。
dm.enabled:设置false忽略所有 DM(默认true)。dm.policy:DM 访问控制(推荐pairing)。"open"需要dm.allowFrom=["*"]。dm.allowFrom:DM 白名单(用户 id 或名称)。由dm.policy="allowlist"使用,也用于dm.policy="open"验证。向导接受用户名并在 bot 能搜索成员时解析为 id。dm.groupEnabled:启用群组 DM(默认false)。dm.groupChannels:群组 DM Channel id 或 slug 的可选白名单。groupPolicy:控制服务器 Channel 处理(open|disabled|allowlist);allowlist需要 Channel 白名单。guilds:按服务器 id(推荐)或 slug 键入的每服务器规则。guilds."*":当没有显式条目时应用的默认每服务器设置。guilds.<id>.slug:用于显示名称的可选友好 slug。guilds.<id>.users:可选的每服务器用户白名单(id 或名称)。guilds.<id>.tools:可选的每服务器工具策略覆盖(allow/deny/alsoAllow),当 Channel 覆盖缺失时使用。guilds.<id>.toolsBySender:可选的服务器级别每发送者工具策略覆盖(当 Channel 覆盖缺失时应用;支持"*"通配符)。guilds.<id>.channels.<channel>.allow:当groupPolicy="allowlist"时允许/拒绝 Channel。guilds.<id>.channels.<channel>.requireMention:Channel 的提及控制。guilds.<id>.channels.<channel>.tools:可选的每 Channel 工具策略覆盖(allow/deny/alsoAllow)。guilds.<id>.channels.<channel>.toolsBySender:Channel 内可选的每发送者工具策略覆盖(支持"*"通配符)。guilds.<id>.channels.<channel>.users:可选的每 Channel 用户白名单。guilds.<id>.channels.<channel>.skills:Skill 过滤器(省略 = 所有 Skill,空 = 无)。guilds.<id>.channels.<channel>.systemPrompt:Channel 的额外系统 Prompt(与 Channel 主题结合)。guilds.<id>.channels.<channel>.enabled:设置false禁用 Channel。guilds.<id>.channels:Channel 规则(键是 Channel slug 或 id)。guilds.<id>.requireMention:每服务器提及要求(可按 Channel 覆盖)。guilds.<id>.reactionNotifications:表情系统事件模式(off、own、all、allowlist)。textChunkLimit:出站文本块大小(字符)。默认:2000。chunkMode:length(默认)仅在超过textChunkLimit时拆分;newline在长度分块前按空行(段落边界)拆分。maxLinesPerMessage:每条消息的软最大行数。默认:17。mediaMaxMb:限制保存到磁盘的入站媒体。historyLimit:回复提及时包含的最近服务器消息数(默认 20;回退到messages.groupChat.historyLimit;0禁用)。dmHistoryLimit:DM 历史限制(用户轮次)。每用户覆盖:dms["<user_id>"].historyLimit。retry:出站 Discord API 调用的重试策略(attempts、minDelayMs、maxDelayMs、jitter)。pluralkit:解析 PluralKit 代理消息,使系统成员显示为不同发送者。actions:每个操作的工具门控;省略允许所有(设置false禁用)。reactions(涵盖 react + 读取表情)stickers、emojiUploads、stickerUploads、polls、permissions、messages、threads、pins、searchmemberInfo、roleInfo、channelInfo、voiceStatus、eventschannels(创建/编辑/删除 Channel + 分类 + 权限)roles(角色添加/移除,默认false)moderation(超时/踢出/封禁,默认false)
execApprovals:Discord 专用执行批准 DM(按钮 UI)。支持enabled、approvers、agentFilter、sessionFilter。
表情通知使用 guilds.<id>.reactionNotifications:
off:无表情事件。own:bot 自己消息上的表情(默认)。all:所有消息上的所有表情。allowlist:来自guilds.<id>.users的表情在所有消息上(空列表禁用)。
PluralKit (PK) 支持
启用 PK 查找,使代理消息解析为底层系统 + 成员。
启用后,OpenClaw 使用成员身份进行白名单检查,并将发送者标记为 Member (PK:System) 以避免意外的 Discord ping。
{
channels: {
discord: {
pluralkit: {
enabled: true,
token: "pk_live_...", // 可选;私有系统需要
},
},
},
}
白名单注意事项(启用 PK):
- 在
dm.allowFrom、guilds.<id>.users或每 Channel 的users中使用pk:<memberId>。 - 成员显示名称也通过名称/slug 匹配。
- 查找使用原始 Discord 消息 ID(代理前的消息),因此 PK API 只在其 30 分钟窗口内解析它。
- 如果 PK 查找失败(例如,没有 token 的私有系统),代理消息被视为 bot 消息,除非
channels.discord.allowBots=true,否则会被丢弃。
工具操作默认值
| 操作组 | 默认 | 注意 |
|---|---|---|
| reactions | 启用 | React + 列出表情 + emojiList |
| stickers | 启用 | 发送贴纸 |
| emojiUploads | 启用 | 上传表情 |
| stickerUploads | 启用 | 上传贴纸 |
| polls | 启用 | 创建投票 |
| permissions | 启用 | Channel 权限快照 |
| messages | 启用 | 读取/发送/编辑/删除 |
| threads | 启用 | 创建/列出/回复 |
| pins | 启用 | 固定/取消固定/列出 |
| search | 启用 | 消息搜索(预览功能) |
| memberInfo | 启用 | 成员信息 |
| roleInfo | 启用 | 角色列表 |
| channelInfo | 启用 | Channel 信息 + 列表 |
| channels | 启用 | Channel/分类管理 |
| voiceStatus | 启用 | 语音状态查找 |
| events | 启用 | 列出/创建计划事件 |
| roles | 禁用 | 角色添加/移除 |
| moderation | 禁用 | 超时/踢出/封禁 |
replyToMode:off(默认)、first或all。仅在模型包含回复标签时应用。
回复标签
要请求线程回复,模型可以在其输出中包含一个标签:
[[reply_to_current]]— 回复触发的 Discord 消息。[[reply_to:<id>]]— 回复上下文/历史中的特定消息 id。 当前消息 id 作为[message_id: …]附加到 Prompt;历史条目已包含 id。
行为由 channels.discord.replyToMode 控制:
off:忽略标签。first:只有第一个出站块/附件是回复。all:每个出站块/附件都是回复。
白名单匹配注意事项:
allowFrom/users/groupChannels接受 id、名称、tag 或像<@id>这样的提及。- 支持前缀如
discord:/user:(用户)和channel:(群组 DM)。 - 使用
*允许任何发送者/Channel。 - 当存在
guilds.<id>.channels时,未列出的 Channel 默认被拒绝。 - 当省略
guilds.<id>.channels时,白名单服务器中的所有 Channel 都被允许。 - 要不允许任何 Channel,设置
channels.discord.groupPolicy: "disabled"(或保持空白名单)。 - 配置向导接受
Guild/Channel名称(公开 + 私有)并在可能时解析为 ID。 - 启动时,OpenClaw 将白名单中的 Channel/用户名称解析为 ID(当 bot 能搜索成员时)并记录映射;未解析的条目保持原样。
原生命令注意事项:
- 注册的命令镜像 OpenClaw 的聊天命令。
- 原生命令遵守与 DM/服务器消息相同的白名单(
channels.discord.dm.allowFrom、channels.discord.guilds、每 Channel 规则)。 - Slash 命令可能仍然对未在白名单中的用户在 Discord UI 中可见;OpenClaw 在执行时强制执行白名单并回复”not authorized”。
工具操作
Agent 可以调用 discord 工具,执行如下操作:
react/reactions(添加或列出表情)sticker、poll、permissionsreadMessages、sendMessage、editMessage、deleteMessage- 读取/搜索/固定工具的 payload 包含规范化的
timestampMs(UTC 纪元毫秒)和timestampUtc,以及原始 Discordtimestamp。 threadCreate、threadList、threadReplypinMessage、unpinMessage、listPinssearchMessages、memberInfo、roleInfo、roleAdd、roleRemove、emojiListchannelInfo、channelList、voiceStatus、eventList、eventCreatetimeout、kick、ban
Discord 消息 id 在注入的上下文中显示([discord message id: …] 和历史行),以便 Agent 可以定位它们。
表情可以是 unicode(如 ✅)或自定义表情语法如 <:party_blob:1234567890>。
安全和运维
- 像对待密码一样对待 bot token;在受监督的主机上优先使用
DISCORD_BOT_TOKEN环境变量,或锁定配置文件权限。 - 只授予 bot 需要的权限(通常是 Read/Send Messages)。
- 如果 bot 卡住或被速率限制,在确认没有其他进程拥有 Discord Session 后重启 Gateway(
openclaw gateway --force)。