Discord (Bot API)
状态:已准备好通过官方 Discord 机器人网关支持私信和服务器文本频道。
快速设置(初学者)
- 创建一个 Discord 机器人并复制机器人令牌。
- 在 Discord 应用设置中,启用 消息内容意图(如果计划使用允许列表或名称查找,还需启用 服务器成员意图)。
- 为 openclaw 设置令牌:
- 环境变量:
DISCORD_BOT_TOKEN=... - 或配置:
channels.discord.token: "..." - 如果两者都设置,配置优先(环境变量回退仅适用于默认账户)。
- 环境变量:
- 邀请机器人到您的服务器并授予消息权限(如果只想使用私信,可以创建一个私有服务器)。
- 启动网关。
- 私信访问默认需要配对;首次联系时批准配对码。
最小配置:
{
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 应用 → 机器人,启用您需要的意图(私信 + 服务器消息 + 消息内容),并获取机器人令牌。
- 邀请机器人到您的服务器,授予在您想使用的地方读取/发送消息所需的权限。
- 使用
channels.discord.token(或DISCORD_BOT_TOKEN作为回退)配置 openclaw。 - 运行网关;当令牌可用时(配置优先,环境变量回退)且
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限制。 - 可选的服务器规则:设置
channels.discord.guilds,键为服务器 ID(首选)或 slug,包含按频道规则。 - 可选的本地命令:
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以禁用。 - 反应:代理可以通过
discord工具触发反应(由channels.discord.actions.*控制)。- 反应移除语义:参见 /tools/reactions。
discord工具仅在当前频道是 Discord 时暴露。
- 本地命令使用隔离的会话键(
agent:<agentId>:discord:slash:<userId>)而不是共享的main会话。
注意:名称 → ID 解析使用服务器成员搜索,需要服务器成员意图;如果机器人无法搜索成员,请使用 ID 或 <@id> 提及。 注意:Slug 是小写的,空格替换为 -。频道名称被 slug 化,不带前导的 #。 注意:服务器上下文 [from:] 行包含 author.tag + id,以便轻松进行可 ping 的回复。
配置写入
默认情况下,Discord 允许写入由 /config set|unset 触发的配置更新(需要 commands.config: true)。
禁用方法:
{
channels: { discord: { configWrites: false } }
}如何创建自己的机器人
这是"Discord 开发者门户"设置,用于在服务器(公会)频道(如 #help)中运行 openclaw。
1) 创建 Discord 应用 + 机器人用户
- Discord 开发者门户 → 应用 → 新建应用
- 在您的应用中:
- 机器人 → 添加机器人
- 复制 机器人令牌(这就是您要放入
DISCORD_BOT_TOKEN的内容)
2) 启用 openclaw 需要的网关意图
Discord 会阻止"特权意图",除非您明确启用它们。
在 机器人 → 特权网关意图中,启用:
- 消息内容意图(需要在大多数服务器中读取消息文本;如果没有它,您会看到"使用了不允许的意图"或机器人会连接但不响应消息)
- 服务器成员意图(推荐;需要用于某些成员/用户查找和服务器中的允许列表匹配)
您通常不需要 在线状态意图。
3) 生成邀请 URL(OAuth2 URL 生成器)
在您的应用中:OAuth2 → URL 生成器
范围
- ✅
bot - ✅
applications.commands(本地命令所需)
机器人权限(最小基线)
- ✅ 查看频道
- ✅ 发送消息
- ✅ 读取消息历史记录
- ✅ 嵌入链接
- ✅ 附加文件
- ✅ 添加反应(可选但推荐)
- ✅ 使用外部表情符号/贴纸(可选;仅在需要时使用)
避免使用 管理员 权限,除非您正在调试并完全信任机器人。
复制生成的 URL,打开它,选择您的服务器,并安装机器人。
4) 获取 ID(服务器/用户/频道)
Discord 到处使用数字 ID;openclaw 配置偏好 ID。
- Discord(桌面版/网页版)→ 用户设置 → 高级 → 启用 开发者模式
- 右键点击:
- 服务器名称 → 复制服务器 ID(服务器 ID)
- 频道(例如
#help)→ 复制频道 ID - 您的用户 → 复制用户 ID
5) 配置 openclaw
令牌
通过环境变量设置机器人令牌(在服务器上推荐):
DISCORD_BOT_TOKEN=...
或通过配置:
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN"
}
}
}多账户支持:使用 channels.discord.accounts 包含每个账户的令牌和可选的 name。有关共享模式,请参见 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(可操作的警告 + 快速审计)。 - "使用了不允许的意图":在开发者门户中启用消息内容意图(可能还有服务器成员意图),然后重启网关。
- 机器人连接但从不回复公会频道:
- 缺少消息内容意图,或
- 机器人缺少频道权限(查看/发送/读取历史),或
- 你的配置需要提及但你没有提及它,或
- 你的公会/频道白名单拒绝了频道/用户。
requireMention: false但仍然没有回复:channels.discord.groupPolicy默认为白名单;将其设置为"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。如果你使用别名/名称作为channels.discord.guilds.*.channels键,审计无法验证权限。 - DM不工作:
channels.discord.dm.enabled=false、channels.discord.dm.policy="disabled",或者你尚未被批准(channels.discord.dm.policy="pairing")。
功能与限制
- DM和公会文本频道(线程被视为单独的频道;不支持语音)。
- 打字指示器尽力发送;消息分块使用
channels.discord.textChunkLimit(默认2000)并按行数分割长回复(channels.discord.maxLinesPerMessage,默认17)。 - 可选的新行分块:设置
channels.discord.chunkMode="newline"在长度分块前按空行(段落边界)分割。 - 支持文件上传,最大为配置的
channels.discord.mediaMaxMb(默认8 MB)。 - 默认提及门控公会回复以避免嘈杂的机器人。
- 当消息引用另一条消息时注入回复上下文(引用内容 + ID)。
- 原生回复线程默认关闭;使用
channels.discord.replyToMode和回复标签启用。
重试策略
出站Discord API调用在遇到速率限制(429)时重试,使用Discord的 retry_after(如果可用),采用指数退避和抖动。通过 channels.discord.retry 配置。参见重试策略。
Config
{
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: ["clawd-dm"]
},
guilds: {
"*": { requireMention: true },
"123456789012345678": {
slug: "friends-of-clawd",
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 在机器人回复后清除确认反应。
dm.enabled:设置为false以忽略所有DM(默认true)。dm.policy:DM访问控制(推荐pairing)。"open"需要dm.allowFrom=["*"]。dm.allowFrom:DM白名单(用户ID或名称)。用于dm.policy="allowlist"和dm.policy="open"验证。向导接受用户名并在机器人可以搜索成员时将其解析为ID。dm.groupEnabled:启用群组DM(默认false)。dm.groupChannels:群组DM频道ID或别名的可选白名单。groupPolicy:控制公会频道处理(open|disabled|allowlist);allowlist需要频道白名单。guilds:按公会ID(首选)或别名键控的每个公会规则。guilds."*":当没有显式条目时应用的默认每个公会设置。guilds.<id>.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: 频道规则(键是频道别名或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: 用户回合中的DM历史限制。每个用户覆盖:dms["<user_id>"].historyLimit。retry: 出站Discord API调用的重试策略(尝试次数、minDelayMs、maxDelayMs、抖动)。actions: 每个操作的工具门控;省略以允许所有(设置为false以禁用)。reactions(包括react + read reactions)stickers、emojiUploads、stickerUploads、polls、permissions、messages、threads、pins、searchmemberInfo、roleInfo、channelInfo、voiceStatus、eventschannels(创建/编辑/删除频道 + 类别 + 权限)roles(角色添加/移除,默认false)moderation(超时/踢出/封禁,默认false)
反应通知使用 guilds.<id>.reactionNotifications:
off: 无反应事件。own: 机器人自己消息上的反应(默认)。all: 所有消息上的所有反应。allowlist: 来自guilds.<id>.users的所有消息上的反应(空列表禁用)。
工具操作默认值
| 操作组 | 默认值 | 说明 |
|---|---|---|
| reactions | 启用 | 反应 + 列出反应 + emojiList |
| stickers | 启用 | 发送贴纸 |
| emojiUploads | 启用 | 上传表情符号 |
| stickerUploads | 启用 | 上传贴纸 |
| polls | 启用 | 创建投票 |
| permissions | 启用 | 频道权限快照 |
| messages | 启用 | 读取/发送/编辑/删除 |
| threads | 启用 | 创建/列出/回复 |
| pins | 启用 | 固定/取消固定/列出 |
| search | 启用 | 消息搜索(预览功能) |
| memberInfo | 启用 | 成员信息 |
| roleInfo | 启用 | 角色列表 |
| channelInfo | 启用 | 频道信息 + 列表 |
| channels | 启用 | 频道/类别管理 |
| voiceStatus | 启用 | 语音状态查找 |
| events | 启用 | 列出/创建计划事件 |
| roles | 禁用 | 角色添加/移除 |
| moderation | 禁用 | 超时/踢出/封禁 |
replyToMode:off(默认)、first或all。仅当模型包含回复标签时应用。
回复标签
要请求线程回复,模型可以在其输出中包含一个标签:
[[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:(群组DM)。 - 使用
*允许任何发送者/频道。 - 当
guilds.<id>.channels存在时,未列出的频道默认被拒绝。 - 当
guilds.<id>.channels省略时,白名单公会中的所有频道都被允许。 - 要允许没有频道,设置
channels.discord.groupPolicy: "disabled"(或保持空的白名单)。 - 配置向导接受
Guild/Channel名称(公共 + 私有)并在可能时将其解析为ID。 - 启动时,openclaw将白名单中的频道/用户名称解析为ID(当机器人可以搜索成员时) 并记录映射关系;未解析的条目保持原样。
原生命令注意事项:
- 注册的命令镜像openclaw的聊天命令。
- 原生命令遵循与DM/公会消息相同的白名单(
channels.discord.dm.allowFrom、channels.discord.guilds、每个频道规则)。 - 斜杠命令在Discord UI中可能仍然对不在白名单中的用户可见;openclaw在执行时强制执行白名单并回复“未授权”。
工具操作
代理可以调用 discord 执行以下操作:
react/reactions(添加或列出反应)sticker、poll、permissionsreadMessages、sendMessage、editMessage、deleteMessage- 读取/搜索/固定工具负载包括标准化的
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: …] 和历史行),以便代理可以定位它们。 表情符号可以是Unicode(例如,✅)或自定义表情符号语法如 <:party_blob:1234567890>。
安全与运维
- 将机器人令牌视为密码;在受监管的主机上首选
DISCORD_BOT_TOKEN环境变量或锁定配置文件权限。 - 仅授予机器人所需的权限(通常是读取/发送消息)。
- 如果机器人卡住或受到速率限制,在确认没有其他进程拥有Discord会话后重启网关(
openclaw gateway --force)。