Discord (Bot API)
状态:通过官方 Discord 机器人网关支持私信和公会文本频道。
快速设置(初学者)
- 创建一个 Discord 机器人并复制 bot token。
- 在 Discord 应用设置中,启用 Message Content Intent(如果你计划使用允许列表或名称查找,还需启用 Server Members Intent)。
- 为 OpenClaw 设置 token:
- 环境变量:DISCORD_BOT_TOKEN=...
- 或配置:channels.discord.token: "..."。
- 如果两者都设置,配置优先(环境变量回退仅用于默认账户)。
- 使用消息权限将机器人邀请到你的服务器(如果你只想使用私信,可以创建一个私人服务器)。
- 启动网关。
- 私信访问默认使用配对(pairing);首次联系时批准配对码。
最小配置:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN"
}
}
}
目标
- 通过 Discord 私信或公会频道与 OpenClaw 对话。
- 直接聊天合并到代理的主会话(默认 agent:main:main);公会频道保持隔离为 agent:<agentId>:discord:channel:<channelId>(显示名称使用 discord:<guildSlug>#<channelSlug>)。
- 默认忽略群组私信;通过 channels.discord.dm.groupEnabled 启用,并可选择通过 channels.discord.dm.groupChannels 限制。
- 保持路由确定性:回复始终返回到消息到达的频道。
工作原理
- 创建 Discord 应用程序 → 机器人,启用所需的意图(intents)(私信 + 公会消息 + 消息内容),并获取 bot token。
- 使用所需权限将机器人邀请到你的服务器,以便在你想使用的地方读取/发送消息。
- 使用 channels.discord.token(或 DISCORD_BOT_TOKEN 作为回退)配置 OpenClaw。
- 运行网关;当 token 可用时(配置优先,环境变量回退)且 channels.discord.enabled 不为 false 时,它会自动启动 Discord 频道。
- 如果你更喜欢环境变量,设置 DISCORD_BOT_TOKEN(配置块是可选的)。
- 直接聊天:传递时使用 user:<id>(或 <@id> 提及);所有回合都进入共享的 main 会话。裸数字 ID 是模糊的并被拒绝。
- 公会频道:传递时使用 channel:<channelId>。默认需要提及,可以按公会或按频道设置。
- 直接聊天:默认通过 channels.discord.dm.policy 保护(默认:"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 中列出发送者。
- 忽略所有私信:设置 channels.discord.dm.enabled=false 或 channels.discord.dm.policy="disabled"。
- 默认忽略群组私信;通过 channels.discord.dm.groupEnabled 启用,并可选择通过 channels.discord.dm.groupChannels 限制。
- 可选的公会规则:按公会 ID(首选)或 slug 设置 channels.discord.guilds,并带有按频道规则。
- 可选的原生命令:commands.native 默认为 "auto"(Discord/Telegram 开启,Slack 关闭)。使用 channels.discord.commands.native: true|false|"auto" 覆盖;false 清除之前注册的命令。文本命令由 commands.text 控制,必须作为独立的 /... 消息发送。使用 commands.useAccessGroups: false 绕过命令的访问组检查。
- 完整命令列表 + 配置:斜杠命令
- 可选的公会上下文历史:设置 channels.discord.historyLimit(默认 20,回退到 messages.groupChat.historyLimit),在回复提及时包含最后 N 条公会消息作为上下文。设置 0 禁用。
- 反应(Reactions):代理可以通过 discord 工具触发反应(由 channels.discord.actions.* 限制)。
- 反应删除语义:参见 /tools/reactions。
- discord 工具仅在当前频道是 Discord 时公开。
- 原生命令使用隔离的会话键(agent:<agentId>:discord:slash:<userId>)而不是共享的 main 会话。
注意:名称 → ID 解析使用公会成员搜索,需要 Server Members Intent;如果机器人无法搜索成员,请使用 ID 或 <@id> 提及。 注意:Slug 是小写的,空格替换为 -。频道名称在 slug 化时不带前导 #。 注意:公会上下文 [from:] 行包含 author.tag + id,以便轻松进行 ping 就绪回复。
配置写入
默认情况下,Discord 允许写入由 /config set|unset 触发的配置更新(需要 commands.config: true)。
禁用:
{
channels: { discord: { configWrites: false } }
}
如何创建你自己的机器人
这是在服务器(公会)频道(如 #help)中运行 OpenClaw 的"Discord 开发者门户"设置。
1) 创建 Discord 应用 + 机器人用户
- Discord 开发者门户 → Applications → New Application
- 在你的应用中:
- Bot → Add Bot
- 复制 Bot Token(这是你放在 DISCORD_BOT_TOKEN 中的内容)
2) 启用 OpenClaw 需要的网关意图(gateway intents)
除非你明确启用,否则 Discord 会阻止"特权意图(privileged intents)"。
在 Bot → Privileged Gateway Intents 中,启用:
- Message Content Intent(在大多数公会中读取消息文本所必需;没有它你会看到"Used disallowed intents"或机器人会连接但不会对消息做出反应)
- 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,除非你正在调试并完全信任该机器人。
复制生成的 URL,打开它,选择你的服务器,并安装机器人。
4) 获取 ID(guild/user/channel)
Discord 到处使用数字 ID;OpenClaw 配置更喜欢 ID。
- Discord(桌面/网页)→ User Settings → Advanced → 启用 Developer Mode
- 右键单击:
- 服务器名称 → Copy Server ID(guild id)
- 频道(例如 #help)→ Copy Channel ID
- 你的用户 → Copy User ID
5) 配置 OpenClaw
Token
通过环境变量设置 bot token(在服务器上推荐):
- DISCORD_BOT_TOKEN=...
或通过配置:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN"
}
}
}
多账户支持:使用带有每账户 token 和可选 name 的 channels.discord.accounts。参见 gateway/configuration 了解共享模式。
允许列表 + 频道路由
示例"单个服务器,只允许我,只允许 #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 表示机器人仅在被提及时回复(推荐用于共享频道)。
- agents.list[].groupChat.mentionPatterns(或 messages.groupChat.mentionPatterns)也算作公会消息的提及。
- 多代理覆盖:在 agents.list[].groupChat.mentionPatterns 上设置按代理模式。
- 如果 channels 存在,默认情况下拒绝任何未列出的频道。
- 使用 "*" 频道条目在所有频道上应用默认值;显式频道条目覆盖通配符。
- 线程继承父频道配置(允许列表、requireMention、技能、提示等),除非你明确添加线程频道 ID。
- 默认忽略机器人创作的消息;设置 channels.discord.allowBots=true 以允许它们(自己的消息仍被过滤)。
- 警告:如果你允许对其他机器人的回复(channels.discord.allowBots=true),请使用 requireMention、channels.discord.guilds.*.channels.<id>.users 允许列表和/或 AGENTS.md 和 SOUL.md 中的清晰防护措施来防止机器人到机器人的回复循环。
6) 验证它是否有效
- 启动网关。
- 在你的服务器频道中,发送:@Krill hello(或你的机器人名称)。
- 如果没有任何反应:检查下面的故障排除。
故障排除
- 首先:运行 openclaw doctor 和 openclaw channels status --probe(可操作的警告 + 快速审计)。
- "Used disallowed intents":在开发者门户中启用 Message Content Intent(以及可能的 Server Members Intent),然后重启网关。
- 机器人连接但从不在公会频道中回复:
- 缺少 Message Content Intent,或
- 机器人缺少频道权限(View/Send/Read History),或
- 你的配置需要提及而你没有提及它,或
- 你的公会/频道允许列表拒绝了频道/用户。
- requireMention: false 但仍然没有回复:
- channels.discord.groupPolicy 默认为 allowlist;将其设置为 "open" 或在 channels.discord.guilds 下添加公会条目(可选择在 channels.discord.guilds.<id>.channels 下列出频道以限制)。
- 如果你只设置 DISCORD_BOT_TOKEN 并且从未创建 channels.discord 部分,运行时会将 groupPolicy 默认为 open。添加 channels.discord.groupPolicy、channels.defaults.groupPolicy 或公会/频道允许列表以锁定它。
- requireMention 必须位于 channels.discord.guilds(或特定频道)下。顶层的 channels.discord.requireMention 被忽略。
- 权限审计(channels status --probe)仅检查数字频道 ID。如果你使用 slug/名称作为 channels.discord.guilds.*.channels 键,审计无法验证权限。
- 私信不起作用:channels.discord.dm.enabled=false、channels.discord.dm.policy="disabled",或你尚未被批准(channels.discord.dm.policy="pairing")。
功能和限制
- 私信和公会文本频道(线程被视为单独的频道;不支持语音)。
- 尽力发送输入指示器;消息分块使用 channels.discord.textChunkLimit(默认 2000)并按行数分割高回复(channels.discord.maxLinesPerMessage,默认 17)。
- 可选的换行分块:设置 channels.discord.chunkMode="newline" 以在长度分块之前在空行(段落边界)处分割。
- 支持文件上传,最大为配置的 channels.discord.mediaMaxMb(默认 8 MB)。
- 默认使用提及门控的公会回复,以避免嘈杂的机器人。
- 当消息引用另一条消息时注入回复上下文(引用内容 + ID)。
- 原生回复线程默认关闭;使用 channels.discord.replyToMode 和回复标签启用。
重试策略(Retry policy)
出站 Discord API 调用在速率限制(429)时重试,在可用时使用 Discord 的 retry_after,并使用指数退避和抖动。通过 channels.discord.retry 配置。参见 重试策略。
配置
{
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."
}
}
}
}
}
}
}
确认反应(Ack reactions)通过 messages.ackReaction + messages.ackReactionScope 全局控制。使用 messages.removeAckAfterReply 在机器人回复后清除确认反应。
- dm.enabled:设置 false 以忽略所有私信(默认 true)。
- dm.policy:私信访问控制(推荐 pairing)。"open" 需要 dm.allowFrom=["*"]。
- dm.allowFrom:私信允许列表(用户 ID 或名称)。由 dm.policy="allowlist" 使用,并用于 dm.policy="open" 验证。向导接受用户名,并在机器人可以搜索成员时将其解析为 ID。
- dm.groupEnabled:启用群组私信(默认 false)。
- dm.groupChannels:群组私信频道 ID 或 slug 的可选允许列表。
- groupPolicy:控制公会频道处理(open|disabled|allowlist);allowlist 需要频道允许列表。
- guilds:按公会 ID(首选)或 slug 键入的按公会规则。
- guilds."*":当不存在显式条目时应用的默认按公会设置。
- guilds.<id>.slug:用于显示名称的可选友好 slug。
- guilds.<id>.users:可选的按公会用户允许列表(ID 或名称)。
- guilds.<id>.tools:当频道覆盖缺失时使用的可选按公会工具策略覆盖(allow/deny/alsoAllow)。
- guilds.<id>.toolsBySender:公会级别的可选按发送者工具策略覆盖(当频道覆盖缺失时应用;支持 "*" 通配符)。
- guilds.<id>.channels.<channel>.allow:当 groupPolicy="allowlist" 时允许/拒绝频道。
- guilds.<id>.channels.<channel>.requireMention:频道的提及门控。
- guilds.<id>.channels.<channel>.tools:可选的按频道工具策略覆盖(allow/deny/alsoAllow)。
- guilds.<id>.channels.<channel>.toolsBySender:频道内可选的按发送者工具策略覆盖(支持 "*" 通配符)。
- guilds.<id>.channels.<channel>.users:可选的按频道用户允许列表。
- guilds.<id>.channels.<channel>.skills:技能过滤器(省略 = 所有技能,空 = 无)。
- guilds.<id>.channels.<channel>.systemPrompt:频道的额外系统提示(与频道主题结合)。
- guilds.<id>.channels.<channel>.enabled:设置 false 以禁用频道。
- guilds.<id>.channels:频道规则(键是频道 slug 或 ID)。
- guilds.<id>.requireMention:按公会提及要求(可按频道覆盖)。
- guilds.<id>.reactionNotifications:反应系统事件模式(off、own、all、allowlist)。
- textChunkLimit:出站文本分块大小(字符)。默认:2000。
- chunkMode:length(默认)仅在超过 textChunkLimit 时分割;newline 在长度分块之前在空行(段落边界)处分割。
- maxLinesPerMessage:每条消息的软最大行数。默认:17。
- mediaMaxMb:限制保存到磁盘的入站媒体。
- historyLimit:回复提及时包含作为上下文的最近公会消息数量(默认 20;回退到 messages.groupChat.historyLimit;0 禁用)。
- dmHistoryLimit:用户回合中的私信历史限制。按用户覆盖:dms["<user_id>"].historyLimit。
- retry:出站 Discord API 调用的重试策略(attempts、minDelayMs、maxDelayMs、jitter)。
- actions:按操作工具门控;省略以允许所有(设置 false 以禁用)。
- reactions(涵盖反应 + 读取反应)
- stickers、emojiUploads、stickerUploads、polls、permissions、messages、threads、pins、search
- memberInfo、roleInfo、channelInfo、voiceStatus、events
- channels(创建/编辑/删除频道 + 类别 + 权限)
- roles(角色添加/删除,默认 false)
- moderation(超时/踢出/封禁,默认 false)
反应通知使用 guilds.<id>.reactionNotifications:
- off:无反应事件。
- own:机器人自己消息上的反应(默认)。
- all:所有消息上的所有反应。
- allowlist:来自 guilds.<id>.users 的对所有消息的反应(空列表禁用)。
工具操作默认值
| 操作组 | 默认 | 注意 |
|---|---|---|
| reactions | 启用 | 反应 + 列出反应 + 表情符号列表 |
| stickers | 启用 | 发送贴纸 |
| emojiUploads | 启用 | 上传表情符号 |
| stickerUploads | 启用 | 上传贴纸 |
| polls | 启用 | 创建投票 |
| permissions | 启用 | 频道权限快照 |
| messages | 启用 | 读取/发送/编辑/删除 |
| threads | 启用 | 创建/列出/回复 |
| pins | 启用 | 置顶/取消置顶/列出 |
| search | 启用 | 消息搜索(预览功能) |
| memberInfo | 启用 | 成员信息 |
| roleInfo | 启用 | 角色列表 |
| channelInfo | 启用 | 频道信息 + 列表 |
| channels | 启用 | 频道/类别管理 |
| voiceStatus | 启用 | 语音状态查找 |
| events | 启用 | 列出/创建计划事件 |
| roles | 禁用 | 角色添加/删除 |
| moderation | 禁用 | 超时/踢出/封禁 |
- replyToMode:off(默认)、first 或 all。仅在模型包含回复标签时应用。
回复标签(Reply tags)
要请求线程回复,模型可以在其输出中包含一个标签:
- [[reply_to_current]] — 回复触发的 Discord 消息。
- [[reply_to:<id>]] — 回复上下文/历史中的特定消息 ID。 当前消息 ID 作为 [message_id: …] 附加到提示;历史条目已经包含 ID。
行为由 channels.discord.replyToMode 控制:
- off:忽略标签。
- first:只有第一个出站块/附件是回复。
- all:每个出站块/附件都是回复。
允许列表匹配注意事项:
- allowFrom/users/groupChannels 接受 ID、名称、标签或提及,如 <@id>。
- 支持前缀如 discord:/user:(用户)和 channel:(群组私信)。
- 使用 * 允许任何发送者/频道。
- 当 guilds.<id>.channels 存在时,默认情况下拒绝未列出的频道。
- 当省略 guilds.<id>.channels 时,允许列表公会中的所有频道都被允许。
- 要允许无频道,设置 channels.discord.groupPolicy: "disabled"(或保持空允许列表)。
- 配置向导接受 Guild/Channel 名称(公共 + 私有)并在可能的情况下将它们解析为 ID。
- 在启动时,OpenClaw 将允许列表中的频道/用户名称解析为 ID(当机器人可以搜索成员时)并记录映射;未解析的条目保持输入状态。
原生命令注意事项:
- 注册的命令镜像 OpenClaw 的聊天命令。
- 原生命令遵守与私信/公会消息相同的允许列表(channels.discord.dm.allowFrom、channels.discord.guilds、按频道规则)。
- 斜杠命令可能仍然在 Discord UI 中对未列入允许列表的用户可见;OpenClaw 在执行时强制执行允许列表并回复"not authorized"。
工具操作
代理可以使用以下操作调用 discord:
- react / reactions(添加或列出反应)
- sticker、poll、permissions
- readMessages、sendMessage、editMessage、deleteMessage
- 读取/搜索/置顶工具负载包括规范化的 timestampMs(UTC epoch ms)和 timestampUtc,以及原始 Discord timestamp。
- threadCreate、threadList、threadReply
- pinMessage、unpinMessage、listPins
- searchMessages、memberInfo、roleInfo、roleAdd、roleRemove、emojiList
- channelInfo、channelList、voiceStatus、eventList、eventCreate
- timeout、kick、ban
Discord 消息 ID 在注入的上下文中显示([discord message id: …] 和历史行),以便代理可以定位它们。 表情符号可以是 unicode(例如 ✅)或自定义表情符号语法,如 <:party_blob:1234567890>。
安全和运维
- 将 bot token 视为密码;在受监督的主机上优先使用 DISCORD_BOT_TOKEN 环境变量或锁定配置文件权限。
- 只授予机器人所需的权限(通常是读取/发送消息)。
- 如果机器人卡住或受速率限制,在确认没有其他进程拥有 Discord 会话后重启网关(openclaw gateway --force)。