Skip to content

iMessage (imsg)

状态:外部 CLI 集成。网关启动 imsg rpc(基于 stdio 的 JSON-RPC)。

快速设置(新手入门)

  1. 确保在此 Mac 上已登录 Messages。
  2. 安装 imsg
    • brew install steipete/tap/imsg
  3. 使用 channels.imessage.cliPathchannels.imessage.dbPath 配置 openclaw。
  4. 启动网关并批准任何 macOS 提示(自动化 + 完全磁盘访问权限)。

最小配置:

json5
{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "/usr/local/bin/imsg",
      dbPath: "/Users/<您>/Library/Messages/chat.db"
    }
  }
}

这是什么

  • 基于 macOS 上 imsg 的 iMessage 频道。
  • 确定性路由:回复始终返回 iMessage。
  • 私聊共享代理的主会话;群组是隔离的(agent:<agentId>:imessage:group:<chat_id>)。
  • 如果多参与者线程以 is_group=false 到达,您仍然可以使用 channels.imessage.groups 通过 chat_id 隔离它(参见下面的"类群组线程")。

配置写入

默认情况下,iMessage 允许写入由 /config set|unset 触发的配置更新(需要 commands.config: true)。

禁用方法:

json5
{
  channels: { imessage: { configWrites: false } }
}

要求

  • 已登录 Messages 的 macOS。
  • openclaw + imsg 的完全磁盘访问权限(Messages 数据库访问)。
  • 发送时的自动化权限。
  • channels.imessage.cliPath 可以指向任何代理 stdin/stdout 的命令(例如,通过 SSH 连接到另一台 Mac 并运行 imsg rpc 的包装脚本)。

设置(快速路径)

  1. 确保在此 Mac 上已登录 Messages。
  2. 配置 iMessage 并启动网关。

专用机器人 macOS 用户(用于隔离身份)

如果您希望机器人从 独立的 iMessage 身份 发送消息(并保持您的个人 Messages 清洁),请使用专用的 Apple ID + 专用的 macOS 用户。

  1. 创建一个专用的 Apple ID(例如:my-cool-bot@icloud.com)。
    • Apple 可能需要电话号码进行验证 / 双重认证。
  2. 创建一个 macOS 用户(例如:clawdshome)并登录。
  3. 在该 macOS 用户中打开 Messages,并使用机器人 Apple ID 登录 iMessage。
  4. 启用远程登录(系统设置 → 通用 → 共享 → 远程登录)。
  5. 安装 imsg
    • brew install steipete/tap/imsg
  6. 设置 SSH,使 ssh <机器人-macos-用户>@localhost true 无需密码即可工作。
  7. channels.imessage.accounts.bot.cliPath 指向一个作为机器人用户运行 imsg 的 SSH 包装脚本。

首次运行注意事项:发送/接收可能需要在 机器人 macOS 用户 中进行 GUI 批准(自动化 + 完全磁盘访问权限)。如果 imsg rpc 看起来卡住或退出,请登录该用户(屏幕共享有帮助),运行一次性的 imsg chats --limit 1 / imsg send ...,批准提示,然后重试。

示例包装脚本(chmod +x)。将 <bot-macos-user> 替换为您的实际 macOS 用户名:

bash
#!/usr/bin/env bash
set -euo pipefail

# 首先运行一次交互式 SSH 以接受主机密钥:
#   ssh <机器人-macos-用户>@localhost true
exec /usr/bin/ssh -o BatchMode=yes -o ConnectTimeout=5 -T <机器人-macos-用>@localhost \
  "/usr/local/bin/imsg" "$@"

示例配置:

json5
{
  channels: {
    imessage: {
      enabled: true,
      accounts: {
        bot: {
          name: "Bot",
          enabled: true,
          cliPath: "/path/to/imsg-bot",
          dbPath: "/Users/<机器人-macos-用户>/Library/Messages/chat.db"
        }
      }
    }
  }
}

对于单账户设置,请使用扁平选项(channels.imessage.cliPathchannels.imessage.dbPath)而不是 accounts 映射。

远程/SSH 变体(可选)

如果您希望在另一台 Mac 上使用 iMessage,请将 channels.imessage.cliPath 设置为通过 SSH 在远程 macOS 主机上运行 imsg 的包装脚本。openclaw 只需要 stdio。

示例包装脚本:

bash
#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"

远程附件:cliPath 通过 SSH 指向远程主机时,Messages 数据库中的附件路径引用远程机器上的文件。openclaw 可以通过设置 channels.imessage.remoteHost 自动通过 SCP 获取这些文件:

json5
{
  channels: {
    imessage: {
      cliPath: "~/imsg-ssh",                     // 到远程 Mac 的 SSH 包装脚本
      remoteHost: "user@gateway-host",           // 用于 SCP 文件传输
      includeAttachments: true
    }
  }
}

如果未设置 remoteHost,openclaw 会尝试通过解析包装脚本中的 SSH 命令来自动检测它。为了可靠性,建议进行显式配置。

通过 Tailscale 的远程 Mac(示例)

如果网关运行在 Linux 主机/虚拟机上,但 iMessage 必须在 Mac 上运行,Tailscale 是最简单的桥梁:网关通过 tailnet 与 Mac 通信,通过 SSH 运行 imsg,并通过 SCP 将附件传回。

架构:

┌──────────────────────────────┐          SSH (imsg rpc)          ┌──────────────────────────┐
│ 网关主机(Linux/虚拟机)      │──────────────────────────────────▶│ 带有 Messages + imsg 的 Mac │
│ - openclaw 网关              │          SCP(附件)              │ - 已登录 Messages         │
│ - channels.imessage.cliPath  │◀──────────────────────────────────│ - 已启用远程登录           │
└──────────────────────────────┘                                   └──────────────────────────┘

              │ Tailscale tailnet(主机名或 100.x.y.z)

        用户@网关主机

具体配置示例(Tailscale 主机名):

json5
{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "~/.clawdbot/scripts/imsg-ssh",
      remoteHost: "bot@mac-mini.tailnet-1234.ts.net",
      includeAttachments: true,
      dbPath: "/Users/bot/Library/Messages/chat.db"
    }
  }
}

示例包装脚本(~/.clawdbot/scripts/imsg-ssh):

bash
#!/usr/bin/env bash
exec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"

注意事项:

  • 确保 Mac 已登录 Messages,并且已启用远程登录。
  • 使用 SSH 密钥,使 ssh bot@mac-mini.tailnet-1234.ts.net 无需提示即可工作。
  • remoteHost 应与 SSH 目标匹配,以便 SCP 可以获取附件。

多账户支持:使用 channels.imessage.accounts 进行每个账户的配置和可选的 name。有关共享模式,请参见gateway/configuration。不要提交 ~/.clawdbot/openclaw.json(它通常包含令牌)。

访问控制(私聊 + 群组)

私聊:

  • 默认:channels.imessage.dmPolicy = "pairing"
  • 未知发送者会收到配对码;消息在被批准前被忽略(配对码在 1 小时后过期)。
  • 通过以下方式批准:
    • openclaw pairing list imessage
    • openclaw pairing approve imessage <配对码>
  • 配对是 iMessage 私聊的默认令牌交换方式。详情:配对

群组:

  • channels.imessage.groupPolicy = open | allowlist | disabled
  • channels.imessage.groupAllowFrom 控制当 allowlist 设置时谁可以在群组中触发。
  • 提及门控使用 agents.list[].groupChat.mentionPatterns(或 messages.groupChat.mentionPatterns),因为 iMessage 没有原生的提及元数据。
  • 多代理覆盖:在 agents.list[].groupChat.mentionPatterns 上设置每个代理的模式。

How it works (behavior)

  • imsg streams message events; the gateway normalizes them into the shared channel envelope.
  • Replies always route back to the same chat id or handle.

Group-ish threads (is_group=false)

Some iMessage threads can have multiple participants but still arrive with is_group=false depending on how Messages stores the chat identifier.

If you explicitly configure a chat_id under channels.imessage.groups, openclaw treats that thread as a “group” for:

  • session isolation (separate agent:<agentId>:imessage:group:<chat_id> session key)
  • group allowlisting / mention gating behavior

Example:

json5
{
  channels: {
    imessage: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15555550123"],
      groups: {
        "42": { "requireMention": false }
      }
    }
  }
}

这在您希望为特定线程使用独立的人格/模型时很有用(参见多智能体路由)。对于文件系统隔离,请参见沙盒

媒体 + 限制

  • 通过 channels.imessage.includeAttachments 可选地摄取附件。
  • 通过 channels.imessage.mediaMaxMb 设置媒体上限。

限制

  • 出站文本会被分块到 channels.imessage.textChunkLimit(默认 4000)。
  • 可选的新行分块:设置 channels.imessage.chunkMode="newline" 以在长度分块之前按空行(段落边界)分割。
  • 媒体上传受 channels.imessage.mediaMaxMb 限制(默认 16)。

寻址 / 发送目标

优先使用 chat_id 进行稳定路由:

  • chat_id:123(首选)
  • chat_guid:...
  • chat_identifier:...
  • 直接句柄:imessage:+1555 / sms:+1555 / user@example.com

列出聊天:

imsg chats --limit 20

配置参考(iMessage)

完整配置:配置

提供者选项:

  • channels.imessage.enabled:启用/禁用通道启动。
  • channels.imessage.cliPathimsg 的路径。
  • channels.imessage.dbPath:Messages 数据库路径。
  • channels.imessage.remoteHost:当 cliPath 指向远程 Mac 时用于 SCP 附件传输的 SSH 主机(例如,user@gateway-host)。如果未设置,则从 SSH 包装器自动检测。
  • channels.imessage.serviceimessage | sms | auto
  • channels.imessage.region:SMS 区域。
  • channels.imessage.dmPolicypairing | allowlist | open | disabled(默认:pairing)。
  • channels.imessage.allowFrom:DM 允许列表(句柄、电子邮件、E.164 号码或 chat_id:*)。open 需要 "*"。iMessage 没有用户名;使用句柄或聊天目标。
  • channels.imessage.groupPolicyopen | allowlist | disabled(默认:allowlist)。
  • channels.imessage.groupAllowFrom:群组发送者允许列表。
  • channels.imessage.historyLimit / channels.imessage.accounts.*.historyLimit:包含为上下文的最大群组消息数(0 表示禁用)。
  • channels.imessage.dmHistoryLimit:DM 历史限制(用户轮次)。每个用户的覆盖:channels.imessage.dms["<handle>"].historyLimit
  • channels.imessage.groups:每个群组的默认值 + 允许列表(使用 "*" 表示全局默认值)。
  • channels.imessage.includeAttachments:将附件摄取到上下文中。
  • channels.imessage.mediaMaxMb:入站/出站媒体上限(MB)。
  • channels.imessage.textChunkLimit:出站分块大小(字符)。
  • channels.imessage.chunkModelength(默认)或 newline 以在长度分块之前按空行(段落边界)分割。

相关全局选项:

  • agents.list[].groupChat.mentionPatterns(或 messages.groupChat.mentionPatterns)。
  • messages.responsePrefix