跳转至

来自 BlueBubbles

BlueBubbles 支持已被移除。OpenClaw 仅通过官方 @openclaw/imessage 插件支持 iMessage,该插件通过 JSON-RPC 驱动 steipete/imsg,并覆盖 BlueBubbles 曾具备的相同私有 API 能力面(react、edit、unsend、reply、sendWithEffect、原生投票、群组管理、附件)。一个 CLI 二进制文件取代了 BlueBubbles 服务器 + 客户端应用 + webhook 管道:没有 REST 端点,没有 webhook 认证。

本指南将旧的 channels.bluebubbles 配置迁移到 channels.imessage。没有其他受支持的迁移路径。在当前 OpenClaw 中,遗留的 channels.bluebubbles 块是无效的——没有运行时读取它。

Note

简短公告和运维摘要,请参见 BlueBubbles 移除与 imsg iMessage 路径。

迁移检查清单

当你已经知道旧的 BlueBubbles 配置时,最短且安全的路径是:

  1. 使用 openclaw plugins install @openclaw/imessage 安装官方插件,并检查应用结果。
  2. 在运行 Messages.app 的 Mac 上直接验证 imsg(imsg chats、imsg history、imsg send、imsg rpc --help)。
  3. 将行为键从 channels.bluebubbles 复制到 channels.imessage:dmPolicy、allowFrom、groupPolicy、groupAllowFrom、groups、includeAttachments、attachmentRoots、mediaMaxMb、textChunkLimit 和 actions。
  4. 删除不再存在的传输键:serverUrl、password、webhook URL 以及 BlueBubbles 服务器设置。
  5. 如果 Gateway 没有运行在 Messages Mac 上,请将 channels.imessage.cliPath 设置为 SSH 包装器的绝对 Gateway 本地路径,并保持 dbPath 为该 Mac 上的绝对路径。对于复杂包装器,将 remoteHost 设置为 Messages Mac;OpenClaw 会自动检测简单的透明包装器形状以兼容。
  6. 启用 channels.imessage,然后运行 openclaw channels status --probe --channel imessage。配置更改遵循热重载;如果 Gateway 离线,请启动它。
  7. 测试一个 DM、一个允许的群组、如果启用了附件则测试附件,以及你期望 agent 使用的每个私有 API 操作。
  8. 在验证 iMessage 路径后,删除 BlueBubbles 服务器和旧的 channels.bluebubbles 配置。

Note

远程 imsg v0.13.4 有两个有限的 RPC 限制:投票必须使用 pollOptionId,而不是索引或选项文本,并且附件回复不能指向非零消息部分索引。本地 imsg 行为不变。

imsg 的作用

imsg 是用于 Messages 的本地 macOS CLI。OpenClaw 将 imsg rpc 作为子进程启动,并通过 stdin/stdout 进行 JSON-RPC 通信。没有 HTTP 服务器、webhook URL、后台守护进程、launch agent 或需要暴露的端口。

  • 读取来自 ~/Library/Messages/chat.db,使用只读 SQLite 句柄。
  • 实时入站消息来自 imsg watch / watch.subscribe,它跟踪 chat.db 文件系统事件,并带有轮询回退。
  • 发送使用 Messages.app 自动化来发送普通文本和文件。
  • 高级操作使用 imsg launch 将 imsg 辅助程序注入 Messages.app。这就是解锁已读回执、正在输入指示器、富发送、编辑、撤回、线程回复、tapbacks、投票和群组管理的方式。
  • Linux 构建可以检查复制的 chat.db,但不能发送、监视实时 Mac 数据库或驱动 Messages.app。对于 OpenClaw iMessage,请在已登录的 Mac 上运行 imsg,或通过到该 Mac 的 SSH 包装器运行。

开始之前

  1. 在运行 Messages.app 的 Mac 上安装 imsg:
brew install steipete/tap/imsg
brew update && brew upgrade imsg
imsg --version
imsg chats --limit 3

对于常见的本地设置,OpenClaw 设置可以在已登录 Messages 的 Mac 上提供用户确认的 Homebrew 安装或更新 imsg。手动设置和 SSH 包装器拓扑仍由运维人员管理:在将运行 imsg 的相同本地或远程用户上下文中重复 Homebrew 更新。如果 imsg chats 因 unable to open database file、空输出或 authorization denied 而失败,请授予启动 imsg 的终端、编辑器、Node 进程、Gateway 服务或 SSH 父进程 Full Disk Access,然后重新打开该父进程。

  1. 在更改 OpenClaw 配置之前,验证读取、监视、发送和 RPC 表面:
imsg chats --limit 10 --json | jq -s
imsg history --chat-id 42 --limit 10 --attachments --json | jq -s
imsg watch --chat-id 42 --reactions --json
imsg send --chat-id 42 --text "OpenClaw imsg test"
imsg rpc --help

将 42 替换为 imsg chats 中的真实聊天 id。发送需要 Messages.app 的 Automation 权限。如果 OpenClaw 将通过 SSH 运行,请通过 OpenClaw 将使用的相同 SSH 包装器或用户上下文运行这些命令。如果读取正常但发送因 AppleEvents -1743 失败,请检查 Automation 是否被授予给了 /usr/libexec/sshd-keygen-wrapper;参见 SSH 包装器发送因 AppleEvents -1743 失败。

  1. 启用私有 API 桥接。强烈建议为 OpenClaw iMessage 启用,因为回复、tapbacks、效果、投票、附件回复和群组操作都依赖于它:
imsg launch
imsg status --json

imsg launch 需要禁用 SIP(并且在现代 macOS 上,需要放宽库验证——参见 启用 imsg 私有 API)。基本发送、历史记录和监视无需 imsg launch 即可工作;完整的 OpenClaw iMessage 操作面则不行。

  1. 在你启用 channels.imessage 并启动 Gateway 后,通过 OpenClaw 验证桥接:
openclaw channels status --probe

iMessage 账户应报告 works;使用 --json 时,探测负载包含 privateApi.available: true。如果它报告 false,请先修复——参见 能力检测。探测需要一个可到达的 Gateway(否则 CLI 会回退到仅配置输出),并且只探测已配置、已启用的账户。

  1. 备份你的配置:
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak

配置迁移

iMessage 和 BlueBubbles 共享大多数通道级别的行为键。变化的是传输方式(REST 服务器 vs 本地 CLI)以及群组注册表键格式。

BlueBubbles iMessage 插件 说明
channels.bluebubbles.enabled channels.imessage.enabled 相同语义(一旦该配置块存在,默认值为 true)。
channels.bluebubbles.serverUrl (已移除) 没有 REST 服务器 —— 插件通过 stdio 启动 imsg rpc。
channels.bluebubbles.password (已移除) 不需要 webhook 身份验证。
(隐式) channels.imessage.cliPath imsg 的路径(默认 imsg);对于 SSH,请使用 Gateway 主机上包装器的绝对路径。
(隐式) channels.imessage.dbPath 可选的 Messages.app chat.db 覆盖;对于 SSH,这是 Messages Mac 上的绝对路径,并且永远不会相对于 Gateway 主目录展开。
(隐式) channels.imessage.remoteHost 以 host 或 user@host 形式指定 Messages Mac;显式配置优先,而简单的透明 SSH 包装器会在每个进程中自动检测一次。启用通过严格 SSH/SCP 获取入站附件以及仅限所有者的出站暂存。清理是尽力而为;失败会发出警告,并可能留下仅限所有者的残留文件。
channels.bluebubbles.dmPolicy channels.imessage.dmPolicy 相同取值(pairing / allowlist / open / disabled);默认 pairing。
channels.bluebubbles.allowFrom channels.imessage.allowFrom 相同的 handle 格式(+15555550123、user@example.com)。配对存储中的批准不会迁移 —— 见下文。
channels.bluebubbles.groupPolicy channels.imessage.groupPolicy 相同取值(allowlist / open / disabled);默认 allowlist。
channels.bluebubbles.groupAllowFrom channels.imessage.groupAllowFrom 相同。未设置时,iMessage 会回退到 allowFrom;显式空值 groupAllowFrom: [] 会在 groupPolicy: "allowlist" 下阻止所有群组。
channels.bluebubbles.groups channels.imessage.groups 逐字复制 "*" 通配符条目;按数字 iMessage chat_id 重新设置每个群组条目的键 —— 参见“群组注册表陷阱”。requireMention、tools、toolsBySender、systemPrompt 可沿用。
channels.bluebubbles.sendReadReceipts channels.imessage.sendReadReceipts 默认 true。仅当私有 API 探测可用时才会触发。
channels.bluebubbles.includeAttachments channels.imessage.includeAttachments 结构相同,默认同样关闭。如果附件曾在 BlueBubbles 上正常流转,请显式设置此项 —— 否则入站照片/媒体会被静默丢弃(没有 Inbound message 日志行),直到你设置为止。
BlueBubbles iMessage 插件 备注
channels.bluebubbles.attachmentRoots channels.imessage.attachmentRoots 本地根目录;通配符规则相同。
(N/A) channels.imessage.remoteAttachmentRoots 仅在为 SCP 获取设置 remoteHost 时使用。
channels.bluebubbles.mediaMaxMb channels.imessage.mediaMaxMb iMessage 上默认为 16 MB(BlueBubbles 默认值为 8 MB)。如需保留较低上限,请显式设置。
channels.bluebubbles.textChunkLimit channels.imessage.textChunkLimit 两者默认均为 4000。
channels.bluebubbles.coalesceSameSenderDms (已移除) 不要迁移此键。imsg 0.13.1 及更高版本会在 OpenClaw 接收之前合并 Apple URL 预览拆分发送;openclaw doctor --fix 会移除过时的 iMessage 键。
channels.bluebubbles.enrichGroupParticipantsFromContacts (N/A) imsg 已从 chat.db 显示发送者显示名称。
channels.bluebubbles.actions.* channels.imessage.actions.* 相同的按操作开关(reactions、edit、unsend、reply、sendWithEffect、renameGroup、setGroupIcon、addParticipant、removeParticipant、leaveGroup、sendAttachment),并新增 polls。所有项默认启用;私有 API 操作仍需要桥接。

多账号配置(channels.bluebubbles.accounts.*)可一对一转换为 channels.imessage.accounts.*。

群组注册表陷阱

iMessage 插件会连续运行两个群组关卡。群组消息必须同时通过这两个关卡才能到达代理:

  1. 发送者 / 聊天目标允许列表(channels.imessage.groupAllowFrom)— 匹配发送者句柄或聊天目标(chat_id:、chat_guid:、chat_identifier: 条目)。当 groupAllowFrom 未设置时,此关卡回退到 allowFrom;显式设置 groupAllowFrom: [] 会禁用该回退,并在 groupPolicy: "allowlist" 下丢弃所有群组消息。
  2. 群组注册表(channels.imessage.groups)— 以数字 iMessage chat_id 为键:
  3. 没有 groups 块(或为空):只要关卡 1 具有非空的有效发送者允许列表,群组即可通过此关卡;发送者过滤控制访问,且不会触发丢弃全部的启动警告。
  4. groups 有条目但没有 "*":只有列出的 chat_id 键可通过。列出任何群组都会使注册表变为允许列表,即使在 groupPolicy: "open" 下也是如此。
  5. groups: { "*": { ... } }:所有群组都通过此关卡。

迁移陷阱:BlueBubbles 按聊天 GUID / 聊天标识符为 groups 条目设置键,而 iMessage 注册表按数字 chat_id 设置键。逐字复制的按群组条目会创建一个非空注册表,但其键永远不匹配,因此所有群组消息都会在关卡 2 被丢弃。逐字复制 "*" 通配符;使用 imsg chats 中的 chat_id 值重新设置特定群组条目的键。

两种丢弃路径在默认日志级别下都可通过 warn 行看到:

  • 启动时每个账号一次,当设置了 groupPolicy: "allowlist" 且有效群组发送者允许列表为空时:imessage: groupPolicy="allowlist" for account "<id>" but no group sender allowlist is configured ...。设置 groupAllowFrom(或 allowFrom)以允许发送者;仅添加 groups 不能满足发送者关卡。
  • 运行时每个 chat_id 一次,当注册表丢弃群组时:imessage: dropping group message from chat_id=<id> ... not in channels.imessage.groups allowlist,其中指明了需要添加的确切键。

无论哪种情况,DM 都会继续工作——它们走不同的代码路径,因此 DM 成功并不能证明群组路由正常。

使用 groupPolicy: "allowlist" 的最小发送者范围配置:

{
  channels: {
    imessage: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15555550123", "chat_guid:any;-;..."],
    },
  },
}

这会放行任意群组中已配置的发送者。添加 groups 条目以限定允许的聊天,或设置按聊天选项(例如 requireMention);逐字复制 BlueBubbles 的 "*" 条目,但使用数字 iMessage chat_id 值重新键入特定条目。

分步指南

  1. 转换配置。编辑期间保持新块处于禁用状态;旧的 channels.bluebubbles 块会被当前 OpenClaw 忽略,可以保留在旁边作为参考:
{
  channels: {
    imessage: {
      enabled: false, // flip to true when ready to cut over
      cliPath: "/opt/homebrew/bin/imsg",
      dmPolicy: "pairing",
      allowFrom: ["+15555550123"], // copy from bluebubbles.allowFrom
      groupPolicy: "allowlist",
      groupAllowFrom: [], // copy from bluebubbles.groupAllowFrom
      groups: { "*": { requireMention: true } }, // wildcard copies verbatim; re-key per-chat entries by chat_id
      // actions default to enabled; set individual toggles false to disable
    },
  },
}
  1. 切换并探测。 设置 channels.imessage.enabled: true,让 热重载 应用更改,并确认通道报告健康:
openclaw channels status --probe --channel imessage   # expect "works"; --json shows privateApi.available: true

探测需要可访问的 Gateway,并且只探测已配置且已启用的账户。使用 开始前 中的直接 imsg 命令来验证 Mac 本身。

  1. 验证私信。 向代理发送一条直接消息;确认回复已送达。

  2. 单独验证群组。 私信和群组走不同的代码路径——私信成功并不能证明群组正在路由。在允许的群聊中发送一条消息,并确认回复已送达。如果群组没有响应(没有代理回复,也没有错误),请检查 gateway 日志中上面“群组注册表陷阱”中的两条 warn 行。启动警告表示有效的发送者允许列表为空;按 chat_id 的警告表示已填充的 groups 注册表不包含该聊天。

  3. 验证操作能力。 从已配对的私信中,要求代理执行回应、编辑、撤回、回复、发送照片,以及(在群组中)重命名群组或添加/移除参与者。每个操作都应原生地出现在 Messages.app 中。如果任何操作抛出 iMessage <action> requires the imsg private API bridge,请再次运行 imsg launch,并使用 openclaw channels status --probe 刷新。

  4. 移除 BlueBubbles 服务器和 channels.bluebubbles 块 在 iMessage 私信、群组和操作验证完成后。OpenClaw 不会读取 channels.bluebubbles。

操作功能对照一览

操作 旧版 BlueBubbles iMessage 插件
发送文本 / SMS 回退 ✅ ✅
发送媒体(照片、视频、文件、语音) ✅ ✅
线程回复(reply_to_guid) ✅ ✅(关闭 #51892)
点按回应(react) ✅ ✅
编辑 / 撤回(macOS 13+ 接收者) ✅ ✅
带屏幕效果发送 ✅ ✅(关闭部分 #9394)
富文本粗体 / 斜体 / 下划线 / 删除线 ✅ ✅(通过 attributedBody 的 typed-run 格式)
原生 Messages 投票(创建和投票) ❌ ✅(actions.polls;接收者需要 iOS/macOS 26+ 才能原生渲染)
重命名群组 / 设置群组图标 ✅ ✅
添加 / 移除参与者、退出群组 ✅ ✅
已读回执和正在输入指示器 ✅ ✅(受私有 API 探测控制)
Apple URL 预览拆分发送的合并 ✅ ✅(由 imsg 0.13.1 及更高版本在上游处理;无 OpenClaw 设置)
重启后的入站恢复 ✅ ✅(自动:since_rowid 重放 + GUID 去重;本地有更大窗口)

iMessage 会恢复 gateway 宕机期间错过的消息:启动时,它通过 imsg watch.subscribe 的 since_rowid 从最后已分发的 rowid 开始重放,按 GUID 去重,并且一个过期积压年龄围栏会抑制 Push-flush “积压炸弹”。这通过 imsg RPC 连接运行,因此也适用于远程 SSH cliPath 设置;本地设置拥有更宽的恢复窗口,因为它们可以读取 chat.db。参见 桥接或 gateway 重启后的入站恢复。

配对、会话和 ACP 绑定

  • 允许列表按 handle 沿用。 channels.imessage.allowFrom 识别 BlueBubbles 使用的相同 +15555550123 / user@example.com 字符串——逐字复制它们。
  • 配对存储中的批准不会转移。 配对存储按通道划分,没有任何内容会迁移旧的 BlueBubbles 存储。仅通过配对获得批准的发送者必须在 iMessage 下再次配对,或者你将他们的 handle 添加到 allowFrom。
  • 会话 仍按代理 + 聊天划分范围。在默认 session.dmScope=main 下,私信会合并到代理主会话;在默认 session.groupScope="per-group" 下,群会话按 chat_id 保持隔离(agent:<agentId>:imessage:group:<chat_id>)。BlueBubbles 会话键下的旧对话历史不会带入 iMessage 会话。
  • ACP 绑定 中引用 match.channel: "bluebubbles" 的必须改为 "imessage"。match.peer.id 的形式(chat_id:、chat_guid:、chat_identifier:、裸 handle)完全相同。

无回滚通道

没有受支持的 BlueBubbles 运行时可供切换回退。如果 iMessage 验证失败,请设置 channels.imessage.enabled: false,使用 openclaw channels status 确认该通道已停止,修复 imsg 阻塞问题,然后重试切换。如果自动配置重载已关闭,请按照 手动应用 操作。

回复缓存位于 SQLite 插件状态中。要导入六月之前的 imessage/reply-cache.jsonl 旁路文件,请先 通过 2026.9.5 升级 并运行其 Doctor。当前版本不会改动旧文件。

  • BlueBubbles 移除与 imsg iMessage 路径 — 简短公告和运维摘要。
  • iMessage — 完整的 iMessage 通道参考,包括 imsg launch 设置和能力检测。
  • /channels/bluebubbles — 重定向到本迁移指南的旧 URL。
  • 配对 — DM 身份验证和配对流程。
  • 通道路由 — 网关如何为出站回复选择通道。

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