跳转至

消息行为

入站和出站 Discord 消息如何被路由、格式化、确认和预览。

运行时模型

  • Gateway 拥有 Discord 连接。
  • 回复路由是确定性的:Discord 入站消息回复到 Discord。
  • 机器人回复和线程绑定的人格回复共享 Markdown 格式,包括 CommonMark 粗体和已配置的表格转换。
  • 两种投递路径都会在格式化和提及展开后重新应用调用方提供的字符限制。
  • 转发消息快照会连同任何附带说明文字一起到达代理。转发文本不被视为输入的命令;命令分类仅使用发送者自己的消息文本。
  • Discord 服务器/频道元数据会作为不可信上下文添加到模型 Prompt 中,而不是作为用户可见的回复前缀。如果模型将该信封复制回来,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 消息 ID 的发送响应保持未确认状态。排队投递会记录缺失的身份信息以便恢复,而不是报告成功或立即发送重复消息;使用 openclaw health --verbose 检查投递警告。

消息行为

加入服务器时的介绍

当机器人加入允许的 Discord 服务器时,OpenClaw 会发布一条针对该房间的介绍。如果机器人可以在服务器的系统频道中查看和发送消息,则优先使用系统频道;否则,使用第一个同时具有 View Channel 和 Send Messages 权限的文本频道。如果不存在符合条件的频道,则不发送介绍。

介绍会使用频道名称和主题,并在可用时加入最近消息。读取更早的消息还需要 Read Message History;当缺少该权限时,OpenClaw 仍会使用频道元数据进行自我介绍,而不是失败。

介绍默认启用,仅适用于新加入的服务器,并且不会在直接消息中运行。设置 channels.discord.joinIntro: false 以禁用它们,或设置 channels.discord.accounts.<accountId>.joinIntro 以覆盖单个账户。有关历史记录限制、目标频道选择、每房间一次的行为以及不可信内容处理,请参阅 群组加入介绍。

回复标签和原生回复

Discord 支持在代理输出中使用回复标签:

  • [[reply_to_current]]
  • [[reply_to:<id>]]

由 channels.discord.replyToMode 控制:

  • off(默认):没有隐式回复线程;显式 [[reply_to_*]] 标签仍会被遵循
  • first:将隐式原生回复引用附加到本轮第一条出站 Discord 消息
  • all:将其附加到每条出站消息
  • batched:仅当入站事件是多个消息的防抖批次时附加它——适用于主要希望在不明确的突发聊天中使用原生回复,而不是每个单消息回合

消息 ID 会在上下文/历史中呈现,以便代理可以定位特定消息。对机器人消息(包括自动化警报)的回复,在上下文可见性允许时,会将所引用文本保留为不可信上下文。机器人自身的入站事件仍会被忽略,且引用的自创媒体不会再次下载。 分块人格投递回执会保留为每个分块选择的回复目标。

链接预览
Discord 默认会为 URL 生成富链接嵌入。OpenClaw 默认会抑制出站 Discord 消息中生成的这些嵌入,因此代理发送的 URL 保持为普通链接,除非你选择加入:
{
  channels: {
    discord: {
      suppressEmbeds: false,
    },
  },
}
设置 `channels.discord.accounts.<id>.suppressEmbeds` 以覆盖单个账户。代理消息工具发送也可以为单条消息传递 `suppressEmbeds: false`。显式 Discord `embeds` 负载不会被默认链接预览设置抑制。
实时流预览
OpenClaw 可以通过发送临时消息并在文本到达时编辑它来流式传输草稿回复。Discord 预览流默认值为 `off`;设置 `channels.discord.streaming.mode` 为 `partial`、`block` 或 `progress` 以选择加入。`streamMode` 是旧版别名;运行 `openclaw doctor --fix` 以将持久化配置重写为规范的嵌套 `streaming` 结构。
{
  channels: {
    discord: {
      streaming: {
        mode: "progress",
        progress: {
          maxLines: 8,
          maxLineChars: 120,
          toolProgress: false,
          commentary: false,
        },
      },
    },
  },
}
- `off` 禁用 Discord 预览编辑。
- `partial` 在 token 到达时编辑单个预览消息。
- `block` 发出草稿大小的分块;使用 `streaming.preview.chunk`(`minChars`、`maxChars`、`breakPreference`)调整大小和断点,并限制在 `textChunkLimit` 内。显式非 `off` 预览模式会覆盖继承的 `agents.defaults.blockStreamingDefault: "on"`;显式 `streaming.block.enabled: true` 会覆盖预览。如果某个回合无法使用预览,继承的块投递仍会应用。
- `progress` 在最终投递前保留一个可编辑的状态草稿。默认情况下它是安静的:将代理最新的开场白或叙述作为状态标题,流式传输时显示 💬 评论和 🧠 推理,✅ / ▸ / ▢ 计划步骤,以及任何审批请求或失败命令。普通工具调用不会添加行。
- 媒体、错误和显式回复的最终消息会取消待处理的预览编辑。
- `streaming.progress.toolProgress: true` 在标题下方添加滚动工具日志:例如 `🛠️ Bash: run tests` 或 `🔎 Web Search: for "query"`(默认 `false`)。`streaming.preview.toolProgress` 控制 `partial` 和 `block` 模式中的工具行,在这些模式中它们默认为 `true`。
- `streaming.progress.commentary`(默认 `false`)选择加入临时进度草稿中的原始助手评论。默认开场白/叙述状态行独立于该选项。评论在显示前会被清理,保持临时状态,并且不会改变最终答案投递。
- `streaming.progress.maxLineChars` 控制每行进度预览预算。散文会在单词边界处缩短;命令和路径细节会保留有用的后缀。
- `streaming.preview.commandText` / `streaming.progress.commandText` 控制紧凑进度行中的命令/执行细节:`status`(默认,仅工具标签)或 `raw`(显式命令文本)。

显示滚动工具日志,同时隐藏原始命令/执行文本:

    ```json
    {
      "channels": {
        "discord": {
          "streaming": {
            "mode": "progress",
            "progress": {
              "toolProgress": true,
              "commandText": "status"
            }
          }
        }
      }
    }
    ```

    预览流式传输仅支持文本;媒体回复将回退到正常投递。
确认反应
状态反应在整个工作过程中保持确认状态稳定。它们不会为每个工具添加表情、不活动警告或成功闪烁。实际失败仍保留错误反应生命周期。

`ackReaction` 会在 OpenClaw 处理传入消息时发送一个确认表情。

解析顺序:

- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- 代理身份表情回退(`agents.entries.*.identity.emoji`,否则为 "👀")

说明:

- Discord 接受 Unicode 表情或自定义表情名称。
- 使用 `""` 可禁用某个频道或账户的反应。

**范围(`messages.ackReactionScope`):**

取值:`"all"`(私信 + 群组,包括环境房间事件)、`"direct"`(仅私信)、`"group-all"`(除环境房间事件外的所有群组消息,不含私信)、`"group-mentions"`(机器人被提及时的群组;**不含私信**,默认值)、`"off"` / `"none"`(禁用)。

Note

默认范围("group-mentions")不会在私信或环境房间事件中触发确认反应。若要在传入的 Discord 私信和安静房间事件中获取确认反应,请将 messages.ackReactionScope 设置为 "all"。

出站提及别名
当代理需要为已知的 Discord 用户生成确定性的出站提及时,请使用 `mentionAliases`。键为不带前导 `@` 的句柄;值为 Discord 用户 ID。未知句柄、`@everyone`、`@here` 以及 Markdown 代码跨度内的提及将保持不变。
{
  channels: {
    discord: {
      mentionAliases: {
        SupportLead: "123456789012345678",
      },
      accounts: {
        ops: {
          mentionAliases: {
            OpsLead: "234567890123456789",
          },
        },
      },
    },
  },
}

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw