diff --git a/docs/zh-CN/channels/bluebubbles.md b/docs/zh-CN/channels/bluebubbles.md index c07ee0a7d..cdb0ae535 100644 --- a/docs/zh-CN/channels/bluebubbles.md +++ b/docs/zh-CN/channels/bluebubbles.md @@ -1,40 +1,41 @@ --- read_when: - 设置 BlueBubbles 渠道 - - Webhook 配对故障排除 + - 故障排除 webhook 配对 - 在 macOS 上配置 iMessage -summary: 通过 BlueBubbles macOS 服务器接入 iMessage(REST 发送/接收、正在输入、回应、配对、高级操作)。 +summary: 通过 BlueBubbles macOS 服务器的 iMessage(REST 发送/接收、正在输入、回应、配对、高级操作)。 title: BlueBubbles x-i18n: - generated_at: "2026-04-24T18:07:25Z" + generated_at: "2026-04-26T04:50:07Z" model: gpt-5.4 provider: openai - source_hash: 5185202d668f56e5f2e22c1858325595eea7cca754b9b3a809c886c53ae68770 + source_hash: 15ca98edc92fa6525167bd8ef814ae17d18bab72f445b75e5df7b361883392b4 source_path: channels/bluebubbles.md workflow: 15 --- -状态:这是一个通过 HTTP 与 BlueBubbles macOS 服务器通信的内置插件。由于其 API 更丰富,且相比旧版 `imsg` 渠道更易于设置,因此**推荐用于 iMessage 集成**。 +Status:内置插件,通过 HTTP 与 BlueBubbles macOS 服务器通信。由于其 API 更丰富且设置比旧版 `imsg` 渠道更简单,因此**推荐用于 iMessage 集成**。 ## 内置插件 -当前的 OpenClaw 版本已内置 BlueBubbles,因此常规打包构建无需单独执行 `openclaw plugins install` 步骤。 +当前的 OpenClaw 版本已内置 BlueBubbles,因此普通打包构建**不需要**单独执行 `openclaw plugins install` 步骤。 -## 概述 +## 概览 - 通过 BlueBubbles 辅助应用在 macOS 上运行([bluebubbles.app](https://bluebubbles.app))。 -- 推荐/已测试:macOS Sequoia(15)。macOS Tahoe(26)可用;目前在 Tahoe 上编辑功能失效,群组图标更新也可能显示成功但不会同步。 -- OpenClaw 通过其 REST API 与之通信(`GET /api/v1/ping`、`POST /message/text`、`POST /chat/:id/*`)。 -- 传入消息通过 webhook 到达;传出回复、正在输入指示器、已读回执和 tapback 都通过 REST 调用完成。 -- 附件和贴纸会作为入站媒体被摄取(并在可能时提供给智能体)。 -- 配对/允许列表的工作方式与其他渠道相同(`/channels/pairing` 等),使用 `channels.bluebubbles.allowFrom` + 配对码。 -- 回应会像 Slack/Telegram 一样以系统事件形式呈现,因此智能体可以在回复前“提及”它们。 +- 推荐/已测试:macOS Sequoia(15)。macOS Tahoe(26)可用;但当前在 Tahoe 上编辑功能已损坏,群组图标更新也可能显示成功但不会同步。 +- OpenClaw 通过它的 REST API 与其通信(`GET /api/v1/ping`、`POST /message/text`、`POST /chat/:id/*`)。 +- 传入消息通过 webhook 到达;传出回复、输入指示器、已读回执和 tapback 都通过 REST 调用完成。 +- 附件和贴纸会作为入站媒体被接收(并在可能时提供给智能体)。 +- 会自动合成 MP3 或 CAF 音频的 Auto-TTS 回复,会以 iMessage 语音备忘录气泡的形式发送,而不是作为普通文件附件。 +- 配对/allowlist 的工作方式与其他渠道相同(`/channels/pairing` 等),使用 `channels.bluebubbles.allowFrom` + pairing 代码。 +- Reactions 会像 Slack/Telegram 一样作为系统事件呈现,因此智能体可以在回复前“提及”它们。 - 高级功能:编辑、撤回、回复线程、消息效果、群组管理。 ## 快速开始 1. 在你的 Mac 上安装 BlueBubbles 服务器(按照 [bluebubbles.app/install](https://bluebubbles.app/install) 上的说明操作)。 -2. 在 BlueBubbles 配置中,启用 Web API 并设置密码。 +2. 在 BlueBubbles 配置中启用 web API 并设置密码。 3. 运行 `openclaw onboard` 并选择 BlueBubbles,或手动配置: ```json5 @@ -56,12 +57,12 @@ x-i18n: 安全说明: - 始终设置 webhook 密码。 -- 始终要求进行 webhook 身份验证。无论 loopback/代理拓扑如何,除非 BlueBubbles webhook 请求包含与 `channels.bluebubbles.password` 匹配的 password/guid(例如 `?password=` 或 `x-password`),否则 OpenClaw 会拒绝该请求。 +- webhook 身份验证始终是必需的。无论 local loopback/代理拓扑如何,除非 BlueBubbles webhook 请求包含与 `channels.bluebubbles.password` 匹配的密码/guid(例如 `?password=` 或 `x-password`),否则 OpenClaw 会拒绝这些请求。 - 在读取/解析完整 webhook 请求体之前,会先检查密码身份验证。 -## 保持 Messages.app 处于活动状态(VM / 无头设置) +## 保持 Messages.app 处于活跃状态(VM / 无头设置) -某些 macOS VM / 常开设置可能会导致 Messages.app 进入“空闲”状态(在应用被打开/切到前台之前,传入事件会停止)。一个简单的解决办法是使用 AppleScript + LaunchAgent **每 5 分钟触碰一次 Messages**。 +某些 macOS VM / 常开设置中,Messages.app 可能会进入“空闲”状态(传入事件会停止,直到应用被打开/切到前台)。一个简单的解决方法是使用 AppleScript + LaunchAgent **每 5 分钟触碰一次 Messages**。 ### 1)保存 AppleScript @@ -123,8 +124,8 @@ end try 说明: -- 这会**每 300 秒**运行一次,并且**在登录时**运行。 -- 首次运行可能会触发 macOS 的**自动化**提示(`osascript` → Messages)。请在运行该 LaunchAgent 的同一用户会话中批准它们。 +- 该任务会**每 300 秒**运行一次,并且会在**登录时**运行。 +- 首次运行时可能会触发 macOS 的**自动化**提示(`osascript` → Messages)。请在运行该 LaunchAgent 的同一用户会话中批准它们。 加载它: @@ -137,7 +138,7 @@ launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist BlueBubbles 可在交互式新手引导中使用: -```bash +``` openclaw onboard ``` @@ -146,12 +147,12 @@ openclaw onboard - **Server URL**(必填):BlueBubbles 服务器地址(例如 `http://192.168.1.100:1234`) - **Password**(必填):BlueBubbles Server 设置中的 API 密码 - **Webhook path**(可选):默认为 `/bluebubbles-webhook` -- **私信策略**:pairing、allowlist、open 或 disabled -- **允许列表**:电话号码、电子邮件地址或聊天目标 +- **DM policy**:pairing、allowlist、open 或 disabled +- **Allow list**:电话号码、电子邮件地址或聊天目标 你也可以通过 CLI 添加 BlueBubbles: -```bash +``` openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password ``` @@ -159,26 +160,26 @@ openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --passwor 私信: -- 默认:`channels.bluebubbles.dmPolicy = "pairing"`。 -- 未知发送者会收到一个配对码;在获批前,消息会被忽略(验证码 1 小时后过期)。 -- 通过以下命令批准: +- 默认值:`channels.bluebubbles.dmPolicy = "pairing"`。 +- 未知发送者会收到一个 pairing 代码;在获准之前,消息会被忽略(代码 1 小时后过期)。 +- 可通过以下方式批准: - `openclaw pairing list bluebubbles` - `openclaw pairing approve bluebubbles ` -- 配对是默认的令牌交换方式。详情参见:[配对](/zh-CN/channels/pairing) +- Pairing 是默认的令牌交换方式。详情请参见:[Pairing](/zh-CN/channels/pairing) 群组: -- `channels.bluebubbles.groupPolicy = open | allowlist | disabled`(默认:`allowlist`)。 -- 当设置为 `allowlist` 时,`channels.bluebubbles.groupAllowFrom` 控制谁可以在群组中触发。 +- `channels.bluebubbles.groupPolicy = open | allowlist | disabled`(默认值:`allowlist`)。 +- 当设置为 `allowlist` 时,`channels.bluebubbles.groupAllowFrom` 用于控制谁可以在群组中触发。 -### 联系人名称增强(macOS,可选) +### 联系人姓名增强(macOS,可选) -BlueBubbles 群组 webhook 通常只包含原始参与者地址。如果你希望 `GroupMembers` 上下文显示本地联系人姓名而不是这些地址,你可以选择在 macOS 上启用本地 Contacts 增强: +BlueBubbles 群组 webhook 通常只包含原始参与者地址。如果你希望 `GroupMembers` 上下文改为显示本地联系人姓名,可以在 macOS 上选择启用本地通讯录增强: - `channels.bluebubbles.enrichGroupParticipantsFromContacts = true` 可启用查找。默认值:`false`。 -- 只有在群组访问、命令授权和提及门控都允许消息通过后,才会运行查找。 -- 仅会增强未命名的电话参与者。 -- 如果找不到本地匹配项,仍会回退为原始电话号码。 +- 查找仅会在群组访问、命令授权和提及门控允许消息通过之后运行。 +- 只会增强未命名的电话参与者。 +- 如果未找到本地匹配项,则仍会回退为原始电话号码。 ```json5 { @@ -192,10 +193,10 @@ BlueBubbles 群组 webhook 通常只包含原始参与者地址。如果你希 ### 提及门控(群组) -BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一致: +BlueBubbles 支持群聊提及门控,与 iMessage/WhatsApp 的行为一致: -- 使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)来检测提及。 -- 当群组启用了 `requireMention` 时,智能体仅在被提及时才会响应。 +- 使用 `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)检测提及。 +- 当群组启用了 `requireMention` 时,智能体仅会在被提及时响应。 - 来自已授权发送者的控制命令会绕过提及门控。 按群组配置: @@ -208,7 +209,7 @@ BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一 groupAllowFrom: ["+15555550123"], groups: { "*": { requireMention: true }, // 所有群组的默认值 - "iMessage;-;chat123": { requireMention: false }, // 对特定群组的覆盖 + "iMessage;-;chat123": { requireMention: false }, // 针对特定群组的覆盖 }, }, }, @@ -219,11 +220,11 @@ BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一 - 控制命令(例如 `/config`、`/model`)需要授权。 - 使用 `allowFrom` 和 `groupAllowFrom` 来确定命令授权。 -- 已授权发送者即使在群组中未提及,也可以运行控制命令。 +- 已授权发送者即使在群组中没有提及,也可以运行控制命令。 -### 按群组的系统提示词 +### 按群组设置 systemPrompt -`channels.bluebubbles.groups.*` 下的每个条目都接受一个可选的 `systemPrompt` 字符串。每次在该群组中处理消息时,这个值都会注入到智能体的系统提示词中,因此你可以在不编辑智能体提示词的情况下,为不同群组设置不同的人设或行为规则: +`channels.bluebubbles.groups.*` 下的每个条目都接受一个可选的 `systemPrompt` 字符串。该值会在该群组中处理消息的每一轮时注入到智能体的系统提示词中,因此你可以在不编辑智能体提示词的情况下,为每个群组设置人格或行为规则: ```json5 { @@ -231,7 +232,7 @@ BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一 bluebubbles: { groups: { "iMessage;-;chat123": { - systemPrompt: "将回复控制在 3 句话以内。模仿该群组的随意语气。", + systemPrompt: "将回复控制在 3 句以内。模仿该群组的随意语气。", }, }, }, @@ -239,11 +240,11 @@ BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一 } ``` -该键与 BlueBubbles 为群组报告的 `chatGuid` / `chatIdentifier` / 数字 `chatId` 相匹配,而 `"*"` 通配符条目则为每个没有精确匹配的群组提供默认值(与 `requireMention` 和按群组工具策略所使用的模式相同)。精确匹配始终优先于通配符。私信会忽略该字段;请改用智能体级或账户级提示词自定义。 +该键与 BlueBubbles 报告的群组 `chatGuid` / `chatIdentifier` / 数字 `chatId` 相匹配,而 `"*"` 通配符条目则为所有没有精确匹配的群组提供默认值(与 `requireMention` 和按群组工具策略使用相同的模式)。精确匹配始终优先于通配符。私信会忽略此字段;请改用智能体级别或账户级别的提示词定制。 -#### 实际示例:线程回复和 tapback 回应(Private API) +#### 示例:线程回复与 tapback reactions(Private API) -启用 BlueBubbles Private API 后,传入消息会带有短消息 ID(例如 `[[reply_to:5]]`),智能体可以调用 `action=reply` 以线程方式回复某条特定消息,或调用 `action=react` 添加一个 tapback。按群组设置 `systemPrompt` 是让智能体稳定选择正确工具的可靠方法: +启用 BlueBubbles Private API 后,入站消息会带有简短消息 ID(例如 `[[reply_to:5]]`),智能体可以调用 `action=reply` 将回复串到特定消息下,或调用 `action=react` 添加一个 tapback。按群组设置 `systemPrompt` 是让智能体稳定选择正确工具的一种可靠方式: ```json5 { @@ -254,12 +255,12 @@ BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一 systemPrompt: [ "在此群组中回复时,始终使用上下文中的", "[[reply_to:N]] messageId 调用 action=reply,", - "这样你的回复会在线程中挂到触发消息下面。", - "绝不要发送一个新的、未关联的消息。", + "这样你的回复会串在触发消息下方。", + "绝不要发送一条新的、未关联的消息。", "", - "对于简短确认(“ok”、“收到”、“知道了”),", - "请使用 action=react 并选择合适的 tapback 表情", - "(❤️、👍、😂、‼️、❓),而不是发送文本回复。", + "对于简短确认(‘ok’、‘got it’、‘on it’),", + "请使用 action=react 搭配合适的 tapback emoji(❤️、👍、😂、‼️、❓),", + "而不是发送文字回复。", ].join(" "), }, }, @@ -268,20 +269,20 @@ BlueBubbles 支持群聊中的提及门控,与 iMessage/WhatsApp 的行为一 } ``` -tapback 回应和线程回复都需要 BlueBubbles Private API;有关底层机制,请参见[高级操作](#advanced-actions)和[消息 ID](#message-ids-short-vs-full)。 +Tapback reactions 和线程回复都需要 BlueBubbles Private API;底层机制请参见[高级操作](#advanced-actions)和[消息 ID](#message-ids-short-vs-full)。 ## ACP 会话绑定 -BlueBubbles 聊天可以转换为持久化的 ACP 工作区,而无需更改传输层。 +BlueBubbles 聊天可以转换为持久的 ACP 工作区,而无需更改传输层。 快速操作流程: - 在私信或允许的群聊中运行 `/acp spawn codex --bind here`。 -- 之后,同一 BlueBubbles 会话中的未来消息都会路由到已生成的 ACP 会话。 +- 之后,该 BlueBubbles 会话中的消息会路由到已生成的 ACP 会话。 - `/new` 和 `/reset` 会在原地重置同一个已绑定的 ACP 会话。 -- `/acp close` 会关闭 ACP 会话并移除该绑定。 +- `/acp close` 会关闭 ACP 会话并移除绑定。 -也支持通过顶层 `bindings[]` 条目配置持久化绑定,使用 `type: "acp"` 和 `match.channel: "bluebubbles"`。 +也支持通过顶层 `bindings[]` 条目配置持久绑定,其中 `type: "acp"` 且 `match.channel: "bluebubbles"`。 `match.peer.id` 可以使用任何受支持的 BlueBubbles 目标形式: @@ -322,13 +323,13 @@ BlueBubbles 聊天可以转换为持久化的 ACP 工作区,而无需更改传 } ``` -有关通用 ACP 绑定行为,请参见 [ACP Agents](/zh-CN/tools/acp-agents)。 +共享的 ACP 绑定行为请参见 [ACP Agents](/zh-CN/tools/acp-agents)。 ## 正在输入 + 已读回执 -- **正在输入指示器**:会在生成回复之前和期间自动发送。 -- **已读回执**:由 `channels.bluebubbles.sendReadReceipts` 控制(默认:`true`)。 -- **正在输入指示器**:OpenClaw 会发送“开始输入”事件;BlueBubbles 会在发送消息或超时后自动清除输入状态(通过 DELETE 手动停止并不可靠)。 +- **输入指示器**:会在生成回复之前和期间自动发送。 +- **已读回执**:由 `channels.bluebubbles.sendReadReceipts` 控制(默认值:`true`)。 +- **输入指示器**:OpenClaw 会发送输入开始事件;BlueBubbles 会在发送消息或超时后自动清除输入状态(通过 DELETE 手动停止并不可靠)。 ```json5 { @@ -342,23 +343,23 @@ BlueBubbles 聊天可以转换为持久化的 ACP 工作区,而无需更改传 ## 高级操作 -当在配置中启用时,BlueBubbles 支持高级消息操作: +BlueBubbles 在配置中启用后支持高级消息操作: ```json5 { channels: { bluebubbles: { actions: { - reactions: true, // tapback 回应(默认:true) - edit: true, // 编辑已发送消息(macOS 13+,在 macOS 26 Tahoe 上已失效) + reactions: true, // tapback(默认:true) + edit: true, // 编辑已发送消息(macOS 13+,在 macOS 26 Tahoe 上已损坏) unsend: true, // 撤回消息(macOS 13+) - reply: true, // 通过消息 GUID 进行线程回复 + reply: true, // 按消息 GUID 进行线程回复 sendWithEffect: true, // 消息效果(slam、loud 等) renameGroup: true, // 重命名群聊 setGroupIcon: true, // 设置群聊图标/照片(在 macOS 26 Tahoe 上不稳定) addParticipant: true, // 向群组添加参与者 removeParticipant: true, // 从群组移除参与者 - leaveGroup: true, // 退出群聊 + leaveGroup: true, // 离开群聊 sendAttachment: true, // 发送附件/媒体 }, }, @@ -368,19 +369,19 @@ BlueBubbles 聊天可以转换为持久化的 ACP 工作区,而无需更改传 可用操作: -- **react**:添加/移除 tapback 回应(`messageId`、`emoji`、`remove`)。iMessage 的原生 tapback 集合为 `love`、`like`、`dislike`、`laugh`、`emphasize` 和 `question`。当智能体选择了该集合之外的表情符号(例如 `👀`)时,回应工具会回退到 `love`,这样 tapback 仍能显示,而不会导致整个请求失败。已配置的确认回应仍会严格校验,未知值会报错。 +- **react**:添加/移除 tapback reactions(`messageId`、`emoji`、`remove`)。iMessage 原生的 tapback 集合为 `love`、`like`、`dislike`、`laugh`、`emphasize` 和 `question`。当智能体选择了该集合之外的 emoji(例如 `👀`)时,reaction 工具会回退到 `love`,这样 tapback 仍能显示,而不会导致整个请求失败。已配置的确认 reactions 仍会严格校验,并在值未知时报错。 - **edit**:编辑已发送消息(`messageId`、`text`) - **unsend**:撤回消息(`messageId`) -- **reply**:回复指定消息(`messageId`、`text`、`to`) +- **reply**:回复特定消息(`messageId`、`text`、`to`) - **sendWithEffect**:使用 iMessage 效果发送(`text`、`to`、`effectId`) - **renameGroup**:重命名群聊(`chatGuid`、`displayName`) - **setGroupIcon**:设置群聊图标/照片(`chatGuid`、`media`)—— 在 macOS 26 Tahoe 上不稳定(API 可能返回成功,但图标不会同步)。 -- **addParticipant**:向群组添加某人(`chatGuid`、`address`) -- **removeParticipant**:从群组移除某人(`chatGuid`、`address`) -- **leaveGroup**:退出群聊(`chatGuid`) +- **addParticipant**:向群组添加成员(`chatGuid`、`address`) +- **removeParticipant**:从群组移除成员(`chatGuid`、`address`) +- **leaveGroup**:离开群聊(`chatGuid`) - **upload-file**:发送媒体/文件(`to`、`buffer`、`filename`、`asVoice`) - - 语音备忘录:将 **MP3** 或 **CAF** 音频与 `asVoice: true` 一起设置,即可作为 iMessage 语音消息发送。BlueBubbles 在发送语音备忘录时会将 MP3 转换为 CAF。 -- 旧别名:`sendAttachment` 仍可使用,但 `upload-file` 是规范的操作名称。 + - 语音备忘录:设置 `asVoice: true`,并使用 **MP3** 或 **CAF** 音频,以 iMessage 语音消息形式发送。BlueBubbles 在发送语音备忘录时会将 MP3 转换为 CAF。 +- 旧别名:`sendAttachment` 仍然可用,但 `upload-file` 是规范的操作名称。 ### 消息 ID(短 ID 与完整 ID) @@ -388,41 +389,41 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 - `MessageSid` / `ReplyToId` 可以是短 ID。 - `MessageSidFull` / `ReplyToIdFull` 包含提供商的完整 ID。 -- 短 ID 存储在内存中;在重启或缓存清除后可能会失效。 -- 操作接受短 `messageId` 或完整 `messageId`,但如果短 ID 已不可用,就会报错。 +- 短 ID 存储于内存中;在重启或缓存逐出后可能失效。 +- 操作接受短或完整 `messageId`,但如果短 ID 已不可用,将会报错。 -对于持久化自动化和存储,请使用完整 ID: +对于持久自动化和存储,请使用完整 ID: - 模板:`{{MessageSidFull}}`、`{{ReplyToIdFull}}` -- 上下文:入站载荷中的 `MessageSidFull` / `ReplyToIdFull` +- 上下文:入站负载中的 `MessageSidFull` / `ReplyToIdFull` 模板变量请参见[配置](/zh-CN/gateway/configuration)。 -## 合并拆分发送的私信(同一条输入中的命令 + URL) +## 合并拆分发送的私信(单次输入中的命令 + URL) -当用户在 iMessage 中同时输入命令和 URL 时——例如 `Dump https://example.com/article`——Apple 会将这次发送拆分为**两个独立的 webhook 投递**: +当用户在 iMessage 中将命令和 URL 一起输入时——例如 `Dump https://example.com/article`——Apple 会将这次发送拆成**两次独立的 webhook 投递**: 1. 一条文本消息(`"Dump"`)。 2. 一个 URL 预览气泡(`"https://..."`),并带有 OG 预览图片作为附件。 -在大多数设置中,这两个 webhook 会相隔大约 0.8-2.0 秒到达 OpenClaw。如果不进行合并,智能体会在第 1 轮只收到命令本身,然后回复(通常是“把 URL 发给我”),直到第 2 轮才看到 URL——而此时命令上下文已经丢失。 +在大多数设置中,这两个 webhook 会相隔约 0.8-2.0 秒到达 OpenClaw。如果不进行合并,智能体会在第 1 轮只收到命令,于是作出回复(通常是“把 URL 发给我”),直到第 2 轮才看到 URL——这时命令上下文已经丢失。 -`channels.bluebubbles.coalesceSameSenderDms` 允许将某个私信中的、来自同一发送者的连续 webhook 合并为一个智能体轮次。群聊仍然按每条消息分别处理,因此能保留多用户轮次结构。 +`channels.bluebubbles.coalesceSameSenderDms` 可让私信将来自同一发送者的连续 webhook 合并为单个智能体轮次。群聊则继续按每条消息分别处理,以保留多用户轮次结构。 ### 何时启用 -在以下情况启用: +在以下情况下启用: -- 你提供的 Skills 需要在一条消息中接收 `命令 + 载荷`(dump、paste、save、queue 等)。 -- 你的用户会把 URL、图片或长内容与命令一起粘贴发送。 +- 你提供的 Skills 期望在一条消息中接收 `命令 + 负载`(dump、paste、save、queue 等)。 +- 你的用户会将 URL、图片或长内容与命令一起粘贴发送。 - 你可以接受增加的私信轮次延迟(见下文)。 -在以下情况保持禁用: +在以下情况下保持禁用: -- 你需要尽可能低的私信单词命令延迟。 -- 你的所有流程都是不带后续载荷的一次性命令。 +- 你需要单词私信触发命令的最低延迟。 +- 你的所有流程都是不带后续负载的一次性命令。 ### 启用方式 @@ -436,7 +437,7 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 } ``` -启用该标志后,如果没有显式设置 `messages.inbound.byChannel.bluebubbles`,防抖窗口会扩大到 **2500 ms**(不合并时的默认值为 500 ms)。必须使用更宽的窗口——Apple 的拆分发送节奏为 0.8-2.0 秒,无法适配更紧的默认值。 +启用该标志后,如果未显式设置 `messages.inbound.byChannel.bluebubbles`,防抖窗口会扩展到 **2500 ms**(非合并模式的默认值为 500 ms)。需要更宽的窗口——Apple 的拆分发送节奏为 0.8-2.0 秒,无法落入更紧的默认窗口。 如需自行调整窗口: @@ -446,7 +447,7 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 inbound: { byChannel: { // 2500 ms 适用于大多数设置;如果你的 Mac 较慢 - // 或处于内存压力下(观察到的间隔可能会超过 2 秒),则提高到 4000 ms。 + // 或处于内存压力下(观察到间隔可能会超过 2 秒),可提高到 4000 ms。 bluebubbles: 2500, }, }, @@ -456,26 +457,26 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 ### 权衡 -- **私信控制命令会增加延迟。** 启用该标志后,私信控制命令消息(如 `Dump`、`Save` 等)现在会在派发前最多等待整个防抖窗口,以防随后还有载荷 webhook 到来。群聊命令仍会立即派发。 -- **合并后的输出有上限** —— 合并文本上限为 4000 个字符,并带有明确的 `…[truncated]` 标记;附件上限为 20 个;源条目上限为 10 个(超过时保留首条和最新条目)。每个源 `messageId` 仍会进入入站去重,因此后续 MessagePoller 重新播放任意单个事件时,仍会被识别为重复。 +- **私信控制命令的延迟增加。** 启用该标志后,私信控制命令消息(如 `Dump`、`Save` 等)现在会在分发前最多等待一个防抖窗口,以防后续还有负载 webhook 到来。群聊命令仍保持即时分发。 +- **合并输出是有界的**——合并文本上限为 4000 个字符,并带有显式的 `…[truncated]` 标记;附件上限为 20;源条目上限为 10(超过后保留首条和最新条)。每个源 `messageId` 仍会进入入站去重,因此之后若 MessagePoller 重放任意单个事件,仍会被识别为重复项。 - **按渠道选择启用。** 其他渠道(Telegram、WhatsApp、Slack、……)不受影响。 -### 场景以及智能体会看到什么 +### 场景以及智能体看到的内容 -| 用户输入内容 | Apple 的投递方式 | 标志关闭(默认) | 标志开启 + 2500 ms 窗口 | -| ---------------------------------------------------------------- | ------------------------ | -------------------------------- | ------------------------------------------------------------- | -| `Dump https://example.com`(一次发送) | 2 个 webhook,相隔约 1 秒 | 两个智能体轮次:先只有 “Dump”,再是 URL | 一个轮次:合并文本 `Dump https://example.com` | -| `Save this 📎image.jpg caption`(附件 + 文本) | 2 个 webhook | 两个轮次 | 一个轮次:文本 + 图片 | -| `/status`(独立命令) | 1 个 webhook | 立即派发 | **最多等待整个窗口后再派发** | -| 单独粘贴一个 URL | 1 个 webhook | 立即派发 | 立即派发(桶中只有一个条目) | -| 文本 + URL 作为两条有意分开的消息发送,相隔数分钟 | 2 个 webhook,超出窗口 | 两个轮次 | 两个轮次(窗口期间已过期) | -| 快速洪泛(窗口内 >10 条小型私信) | N 个 webhook | N 个轮次 | 一个轮次,受上限约束的输出(保留首条 + 最新条,应用文本/附件上限) | +| 用户输入内容 | Apple 投递方式 | 标志关闭(默认) | 标志开启 + 2500 ms 窗口 | +| ------------------------------------------------------------------ | ------------------------- | --------------------------------------- | ----------------------------------------------------------------------- | +| `Dump https://example.com`(一次发送) | 2 个 webhook,相隔约 1 秒 | 两个智能体轮次:仅有 “Dump”,然后是 URL | 一个轮次:合并文本 `Dump https://example.com` | +| `Save this 📎image.jpg caption`(附件 + 文本) | 2 个 webhook | 两个轮次 | 一个轮次:文本 + 图片 | +| `/status`(独立命令) | 1 个 webhook | 即时分发 | **最多等待整个窗口后再分发** | +| 单独粘贴的 URL | 1 个 webhook | 即时分发 | 即时分发(桶中只有一个条目) | +| 文本 + URL 故意分成两条消息发送,相隔数分钟 | 2 个 webhook,超出窗口 | 两个轮次 | 两个轮次(窗口已在它们之间过期) | +| 快速洪泛(窗口内超过 10 条小型私信) | N 个 webhook | N 个轮次 | 一个轮次,有界输出(应用首条 + 最新条保留、文本/附件上限) | -### 拆分发送合并故障排除 +### 拆分发送合并的故障排除 -如果该标志已启用,但拆分发送仍以两个轮次到达,请逐层检查: +如果标志已开启,但拆分发送仍然作为两个轮次到达,请检查每一层: -1. **配置确实已加载。** +1. **配置是否确实已加载。** ``` grep coalesceSameSenderDms ~/.openclaw/openclaw.json @@ -483,43 +484,33 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 然后执行 `openclaw gateway restart` —— 该标志会在 debouncer-registry 创建时读取。 -2. **防抖窗口对你的环境来说足够宽。** 查看 BlueBubbles 服务器日志 `~/Library/Logs/bluebubbles-server/main.log`: +2. **你的设置是否有足够宽的防抖窗口。** 查看 `~/Library/Logs/bluebubbles-server/main.log` 下的 BlueBubbles 服务器日志: ``` grep -E "Dispatching event to webhook" main.log | tail -20 ``` - 测量 `"Dump"` 这类文本投递与随后 `"https://..."`; `Attachments:` 投递之间的间隔。把 `messages.inbound.byChannel.bluebubbles` 提高到能够充分覆盖该间隔的值。 + 测量 `"Dump"` 这类文本投递与其后 `"https://..."`; Attachments:` 投递之间的间隔。将 `messages.inbound.byChannel.bluebubbles` 调高到能够从容覆盖该间隔。 -3. **会话 JSONL 时间戳 ≠ webhook 到达时间。** 会话事件时间戳(`~/.openclaw/agents//sessions/*.jsonl`)反映的是 Gateway 网关将消息交给智能体的时间,**而不是** webhook 到达的时间。若第二条消息被标记为 `[Queued messages while agent was busy]`,说明第二个 webhook 到达时第一轮仍在运行——此时合并桶已经刷出。请根据 BB 服务器日志调整窗口,而不是根据会话日志。 +3. **会话 JSONL 时间戳 ≠ webhook 到达时间。** 会话事件时间戳(`~/.openclaw/agents//sessions/*.jsonl`)反映的是 Gateway 网关何时将消息交给智能体,**而不是** webhook 何时到达。如果排队中的第二条消息带有 `[Queued messages while agent was busy]` 标签,说明第二个 webhook 到达时,第一轮仍在运行——合并桶已经刷新。请根据 BB 服务器日志而不是会话日志来调整窗口。 -4. **内存压力导致回复派发变慢。** 在配置较低的机器(8 GB)上,智能体轮次可能耗时过长,导致合并桶在回复完成前就已刷出,而 URL 则作为排队的第二轮到达。检查 `memory_pressure` 和 `ps -o rss -p $(pgrep openclaw-gateway)`;如果 Gateway 网关的 RSS 超过约 500 MB,且压缩器处于活动状态,请关闭其他占用较重的进程,或升级到更大的主机。 +4. **内存压力导致回复分发变慢。** 在较小的机器(8 GB)上,智能体轮次可能耗时较长,导致在回复完成前合并桶就已刷新,URL 于是作为排队的第二轮消息到达。检查 `memory_pressure` 和 `ps -o rss -p $(pgrep openclaw-gateway)`;如果 Gateway 网关 RSS 超过约 500 MB 且压缩器处于活跃状态,请关闭其他高负载进程或升级到更大的主机。 -5. **回复引用发送走的是另一条路径。** 如果用户把 `Dump` 作为对现有 URL 气泡的**回复**发送(iMessage 会在 Dump 气泡上显示 “1 Reply” 标记),那么 URL 位于 `replyToBody` 中,而不是第二个 webhook 中。此时合并机制不适用——这是 Skills/提示词问题,而不是 debouncer 问题。 +5. **回复引用发送是另一条路径。** 如果用户将 `Dump` 作为对现有 URL 气泡的**回复**发送(iMessage 会在 Dump 气泡上显示 “1 Reply” 标记),那么 URL 位于 `replyToBody` 中,而不是第二个 webhook。此时合并机制不适用——这是 Skills/提示词问题,而不是防抖器问题。 ## 分块流式传输 -控制响应是作为单条消息发送,还是以分块形式流式发送: - -```json5 -{ - channels: { - bluebubbles: { - blockStreaming: true, // 启用分块流式传输(默认关闭) - }, - }, -} -``` - +控制响应是作为单条消息发送,还是按块流式发送: +__OC_I18N_900017__ ## 媒体 + 限制 - 入站附件会被下载并存储到媒体缓存中。 -- 通过 `channels.bluebubbles.mediaMaxMb` 控制入站和出站媒体的大小上限(默认:8 MB)。 +- 入站和出站媒体都通过 `channels.bluebubbles.mediaMaxMb` 限制媒体大小(默认:8 MB)。 - 出站文本会按 `channels.bluebubbles.textChunkLimit` 分块(默认:4000 个字符)。 ## 配置参考 -完整配置:[配置](/zh-CN/gateway/configuration) +完整配置:[配置](/gateway/configuration) 提供商选项: @@ -528,20 +519,20 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 - `channels.bluebubbles.password`:API 密码。 - `channels.bluebubbles.webhookPath`:webhook 端点路径(默认:`/bluebubbles-webhook`)。 - `channels.bluebubbles.dmPolicy`:`pairing | allowlist | open | disabled`(默认:`pairing`)。 -- `channels.bluebubbles.allowFrom`:私信允许列表(handles、电子邮件、E.164 号码、`chat_id:*`、`chat_guid:*`)。 +- `channels.bluebubbles.allowFrom`:私信 allowlist(句柄、电子邮件、E.164 号码、`chat_id:*`、`chat_guid:*`)。 - `channels.bluebubbles.groupPolicy`:`open | allowlist | disabled`(默认:`allowlist`)。 -- `channels.bluebubbles.groupAllowFrom`:群组发送者允许列表。 -- `channels.bluebubbles.enrichGroupParticipantsFromContacts`:在 macOS 上,可在门控通过后选择从本地 Contacts 增强未命名的群组参与者。默认:`false`。 +- `channels.bluebubbles.groupAllowFrom`:群组发送者 allowlist。 +- `channels.bluebubbles.enrichGroupParticipantsFromContacts`:在 macOS 上,可在门控通过后选择性地从本地通讯录增强未命名的群组参与者。默认:`false`。 - `channels.bluebubbles.groups`:按群组配置(`requireMention` 等)。 - `channels.bluebubbles.sendReadReceipts`:发送已读回执(默认:`true`)。 - `channels.bluebubbles.blockStreaming`:启用分块流式传输(默认:`false`;流式回复需要启用)。 -- `channels.bluebubbles.textChunkLimit`:出站分块大小(按字符计,默认:4000)。 -- `channels.bluebubbles.sendTimeoutMs`:通过 `/api/v1/message/text` 发送出站文本时,每个请求的超时时间(毫秒,默认:30000)。在 macOS 26 环境中,如果 Private API iMessage 发送会在 iMessage 框架内部卡住 60 秒以上,可提高该值,例如设为 `45000` 或 `60000`。探测、聊天查找、回应、编辑和健康检查目前仍保持较短的 10 秒默认值;后续计划将更长超时扩展到回应和编辑。按账户覆盖:`channels.bluebubbles.accounts..sendTimeoutMs`。 -- `channels.bluebubbles.chunkMode`:`length`(默认)仅在超过 `textChunkLimit` 时拆分;`newline` 会先按空行(段落边界)拆分,再按长度分块。 -- `channels.bluebubbles.mediaMaxMb`:入站/出站媒体大小上限(MB,默认:8)。 -- `channels.bluebubbles.mediaLocalRoots`:允许用于出站本地媒体路径的绝对本地目录显式允许列表。默认情况下,除非配置了此项,否则会拒绝发送本地路径。按账户覆盖:`channels.bluebubbles.accounts..mediaLocalRoots`。 -- `channels.bluebubbles.coalesceSameSenderDms`:将同一发送者连续的私信 webhook 合并为一个智能体轮次,以便 Apple 的“文本 + URL”拆分发送能作为单条消息到达(默认:`false`)。有关场景、窗口调优和权衡,请参见[合并拆分发送的私信](#coalescing-split-send-dms-command--url-in-one-composition)。启用该项且未显式设置 `messages.inbound.byChannel.bluebubbles` 时,默认入站防抖窗口会从 500 ms 扩大到 2500 ms。 -- `channels.bluebubbles.historyLimit`:用于上下文的群组消息最大数量(设为 0 则禁用)。 +- `channels.bluebubbles.textChunkLimit`:出站分块大小,单位为字符(默认:4000)。 +- `channels.bluebubbles.sendTimeoutMs`:通过 `/api/v1/message/text` 发送出站文本时,每个请求的超时时间(毫秒,默认:30000)。在 macOS 26 设置中,如果 Private API iMessage 发送可能在 iMessage 框架内部停滞 60+ 秒,请调高此值;例如 `45000` 或 `60000`。探测、聊天查询、reactions、编辑和健康检查目前仍保持较短的 10 秒默认值;后续计划扩展到 reactions 和编辑。按账户覆盖:`channels.bluebubbles.accounts..sendTimeoutMs`。 +- `channels.bluebubbles.chunkMode`:`length`(默认)仅在超过 `textChunkLimit` 时分割;`newline` 会先按空行(段落边界)分割,然后再按长度分块。 +- `channels.bluebubbles.mediaMaxMb`:入站/出站媒体大小上限,单位为 MB(默认:8)。 +- `channels.bluebubbles.mediaLocalRoots`:允许用于出站本地媒体路径的绝对本地目录显式 allowlist。默认情况下,除非配置此项,否则会拒绝本地路径发送。按账户覆盖:`channels.bluebubbles.accounts..mediaLocalRoots`。 +- `channels.bluebubbles.coalesceSameSenderDms`:将同一发送者的连续私信 webhook 合并为一个智能体轮次,以便 Apple 的“文本 + URL”拆分发送作为一条消息到达(默认:`false`)。有关场景、窗口调优和权衡,请参见[合并拆分发送的私信](#coalescing-split-send-dms-command--url-in-one-composition)。如果启用且未显式设置 `messages.inbound.byChannel.bluebubbles`,默认入站防抖窗口会从 500 ms 扩大到 2500 ms。 +- `channels.bluebubbles.historyLimit`:用于上下文的群组消息最大数量(0 表示禁用)。 - `channels.bluebubbles.dmHistoryLimit`:私信历史记录上限。 - `channels.bluebubbles.actions`:启用/禁用特定操作。 - `channels.bluebubbles.accounts`:多账户配置。 @@ -551,44 +542,44 @@ OpenClaw 可能会显示_短_消息 ID(例如 `1`、`2`)以节省 token。 - `agents.list[].groupChat.mentionPatterns`(或 `messages.groupChat.mentionPatterns`)。 - `messages.responsePrefix`。 -## 寻址 / 传递目标 +## 寻址 / 投递目标 优先使用 `chat_guid` 以获得稳定路由: - `chat_guid:iMessage;-;+15555550123`(群组首选) - `chat_id:123` - `chat_identifier:...` -- 直接 handles:`+15555550123`、`user@example.com` - - 如果某个直接 handle 没有现有私信聊天,OpenClaw 会通过 `POST /api/v1/chat/new` 创建一个。这要求启用 BlueBubbles Private API。 +- 直接句柄:`+15555550123`、`user@example.com` + - 如果直接句柄没有现有私信聊天,OpenClaw 会通过 `POST /api/v1/chat/new` 创建一个。这要求启用 BlueBubbles Private API。 ### iMessage 与 SMS 路由 -当同一个 handle 在 Mac 上同时存在 iMessage 聊天和 SMS 聊天时(例如某个电话号码已注册 iMessage,但也曾收到绿色气泡的回退消息),OpenClaw 会优先选择 iMessage 聊天,并且绝不会静默降级到 SMS。若要强制使用 SMS 聊天,请使用显式 `sms:` 目标前缀(例如 `sms:+15555550123`)。如果某个 handle 没有匹配的 iMessage 聊天,仍会通过 BlueBubbles 报告的相应聊天发送。 +当同一句柄在 Mac 上同时存在 iMessage 聊天和 SMS 聊天时(例如某个电话号码已注册 iMessage,但也曾收到过绿色气泡回退消息),OpenClaw 会优先选择 iMessage 聊天,绝不会静默降级到 SMS。如需强制使用 SMS 聊天,请使用显式的 `sms:` 目标前缀(例如 `sms:+15555550123`)。对于没有匹配 iMessage 聊天的句柄,仍会通过 BlueBubbles 报告的聊天进行发送。 ## 安全 -- webhook 请求通过将查询参数或请求头中的 `guid`/`password` 与 `channels.bluebubbles.password` 进行比较来完成身份验证。 -- 请对 API 密码和 webhook 端点保密(应将它们视为凭证)。 -- BlueBubbles webhook 身份验证不存在 localhost 绕过。如果你代理 webhook 流量,请在整个请求链路中保留 BlueBubbles 密码。这里的 `gateway.trustedProxies` 不能替代 `channels.bluebubbles.password`。参见 [Gateway 网关安全](/zh-CN/gateway/security#reverse-proxy-configuration)。 -- 如果要将 BlueBubbles 服务器暴露到局域网外部,请启用 HTTPS 和防火墙规则。 +- webhook 请求通过将查询参数或请求头中的 `guid`/`password` 与 `channels.bluebubbles.password` 比较来完成身份验证。 +- 请对 API 密码和 webhook 端点保密(将其视为凭证)。 +- BlueBubbles webhook 身份验证没有 localhost 绕过。如果你代理 webhook 流量,请在整个请求链路中保留 BlueBubbles 密码。这里的 `gateway.trustedProxies` 不能替代 `channels.bluebubbles.password`。参见[Gateway 网关安全](/gateway/security#reverse-proxy-configuration)。 +- 如果要将 BlueBubbles 服务器暴露到你的 LAN 之外,请启用 HTTPS + 防火墙规则。 ## 故障排除 -- 如果正在输入/已读事件停止工作,请检查 BlueBubbles webhook 日志,并确认 Gateway 网关路径与 `channels.bluebubbles.webhookPath` 匹配。 -- 配对码会在一小时后过期;请使用 `openclaw pairing list bluebubbles` 和 `openclaw pairing approve bluebubbles `。 -- 回应需要 BlueBubbles private API(`POST /api/v1/message/react`);请确认服务器版本已提供该接口。 -- 编辑/撤回需要 macOS 13+ 和兼容的 BlueBubbles 服务器版本。在 macOS 26(Tahoe)上,由于 private API 发生变化,编辑目前已失效。 -- 在 macOS 26(Tahoe)上,群组图标更新可能不稳定:API 可能返回成功,但新图标不会同步。 -- OpenClaw 会根据 BlueBubbles 服务器的 macOS 版本自动隐藏已知失效的操作。如果在 macOS 26(Tahoe)上仍然显示编辑功能,请通过 `channels.bluebubbles.actions.edit=false` 手动禁用。 -- 已启用 `coalesceSameSenderDms`,但拆分发送(例如 `Dump` + URL)仍以两个轮次到达:请参见[拆分发送合并故障排除](#split-send-coalescing-troubleshooting)检查清单——常见原因包括防抖窗口过窄、将会话日志时间戳误读为 webhook 到达时间,或属于回复引用发送(它使用 `replyToBody`,而不是第二个 webhook)。 -- 若要查看状态/健康信息:`openclaw status --all` 或 `openclaw status --deep`。 +- 如果输入/已读事件停止工作,请检查 BlueBubbles webhook 日志,并确认 Gateway 网关路径与 `channels.bluebubbles.webhookPath` 匹配。 +- Pairing 代码一小时后过期;请使用 `openclaw pairing list bluebubbles` 和 `openclaw pairing approve bluebubbles `。 +- Reactions 需要 BlueBubbles Private API(`POST /api/v1/message/react`);请确保服务器版本已提供该接口。 +- 编辑/撤回需要 macOS 13+ 和兼容的 BlueBubbles 服务器版本。在 macOS 26(Tahoe)上,由于 Private API 变更,编辑当前已损坏。 +- 群组图标更新在 macOS 26(Tahoe)上可能不稳定:API 可能返回成功,但新图标不会同步。 +- OpenClaw 会根据 BlueBubbles 服务器的 macOS 版本自动隐藏已知损坏的操作。如果在 macOS 26(Tahoe)上仍显示编辑功能,请使用 `channels.bluebubbles.actions.edit=false` 手动禁用它。 +- 已启用 `coalesceSameSenderDms`,但拆分发送(例如 `Dump` + URL)仍作为两个轮次到达:请参见[拆分发送合并的故障排除](#split-send-coalescing-troubleshooting)检查清单——常见原因包括防抖窗口过窄、误将会话日志时间戳当作 webhook 到达时间,或回复引用发送(其使用的是 `replyToBody`,而不是第二个 webhook)。 +- 如需查看 Status/健康信息:`openclaw status --all` 或 `openclaw status --deep`。 -有关通用渠道工作流参考,请参见[渠道](/zh-CN/channels)和[插件](/zh-CN/tools/plugin)指南。 +有关一般渠道工作流参考,请参见[Channels](/zh-CN/channels)和 [Plugins](/zh-CN/tools/plugin) 指南。 ## 相关内容 -- [渠道概览](/zh-CN/channels) —— 所有受支持的渠道 -- [配对](/zh-CN/channels/pairing) —— 私信身份验证与配对流程 -- [群组](/zh-CN/channels/groups) —— 群聊行为与提及门控 -- [渠道路由](/zh-CN/channels/channel-routing) —— 消息的会话路由 -- [安全](/zh-CN/gateway/security) —— 访问模型与加固 +- [Channels Overview](/zh-CN/channels) — 所有受支持的渠道 +- [Pairing](/zh-CN/channels/pairing) — 私信身份验证与配对流程 +- [Groups](/zh-CN/channels/groups) — 群聊行为与提及门控 +- [Channel Routing](/zh-CN/channels/channel-routing) — 消息的会话路由 +- [Security](/zh-CN/gateway/security) — 访问模型与加固 diff --git a/docs/zh-CN/channels/whatsapp.md b/docs/zh-CN/channels/whatsapp.md index 0c45e60cb..824ac11d3 100644 --- a/docs/zh-CN/channels/whatsapp.md +++ b/docs/zh-CN/channels/whatsapp.md @@ -1,29 +1,29 @@ --- read_when: - - 处理 WhatsApp /web 渠道行为或收件箱路由 + - 正在处理 WhatsApp / 网页渠道行为或收件箱路由 summary: WhatsApp 渠道支持、访问控制、投递行为和运维 title: WhatsApp x-i18n: - generated_at: "2026-04-26T04:44:22Z" + generated_at: "2026-04-26T04:50:08Z" model: gpt-5.4 provider: openai - source_hash: 300a8c7ff5768a8da869a4052c01639e7763550adceb40dabc908be44602f352 + source_hash: fd4217adb673bc4c071fc1bff6994fb214966c2b28fe59253a1a6f4b4b7fcdba source_path: channels/whatsapp.md workflow: 15 --- -Status:通过 WhatsApp Web(Baileys)达到可用于生产的状态。Gateway 网关拥有已关联的会话。 +Status:通过 WhatsApp Web(Baileys)已可用于生产环境。Gateway 网关拥有已关联的会话。 ## 安装(按需) - 新手引导(`openclaw onboard`)和 `openclaw channels add --channel whatsapp` - 会在你第一次选择 WhatsApp 插件时提示安装。 + 会在你第一次选择 WhatsApp 插件时提示安装它。 - `openclaw channels login --channel whatsapp` 也会在 插件尚未安装时提供安装流程。 - 开发渠道 + git 检出:默认使用本地插件路径。 - Stable/Beta:默认使用 npm 包 `@openclaw/whatsapp`。 -也可以继续使用手动安装: +仍然可以手动安装: ```bash openclaw plugins install @openclaw/whatsapp @@ -31,10 +31,10 @@ openclaw plugins install @openclaw/whatsapp - 对未知发送者的默认私信策略是配对。 + 未知发送者的默认私信策略是配对。 - 跨渠道诊断与修复手册。 + 跨渠道诊断与修复操作手册。 完整的渠道配置模式和示例。 @@ -61,19 +61,19 @@ openclaw plugins install @openclaw/whatsapp - + ```bash openclaw channels login --channel whatsapp ``` - 针对特定账号: + 对于特定账号: ```bash openclaw channels login --channel whatsapp --account work ``` - 如需在登录前附加现有 / 自定义的 WhatsApp Web 认证目录: + 若要在登录前附加现有/自定义的 WhatsApp Web 认证目录: ```bash openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth @@ -103,7 +103,7 @@ openclaw pairing approve whatsapp -OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据和设置流程针对这种部署进行了优化,但也支持个人号码部署。) +OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据和设置流程已针对这种设置进行优化,但也支持个人号码设置。) ## 部署模式 @@ -112,8 +112,8 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据 这是最清晰的运维模式: - - 为 OpenClaw 使用单独的 WhatsApp 身份 - - 更清晰的私信 allowlist 和路由边界 + - OpenClaw 使用独立的 WhatsApp 身份 + - 更清晰的私信允许列表和路由边界 - 更低的自聊混淆概率 最小策略模式: @@ -131,19 +131,19 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据 - + 新手引导支持个人号码模式,并会写入适合自聊的基线配置: - `dmPolicy: "allowlist"` - `allowFrom` 包含你的个人号码 - `selfChatMode: true` - 在运行时,自聊保护基于已关联的自身号码和 `allowFrom` 生效。 + 在运行时,自聊保护依赖已关联的自身号码和 `allowFrom`。 - 在当前 OpenClaw 渠道架构中,消息平台渠道基于 WhatsApp Web(`Baileys`)。 + 当前 OpenClaw 渠道架构中的消息平台渠道基于 WhatsApp Web(`Baileys`)。 内置聊天渠道注册表中没有单独的 Twilio WhatsApp 消息渠道。 @@ -153,19 +153,19 @@ OpenClaw 建议尽可能为 WhatsApp 使用单独的号码。(渠道元数据 ## 运行时模型 - Gateway 网关拥有 WhatsApp socket 和重连循环。 -- 出站发送要求目标账号存在活动中的 WhatsApp 监听器。 -- 会忽略 Status 和 broadcast 聊天(`@status`、`@broadcast`)。 -- 私聊使用私信会话规则(`session.dmScope`;默认 `main` 会把私信折叠到智能体主会话)。 +- 向外发送消息要求目标账号存在活跃的 WhatsApp 监听器。 +- 会忽略状态和广播聊天(`@status`、`@broadcast`)。 +- 直接聊天使用私信会话规则(`session.dmScope`;默认 `main` 会将私信折叠到智能体主会话)。 - 群组会话彼此隔离(`agent::whatsapp:group:`)。 -- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` / 小写变体)。优先使用主机级代理配置,而不是渠道特定的 WhatsApp 代理设置。 -- 启用 `messages.removeAckAfterReply` 时,OpenClaw 会在可见回复送达后清除 WhatsApp 的 ack 反应。 +- WhatsApp Web 传输遵循 Gateway 网关主机上的标准代理环境变量(`HTTPS_PROXY`、`HTTP_PROXY`、`NO_PROXY` / 小写变体)。优先使用主机级代理配置,而不是渠道专用的 WhatsApp 代理设置。 +- 启用 `messages.removeAckAfterReply` 时,OpenClaw 会在可见回复送达后清除 WhatsApp 的确认反应。 ## 插件钩子和隐私 WhatsApp 入站消息可能包含个人消息内容、电话号码、 -群组标识符、发送者名称以及会话关联字段。因此, -除非你显式选择启用,否则 WhatsApp 不会向插件广播入站 -`message_received` 钩子负载: +群组标识符、发送者姓名以及会话关联字段。因此, +除非你显式选择启用,否则 WhatsApp 不会将入站 `message_received` +钩子负载广播给插件: ```json5 { @@ -179,7 +179,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 } ``` -你也可以把这个选择启用范围限定到某个账号: +你也可以将此启用范围限定到某一个账号: ```json5 { @@ -197,79 +197,81 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 } ``` -仅在你信任相关插件可以接收入站 WhatsApp 消息内容和标识符时启用此功能。 +仅当你信任这些插件可以接收入站 WhatsApp 消息内容和标识符时, +才启用此选项。 -## 访问控制和激活 +## 访问控制与激活 - `channels.whatsapp.dmPolicy` 控制私聊访问: + `channels.whatsapp.dmPolicy` 控制直接聊天访问: - `pairing`(默认) - `allowlist` - `open`(要求 `allowFrom` 包含 `"*"`) - `disabled` - `allowFrom` 接受 E.164 风格号码(内部会标准化)。 + `allowFrom` 接受 E.164 风格号码(内部会进行标准化)。 - 多账号覆盖:对于该账号,`channels.whatsapp.accounts..dmPolicy`(以及 `allowFrom`)优先于渠道级默认值。 + 多账号覆盖:该账号的 `channels.whatsapp.accounts..dmPolicy`(以及 `allowFrom`)会优先于渠道级默认值。 运行时行为细节: - - 配对会持久化到渠道 allow-store,并与已配置的 `allowFrom` 合并 - - 如果未配置任何 allowlist,默认允许已关联的自身号码 - - OpenClaw 绝不会自动配对出站 `fromMe` 私信(即你从已关联设备发给自己的消息) + - 配对会持久化到渠道允许存储中,并与已配置的 `allowFrom` 合并 + - 如果没有配置允许列表,则默认允许已关联的自身号码 + - OpenClaw 绝不会自动配对出站的 `fromMe` 私信(即你从已关联设备发给自己的消息) - + 群组访问有两层: - 1. **群组成员 allowlist**(`channels.whatsapp.groups`) - - 如果省略 `groups`,则所有群组都有资格 - - 如果存在 `groups`,它就作为群组 allowlist(允许 `"*"`) + 1. **群组成员允许列表**(`channels.whatsapp.groups`) + - 如果省略 `groups`,则所有群组都有资格接入 + - 如果存在 `groups`,它将作为群组允许列表(允许使用 `"*"`) 2. **群组发送者策略**(`channels.whatsapp.groupPolicy` + `groupAllowFrom`) - - `open`:绕过发送者 allowlist + - `open`:绕过发送者允许列表 - `allowlist`:发送者必须匹配 `groupAllowFrom`(或 `*`) - `disabled`:阻止所有群组入站消息 - 发送者 allowlist 回退: + 发送者允许列表回退规则: - 如果未设置 `groupAllowFrom`,运行时会在可用时回退到 `allowFrom` - - 发送者 allowlist 会在提及 / 回复激活之前进行评估 + - 发送者允许列表会在提及/回复激活之前进行评估 - 注意:如果完全不存在 `channels.whatsapp` 配置块,运行时群组策略回退为 `allowlist`(并记录警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。 + 注意:如果完全不存在 `channels.whatsapp` 配置块,运行时的群组策略回退值为 `allowlist`(并记录警告日志),即使设置了 `channels.defaults.groupPolicy` 也是如此。 - 默认情况下,群组回复需要被提及。 + 群组回复默认需要提及。 提及检测包括: - 对机器人身份的显式 WhatsApp 提及 - 已配置的提及正则模式(`agents.list[].groupChat.mentionPatterns`,回退到 `messages.groupChat.mentionPatterns`) - - 隐式回复机器人检测(回复目标发送者与机器人身份匹配) + - 已授权群组消息的入站语音笔记转录 + - 隐式回复机器人检测(回复发送者与机器人身份匹配) 安全说明: - - 引用 / 回复只能满足提及门控;它**不会**授予发送者授权 - - 当 `groupPolicy: "allowlist"` 时,即使非 allowlist 发送者回复了 allowlist 用户的消息,仍会被阻止 + - 引用/回复仅满足提及门控;它**不会**授予发送者授权 + - 当 `groupPolicy: "allowlist"` 时,未在允许列表中的发送者即使回复了允许列表用户的消息,仍会被阻止 会话级激活命令: - `/activation mention` - `/activation always` - `activation` 会更新会话状态(而不是全局配置)。它受所有者权限控制。 + `activation` 会更新会话状态(而不是全局配置)。它受 owner 权限控制。 ## 个人号码和自聊行为 -当已关联的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会启用: +当已关联的自身号码也存在于 `allowFrom` 中时,WhatsApp 自聊保护会生效: - 跳过自聊轮次的已读回执 - 忽略原本会提醒你自己的 mention-JID 自动触发行为 @@ -278,10 +280,10 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 ## 消息标准化和上下文 - - 入站 WhatsApp 消息会封装到共享的入站信封中。 + + 入站 WhatsApp 消息会被封装进共享的入站信封结构中。 - 如果存在引用回复,会以如下形式附加上下文: + 如果存在引用回复,上下文会以下列形式追加: ```text [Replying to id:] @@ -289,12 +291,12 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 [/Replying] ``` - 在可用时,还会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。 + 若可用,也会填充回复元数据字段(`ReplyToId`、`ReplyToBody`、`ReplyToSender`、发送者 JID/E.164)。 - - 仅媒体的入站消息会使用如下占位符进行标准化: + + 仅包含媒体的入站消息会使用如下占位符进行标准化: - `` - `` @@ -302,14 +304,16 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - `` - `` - 位置消息正文会使用简洁的坐标文本。位置标签 / 注释以及联系人 / vCard 详情会渲染为带围栏的不可信元数据,而不是内联提示词文本。 + 对于已授权群组中的语音笔记,如果消息正文仅为 ``,会在提及门控之前先进行转录,因此在语音笔记中说出机器人的提及内容也可以触发回复。如果转录内容仍然没有提及机器人,转录文本会保留在待处理群组历史中,而不是保留原始占位符。 + + 位置正文使用简洁的坐标文本。位置标签/备注以及联系人/vCard 详细信息会渲染为带围栏的不受信任元数据,而不是内联提示文本。 - 对于群组,在机器人最终被触发时,可以缓冲尚未处理的消息并作为上下文注入。 + 对于群组,未处理的消息可以被缓冲,并在机器人最终被触发时作为上下文注入。 - - 默认限制:`50` + - 默认上限:`50` - 配置:`channels.whatsapp.historyLimit` - 回退:`messages.groupChat.historyLimit` - `0` 表示禁用 @@ -322,7 +326,7 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - 对已接受的入站 WhatsApp 消息,默认启用已读回执。 + 对于已接受的入站 WhatsApp 消息,默认启用已读回执。 全局禁用: @@ -361,44 +365,44 @@ WhatsApp 入站消息可能包含个人消息内容、电话号码、 - - 默认分块限制:`channels.whatsapp.textChunkLimit = 4000` + - 默认分块上限:`channels.whatsapp.textChunkLimit = 4000` - `channels.whatsapp.chunkMode = "length" | "newline"` - - `newline` 模式优先按段落边界(空行)拆分,然后回退到按长度安全分块 + - `newline` 模式优先按段落边界(空行)分块,然后再回退到按长度安全分块 - - 支持图片、视频、音频(PTT 语音便笺)和文档负载 - - 音频媒体通过 Baileys 的 `audio` 负载发送,并设置 `ptt: true`,因此 WhatsApp 客户端会将其渲染为按住说话语音便笺 - - 回复负载会保留 `audioAsVoice`;WhatsApp 的 TTS 语音便笺输出即使提供商返回 MP3 或 WebM,也会继续走这个 PTT 路径 - - 原生 Ogg/Opus 音频会以 `audio/ogg; codecs=opus` 发送,以确保语音便笺兼容性 - - 非 Ogg 音频,包括 Microsoft Edge TTS MP3/WebM 输出,会在 PTT 投递前使用 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus - - `/tts latest` 会将最近一条助手回复作为单条语音便笺发送,并抑制对同一条回复的重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS - - 动态 GIF 播放通过视频发送上的 `gifPlayback: true` 提供支持 - - 发送多媒体回复负载时,标题说明会应用到第一个媒体项;但 PTT 语音便笺会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端对语音便笺标题说明的渲染并不一致 - - 媒体源可以是 HTTP(S)、`file://` 或本地路径 + - 支持图片、视频、音频(PTT 语音笔记)和文档负载 + - 音频媒体通过 Baileys 的 `audio` 负载发送,并带有 `ptt: true`,因此 WhatsApp 客户端会将其渲染为按住说话语音笔记 + - 回复负载会保留 `audioAsVoice`;WhatsApp 的 TTS 语音笔记输出即使提供商返回的是 MP3 或 WebM,也仍然走这条 PTT 路径 + - 原生 Ogg/Opus 音频会以 `audio/ogg; codecs=opus` 发送,以兼容语音笔记 + - 非 Ogg 音频(包括 Microsoft Edge TTS 的 MP3/WebM 输出)会在 PTT 投递前使用 `ffmpeg` 转码为 48 kHz 单声道 Ogg/Opus + - `/tts latest` 会将最新的助手回复作为一条语音笔记发送,并抑制同一回复的重复发送;`/tts chat on|off|default` 控制当前 WhatsApp 聊天的自动 TTS + - 动态 GIF 播放通过视频发送上的 `gifPlayback: true` 支持 + - 发送多媒体回复负载时,说明文字会应用到第一项媒体;但 PTT 语音笔记会先发送音频,再单独发送可见文本,因为 WhatsApp 客户端对语音笔记说明文字的渲染并不一致 + - 媒体来源可以是 HTTP(S)、`file://` 或本地路径 - 入站媒体保存上限:`channels.whatsapp.mediaMaxMb`(默认 `50`) - 出站媒体发送上限:`channels.whatsapp.mediaMaxMb`(默认 `50`) - 按账号覆盖使用 `channels.whatsapp.accounts..mediaMaxMb` - - 图片会自动优化(调整尺寸 / 质量扫描)以适配限制 - - 媒体发送失败时,首项回退会发送文本警告,而不是静默丢弃回复 + - 图片会自动优化(调整尺寸/质量扫描)以满足限制 + - 媒体发送失败时,首项回退会发送文本警告,而不是静默丢弃响应 ## 回复引用 -WhatsApp 支持原生回复引用,也就是出站回复会以可见方式引用入站消息。可通过 `channels.whatsapp.replyToMode` 控制。 +WhatsApp 支持原生回复引用,即出站回复会以可见方式引用入站消息。可通过 `channels.whatsapp.replyToMode` 控制。 -| 值 | 行为 | -| ----------- | -------------------------------------------------------------------- | -| `"off"` | 从不引用;作为普通消息发送 | -| `"first"` | 仅引用第一段出站回复分块 | -| `"all"` | 引用每一段出站回复分块 | -| `"batched"` | 引用排队的批量回复,同时让即时回复保持不引用 | +| 值 | 行为 | +| ----------- | --------------------------------------------------------------------- | +| `"off"` | 从不引用;作为普通消息发送 | +| `"first"` | 仅引用第一段出站回复分块 | +| `"all"` | 引用每一段出站回复分块 | +| `"batched"` | 引用排队的批量回复,同时让即时回复不带引用 | -默认值是 `"off"`。按账号覆盖使用 `channels.whatsapp.accounts..replyToMode`。 +默认值为 `"off"`。按账号覆盖使用 `channels.whatsapp.accounts..replyToMode`。 ```json5 { @@ -414,12 +418,12 @@ WhatsApp 支持原生回复引用,也就是出站回复会以可见方式引 `channels.whatsapp.reactionLevel` 控制智能体在 WhatsApp 上使用 emoji 反应的范围: -| 级别 | Ack 反应 | 智能体主动反应 | 说明 | -| ------------- | -------- | ----------------------- | ---------------------------------- | -| `"off"` | 否 | 否 | 完全不使用反应 | -| `"ack"` | 是 | 否 | 仅使用 Ack 反应(回复前确认接收) | -| `"minimal"` | 是 | 是(保守) | Ack + 智能体反应,采用保守指引 | -| `"extensive"` | 是 | 是(鼓励) | Ack + 智能体反应,采用鼓励性指引 | +| 级别 | Ack 反应 | 智能体主动发起的反应 | 说明 | +| ------------ | -------- | -------------------- | ------------------------------------ | +| `"off"` | 否 | 否 | 完全不使用反应 | +| `"ack"` | 是 | 否 | 仅使用 Ack 反应(回复前确认) | +| `"minimal"` | 是 | 是(保守) | Ack + 智能体反应,采用保守指导 | +| `"extensive"`| 是 | 是(鼓励) | Ack + 智能体反应,采用鼓励式指导 | 默认值:`"minimal"`。 @@ -437,7 +441,7 @@ WhatsApp 支持原生回复引用,也就是出站回复会以可见方式引 ## 确认反应 -WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在接收入站消息时立即发送 Ack 反应。 +WhatsApp 支持通过 `channels.whatsapp.ackReaction` 在收到入站消息时立即发送 Ack 反应。 Ack 反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会被抑制。 ```json5 @@ -458,22 +462,22 @@ Ack 反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会 - 在入站消息被接受后立即发送(回复前) - 失败会记录日志,但不会阻止正常回复投递 -- 群组模式 `mentions` 会在由提及触发的轮次发送反应;群组激活 `always` 会绕过此检查 -- WhatsApp 使用 `channels.whatsapp.ackReaction`(这里不使用旧版 `messages.ackReaction`) +- 群组模式 `mentions` 会在由提及触发的轮次中发送反应;群组激活 `always` 会绕过此检查 +- WhatsApp 使用 `channels.whatsapp.ackReaction`(此处不使用旧版 `messages.ackReaction`) ## 多账号和凭证 - 账号 id 来自 `channels.whatsapp.accounts` - - 默认账号选择:如果存在 `default` 则使用它,否则使用第一个已配置的账号 id(已排序) - - 账号 id 会在内部标准化以便查找 + - 默认账号选择:如果存在则为 `default`,否则为首个已配置的账号 id(排序后) + - 账号 id 会在内部标准化后用于查找 - 当前认证路径:`~/.openclaw/credentials/whatsapp//creds.json` - 备份文件:`creds.json.bak` - - `~/.openclaw/credentials/` 中的旧版默认认证仍会被识别 / 迁移,用于默认账号流程 + - `~/.openclaw/credentials/` 中的旧版默认认证仍会被识别/迁移,用于默认账号流程 @@ -484,10 +488,10 @@ Ack 反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会 -## 工具、动作和配置写入 +## 工具、操作和配置写入 -- 智能体工具支持包括 WhatsApp 反应动作(`react`)。 -- 动作门控: +- 智能体工具支持包括 WhatsApp 反应操作(`react`)。 +- 操作门控: - `channels.whatsapp.actions.reactions` - `channels.whatsapp.actions.polls` - 默认启用由渠道发起的配置写入(可通过 `channels.whatsapp.configWrites=false` 禁用)。 @@ -495,10 +499,10 @@ Ack 反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会 ## 故障排除 - + 症状:渠道状态显示未关联。 - 解决方法: + 修复: ```bash openclaw channels login --channel whatsapp @@ -507,34 +511,34 @@ Ack 反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会 - - 症状:账号已关联,但反复断开或不断尝试重连。 + + 症状:账号已关联,但反复断开或重复尝试重连。 - 解决方法: + 修复: ```bash openclaw doctor openclaw logs --follow ``` - 如有需要,可使用 `channels login` 重新关联。 + 如有需要,使用 `channels login` 重新关联。 - - 当目标账号没有活动中的 Gateway 网关监听器时,出站发送会快速失败。 + + 当目标账号不存在活跃的 Gateway 网关监听器时,出站发送会快速失败。 - 请确保 Gateway 网关正在运行,且该账号已关联。 + 请确认 Gateway 网关正在运行,并且该账号已关联。 - 按以下顺序检查: + 请按以下顺序检查: - `groupPolicy` - `groupAllowFrom` / `allowFrom` - - `groups` allowlist 条目 - - 提及门控(`requireMention` + mention patterns) + - `groups` 允许列表条目 + - 提及门控(`requireMention` + 提及模式) - `openclaw.json`(JSON5)中的重复键:后面的条目会覆盖前面的条目,因此每个作用域只保留一个 `groupPolicy` @@ -546,32 +550,32 @@ Ack 反应受 `reactionLevel` 控制——当 `reactionLevel` 为 `"off"` 时会 ## 系统提示词 -WhatsApp 支持类似 Telegram 的群组和私聊系统提示词,分别通过 `groups` 和 `direct` 映射配置。 +WhatsApp 通过 `groups` 和 `direct` 映射支持 Telegram 风格的群组和直接聊天系统提示词。 群组消息的解析层级: -首先确定生效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不做深度合并)。随后会在得到的这个单一映射上执行提示词查找: +首先确定生效的 `groups` 映射:如果账号定义了自己的 `groups`,它会完全替换根级 `groups` 映射(不进行深度合并)。随后会在得到的单一映射上执行提示词查找: -1. **群组专用系统提示词**(`groups[""].systemPrompt`):当映射中存在该特定群组条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,不应用任何系统提示词。 -2. **群组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在该特定群组条目,或该条目存在但未定义 `systemPrompt` 键时使用。 +1. **群组特定系统提示词**(`groups[""].systemPrompt`):当映射中存在该特定群组条目,且其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,并且不应用任何系统提示词。 +2. **群组通配符系统提示词**(`groups["*"].systemPrompt`):当映射中完全不存在该特定群组条目,或者该条目存在但未定义 `systemPrompt` 键时使用。 -私信的解析层级: +直接消息的解析层级: -首先确定生效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不做深度合并)。随后会在得到的这个单一映射上执行提示词查找: +首先确定生效的 `direct` 映射:如果账号定义了自己的 `direct`,它会完全替换根级 `direct` 映射(不进行深度合并)。随后会在得到的单一映射上执行提示词查找: -1. **私聊专用系统提示词**(`direct[""].systemPrompt`):当映射中存在该特定对端条目,**且**其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,不应用任何系统提示词。 -2. **私聊通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在该特定对端条目,或该条目存在但未定义 `systemPrompt` 键时使用。 +1. **直接消息特定系统提示词**(`direct[""].systemPrompt`):当映射中存在该特定对端条目,且其定义了 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则会抑制通配符,并且不应用任何系统提示词。 +2. **直接消息通配符系统提示词**(`direct["*"].systemPrompt`):当映射中完全不存在该特定对端条目,或者该条目存在但未定义 `systemPrompt` 键时使用。 -注意:`dms` 仍然是轻量级的逐私信历史覆盖配置桶(`dms..historyLimit`);提示词覆盖配置位于 `direct` 下。 +注意:`dms` 仍然是轻量级的按私信历史覆盖桶(`dms..historyLimit`);提示词覆盖位于 `direct` 下。 -**与 Telegram 多账号行为的区别:** 在 Telegram 中,多账号设置下会有意抑制所有账号的根级 `groups`——即使某些账号没有定义自己的 `groups` 也是如此——以防机器人接收到它不属于的群组消息。WhatsApp 不应用这一保护:无论配置了多少账号,没有定义账号级覆盖的账号始终会继承根级 `groups` 和根级 `direct`。在多账号 WhatsApp 设置中,如果你希望为每个账号配置不同的群组或私聊提示词,请在每个账号下显式定义完整映射,而不要依赖根级默认值。 +**与 Telegram 多账号行为的区别:** 在 Telegram 中,在多账号设置下,根级 `groups` 会被有意抑制——即使某些账号没有定义自己的 `groups` 也是如此——以防止某个机器人接收到它不属于的群组消息。WhatsApp 不应用这一保护:无论配置了多少账号,未定义账号级覆盖的账号始终会继承根级 `groups` 和根级 `direct`。在多账号 WhatsApp 设置中,如果你希望为每个账号设置单独的群组或直接消息提示词,请在每个账号下显式定义完整映射,而不要依赖根级默认值。 重要行为: -- `channels.whatsapp.groups` 同时是逐群组配置映射和聊天级群组 allowlist。在根级或账号作用域中,`groups["*"]` 表示该作用域“允许所有群组接入”。 -- 只有在你本来就希望该作用域允许所有群组时,才添加通配符群组 `systemPrompt`。如果你仍希望只有固定的一组群组 id 可以使用,请不要用 `groups["*"]` 作为默认提示词。应改为在每个显式加入 allowlist 的群组条目上重复设置提示词。 -- 群组准入和发送者授权是两个独立检查。`groups["*"]` 会扩大可以进入群组处理流程的群组集合,但它本身不会授权这些群组中的每个发送者。发送者访问仍单独由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 控制。 -- `channels.whatsapp.direct` 对私信没有同样的副作用。`direct["*"]` 只会在私信已经通过 `dmPolicy` 加上 `allowFrom` 或 pairing-store 规则被允许后,提供默认的私聊配置。 +- `channels.whatsapp.groups` 既是按群组的配置映射,也是聊天级群组允许列表。在根级或账号级作用域中,`groups["*"]` 表示该作用域“允许所有群组接入”。 +- 只有当你本来就希望该作用域允许所有群组时,才添加通配符群组 `systemPrompt`。如果你仍然只希望固定的一组群组 id 有资格接入,请不要使用 `groups["*"]` 作为提示词默认值。相反,请在每个显式加入允许列表的群组条目上重复该提示词。 +- 群组接入和发送者授权是两个独立检查。`groups["*"]` 会扩大可进入群组处理的群组集合,但它本身不会授权这些群组中的所有发送者。发送者访问仍由 `channels.whatsapp.groupPolicy` 和 `channels.whatsapp.groupAllowFrom` 单独控制。 +- `channels.whatsapp.direct` 对私信没有同样的副作用。`direct["*"]` 仅在某个私信已经通过 `dmPolicy` 加 `allowFrom` 或配对存储规则被允许后,才提供默认的直接聊天配置。 示例: @@ -580,31 +584,31 @@ WhatsApp 支持类似 Telegram 的群组和私聊系统提示词,分别通过 channels: { whatsapp: { groups: { - // 仅在根级作用域确实应允许所有群组时使用。 + // 仅当根级作用域应允许所有群组时使用。 // 适用于所有未定义自己 groups 映射的账号。 "*": { systemPrompt: "所有群组的默认提示词。" }, }, direct: { // 适用于所有未定义自己 direct 映射的账号。 - "*": { systemPrompt: "所有私聊的默认提示词。" }, + "*": { systemPrompt: "所有直接聊天的默认提示词。" }, }, accounts: { work: { groups: { - // 该账号定义了自己的 groups,因此根级 groups 会被完全 - // 替换。若要保留通配符,这里也要显式定义 "*"。 + // 此账号定义了自己的 groups,因此根级 groups 会被完全 + // 替换。若要保留通配符,也需要在这里显式定义 "*"。 "120363406415684625@g.us": { requireMention: false, - systemPrompt: "专注于项目管理。", + systemPrompt: "聚焦项目管理。", }, - // 仅在该账号中确实应允许所有群组时使用。 + // 仅当此账号应允许所有群组时使用。 "*": { systemPrompt: "工作群组的默认提示词。" }, }, direct: { - // 该账号定义了自己的 direct 映射,因此根级 direct 条目会被 - // 完全替换。若要保留通配符,这里也要显式定义 "*"。 - "+15551234567": { systemPrompt: "特定工作私聊的提示词。" }, - "*": { systemPrompt: "工作私聊的默认提示词。" }, + // 此账号定义了自己的 direct 映射,因此根级 direct 条目会被 + // 完全替换。若要保留通配符,也需要在这里显式定义 "*"。 + "+15551234567": { systemPrompt: "特定工作直接聊天的提示词。" }, + "*": { systemPrompt: "工作直接聊天的默认提示词。" }, }, }, }, @@ -613,7 +617,7 @@ WhatsApp 支持类似 Telegram 的群组和私聊系统提示词,分别通过 } ``` -## 配置参考指引 +## 配置参考指针 主要参考: diff --git a/docs/zh-CN/tools/media-overview.md b/docs/zh-CN/tools/media-overview.md index 08c6b2de1..10264b564 100644 --- a/docs/zh-CN/tools/media-overview.md +++ b/docs/zh-CN/tools/media-overview.md @@ -1,83 +1,85 @@ --- read_when: - - 正在寻找媒体能力概览 + - 正在查找媒体能力概览 - 决定要配置哪个媒体提供商 - 了解异步媒体生成的工作方式 summary: 用于媒体生成、理解和语音能力的统一落地页 title: 媒体概览 x-i18n: - generated_at: "2026-04-25T11:16:05Z" + generated_at: "2026-04-26T04:50:05Z" model: gpt-5.4 provider: openai - source_hash: c674df701b88c807842078b2e2e53821f1b2fc6037fd2e4d688caea147e769f1 + source_hash: 964081a900eb674f5fd719940ff129968563b2e9e20d754ac086b2fd1401bd7a source_path: tools/media-overview.md workflow: 15 --- # 媒体生成与理解 -OpenClaw 可以生成图像、视频和音乐,理解传入的媒体内容(图像、音频、视频),并通过文本转语音将回复朗读出来。所有媒体能力都由工具驱动:智能体会根据对话决定何时使用它们,并且只有在至少配置了一个底层提供商时,对应工具才会出现。 +OpenClaw 可以生成图片、视频和音乐,理解传入的媒体内容(图片、音频、视频),并通过文本转语音将回复朗读出来。所有媒体能力都由工具驱动:智能体会根据对话决定何时使用它们,并且只有在至少配置了一个底层提供商时,相应工具才会出现。 -## 能力概览 +## 能力一览 -| 能力 | 工具 | 提供商 | 功能说明 | +| 能力 | 工具 | 提供商 | 作用 | | -------------------- | ---------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------- | -| 图像生成 | `image_generate` | ComfyUI、fal、Google、MiniMax、OpenAI、Vydra、xAI | 根据文本提示或参考内容创建或编辑图像 | -| 视频生成 | `video_generate` | Alibaba、BytePlus、ComfyUI、fal、Google、MiniMax、OpenAI、Qwen、Runway、Together、Vydra、xAI | 根据文本、图像或现有视频创建视频 | +| 图片生成 | `image_generate` | ComfyUI、fal、Google、MiniMax、OpenAI、Vydra、xAI | 根据文本提示或参考内容创建或编辑图片 | +| 视频生成 | `video_generate` | Alibaba、BytePlus、ComfyUI、fal、Google、MiniMax、OpenAI、Qwen、Runway、Together、Vydra、xAI | 根据文本、图片或现有视频创建视频 | | 音乐生成 | `music_generate` | ComfyUI、Google、MiniMax | 根据文本提示创建音乐或音频轨道 | | 文本转语音(TTS) | `tts` | ElevenLabs、Google、Gradium、Local CLI、Microsoft、MiniMax、OpenAI、Vydra、xAI、Xiaomi MiMo | 将发出的回复转换为语音音频 | -| 媒体理解 | (自动) | 任何支持视觉/音频的模型提供商,以及 CLI 回退方案 | 总结传入的图像、音频和视频 | +| 媒体理解 | (自动) | 任何支持视觉/音频的模型提供商,外加 CLI 回退方案 | 总结传入的图片、音频和视频 | ## 提供商能力矩阵 -下表展示了各个提供商在整个平台上支持哪些媒体能力。 +下表展示了各个提供商在整个平台中支持哪些媒体能力。 -| 提供商 | 图像 | 视频 | 音乐 | TTS | STT / 转录 | 实时语音 | 媒体理解 | +| 提供商 | 图片 | 视频 | 音乐 | TTS | STT / 转录 | 实时语音 | 媒体理解 | | ----------- | ----- | ----- | ----- | --- | ------------------- | -------------- | ------------------- | -| Alibaba | | 是 | | | | | | -| BytePlus | | 是 | | | | | | -| ComfyUI | 是 | 是 | 是 | | | | | -| Deepgram | | | | | 是 | 是 | | -| ElevenLabs | | | | 是 | 是 | | | -| fal | 是 | 是 | | | | | | -| Google | 是 | 是 | 是 | 是 | | 是 | 是 | -| Gradium | | | | 是 | | | | -| Local CLI | | | | 是 | | | | -| Microsoft | | | | 是 | | | | -| MiniMax | 是 | 是 | 是 | 是 | | | | -| Mistral | | | | | 是 | | | -| OpenAI | 是 | 是 | | 是 | 是 | 是 | 是 | -| Qwen | | 是 | | | | | | -| Runway | | 是 | | | | | | -| SenseAudio | | | | | 是 | | | -| Together | | 是 | | | | | | -| Vydra | 是 | 是 | | 是 | | | | -| xAI | 是 | 是 | | 是 | 是 | | 是 | -| Xiaomi MiMo | 是 | | | 是 | | | 是 | +| Alibaba | | 是 | | | | | | +| BytePlus | | 是 | | | | | | +| ComfyUI | 是 | 是 | 是 | | | | | +| Deepgram | | | | | 是 | 是 | | +| ElevenLabs | | | | 是 | 是 | | | +| fal | 是 | 是 | | | | | | +| Google | 是 | 是 | 是 | 是 | | 是 | 是 | +| Gradium | | | | 是 | | | | +| Local CLI | | | | 是 | | | | +| Microsoft | | | | 是 | | | | +| MiniMax | 是 | 是 | 是 | 是 | | | | +| Mistral | | | | | 是 | | | +| OpenAI | 是 | 是 | | 是 | 是 | 是 | 是 | +| Qwen | | 是 | | | | | | +| Runway | | 是 | | | | | | +| SenseAudio | | | | | 是 | | | +| Together | | 是 | | | | | | +| Vydra | 是 | 是 | | 是 | | | | +| xAI | 是 | 是 | | 是 | 是 | | 是 | +| Xiaomi MiMo | 是 | | | 是 | | | 是 | -媒体理解会使用你在提供商配置中注册的任何支持视觉或音频的模型。上表重点列出了具有专用媒体理解支持的提供商;大多数带有多模态模型的 LLM 提供商(Anthropic、Google、OpenAI 等)在被配置为当前活动回复模型时,也可以理解传入的媒体内容。 +媒体理解会使用你在提供商配置中注册的任何支持视觉或音频的模型。上表重点标出了具有专门媒体理解支持的提供商;大多数带有多模态模型的 LLM 提供商(Anthropic、Google、OpenAI 等)在被配置为当前活动回复模型时,也能够理解传入的媒体内容。 ## 异步生成的工作方式 -视频和音乐生成会作为后台任务运行,因为提供商的处理通常需要 30 秒到数分钟。当智能体调用 `video_generate` 或 `music_generate` 时,OpenClaw 会将请求提交给提供商、立即返回任务 ID,并在任务账本中跟踪该作业。作业运行期间,智能体会继续响应其他消息。当提供商处理完成后,OpenClaw 会唤醒智能体,以便它将完成的媒体内容发布回原始渠道。图像生成和 TTS 是同步的,会在回复过程中内联完成。 +视频和音乐生成以后台任务方式运行,因为提供商处理通常需要 30 秒到数分钟。当智能体调用 `video_generate` 或 `music_generate` 时,OpenClaw 会将请求提交给提供商,立即返回任务 ID,并在任务账本中跟踪该任务。任务运行期间,智能体会继续响应其他消息。当提供商完成后,OpenClaw 会唤醒智能体,以便它将完成的媒体内容发布回原始渠道。图片生成和 TTS 是同步的,会随回复内联完成。 -在完成配置后,Deepgram、ElevenLabs、Mistral、OpenAI、SenseAudio 和 xAI 都可以通过批处理 `tools.media.audio` 路径转录传入音频。Deepgram、ElevenLabs、Mistral、OpenAI 和 xAI 还会注册语音通话流式 STT 提供商,因此实时电话音频可以直接转发到所选供应商,而无需等待录音完成。 +在已配置的情况下,Deepgram、ElevenLabs、Mistral、OpenAI、SenseAudio 和 xAI 都可以通过批处理 `tools.media.audio` 路径转录传入音频。 +会为语音留言预检以进行提及门控或命令解析的渠道插件,会在传入上下文中标记已转录的附件,因此共享的媒体理解流程会复用该转录结果,而不会为同一段音频再次发起一次 STT 调用。 +Deepgram、ElevenLabs、Mistral、OpenAI 和 xAI 还会注册 Voice Call 流式 STT 提供商,因此实时电话音频可以直接转发给所选供应商,而无需等待完整录音结束。 -Google 映射到 OpenClaw 的图像、视频、音乐、批处理 TTS、后端实时语音和媒体理解表面。OpenAI 映射到 OpenClaw 的图像、视频、批处理 TTS、批处理 STT、语音通话流式 STT、后端实时语音和记忆嵌入表面。xAI 目前映射到 OpenClaw 的图像、视频、搜索、代码执行、批处理 TTS、批处理 STT 和语音通话流式 STT 表面。xAI Realtime voice 是上游能力,但在共享的实时语音契约可以表示它之前,它不会在 OpenClaw 中注册。 +Google 映射到 OpenClaw 的图片、视频、音乐、批处理 TTS、后端实时语音和媒体理解能力。OpenAI 映射到 OpenClaw 的图片、视频、批处理 TTS、批处理 STT、Voice Call 流式 STT、后端实时语音和记忆嵌入能力。xAI 当前映射到 OpenClaw 的图片、视频、搜索、代码执行、批处理 TTS、批处理 STT 和 Voice Call 流式 STT 能力。xAI Realtime voice 是上游能力,但在共享的实时语音契约能够表示它之前,它不会在 OpenClaw 中注册。 ## 快速链接 -- [图像生成](/zh-CN/tools/image-generation) -- 生成和编辑图像 -- [视频生成](/zh-CN/tools/video-generation) -- 文本生成视频、图像生成视频和视频生成视频 +- [图片生成](/zh-CN/tools/image-generation) -- 生成和编辑图片 +- [视频生成](/zh-CN/tools/video-generation) -- 文本生成视频、图片生成视频和视频生成视频 - [音乐生成](/zh-CN/tools/music-generation) -- 创建音乐和音频轨道 - [文本转语音](/zh-CN/tools/tts) -- 将回复转换为语音音频 -- [媒体理解](/zh-CN/nodes/media-understanding) -- 理解传入的图像、音频和视频 +- [媒体理解](/zh-CN/nodes/media-understanding) -- 理解传入的图片、音频和视频 ## 相关内容 -- [图像生成](/zh-CN/tools/image-generation) +- [图片生成](/zh-CN/tools/image-generation) - [视频生成](/zh-CN/tools/video-generation) - [音乐生成](/zh-CN/tools/music-generation) - [文本转语音](/zh-CN/tools/tts)