Skip to main content

Documentation Index

Fetch the complete documentation index at: https://openclaw.zhcndoc.com/llms.txt

Use this file to discover all available pages before exploring further.

可通过官方 Discord 网关用于私信和服务器频道。

配对

Discord 私信默认使用配对模式。

斜杠命令

原生命令行为和命令目录。

频道故障排除

跨频道诊断和修复流程。

快速设置

你需要创建一个带有 bot 的新应用,将 bot 添加到你的服务器,并将其配对到 OpenClaw。我们建议将 bot 添加到你自己的私人服务器。如果你还没有服务器,先创建一个(选择 Create My Own > For me and my friends)。
1

创建 Discord 应用和 bot

前往 Discord Developer Portal,点击 New Application。将其命名为类似 “OpenClaw” 的名称。点击侧边栏中的 Bot。将 Username 设置为你给 OpenClaw 代理起的名称。
2

启用特权 intents

仍在 Bot 页面,向下滚动到 Privileged Gateway Intents 并启用:
  • Message Content Intent(必需)
  • Server Members Intent(推荐;角色白名单和名称到 ID 匹配所必需)
  • Presence Intent(可选;仅在需要 presence 更新时使用)
3

复制你的 bot token

返回 Bot 页面顶部并点击 Reset Token
尽管名字如此,这会生成你的第一个 token —— 并没有发生任何“重置”。
复制该 token 并保存到某处。这就是你的 Bot Token,你很快就会用到它。
4

生成邀请 URL 并将 bot 添加到你的服务器

点击侧边栏中的 OAuth2。你将生成一个具有正确权限的邀请 URL,以便将 bot 添加到你的服务器。向下滚动到 OAuth2 URL Generator 并启用:
  • bot
  • applications.commands
下方会出现 Bot Permissions 部分。至少启用:General Permissions
  • 查看频道 Text Permissions
  • 发送消息
  • 读取消息历史
  • 嵌入链接
  • 附加文件
  • 添加表情反应(可选)
这是普通文本频道的基础权限集合。如果你计划在 Discord 线程中发帖,包括会创建或继续线程的论坛或媒体频道工作流,也请启用 在线程中发送消息。 复制底部生成的 URL,将其粘贴到浏览器中,选择你的服务器,然后点击 Continue 进行连接。现在你应该可以在 Discord 服务器中看到你的 bot 了。
5

启用开发者模式并收集你的 ID

回到 Discord 应用中,你需要启用开发者模式,以便复制内部 ID。
  1. 点击 User Settings(头像旁的齿轮图标)→ Advanced → 打开 Developer Mode
  2. 右键单击侧边栏中的 server iconCopy Server ID
  3. 右键单击你自己的 avatarCopy User ID
将你的 Server IDUser ID 与 Bot Token 一起保存——下一步你会把这三者都发送给 OpenClaw。
6

允许来自服务器成员的私信

为了让配对生效,Discord 需要允许你的 bot 向你发送私信。右键单击你的 server iconPrivacy Settings → 打开 Direct Messages这允许服务器成员(包括 bot)向你发送私信。如果你希望使用 Discord 私信与 OpenClaw 交互,请保持启用此项。如果你只打算使用服务器频道,可以在配对后禁用私信。
7

安全设置你的 bot token(不要在聊天中发送)

你的 Discord bot token 是机密信息(类似密码)。在向你的代理发送消息之前,请将它设置到运行 OpenClaw 的机器上。
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
cat > discord.patch.json5 <<'JSON5'
{
  channels: {
    discord: {
      enabled: true,
      token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
    },
  },
}
JSON5
openclaw config patch --file ./discord.patch.json5 --dry-run
openclaw config patch --file ./discord.patch.json5
openclaw gateway
如果 OpenClaw 已作为后台服务运行,请通过 OpenClaw Mac 应用重启它,或停止并重新启动 openclaw gateway run 进程。 对于托管服务安装,请在包含 DISCORD_BOT_TOKEN 的 shell 中运行 openclaw gateway install,或将该变量存储在 ~/.openclaw/.env 中,这样服务在重启后就能解析该 env SecretRef。 如果你的主机因 Discord 启动时的应用查询而被阻止或限流,请从 Developer Portal 设置 Discord application/client ID,以便启动时跳过该 REST 调用。默认账户使用 channels.discord.applicationId,当你运行多个 Discord bot 时,则使用 channels.discord.accounts.<accountId>.applicationId
8

配置 OpenClaw 并完成配对

在任何现有频道(例如 Telegram)中与 OpenClaw 代理聊天并告诉它。如果 Discord 是你的第一个频道,请改用 CLI / config 选项卡。
“我已经在 config 中设置好了我的 Discord bot token。请使用 User ID <user_id> 和 Server ID <server_id> 完成 Discord 设置。”
9

批准首次 DM 配对

等待网关运行,然后在 Discord 中向你的 bot 发送私信。它会返回一个配对码。
在你现有频道中将配对码发送给你的代理:
“批准这个 Discord 配对码:<CODE>
配对码在 1 小时后过期。现在你应该可以通过 DM 在 Discord 中与代理聊天了。
令牌解析会感知账户。配置中的 token 值优先于 env 回退。DISCORD_BOT_TOKEN 仅用于默认账户。 如果两个已启用的 Discord 账户解析到同一个 bot token,OpenClaw 只会为该 token 启动一个网关监视器。来自配置的 token 优先于默认 env 回退;否则,首先启用的账户获胜,重复账户会被报告为已禁用。 对于高级出站调用(消息工具/频道操作),该调用会使用显式的每次调用 token。这适用于发送和读取/探测类操作(例如 read/search/fetch/thread/pins/permissions)。账户策略/重试设置仍来自活动运行时快照中选定的账户。

推荐:设置服务器工作区

一旦 DM 正常工作,你就可以将 Discord 服务器设置为一个完整的工作区,让每个频道都有自己的代理会话和独立上下文。这对于只有你和 bot 的私人服务器来说很适合。
1

将你的服务器加入服务器白名单

这使你的代理能够在服务器上的任何频道中响应,而不仅仅是 DM。
“将我的 Discord Server ID <server_id> 添加到服务器白名单”
2

允许在没有 @mention 的情况下响应

默认情况下,你的代理只会在服务器频道中被 @mention 时才响应。对于私人服务器,你可能希望它响应每条消息。在服务器频道中,普通助手的最终回复默认保持私有。可见的 Discord 输出必须通过 message 工具显式发送,这样代理就可以默认潜伏,只有在它认为频道回复有用时才发帖。
“允许我的代理在这个服务器上响应,而不必被 @mention”
3

规划服务器频道中的记忆

默认情况下,长期记忆(MEMORY.md)只会加载到 DM 会话中。服务器频道不会自动加载 MEMORY.md。
“当我在 Discord 频道中提问时,如果你需要来自 MEMORY.md 的长期上下文,请使用 memory_search 或 memory_get。”
现在在你的 Discord 服务器上创建一些频道并开始聊天。你的代理可以看到频道名称,并且每个频道都有自己独立的会话——因此你可以设置 #coding#home#research,或者任何适合你工作流的频道。

运行时模型

  • Gateway 负责 Discord 连接。
  • 回复路由是确定性的:Discord 的入站回复会回到 Discord。
  • Discord 服务器/频道元数据会作为不受信任的上下文添加到模型提示中,而不是作为对用户可见的回复前缀。如果模型将该封装复制回去,OpenClaw 会从出站回复以及未来的回放上下文中剥离复制的元数据。
  • 默认情况下(session.dmScope=main),直接聊天共享代理主会话(agent:main:main)。
  • 服务器频道是隔离的会话键(agent:<agentId>:discord:channel:<channelId>)。
  • 群组 DM 默认被忽略(channels.discord.dm.groupEnabled=false)。
  • 原生斜杠命令在隔离的命令会话中运行(agent:<agentId>:discord:slash:<userId>),同时仍携带指向路由会话的 CommandTargetSessionKey
  • 仅文本的 cron/heartbeat 宣告发往 Discord 时,会使用最终的、用户可见的助手答案一次。媒体和结构化组件载荷在代理发出多个可交付载荷时仍保持多消息。

论坛频道

Discord 论坛和媒体频道只接受线程帖子。OpenClaw 支持两种创建方式:
  • 向论坛父频道发送消息(channel:<forumId>)以自动创建线程。线程标题使用消息中第一个非空行。
  • 使用 openclaw message thread create 直接创建线程。对于论坛频道,不要传递 --message-id
示例:发送到论坛父频道以创建线程
openclaw message send --channel discord --target channel:<forumId> \
  --message "Topic title\nBody of the post"
示例:显式创建论坛线程
openclaw message thread create --channel discord --target channel:<forumId> \
  --thread-name "Topic title" --message "Body of the post"
论坛父频道不接受 Discord 组件。如果你需要组件,请发送到线程本身(channel:<threadId>)。

交互式组件

OpenClaw 支持用于代理消息的 Discord components v2 容器。使用带有 components 负载的 message 工具。交互结果会作为正常的入站消息路由回代理,并遵循现有的 Discord replyToMode 设置。 支持的块:
  • textsectionseparatoractionsmedia-galleryfile
  • 操作行最多允许 5 个按钮或一个单选菜单
  • 选择类型:stringuserrolementionablechannel
默认情况下,组件仅可使用一次。将 components.reusable=true 可允许按钮、选择器和表单在过期前多次使用。 要限制谁可以点击按钮,请在该按钮上设置 allowedUsers(Discord 用户 ID、标签或 *)。配置后,不匹配的用户会收到一条临时拒绝提示。 /model/models 斜杠命令会打开一个交互式模型选择器,包含提供方、模型和兼容运行时下拉菜单以及提交步骤。/models add 已弃用,现在会返回弃用消息,而不是从聊天中注册模型。该选择器回复是临时性的,且只有调用者可以使用它。 文件附件:
  • file 块必须指向附件引用(attachment://<filename>
  • 通过 media/path/filePath 提供附件(单文件);多个文件请使用 media-gallery
  • 当上传名称应与附件引用匹配时,使用 filename 覆盖上传名称
模态表单:
  • 添加 components.modal,最多 5 个字段
  • 字段类型:textcheckboxradioselectrole-selectuser-select
  • OpenClaw 会自动添加一个触发按钮
示例:
{
  channel: "discord",
  action: "send",
  to: "channel:123456789012345678",
  message: "Optional fallback text",
  components: {
    reusable: true,
    text: "Choose a path",
    blocks: [
      {
        type: "actions",
        buttons: [
          {
            label: "Approve",
            style: "success",
            allowedUsers: ["123456789012345678"],
          },
          { label: "Decline", style: "danger" },
        ],
      },
      {
        type: "actions",
        select: {
          type: "string",
          placeholder: "Pick an option",
          options: [
            { label: "Option A", value: "a" },
            { label: "Option B", value: "b" },
          ],
        },
      },
    ],
    modal: {
      title: "Details",
      triggerLabel: "Open form",
      fields: [
        { type: "text", label: "Requester" },
        {
          type: "select",
          label: "Priority",
          options: [
            { label: "Low", value: "low" },
            { label: "High", value: "high" },
          ],
        },
      ],
    },
  },
}

访问控制与路由

channels.discord.dmPolicy 控制 DM 访问。channels.discord.allowFrom 是标准的 DM 白名单。
  • pairing(默认)
  • allowlist
  • open(要求 channels.discord.allowFrom 包含 "*"
  • disabled
如果 DM policy 不是 open,未知用户会被阻止(或在 pairing 模式下提示配对)。多账号优先级:
  • channels.discord.accounts.default.allowFrom 仅适用于 default 账号。
  • 对于单个账号,allowFrom 优先于旧版 dm.allowFrom
  • 当命名账号自身的 allowFrom 和旧版 dm.allowFrom 都未设置时,会继承 channels.discord.allowFrom
  • 命名账号不会继承 channels.discord.accounts.default.allowFrom
为兼容性考虑,旧版 channels.discord.dm.policychannels.discord.dm.allowFrom 仍会被读取。openclaw doctor --fix 会在不改变访问权限的情况下尽可能将它们迁移到 dmPolicyallowFromDM 目标的交付格式:
  • user:<id>
  • <@id> 提及
纯数字 ID 通常会在启用频道默认值时解析为频道 ID,但列在账号有效 DM allowFrom 中的 ID 为兼容性会被视为用户 DM 目标。

基于角色的代理路由

使用 bindings[].match.roles 可通过 Discord 服务器成员的角色 ID 将其路由到不同代理。基于角色的绑定仅接受角色 ID,并在 peer 或 parent-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 slash 命令注册和清理。先前注册的命令可能仍会在 Discord 中可见,直到你将它们从 Discord 应用中移除。
  • 原生命令授权使用与普通消息处理相同的 Discord allowlist/策略。
  • 对于未授权用户,命令仍可能在 Discord UI 中可见;执行时仍会强制 OpenClaw 授权并返回 “not authorized”。
命令目录和行为请参见 Slash commands 默认斜杠命令设置:
  • ephemeral: true

功能细节

Discord 支持代理输出中的回复标签:
  • [[reply_to_current]]
  • [[reply_to:<id>]]
channels.discord.replyToMode 控制:
  • off(默认)
  • first
  • all
  • batched
注意:off 会禁用隐式回复线程化。显式的 [[reply_to_*]] 标签仍会被保留。 first 总是将隐式原生回复引用附加到该轮中的第一条发出的 Discord 消息。 batched 只有在入站回合是由多条消息去抖后的批次时,才附加 Discord 的隐式原生回复引用。这在你主要想为含糊的爆发式聊天保留原生回复,而不是每个单消息回合都保留时很有用。消息 ID 会在上下文/历史中暴露,以便代理可以针对特定消息。
OpenClaw 可以通过发送临时消息并在文本到达时编辑它来流式输出草稿回复。channels.discord.streaming 取值为 off(默认)| partial | block | progressprogress 会保留一条可编辑的状态草稿,并在最终交付前用工具进度更新它;streamMode 是旧版别名,会自动迁移。默认仍为 off,因为当多个机器人或网关共享一个账号时,Discord 预览编辑很快会触发速率限制。
{
  channels: {
    discord: {
      streaming: "block",
      draftChunk: {
        minChars: 200,
        maxChars: 800,
        breakPreference: "paragraph",
      },
    },
  },
}
  • partial 会在 token 到达时编辑同一条预览消息。
  • block 会输出草稿大小的块(使用 draftChunk 调整大小和断点,并会被限制到 textChunkLimit)。
  • 媒体、错误和显式回复的最终消息会取消挂起的预览编辑。
  • streaming.preview.toolProgress(默认 true)控制工具/进度更新是否重用预览消息。
预览流仅支持文本;媒体回复会回退为普通发送。显式启用 block 流式时,OpenClaw 会跳过预览流,以避免双重流式输出。
服务器历史上下文:
  • channels.discord.historyLimit 默认 20
  • 回退:messages.groupChat.historyLimit
  • 0 表示禁用
DM 历史控制:
  • channels.discord.dmHistoryLimit
  • channels.discord.dms["<user_id>"].historyLimit
线程行为:
  • Discord 线程会作为频道会话路由,并继承父频道配置,除非被覆盖。
  • 线程会话会继承父频道会话级 /model 选择,作为仅模型的回退;线程本地的 /model 选择仍然优先,且除非启用了转录继承,否则不会复制父转录历史。
  • channels.discord.thread.inheritParent(默认 false)会让新自动线程从父转录中初始化种子内容。按账号覆盖位于 channels.discord.accounts.<id>.thread.inheritParent
  • 消息工具反应可以解析 user:<id> DM 目标。
  • guilds.<guild>.channels.<channel>.requireMention: false 会在回复阶段激活回退期间被保留。
频道主题会作为不受信任的上下文注入。白名单限制的是谁可以触发代理,而不是完整的补充上下文红action边界。
Discord 可以将线程绑定到会话目标,以便该线程中的后续消息继续路由到同一个会话(包括子代理会话)。命令:
  • /focus <target> 将当前/新线程绑定到子代理/会话目标
  • /unfocus 移除当前线程绑定
  • /agents 显示活动运行和绑定状态
  • /session idle <duration|off> 检查/更新聚焦绑定的空闲自动取消聚焦
  • /session max-age <duration|off> 检查/更新聚焦绑定的硬最大时长
配置:
{
  session: {
    threadBindings: {
      enabled: true,
      idleHours: 24,
      maxAgeHours: 0,
    },
  },
  channels: {
    discord: {
      threadBindings: {
        enabled: true,
        idleHours: 24,
        maxAgeHours: 0,
        spawnSessions: true,
        defaultSpawnContext: "fork",
      },
    },
  },
}
说明:
  • session.threadBindings.* 设置全局默认值。
  • channels.discord.threadBindings.* 覆盖 Discord 行为。
  • spawnSessions 控制 sessions_spawn({ thread: true }) 和 ACP 线程创建的自动创建/绑定。默认:true
  • defaultSpawnContext 控制线程绑定 spawn 的原生子代理上下文。默认:"fork"
  • 已弃用的 spawnSubagentSessions/spawnAcpSessions 键会由 openclaw doctor --fix 迁移。
  • 如果某个账号禁用了线程绑定,则 /focus 和相关线程绑定操作不可用。
参见 Sub-agentsACP AgentsConfiguration Reference
对于稳定的“始终在线” ACP 工作区,请配置指向 Discord 会话的顶层类型化 ACP 绑定。配置路径:
  • bindings[],并设置 type: "acp"match.channel: "discord"
示例:
{
  agents: {
    list: [
      {
        id: "codex",
        runtime: {
          type: "acp",
          acp: {
            agent: "codex",
            backend: "acpx",
            mode: "persistent",
            cwd: "/workspace/openclaw",
          },
        },
      },
    ],
  },
  bindings: [
    {
      type: "acp",
      agentId: "codex",
      match: {
        channel: "discord",
        accountId: "default",
        peer: { kind: "channel", id: "222222222222222222" },
      },
      acp: { label: "codex-main" },
    },
  ],
  channels: {
    discord: {
      guilds: {
        "111111111111111111": {
          channels: {
            "222222222222222222": {
              requireMention: false,
            },
          },
        },
      },
    },
  },
}
说明:
  • /acp spawn codex --bind here 将当前频道或线程原地绑定,并让未来消息继续使用同一个 ACP 会话。线程消息会继承父频道绑定。
  • 在已绑定的频道或线程中,/new/reset 会就地重置同一个 ACP 会话。临时线程绑定在激活时可以覆盖目标解析。
  • spawnSessions 通过 --thread auto|here 控制子线程的创建/绑定。
绑定行为详情请参见 ACP Agents
每个服务器的反应通知模式:
  • off
  • own(默认)
  • all
  • allowlist(使用 guilds.<id>.users
反应事件会转换为系统事件并附加到已路由的 Discord 会话。
ackReaction 会在 OpenClaw 处理入站消息时发送一个确认表情。解析顺序:
  • channels.discord.accounts.<accountId>.ackReaction
  • channels.discord.ackReaction
  • messages.ackReaction
  • 代理身份表情回退(agents.list[].identity.emoji,否则为 ”👀”)
说明:
  • Discord 接受 Unicode 表情或自定义表情名称。
  • 使用 "" 可为某个频道或账号禁用该反应。
默认启用由频道发起的配置写入。这会影响 /config set|unset 流程(当命令功能已启用时)。禁用:
{
  channels: {
    discord: {
      configWrites: false,
    },
  },
}
通过 channels.discord.proxy 将 Discord 网关 WebSocket 流量和启动时 REST 查询(application ID + allowlist 解析)路由经由 HTTP(S) 代理。
{
  channels: {
    discord: {
      proxy: "http://proxy.example:8080",
    },
  },
}
按账号覆盖:
{
  channels: {
    discord: {
      accounts: {
        primary: {
          proxy: "http://proxy.example:8080",
        },
      },
    },
  },
}
启用 PluralKit 解析,将代理消息映射到系统成员身份:
{
  channels: {
    discord: {
      pluralkit: {
        enabled: true,
        token: "pk_live_...", // 可选;私有系统需要
      },
    },
  },
}
说明:
  • 白名单可以使用 pk:<memberId>
  • 仅当 channels.discord.dangerouslyAllowNameMatching: true 时,才会按名称/slug 匹配成员显示名
  • 查找使用原始消息 ID,并受时间窗口限制
  • 如果查找失败,代理消息会被视为机器人消息并丢弃,除非 allowBots=true
当代理需要对已知 Discord 用户进行可确定的发出提及时,请使用 mentionAliases。键是不带前导 @ 的句柄;值是 Discord 用户 ID。未知句柄、@everyone@here,以及 Markdown 代码跨度中的提及都会保持不变。
{
  channels: {
    discord: {
      mentionAliases: {
        Vladislava: "123456789012345678",
      },
      accounts: {
        ops: {
          mentionAliases: {
            OpsLead: "234567890123456789",
          },
        },
      },
    },
  },
}
当你设置状态或活动字段,或者启用自动 presence 时,会应用 presence 更新。仅状态示例:
{
  channels: {
    discord: {
      status: "idle",
    },
  },
}
活动示例(自定义状态是默认活动类型):
{
  channels: {
    discord: {
      activity: "Focus time",
      activityType: 4,
    },
  },
}
流式示例:
{
  channels: {
    discord: {
      activity: "Live coding",
      activityType: 1,
      activityUrl: "https://twitch.tv/openclaw",
    },
  },
}
活动类型映射:
  • 0:Playing
  • 1:Streaming(需要 activityUrl
  • 2:Listening
  • 3:Watching
  • 4:Custom(使用活动文本作为状态值;表情可选)
  • 5:Competing
自动 presence 示例(运行时健康信号):
{
  channels: {
    discord: {
      autoPresence: {
        enabled: true,
        intervalMs: 30000,
        minUpdateIntervalMs: 15000,
        exhaustedText: "token exhausted",
      },
    },
  },
}
自动 presence 会将运行时可用性映射为 Discord 状态:健康 => online,降级或未知 => idle,耗尽或不可用 => dnd。可选文本覆盖:
  • autoPresence.healthyText
  • autoPresence.degradedText
  • autoPresence.exhaustedText(支持 {reason} 占位符)
Discord 支持在 DM 中基于按钮的审批处理,也可以选择在发起的频道中发布审批提示。配置路径:
  • channels.discord.execApprovals.enabled
  • channels.discord.execApprovals.approvers(可选;在可能时回退到 commands.ownerAllowFrom
  • channels.discord.execApprovals.targetdm | channel | both,默认:dm
  • agentFiltersessionFiltercleanupAfterResolve
enabled 未设置或为 "auto",并且至少能从 execApprovals.approverscommands.ownerAllowFrom 解析出一个审批人时,Discord 会自动启用原生 exec approvals。Discord 不会从频道 allowFrom、旧版 dm.allowFrom 或私信 defaultTo 推断 exec 审批人。要显式禁用 Discord 作为原生审批客户端,请设置 enabled: false对于诸如 /diagnostics/export-trajectory 之类仅限所有者的敏感组命令,OpenClaw 会私下发送审批提示和最终结果。如果调用者所属的所有者有 Discord 路由,则会优先尝试 Discord DM;如果不可用,则回退到 commands.ownerAllowFrom 中第一个可用的所有者路由,例如 Telegram。targetchannelboth 时,审批提示会在频道中可见。只有已解析出的审批人可以使用这些按钮;其他用户会收到一条临时拒绝提示。审批提示包含命令文本,因此仅应在受信任的频道中启用频道投放。如果无法从会话键派生频道 ID,OpenClaw 会回退为 DM 投放。Discord 还会渲染其他聊天频道所使用的共享审批按钮。原生 Discord 适配器主要添加审批人 DM 路由和频道扇出。 当这些按钮存在时,它们是主要的审批交互方式;只有当工具结果表明聊天审批不可用,或者手动审批是唯一途径时,OpenClaw 才应包含手动 /approve 命令。 如果 Discord 原生审批运行时未激活,OpenClaw 会继续显示本地确定性的 /approve <id> <decision> 提示。如果运行时已激活但无法将原生卡片投递到任何目标,OpenClaw 会发送一条同聊天回退通知,并附上待审批项中的确切 /approve 命令。网关认证和审批解析遵循共享的 Gateway 客户端契约(plugin: ID 通过 plugin.approval.resolve 解析;其他 ID 通过 exec.approval.resolve 解析)。审批默认在 30 分钟后过期。参见 Exec approvals

工具与动作门禁

Discord 消息动作包括消息发送、频道管理、审核、状态和元数据动作。 核心示例:
  • 消息:sendMessagereadMessageseditMessagedeleteMessagethreadReply
  • 反应:reactreactionsemojiList
  • 审核:timeoutkickban
  • 状态:setPresence
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已禁用

Components v2 UI

OpenClaw 使用 Discord components v2 进行执行审批和跨上下文标记。Discord 消息动作也可以接受 components 来实现自定义 UI(高级功能;需要通过 discord 工具构造 component payload),而旧版 embeds 仍然可用,但不推荐使用。
  • channels.discord.ui.components.accentColor 设置 Discord 组件容器使用的强调色(十六进制)。
  • 可按账号通过 channels.discord.accounts.<id>.ui.components.accentColor 单独设置。
  • 当存在 components v2 时,embeds 会被忽略。
示例:
{
  channels: {
    discord: {
      ui: {
        components: {
          accentColor: "#5865F2",
        },
      },
    },
  },
}

语音

Discord 有两个不同的语音表面:实时 语音频道(连续对话)和 语音消息附件(波形预览格式)。网关同时支持两者。

语音频道

设置清单:
  1. 在 Discord Developer Portal 中启用 Message Content Intent。
  2. 当使用角色/用户允许名单时,启用 Server Members Intent。
  3. 使用 botapplications.commands 范围邀请机器人。
  4. 在目标语音频道中授予 Connect、Speak、Send Messages 和 Read Message History 权限。
  5. 启用原生命令(commands.nativechannels.discord.commands.native)。
  6. 配置 channels.discord.voice
使用 /vc join|leave|status 来控制会话。该命令使用账号默认 agent,并遵循与其他 Discord 命令相同的允许名单和组策略规则。
/vc join channel:<voice-channel-id>
/vc status
/vc leave
自动加入示例:
{
  channels: {
    discord: {
      voice: {
        enabled: true,
        model: "openai/gpt-5.4-mini",
        autoJoin: [
          {
            guildId: "123456789012345678",
            channelId: "234567890123456789",
          },
        ],
        daveEncryption: true,
        decryptionFailureTolerance: 24,
        connectTimeoutMs: 30000,
        reconnectGraceMs: 15000,
        tts: {
          provider: "openai",
          openai: { voice: "onyx" },
        },
      },
    },
  },
}
注意:
  • voice.tts 仅覆盖语音播放所用的 messages.tts
  • voice.model 仅覆盖 Discord 语音频道响应所使用的 LLM。保持未设置可继承路由后的 agent 模型。
  • STT 使用 tools.media.audiovoice.model 不影响转写。
  • 逐频道的 Discord systemPrompt 覆盖会应用于该语音频道的语音转写轮次。
  • 语音转写轮次会从 Discord allowFrom(或 dm.allowFrom)派生所有者状态;非所有者说话者无法访问仅所有者可用的工具(例如 gatewaycron)。
  • 对于仅文本配置,Discord 语音是可选启用的;设置 channels.discord.voice.enabled=true(或保留现有的 channels.discord.voice 块)即可启用 /vc 命令、语音运行时和 GuildVoiceStates 网关 intent。
  • channels.discord.intents.voiceStates 可以显式覆盖 voice-state intent 订阅。保持未设置可让该 intent 跟随实际的语音启用状态。
  • voice.daveEncryptionvoice.decryptionFailureTolerance 会透传到 @discordjs/voice 的 join 选项。
  • 如果未设置,@discordjs/voice 的默认值为 daveEncryption=truedecryptionFailureTolerance=24
  • voice.connectTimeoutMs 控制 /vc join 和自动加入尝试时,@discordjs/voice 初始 Ready 等待时长。默认值:30000
  • voice.reconnectGraceMs 控制 OpenClaw 在销毁断开的语音会话之前,等待其开始重新连接的时间。默认值:15000
  • OpenClaw 还会监控接收解密失败,并在短时间内重复失败后通过离开/重新加入语音频道来自行恢复。
  • 如果在更新后接收日志持续出现 DecryptionFailed(UnencryptedWhenPassthroughDisabled),请收集依赖报告和日志。捆绑的 @discordjs/voice 版本包含 discord.js PR #11449 中的上游 padding 修复,该修复关闭了 discord.js issue #11419。
语音频道流水线:
  • Discord PCM 捕获会转换为 WAV 临时文件。
  • tools.media.audio 负责 STT,例如 openai/gpt-4o-mini-transcribe
  • 转写内容会通过 Discord ingress 和路由传递,而响应 LLM 会在语音输出策略下运行,该策略会隐藏 agent 的 tts 工具并请求返回文本,因为 Discord 语音负责最终的 TTS 播放。
  • 当设置了 voice.model 时,它只会覆盖该语音频道回合的响应 LLM。
  • voice.tts 会基于 messages.tts 进行合并;生成的音频会在加入的频道中播放。
凭据按组件分别解析:voice.model 使用 LLM 路由认证,tools.media.audio 使用 STT 认证,messages.tts/voice.tts 使用 TTS 认证。

语音消息

Discord 语音消息会显示波形预览,并要求 OGG/Opus 音频。OpenClaw 会自动生成波形,但需要网关主机上的 ffmpegffprobe 来进行检查和转换。
  • 提供一个本地文件路径(不接受 URL)。
  • 省略文本内容(Discord 会拒绝同一 payload 中同时包含文本和语音消息)。
  • 接受任何音频格式;OpenClaw 会按需转换为 OGG/Opus。
message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true)

故障排查

  • 启用 Message Content Intent
  • 当你依赖用户/成员解析时,启用 Server Members Intent
  • 更改 intents 后重启网关
  • 检查 groupPolicy
  • 检查 channels.discord.guilds 下的 guild 允许名单
  • 如果存在 guild channels 映射,则只允许列出的频道
  • 检查 requireMention 行为和提及模式
有用的检查:
openclaw doctor
openclaw channels status --probe
openclaw logs --follow
常见原因:
  • groupPolicy="allowlist" 但没有匹配的 guild/channel 允许名单
  • requireMention 配置在错误位置(必须位于 channels.discord.guilds 或频道条目下)
  • 发送者被 guild/channel users 允许名单阻止
典型日志:
  • Slow listener detected ...
  • stuck session: sessionKey=agent:...:discord:... state=processing ...
Discord gateway queue knobs:
  • single-account: channels.discord.eventQueue.listenerTimeout
  • multi-account: channels.discord.accounts.<accountId>.eventQueue.listenerTimeout
  • this only controls Discord gateway listener work, not agent turn lifetime
Discord 不会对排队中的 agent 回合应用 channel-owned 超时。消息监听器会立即移交,而排队中的 Discord 运行会保持每个会话的顺序,直到会话/工具/运行时生命周期完成或中止工作。
{
  channels: {
    discord: {
      accounts: {
        default: {
          eventQueue: {
            listenerTimeout: 120000,
          },
        },
      },
    },
  },
}
OpenClaw 在连接前会获取 Discord /gateway/bot 元数据。临时性失败会回退到 Discord 的默认网关 URL,并在日志中进行限流。元数据超时参数:
  • 单账号:channels.discord.gatewayInfoTimeoutMs
  • 多账号:channels.discord.accounts.<accountId>.gatewayInfoTimeoutMs
  • 当配置未设置时的环境变量回退:OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS
  • 默认值:30000(30 秒),最大值:120000
OpenClaw 在启动期间以及运行时重新连接后都会等待 Discord 的 gateway READY 事件。带有启动错峰的多账号设置,可能需要比默认值更长的启动 READY 窗口。READY 超时参数:
  • 启动单账号:channels.discord.gatewayReadyTimeoutMs
  • 启动多账号:channels.discord.accounts.<accountId>.gatewayReadyTimeoutMs
  • 配置未设置时的启动环境变量回退:OPENCLAW_DISCORD_READY_TIMEOUT_MS
  • 启动默认值:15000(15 秒),最大值:120000
  • 运行时单账号:channels.discord.gatewayRuntimeReadyTimeoutMs
  • 运行时多账号:channels.discord.accounts.<accountId>.gatewayRuntimeReadyTimeoutMs
  • 配置未设置时的运行时环境变量回退:OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS
  • 运行时默认值:30000(30 秒),最大值:120000
channels status --probe 权限检查只对数字频道 ID 有效。如果你使用 slug 键,运行时匹配仍可能工作,但 probe 无法完全验证权限。
  • DM 已禁用:channels.discord.dm.enabled=false
  • DM 策略已禁用:channels.discord.dmPolicy="disabled"(旧版:channels.discord.dm.policy
  • pairing 模式下等待配对批准
默认会忽略机器人发出的消息。如果你设置了 channels.discord.allowBots=true,请使用严格的提及和允许名单规则,以避免循环行为。 建议使用 channels.discord.allowBots="mentions",仅接受提及机器人的机器人消息。
{
  channels: {
    discord: {
      accounts: {
        mantis: {
          // 螳螂只会在其他机器人提及她时监听它们。
          allowBots: "mentions",
        },
        molty: {
          // Molty 会监听所有机器人发送的 Discord 消息。
          allowBots: true,
          mentionAliases: {
            // 允许 Molty 写出 "@Mantis" 并发送真正的 Discord 提及。
            Mantis: "MANTIS_DISCORD_USER_ID",
          },
        },
      },
    },
  },
}
  • 保持 OpenClaw 为最新版本(openclaw update),以确保 Discord 语音接收恢复逻辑存在
  • 确认 channels.discord.voice.daveEncryption=true(默认)
  • channels.discord.voice.decryptionFailureTolerance=24(上游默认)开始,仅在需要时调优
  • 关注日志中的:
    • discord voice: DAVE decrypt failures detected
    • discord voice: repeated decrypt failures; attempting rejoin
  • 如果自动重新加入后失败仍持续,请收集日志并与上游 DAVE 接收历史对照:discord.js #11419discord.js #11449

配置参考

主要参考:Configuration reference - Discord
  • startup/auth: enabled, token, accounts.*, allowBots
  • policy: groupPolicy, dm.*, guilds.*, guilds.*.channels.*
  • command: commands.native, commands.useAccessGroups, configWrites, slashCommand.*
  • event queue: eventQueue.listenerTimeout (listener budget), eventQueue.maxQueueSize, eventQueue.maxConcurrency
  • gateway: gatewayInfoTimeoutMs, gatewayReadyTimeoutMs, gatewayRuntimeReadyTimeoutMs
  • reply/history: replyToMode, historyLimit, dmHistoryLimit, dms.*.historyLimit
  • delivery: textChunkLimit, chunkMode, maxLinesPerMessage
  • streaming: streaming (legacy alias: streamMode), streaming.preview.toolProgress, draftChunk, blockStreaming, blockStreamingCoalesce
  • media/retry: mediaMaxMb (caps outbound Discord uploads, default 100MB), retry
  • actions: actions.*
  • presence: activitystatusactivityTypeactivityUrl
  • UI: ui.components.accentColor
  • features: threadBindings、顶层 bindings[]type: "acp")、pluralkitexecApprovalsintentsagentComponentsheartbeatresponsePrefix

安全与运维

  • 将 bot token 视为密钥(在受监管环境中优先使用 DISCORD_BOT_TOKEN)。
  • 授予最小权限的 Discord 权限。
  • 如果命令部署/状态已过期,重启 gateway,并使用 openclaw channels status --probe 重新检查。

相关内容

配对

将 Discord 用户与 gateway 配对。

分组

群聊和允许列表行为。

频道路由

将传入消息路由给 agents。

安全

威胁模型与加固。

多 agent 路由

将 guilds 和 channels 映射到 agents。

斜杠命令

原生命令行为。