Skip to content

Discord (Bot API)

状态:已准备就绪,通过官方 Discord 机器人网关支持私信和服务器文字频道。

快速设置(初学者)

  1. 创建一个 Discord 机器人并复制机器人令牌。
  2. 在 Discord 应用设置中,启用 Message Content Intent(以及 Server Members Intent,如果您计划使用白名单或名称查找)。
  3. 为 OpenClaw 设置令牌:
    • 环境变量:DISCORD_BOT_TOKEN=...
    • 或配置:channels.discord.token: "..."
    • 如果两者都设置,配置优先(环境变量回退仅用于默认账户)。
  4. 使用消息权限将机器人邀请到您的服务器(如果您只想使用私信,可以创建一个私有服务器)。
  5. 启动网关。
  6. 私信访问默认需要配对;首次联系时批准配对代码。

最小配置:

json5
{
  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 限制。
  • 保持路由确定性:回复始终返回到消息到达的频道。

工作原理

  1. 创建 Discord 应用程序 → 机器人,启用所需的意图(私信 + 服务器消息 + 消息内容),并获取机器人令牌。
  2. 使用所需权限将机器人邀请到您的服务器,以便在您想使用它的地方读取/发送消息。
  3. 使用 channels.discord.token(或 DISCORD_BOT_TOKEN 作为回退)配置 OpenClaw。
  4. 运行网关;当令牌可用时(配置优先,环境变量回退),且 channels.discord.enabled 不是 false 时,它会自动启动 Discord 频道。
    • 如果您更喜欢环境变量,设置 DISCORD_BOT_TOKEN(配置块是可选的)。
  5. 私信:在投递时使用 user:<id>(或 <@id> 提及);所有轮次都落在共享的 main 会话中。纯数字 ID 是不明确的,会被拒绝。
  6. 服务器频道:使用 channel:<channelId> 进行投递。默认需要提及,可以按服务器或按频道设置。
  7. 私信:默认通过 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=falsechannels.discord.dm.policy="disabled"
  8. 默认忽略群组私信;通过 channels.discord.dm.groupEnabled 启用,可选通过 channels.discord.dm.groupChannels 限制。
  9. 可选服务器规则:设置 channels.discord.guilds,按服务器 id(首选)或 slug 键入,带有每个频道的规则。
  10. 可选原生命令:commands.native 默认为 "auto"(Discord/Telegram 开启,Slack 关闭)。使用 channels.discord.commands.native: true|false|"auto" 覆盖;false 清除先前注册的命令。文本命令由 commands.text 控制,必须作为独立的 /... 消息发送。使用 commands.useAccessGroups: false 为命令绕过访问组检查。
  11. 可选服务器上下文历史:设置 channels.discord.historyLimit(默认 20,回退到 messages.groupChat.historyLimit),以在回复提及时包含最后 N 条服务器消息作为上下文。设置 0 以禁用。
  12. 反应:代理可以通过 discord 工具触发反应(由 channels.discord.actions.* 控制)。
    • 反应移除语义:参见 /tools/reactions
    • discord 工具仅在当前频道是 Discord 时暴露。
  13. 原生命令使用隔离的会话键(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)。

使用以下方式禁用:

json5
{
  channels: { discord: { configWrites: false } },
}

如何创建您自己的机器人

这是在服务器(guild)频道(如 #help)中运行 OpenClaw 的"Discord 开发者门户"设置。

1) 创建 Discord 应用 + 机器人用户

  1. Discord 开发者门户 → ApplicationsNew Application
  2. 在您的应用中:
    • BotAdd Bot
    • 复制 Bot Token(这是您放入 DISCORD_BOT_TOKEN 的内容)

2) 启用 OpenClaw 需要的网关意图

Discord 会阻止"特权意图",除非您明确启用它们。

BotPrivileged Gateway Intents 中,启用:

  • Message Content Intent(在大多数服务器中读取消息文本所必需;没有它,您会看到"使用了不允许的意图"或机器人会连接但不对消息做出反应)
  • Server Members Intent(推荐;在服务器中进行某些成员/用户查找和白名单匹配所必需)

您通常不需要 Presence Intent。设置机器人自己的在线状态(setPresence 操作)使用网关 OP3,不需要此意图;只有当您想接收关于其他服务器成员的在线状态更新时才需要它。

3) 生成邀请 URL(OAuth2 URL Generator)

在您的应用中:OAuth2URL 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(服务器/用户/频道)

Discord 在所有地方都使用数字 id;OpenClaw 配置更喜欢 id。

  1. Discord(桌面/网页)→ 用户设置高级 → 启用 开发者模式
  2. 右键单击:
    • 服务器名称 → 复制服务器 ID(服务器 id)
    • 频道(例如 #help)→ 复制频道 ID
    • 您的用户 → 复制用户 ID

5) 配置 OpenClaw

令牌

通过环境变量设置机器人令牌(在服务器上推荐):

  • DISCORD_BOT_TOKEN=...

或通过配置:

json5
{
  channels: {
    discord: {
      enabled: true,
      token: "YOUR_BOT_TOKEN",
    },
  },
}

多账户支持:使用 channels.discord.accounts,带有每个账户的令牌和可选的 name。参见 gateway/configuration 以了解共享模式。

白名单 + 频道路由

示例"单个服务器,只允许我,只允许 #help":

json5
{
  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),请使用 requireMentionchannels.discord.guilds.*.channels.<id>.users 白名单和/或 AGENTS.mdSOUL.md 中的明确防护措施来防止机器人之间的回复循环。

6) 验证它是否工作

  1. 启动网关。
  2. 在您的服务器频道中,发送:@Krill hello(或您的机器人名称)。
  3. 如果没有任何反应:检查下面的 故障排除

故障排除

  • 首先:运行 openclaw doctoropenclaw channels status --probe(可操作的警告 + 快速审计)。
  • "使用了不允许的意图":在开发者门户中启用 Message Content Intent(以及可能的 Server Members Intent),然后重启网关。
  • 机器人连接但从不在服务器频道中回复:
    • 缺少 Message Content Intent,或
    • 机器人缺少频道权限(查看/发送/读取历史),或
    • 您的配置需要提及但您没有提及它,或
    • 您的服务器/频道白名单拒绝了该频道/用户。
  • requireMention: false 但仍然没有回复:
  • channels.discord.groupPolicy 默认为 白名单;将其设置为 "open" 或在 channels.discord.guilds 下添加服务器条目(可选在 channels.discord.guilds.<id>.channels 下列出频道以限制)。
    • 如果您只设置 DISCORD_BOT_TOKEN 而从不创建 channels.discord 部分,运行时 将 groupPolicy 默认为 open。添加 channels.discord.groupPolicychannels.defaults.groupPolicy 或服务器/频道白名单来锁定它。
  • requireMention 必须位于 channels.discord.guilds(或特定频道)下。顶级的 channels.discord.requireMention 会被忽略。
  • 权限审计(channels status --probe)仅检查数字频道 ID。如果您使用 slug/名称作为 channels.discord.guilds.*.channels 键,审计无法验证权限。
  • 私信不工作:channels.discord.dm.enabled=falsechannels.discord.dm.policy="disabled" 或您尚未被批准(channels.discord.dm.policy="pairing")。
  • Discord 中的执行批准:Discord 支持私信中的 按钮 UI 用于执行批准(允许一次/始终允许/拒绝)。/approve <id> ... 仅用于转发的批准,不会解析 Discord 的按钮提示。如果您看到 ❌ Failed to submit approval: Error: unknown approval id 或 UI 从未显示,请检查:
    • 您的配置中的 channels.discord.execApprovals.enabled: true
    • 您的 Discord 用户 ID 列在 channels.discord.execApprovals.approvers 中(UI 仅发送给批准者)。
    • 在私信提示中使用按钮(允许一次始终允许拒绝)。
    • 参见 执行批准斜杠命令 以了解更广泛的批准和命令流程。

功能和限制

  • 私信和服务器文字频道(线程被视为单独的频道;不支持语音)。
  • 尽力发送输入指示器;消息分块使用 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 配置。参见 重试策略

配置

json5
{
  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,
        presence: 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 在机器人回复后清除 确认反应。

  • 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:反应系统事件模式(offownallallowlist)。
  • textChunkLimit:出站文本块大小(字符)。默认:2000。
  • chunkMode:length(默认)仅在超过 textChunkLimit 时拆分;newline 在长度分块之前在空行(段落边界)上拆分。
  • maxLinesPerMessage:每条消息的软最大行数。默认:17。
  • mediaMaxMb:限制保存到磁盘的入站媒体。
  • historyLimit:在回复提及时包含的最近服务器消息数量作为上下文(默认 20;回退到 messages.groupChat.historyLimit;0 禁用)。
  • dmHistoryLimit:用户轮次的私信历史限制。每个用户覆盖:dms["<user_id>"].historyLimit
  • retry:出站 Discord API 调用的重试策略(尝试次数、minDelayMs、maxDelayMs、抖动)。
  • pluralkit:解析 PluralKit 代理消息,以便系统成员显示为不同的发送者。
  • actions:每个操作的工具门控;省略以允许所有(设置 false 以禁用)。
    • reactions(涵盖反应 + 读取反应)
    • stickersemojiUploadsstickerUploadspollspermissionsmessagesthreadspinssearch
    • memberInforoleInfochannelInfovoiceStatusevents
    • channels(创建/编辑/删除频道 + 类别 + 权限)
    • roles(角色添加/移除,默认 false)
    • moderation(超时/踢出/封禁,默认 false)
    • presence(机器人状态/活动,默认 false)
  • execApprovals:仅限 Discord 的执行批准私信(按钮 UI)。支持 enabledapproversagentFiltersessionFilter

反应通知使用 guilds.<id>.reactionNotifications:

  • off:无反应事件。
  • own:机器人自己消息上的反应(默认)。
  • all:所有消息上的所有反应。
  • allowlist:来自 guilds.<id>.users 的所有消息上的反应(空列表禁用)。

PluralKit (PK) 支持

启用 PK 查找,以便代理消息解析到底层系统 + 成员。 启用后,OpenClaw 使用成员身份进行白名单,并将 发送者标记为 Member (PK:System),以避免意外的 Discord ping。

json5
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // optional; required for private systems
      },
    },
  },
}

白名单注意事项(启用 PK):

  • dm.allowFromguilds.<id>.users 或每个频道的 users 中使用 pk:<memberId>
  • 成员显示名称也按名称/slug 匹配。
  • 查找使用原始 Discord 消息 ID(预代理消息),因此 PK API 仅在其 30 分钟窗口内解析它。
  • 如果 PK 查找失败(例如,没有令牌的私有系统),代理消息 被视为机器人消息,除非 channels.discord.allowBots=true,否则会被丢弃。

工具操作默认值

操作组默认值注意
reactions启用反应 + 列出反应 + 表情符号列表
stickers启用发送贴纸
emojiUploads启用上传表情符号
stickerUploads启用上传贴纸
polls启用创建投票
permissions启用频道权限快照
messages启用读取/发送/编辑/删除
threads启用创建/列出/回复
pins启用固定/取消固定/列出
search启用消息搜索(预览功能)
memberInfo启用成员信息
roleInfo启用角色列表
channelInfo启用频道信息 + 列表
channels启用频道/类别管理
voiceStatus启用语音状态查找
events启用列出/创建计划事件
roles禁用角色添加/移除
moderation禁用超时/踢出/封禁
presence禁用机器人状态/活动(setPresence)
  • replyToMode:off(默认)、firstall。仅在模型包含回复标签时应用。

回复标签

要请求线程回复,模型可以在其输出中包含一个标签:

  • [[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.allowFromchannels.discord.guilds、每个频道规则)。
  • 斜杠命令可能仍然在 Discord UI 中对未列入白名单的用户可见;OpenClaw 在执行时强制执行白名单,并回复"未授权"。

工具操作

代理可以调用 discord,带有如下操作:

  • react / reactions(添加或列出反应)
  • stickerpollpermissions
  • readMessagessendMessageeditMessagedeleteMessage
  • 读取/搜索/固定工具有效负载包括规范化的 timestampMs(UTC 纪元毫秒)和 timestampUtc,以及原始 Discord timestamp
  • threadCreatethreadListthreadReply
  • pinMessageunpinMessagelistPins
  • searchMessagesmemberInforoleInforoleAddroleRemoveemojiList
  • channelInfochannelListvoiceStatuseventListeventCreate
  • timeoutkickban
  • setPresence(机器人活动和在线状态)

Discord 消息 id 在注入的上下文([discord message id: …] 和历史行)中显示,以便代理可以定位它们。 表情符号可以是 unicode(例如,)或自定义表情符号语法,如 <:party_blob:1234567890>

安全和操作

  • 像对待密码一样对待机器人令牌;在受监督的主机上优先使用 DISCORD_BOT_TOKEN 环境变量,或锁定配置文件权限。
  • 仅授予机器人所需的权限(通常是读取/发送消息)。
  • 如果机器人卡住或速率受限,在确认没有其他进程拥有 Discord 会话后重启网关(openclaw gateway --force)。