访问控制
谁可以联系机器人、它在哪些公会频道中回复,以及允许它执行哪些 Discord 操作。
访问控制与路由¶
channels.discord.dmPolicy 控制 DM 访问权限。channels.discord.allowFrom 是规范的 DM 允许列表。
pairing(默认)allowlist(至少需要一个allowFrom发送者)open(要求channels.discord.allowFrom包含"*")disabled
如果 DM 策略不是 open,未知用户将被阻止(在 pairing 模式下会提示进行配对)。
多账户优先级:
- 省略账户的
dmPolicy和groupPolicy时,继承频道根设置。显式账户策略优先;若两个作用域均未设置,默认值分别为pairing和allowlist。 channels.discord.accounts.default.allowFrom仅适用于default账户。- 对于单个账户,
allowFrom优先于旧版dm.allowFrom。 - 具名账户在自身
allowFrom和旧版dm.allowFrom均未设置时,继承channels.discord.allowFrom。 - 具名账户不继承
channels.discord.accounts.default.allowFrom。
旧版 channels.discord.dm.policy 和 channels.discord.dm.allowFrom 仍会出于兼容性被读取。openclaw doctor --fix 会在不改变访问权限的前提下将其迁移为 dmPolicy 和 allowFrom。
用于投递的 DM 目标格式:
user:<id><@id>提及
在频道默认值生效时,纯数字 ID 通常会解析为频道 ID;但账户有效 DM allowFrom 中列出的 ID 会出于兼容性被视为用户 DM 目标。
在 `channels.discord.allowFrom` 中,Discord DM 和文本命令授权可以使用动态的 `accessGroup:<name>` 条目。
访问组名称在所有消息频道间共享。对于静态组,使用 `type: "message.senders"`,其成员以各频道正常的 `allowFrom` 语法表示;当 Discord 频道当前的 `ViewChannel` 受众应动态定义成员资格时,使用 `type: "discord.channelAudience"`。共享访问组行为:[访问组](../access-groups.md)。
{
accessGroups: {
operators: {
type: "message.senders",
members: {
"*": ["global-owner-id"],
discord: ["discord:123456789012345678"],
telegram: ["987654321"],
},
},
},
channels: {
discord: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:operators"],
},
},
}
Discord 文本频道没有独立的成员列表。`type: "discord.channelAudience"` 将成员资格建模为:DM 发送者是所配置公会的成员,并且在应用角色和频道覆盖设置后,当前对所配置频道拥有有效的 `ViewChannel` 权限。
示例:允许任何能看到 `#maintainers` 的人向机器人发送 DM,同时保持 DM 对其他所有人关闭。
{
accessGroups: {
maintainers: {
type: "discord.channelAudience",
guildId: "1456350064065904867",
channelId: "1456744319972282449",
membership: "canViewChannel",
},
},
channels: {
discord: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:maintainers"],
},
},
}
你可以混合使用动态和静态条目:
{
accessGroups: {
maintainers: {
type: "discord.channelAudience",
guildId: "1456350064065904867",
channelId: "1456744319972282449",
},
},
channels: {
discord: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:maintainers", "discord:123456789012345678"],
},
},
}
查找失败时默认拒绝。如果 Discord 返回 `Missing Access`、成员查找失败,或者频道属于不同的公会,则 DM 发送者被视为未经授权。
使用频道受众访问组时,请启用 Discord 开发者门户的 **Server Members Intent**。DM 不包含公会成员状态,因此 OpenClaw 会在授权时通过 Discord REST 解析成员。
公会处理由 `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: { enabled: true },
help: { enabled: true, requireMention: true },
},
},
},
},
},
}
旧的每频道 `allow` 键由 `openclaw doctor --fix` 迁移为 `enabled`。
如果没有 `channels.discord` 块,网关不会从 `DISCORD_BOT_TOKEN` 自动启动 Discord。一旦该块存在,`DISCORD_BOT_TOKEN` 仍作为默认账户的令牌回退。传入 `--ambient-channels` 会选择仅环境变量的自动配置;该路径使用 `groupPolicy="allowlist"` 并记录警告,即使 `channels.defaults.groupPolicy` 为 `open`。
默认情况下,公会消息受提及(mention)机制约束。
提及检测包括:
- 显式提及机器人
- 已配置的提及模式(
agents.entries.*.groupChat.mentionPatterns,回退到messages.groupChat.mentionPatterns) - 在受支持的情况下,隐式的回复机器人行为
在编写外发的 Discord 消息时,请使用规范的提及语法:用户使用 <@USER_ID>,频道使用 <#CHANNEL_ID>,身份组使用 <@&ROLE_ID>。不要使用旧的 <@!USER_ID> 昵称提及形式。
requireMention 按公会/频道进行配置(channels.discord.guilds...)。
在公会或频道上设置 requireMentionInBotThreads: false,即可接受在由该机器人创建的线程(包括通过消息工具创建的线程)中未提及机器人的后续消息。频道设置会覆盖公会设置。将其设为 true 则需要在这些线程中提及机器人,包括启用 autoThread 时;仅靠对话式回复机器人信号无法绕过该要求。省略该设置则保留现有行为:只有在启用 autoThread 时,机器人拥有的线程才能绕过提及要求。绑定到线程的会话保留其自身的路由激活规则。
将此合并到现有的公会条目中,同时保留其频道和发送者白名单:
{
channels: {
discord: {
intents: { messageContent: true },
guilds: {
"123456789012345678": {
requireMention: true,
requireMentionInBotThreads: false,
},
},
},
},
}
对于命名账户,请使用 channels.discord.accounts.<accountId>.intents 和 .guilds。若要将覆盖范围限制为单个父频道,请在其现有公会的 channels.<channelId> 条目中添加 requireMentionInBotThreads: false。添加新的频道映射也会改变公会白名单。
公会/频道和发送者白名单仍然适用。父频道以及其他用户创建的线程保留其配置的提及要求;线程属主不明时不启用该覆盖。请在 Discord 开发者门户中启用 Message Content Intent,并在 OpenClaw 中启用 intents.messageContent。否则,Discord 会省略普通的未提及公会消息内容。验证方法:让机器人创建一个线程,然后从允许的账户在该线程中发送一条未提及的后续消息。其他频道请参阅机器人创建线程策略。
ignoreOtherMentions 可选地丢弃那些发给其他身份(而非本机器人)的消息。这包括显式的用户/身份组提及(不包括 @everyone/@here),以及对其他非 webhook 机器人的回复。显式提及当前机器人仍然优先。
群组私信(Group DM):
- 默认:忽略(
dm.groupEnabled=false) - 可通过
dm.groupChannels配置可选白名单(频道 ID 或 slug)
公会频道映射是白名单¶
没有 channels 映射的公会条目会让机器人在其能看到的每个频道中工作,但须遵守公会的 requireMention 和 users 规则。即使只添加一个频道条目,该映射也会变成白名单:任何未被条目匹配的频道都会被拒绝,而不只是沿用公会默认设置。
这会让那些只想给某个频道添加特殊设置、结果发现机器人在其他所有地方都不再响应的人感到意外。使用 "*" 通配符键可保持公会其余部分可访问:
{
channels: {
discord: {
guilds: {
YOUR_SERVER_ID: {
requireMention: true,
users: ["YOUR_USER_ID"],
channels: {
// always-on room: everyone in it can talk to the bot, no mention needed
YOUR_CHANNEL_ID: { enabled: true, requireMention: false, users: ["*"] },
// every other channel keeps the guild defaults
"*": { enabled: true, requireMention: true },
},
},
},
},
},
}
频道条目会覆盖公会级别的值,因此带有 users: ["*"] 的频道条目会将这一个房间开放给任何发送者,即使公会的 users 列表范围很窄。条目按频道 ID、名称或 slug 匹配;如果某频道是线程,则回退使用其父频道的条目。
应用访问策略变更¶
对于正在运行的 Discord 账户,仅在 Control UI 中保存策略变更,即可通过 Gateway 的已验证运行时配置发布机制生效,无需重启 Discord 连接,也无需等待进行中的 Control UI 回合结束。这涵盖 groupPolicy、dmPolicy、allowFrom、dm、guilds、allowBots 和 dangerouslyAllowNameMatching,既包括 channels.discord 级别,也包括 channels.discord.accounts.<accountId> 之下。
新消息和交互都会使用已发布的策略,包括公会/频道成员资格、用户和身份组白名单以及提及要求。基于名称的条目会在准入之前,按相应的策略修订版进行解析并缓存;已准入的处理保留其现有上下文。如果名称策略查找无法在交互的响应预算内完成,组件会显示一条临时的“策略更新中”消息,自动补全也不返回任何选项。之后的交互会使用已解析的策略;过期的交互不会被恢复。
令牌、应用程序 ID、代理、intents、命令注册、语音配置和账户启用仍走该频道的重启路径和排空推迟(drain deferral)。同时包含策略设置和需要重启的设置的写入,仍作为同一个延迟事务处理。手动停止/启动频道会读取已提交的配置;它不会将磁盘上待处理的传输变更发布出去。
基于身份组的智能体路由¶
使用 bindings[].match.roles 按身份组 ID 将 Discord 公会成员路由到不同的智能体。基于身份组的绑定只接受身份组 ID,并且会在对等(peer)或父级-对等绑定之后、仅限公会的绑定之前进行评估。如果某个绑定还设置了其他匹配字段(例如 peer + guildId + roles),则所有已配置的字段都必须匹配。
{
bindings: [
{
agentId: "opus",
match: {
channel: "discord",
guildId: "123456789012345678",
roles: ["111111111111111111"],
},
},
{
agentId: "sonnet",
match: {
channel: "discord",
guildId: "123456789012345678",
},
},
],
}
原生命令与命令鉴权¶
commands.native默认为"auto",并对 Discord 启用。- 按频道覆盖:
channels.discord.commands.native。 commands.native=false会在启动时跳过 Discord 斜杠命令注册和清理。之前注册的命令可能仍会显示在 Discord 中,直到你从 Discord 应用中移除它们。- 原生命令鉴权使用与常规消息处理相同的 Discord 允许列表/策略。
- 对于未授权用户,命令可能仍会显示在 Discord 界面中;执行时会强制 OpenClaw 鉴权,并回复 "not authorized"。
- 默认斜杠命令设置:
ephemeral: true(channels.discord.slashCommand.ephemeral)。
有关命令目录和行为,请参阅 斜杠命令。
工具与操作门控¶
Discord 消息操作涵盖消息、频道管理、审核、在线状态和元数据。
核心示例:
- 消息:
sendMessage、readMessages、editMessage、deleteMessage、threadReply - 表情回应:
react、reactions、emoji-list - 审核:
timeout、kick、ban - 在线状态:
setPresence
使用 emoji-list 发现当前服务器的自定义表情:
guildId 默认为当前对话所在的服务器;如需查询其他服务器,请显式提供。结果按名称排序,limit 默认为 100,且不能超过 100:
{
"ok": true,
"emojis": [
{ "name": "dance", "identifier": "dance:456", "animated": true },
{ "name": "party", "identifier": "party:123" }
]
}
将 identifier 直接传递给 react。Discord 接受 Unicode 表情、自定义 name:id 标识符,以及 <:name:id> 或 <a:name:id> 形式。emoji-list、react 和 reactions 均由 channels.discord.actions.reactions 控制。
event-create 操作接受可选的 image 参数(URL 或本地文件路径),用于设置计划事件的封面图片。
操作门控位于 channels.discord.actions.* 下。
默认门控行为:
| 操作组 | 默认 |
|---|---|
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 启用 |
| roles | 禁用 |
| moderation | 禁用 |
| presence | 禁用 |
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw