跳转到内容

iMessageiMessage

状态:原生外部 CLI 集成。Gateway(网关) 生成 imsg rpc 并通过 stdio 上的 JSON-RPC 进行通信(无单独的守护进程/端口)。高级操作需要 imsg launch 和成功的私有 API 探测。

Private API actions

回复、点回、特效、附件和群组管理。

Pairing

iMessage 私信默认为配对模式。

Remote Mac

当 Gateway(网关) 未运行在信息 Mac 上时,请使用 SSH 封装程序。

Configuration reference

完整的 iMessage 字段参考。

  1. Install and verify imsg

    Terminal window
    brew install steipete/tap/imsg
    imsg rpc --help
    imsg launch
    openclaw channels status --probe
  2. Configure OpenClaw

    {
    channels: {
    imessage: {
    enabled: true,
    cliPath: "/usr/local/bin/imsg",
    dbPath: "/Users/user/Library/Messages/chat.db",
    },
    },
    }
  3. Start gateway

    Terminal window
    openclaw gateway
  4. Approve first 私信 pairing (default dmPolicy)

    Terminal window
    openclaw pairing list imessage
    openclaw pairing approve imessage
    配对请求将在 1 小时后过期。
  • 运行 imsg 的 Mac 上的 Messages 必须已登录。
  • 运行 OpenClaw/imsg 的进程上下文需要“完全磁盘访问权限”(访问 Messages 数据库)。
  • 需要“自动化”权限才能通过 Messages.app 发送消息。
  • 对于高级操作(反应 / 编辑 / 撤销 / 串联回复 / 特效 / 群组操作),必须禁用系统完整性保护 —— 请参阅下方的 启用 imsg 私有 API。基本的文本和媒体收发无需此操作。

imsg 提供两种操作模式:

  • 基础模式(默认,无需更改 SIP):通过 send 发送出站文本和媒体,入站监视/历史记录,聊天列表。这是全新的 brew install steipete/tap/imsg 加上上述标准 macOS 权限即可获得的现成功能。
  • 私有 API 模式imsg 将辅助 dylib 注入 Messages.app 以调用内部 IMCore 函数。这正是解锁 reacteditunsendreply(串联回复)、sendWithEffectrenameGroupsetGroupIconaddParticipantremoveParticipantleaveGroup,以及正在输入指示器和已读回执的方式。

要使用本渠道页面所述的高级操作功能,您需要私有 API 模式。imsg README 中明确说明了这一要求:

readtypinglaunch、网桥支持的高级发送、消息变更和聊天管理等高级功能是可选的。它们需要禁用 SIP 并将辅助 dylib 注入 Messages.appimsg launch 在启用 SIP 时拒绝注入。

Helper-injection 技术使用 imsg 自带的 dylib 来访问 Messages 私有 API。在 BlueBubbles OpenClaw 路径中不存在第三方服务器或 iMessage 运行时。

  1. 在运行 Messages.app 的 Mac 上 安装(或升级) imsg

    Terminal window
    brew install steipete/tap/imsg
    imsg --version
    imsg status --json

    imsg status --json 输出报告 bridge_versionrpc_methods 和每个方法的 selectors,以便您在开始之前了解当前构建支持的内容。

  2. 禁用系统完整性保护(System Integrity Protection)。 这取决于 macOS 版本,因为底层的 Apple 要求取决于操作系统和硬件:

    • macOS 10.13–10.15 (Sierra–Catalina): 通过终端禁用库验证,重启进入恢复模式,运行 csrutil disable,然后重启。
    • macOS 11+ (Big Sur 及更高版本),Intel: 恢复模式(或网络恢复),csrutil disable,重启。
    • macOS 11+,Apple Silicon: 按电源键启动序列进入恢复;在最近的 macOS 版本中,点击“继续”时按住 Left Shift 键,然后 csrutil disable。虚拟机设置遵循单独的流程 — 请先拍摄 VM 快照。
    • macOS 26 / Tahoe: 库验证策略和 imagent 私有权限检查已进一步收紧;imsg 可能需要更新的构建以跟上。如果在 macOS 主要升级后,imsg launch 注入或特定的 selectors 开始返回 false,请在假定 SIP 步骤成功之前检查 imsg 的发行说明。

    按照 Apple 针对 Mac 的恢复模式流程,在运行 imsg launch 之前禁用 SIP。

  3. 注入辅助程序。 在 SIP 已禁用且 Messages.app 已登录的情况下:

    Terminal window
    imsg launch

    当 SIP 仍处于启用状态时,imsg launch 将拒绝注入,因此这也可作为确认步骤 2 已完成的双重检查。

  4. 从 OpenClaw 验证网桥:

    Terminal window
    openclaw channels status --probe

    iMessage 条目应报告 iMessageworks,并且 imsg status --json | jq '.selectors' 应显示 retractMessagePart: truemacOSOpenClaw 以及您的 macOS 版本所暴露的任何编辑/输入/已读选择器。actions.ts 中的 OpenClaw 插件每方法过滤仅广告基础选择器为 true 的操作,因此您在代理工具列表中看到的操作界面反映了该桥接在此主机上实际可执行的操作。

如果 openclaw channels status --probe 将渠道报告为 worksiMessage,但特定操作在调度时抛出“iMessage `

API 需要 imsg 私有 API 桥接”错误,请再次运行 imsg launch—— 辅助进程可能会失效(Messages.app 重启、操作系统更新等),并且缓存的available: true` 状态将继续广告操作,直到下次探测刷新。

如果对于您的威胁模型而言,禁用 SIP 是不可接受的:

  • imsg 回退到基本模式 —— 文本 + 媒体 + 仅接收。
  • OpenClaw 插件仍然广告文本/媒体发送和入站监控;它只是在操作界面中隐藏了 OpenClawreacteditunsendreplysendWithEffect 和群组操作(根据每方法功能过滤)。
  • 您可以在一台独立的非 Apple Silicon Mac(或专用机器人 Mac)上关闭 SIP 以运行 iMessage 工作负载,同时在您的主设备上保持 SIP 启用。请参阅下方的 专用机器人 macOS 用户(独立的 iMessage 身份)

channels.imessage.dmPolicy 控制私信:

  • pairing (默认)
  • allowlist
  • open (要求 allowFrom 包含 "*"
  • disabled

允许列表字段:channels.imessage.allowFrom

允许列表条目必须识别发送者:句柄或静态发送者访问组(`accessGroup:

)。对于聊天目标(如 %%PH:INLINE_CODE:212:7f2194b%%、chat_guid:chat_identifier:),请使用 channels.imessage.groupAllowFrom“chat_id:*;对于数字 chat_id注册表键,请使用channels.imessage.groups`。

旧版 iMessage 聊天也可以绑定到 ACP 会话。

快速操作员流程:

  • 在私信或允许的群组聊天中运行 /acp spawn codex --bind here
  • 该同一 iMessage 会话中的后续消息将路由到生成的 ACP 会话。
  • /new/reset 会原地重置同一个绑定的 ACP 会话。
  • /acp close 会关闭 ACP 会话并移除绑定。

支持通过顶级 bindings[] 条目配置持久绑定,包含 type: "acp"match.channel: "imessage"

match.peer.id 可以使用:

`(推荐用于稳定的群组绑定)

  • `chat_guid:

`

  • `chat_identifier:

`

示例:

{
agents: {
list: [
{
id: "codex",
runtime: {
type: "acp",
acp: { agent: "codex", backend: "acpx", mode: "persistent" },
},
},
],
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "imessage",
accountId: "default",
peer: { kind: "group", id: "chat_id:123" },
},
acp: { label: "codex-group" },
},
],
}

有关共享 ACP 绑定行为,请参阅 ACP Agents

macOSiMessage专用的机器人 macOS 用户(独立的 iMessage 身份)

使用专用的 Apple ID 和 macOS 用户,以便将机器人流量与您的个人“信息”配置文件隔离开来。

典型流程:

  1. 创建/登录专用的 macOS 用户。
  2. 在该用户中使用机器人 Apple ID 登录“信息”。
  3. 在该用户中安装 imsgOpenClaw。
  4. 创建 SSH 包装器,以便 OpenClaw 可以在该用户上下文中运行 imsg
  5. 将 `channels.imessage.accounts.

.cliPath.dbPath` 指向该用户配置文件。

首次运行可能需要在该机器人用户会话中进行 GUI 批准(自动化 + 完全磁盘访问权限)。
Tailscale通过 Tailscale 连接远程 Mac(示例)

常见拓扑结构:

  • Gateway 运行在 Linux/VM 上
  • iMessage + imsg 运行在您 tailnet 中的 Mac 上
  • cliPath 包装器使用 SSH 运行 imsg
  • remoteHost 启用 SCP 附件获取

示例:

{
channels: {
imessage: {
enabled: true,
cliPath: "~/.openclaw/scripts/imsg-ssh",
remoteHost: "[email protected]",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}
#!/usr/bin/env bash
exec ssh -T [email protected] imsg "$@"

使用 SSH 密钥,使 SSH 和 SCP 均为非交互式。 确保首先信任主机密钥(例如 ssh [email protected]),以便填充 known_hosts

多账户模式

iMessage 支持在 channels.imessage.accounts 下进行按账户配置。

每个账户都可以覆盖字段,例如 cliPathdbPathallowFromgroupPolicymediaMaxMb、历史记录设置和附件根目录允许列表。

附件和媒体
  • 入站附件摄取默认关闭 — 设置 channels.imessage.includeAttachments: true 以将照片、语音备忘录、视频和其他附件转发给代理。如果禁用此功能,仅包含附件的 iMessage 将在到达代理之前被丢弃,并且可能根本不会产生 Inbound message 日志行。
  • 当设置 remoteHost 时,可以通过 SCP 获取远程附件路径
  • 附件路径必须匹配允许的根目录:
    • channels.imessage.attachmentRoots (本地)
    • channels.imessage.remoteAttachmentRoots (远程 SCP 模式)
    • 默认根目录模式:/Users/*/Library/Messages/Attachments
  • SCP 使用严格的主机密检查 (StrictHostKeyChecking=yes)
  • 出站媒体大小使用 channels.imessage.mediaMaxMb (默认 16 MB)
出站分块
  • 文本分块限制:channels.imessage.textChunkLimit (默认 4000)
  • 分块模式:channels.imessage.chunkMode
    • length (默认)
    • newline (段落优先分割)
寻址格式

首选显式目标:

  • chat_id:123 (推荐用于稳定路由)
  • chat_guid:...
  • chat_identifier:...

也支持句柄目标:

Terminal window
imsg chats --limit 20

imsg launch 正在运行且 openclaw channels status --probe 报告 privateApi.available: trueiMessage 时,消息工具除了普通文本发送外,还可以使用 iMessage 原生操作。

{
channels: {
imessage: {
actions: {
reactions: true,
edit: true,
unsend: true,
reply: true,
sendWithEffect: true,
sendAttachment: true,
renameGroup: true,
setGroupIcon: true,
addParticipant: true,
removeParticipant: true,
leaveGroup: true,
},
},
},
}
可用操作
  • react: 添加/移除 iMessage 点赞(messageIdemojiremove)。支持的点赞类型包括爱心、喜欢、不喜欢、大笑、强调和疑问。
  • reply: 发送对现有消息的 threaded reply(messageIdtextmessage,加上 chatGuidchatIdchatIdentifierto)。
  • sendWithEffect: 发送带有 iMessage 特效的文本(textmessageeffecteffectId)。
  • edit: 在支持的 macOS/private API 版本上编辑已发送的消息(messageIdtextnewText)。
  • unsend: 在支持的 macOS/private API 版本上撤回已发送的消息(messageId)。
  • upload-file: 发送媒体/文件(buffer 为 base64 或一个 hydrated media/path/filePathfilename、可选 asVoice)。旧别名:sendAttachment
  • renameGroupsetGroupIconaddParticipantremoveParticipantleaveGroup:当当前目标是群组对话时,管理群组聊天。
消息 ID

入站 iMessage 上下文在可用时包含短 MessageSid 值和完整的消息 GUID。短 ID 的作用域是最近的内存回复缓存,并在使用前针对当前聊天进行检查。如果短 ID 已过期或属于另一个聊天,请使用完整的 MessageSidFull 重试。

Capability detection

OpenClaw 仅在缓存探测状态显示桥接不可用时隐藏私有 API 操作。如果状态未知,操作保持可见并惰性调度探测,以便第一个操作能在 imsg launch 后成功,而无需单独手动刷新状态。

<Accordion title=“Read receipts and typing”API> 当私有 API 桥接启动时,接受的入站聊天会在调度前标记为已读,并且在代理生成期间向发送者显示输入气泡。可以使用以下方式禁用已读标记:

```json5
{
channels: {
imessage: {
sendReadReceipts: false,
},
},
}
```
早于每方法能力列表的旧版 `imsg`OpenClaw 构建版本将静默关闭输入/已读功能;OpenClaw 会在每次重启时记录一次性警告,以便对缺失的回执进行溯源。

<Accordion title=“Inbound tapbacks”OpenClawiMessage> OpenClaw 订阅 iMessage 点回(tapbacks),并将接受的反应作为系统事件而非普通消息文本进行路由,因此用户的点回不会触发普通的回复循环。

通知模式由 `channels.imessage.reactionNotifications` 控制:
- `"own"`(默认):仅当用户对机器人发送的消息做出反应时通知。
- `"all"`:对来自授权发送者的所有入站点回进行通知。
- `"off"`:忽略入站点回。
每个账户的覆盖设置使用 `channels.imessage.accounts.<id>.reactionNotifications`。

iMessage 默认允许由渠道发起的配置写入(用于 iMessage/config set|unsetcommands.config: true 时)。

禁用:

{
channels: {
imessage: {
configWrites: false,
},
},
}

合并拆分发送的私信(在一个组合中包含命令 + URL)

Section titled “合并拆分发送的私信(在一个组合中包含命令 + URL)”

当用户同时输入命令和 URL 时——例如 Dump https://example.com/article —— Apple 的“信息”应用会将发送拆分为两个单独的 chat.db

  1. 一条文本消息("Dump")。
  2. 一个 URL 预览气泡("https://..."),其中 OG 预览图片作为附件。

在大多数设置中,这两行数据到达 OpenClaw 的时间相隔约 0.8-2.0 秒。如果不合并,代理会在第一轮仅收到指令,然后回复(通常是“发给我 URL”),直到第二轮才看到 URL —— 此时指令上下文已丢失。这是 Apple 的发送管道,而非 OpenClaw 或 imsg 引入的机制。

channels.imessage.coalesceSameSenderDms 将私信设为合并来自同一发送者的连续行,使其作为单个代理轮次处理。群聊继续按消息分发,以保留多用户轮次结构。

启用条件:

  • 你发布的技能期望在一条消息中包含 command + payload(如转储、粘贴、保存、队列等)。
  • 你的用户会随指令粘贴 URL、图片或长内容。
  • 你可以接受增加的私信轮次延迟(见下文)。

保持禁用条件:

  • 你需要对单字私信触发器实现最低指令延迟。
  • 你的所有流程均为一次性指令,无后续负载。
用户输入chat.db 产生标志关闭(默认)标志开启 + 2500 毫秒窗口
Dump https://example.com(一次发送)2 行,间隔约 1 秒两次 Agent 回合:先是“Dump”,然后是 URL一轮对话:合并文本 Dump https://example.com
Save this 📎image.jpg caption(附件 + 文本)2 行两次回合(合并时丢弃附件)一次回合:文本 + 图片保留
/status(独立命令)1 行即时发送最多等待窗口期,然后发送
单独粘贴 URL1 行即时发送即时发送(桶中仅有一条)
文本 + URL 作为两条刻意分开的消息发送,间隔数分钟2 行,超出窗口期两次回合两次回合(窗口期在两者之间过期)
快速连发(窗口期内超过 10 条小私信)N 行N 次回合一次回合,输出受限(保留最早和最新,应用文本/附件上限)
两人在群聊中输入来自 M 个发送者的 N 行M+ 次回合(每个发送者桶一次)M+ 次回合 — 群聊不会合并

当网关处于离线状态(崩溃、重启、Mac 休眠、机器关机)时,imsg watch 会在网关重新上线后从当前的 chat.db 状态恢复 — 默认情况下,离线期间到达的任何消息都将被忽略。追赶功能会在下次启动时重放这些消息,以便代理不会静默地错过入站流量。

追赶功能默认禁用。请按渠道启用:

channels: {
imessage: {
catchup: {
enabled: true, // master switch (default: false)
maxAgeMinutes: 120, // skip rows older than now - 2h (default: 120, clamp 1..720)
perRunLimit: 50, // max rows replayed per startup (default: 50, clamp 1..500)
firstRunLookbackMinutes: 30, // first run with no cursor: look back 30 min (default: 30)
maxFailureRetries: 10, // give up on a wedged guid after 10 dispatch failures (default: 10)
},
},
}

每次 monitorIMessageProvider 启动时运行一次,顺序为 imsg launch 就绪 → watch.subscribeperformIMessageCatchup → 实时发送循环。追赶功能本身针对 imsg watch 使用的同一 JSON-RPC 客户端,使用 chats.list 加上逐聊 messages.history。在追赶过程中到达的任何消息都会正常通过实时发送流程;现有的入站去重缓存会吸收与重放行重叠的部分。

每条重放的行都会通过实时分发路径 (evaluateIMessageInbound + dispatchInboundMessage) 进行处理,因此允许列表、群组策略、去抖动器、回显缓存和已读回执在重放消息和实时消息上的表现完全一致。

Catchup 会在 <openclawStateDir>/imessage/catchup/<account>__<hash>.jsonOpenClaw 处为每个账户保留一个游标(OpenClaw 状态目录默认为 ~/.openclaw,可通过 OPENCLAW_STATE_DIR 覆盖):

{
"lastSeenMs": 1717900800000,
"lastSeenRowid": 482910,
"updatedAt": 1717900801234,
"failureRetries": { "<guid>": 1 }
}
  • 游标在每次成功分发时前进,并在某行的分发引发错误时保持不变 —— 下次启动时会从保持的游标重试同一行。
  • 在对同一个 guid 连续抛出 maxFailureRetries 次异常后,catchup 会记录一条 warn 并强制推进游标跳过卡住的消息,以便后续启动时可以继续处理。
  • 在后续运行中,已被放弃的 guid 会被直接跳过(不尝试分发),并在运行摘要中计入 skippedGivenUp
imessage catchup: replayed=N skippedFromMe=… skippedGivenUp=… failed=… givenUp=… fetchedCount=…
imessage catchup: giving up on guid=<guid> after <N> failures; advancing cursor past it
imessage catchup: fetched <X> rows across chats, capped to perRunLimit=<Y>

如果出现 WARN ... capped to perRunLimit 行,意味着单次启动未能处理完所有积压。如果你的差距定期超过默认的 50 行通过量,请提高 perRunLimit(最大 500)。

  • Gateway(网关) 持续运行并带有看门狗自动重启功能,且间隔始终小于几秒 —— 默认的关闭状态即可。
  • 私信量很低,且遗漏的消息不会改变代理的行为——firstRunLookbackMinutes 的初始窗口可能会在首次启用时分发令人惊讶的旧上下文。

当你开启 catchup 时,没有游标的首次启动只会回溯 firstRunLookbackMinutes(默认 30 分钟),而不是完整的 maxAgeMinutes 窗口——这避免了重放启用前的大量历史消息。

RPC未找到 imsg 或不支持 RPC

验证二进制文件和 RPC 支持:

Terminal window
imsg rpc --help
imsg status --json
openclaw channels status --probe
```RPC
如果探测报告不支持 RPC,请更新 `imsg`API。如果私有 API 操作不可用,请在已登录的 macOS 用户会话中运行 `imsg launch`macOSGateway(网关)macOS 并再次探测。如果 Gateway 不在 macOS 上运行,请使用上述的“通过 SSH 连接远程 Mac”设置,而不是默认的本地 `imsg` 路径。
Gateway(网关)macOSGateway(网关) 未运行在 macOS 上
默认的 `cliPath: "imsg"`LinuxWindows 必须在登录了 Messages 的 Mac 上运行。在 Linux 或 Windows 上,请将 `channels.imessage.cliPath` 设置为一个通过 SSH 连接到该 Mac 并运行 `imsg "$@"` 的包装脚本。
#!/usr/bin/env bash
exec ssh -T messages-mac imsg "$@"
然后运行:
Terminal window
openclaw channels status --probe --channel imessage
私信被忽略

检查:

  • channels.imessage.dmPolicy
  • channels.imessage.allowFrom
  • 配对批准 (openclaw pairing list imessage)
群组消息被忽略

检查:

  • channels.imessage.groupPolicy
  • channels.imessage.groupAllowFrom
  • channels.imessage.groups 允许列表行为
  • 提及模式配置 (agents.list[].groupChat.mentionPatterns)
远程附件失败

检查:

  • channels.imessage.remoteHost
  • channels.imessage.remoteAttachmentRoots
  • 从 Gateway 主机进行的 SSH/SCP 密钥认证
  • Gateway 主机的 ~/.ssh/known_hosts 中存在主机密钥
  • 运行 Messages 的 Mac 上的远程路径可读性
macOS错过了 macOS 权限提示

在相同的用户/会话上下文中,以交互式 GUI 终端重新运行并批准提示:

Terminal window
imsg chats --limit 1
imsg send

“test”

确认为运行 OpenClaw/`imsg` 的进程上下文授予了完全磁盘访问权限 + 自动化权限。