跳转到内容

iMessage

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

  1. 确保在此 Mac 上已登录”信息”。
  2. 安装 imsg
    • brew install steipete/tap/imsg
  3. 配置 CoderClaw 的 channels.imessage.cliPathchannels.imessage.dbPath
  4. 启动 Gateway 网关并批准所有 macOS 提示(自动化 + 完全磁盘访问权限)。

最小配置:

{
channels: {
imessage: {
enabled: true,
cliPath: "/usr/local/bin/imsg",
dbPath: "/Users/<you>/Library/Messages/chat.db",
},
},
}
  • 基于 macOS 上 imsg 的 iMessage 渠道。
  • 确定性路由:回复始终返回到 iMessage。
  • 私信共享智能体的主会话;群组是隔离的(agent:<agentId>:imessage:group:<chat_id>)。
  • 如果多参与者会话以 is_group=false 到达,你仍可使用 channels.imessage.groupschat_id 隔离(参见下方”类群组会话”)。

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

禁用方式:

{
channels: { imessage: { configWrites: false } },
}
  • 已登录”信息”的 macOS。
  • CoderClaw + imsg 的完全磁盘访问权限(访问”信息”数据库)。
  • 发送时需要自动化权限。
  • channels.imessage.cliPath 可以指向任何代理 stdin/stdout 的命令(例如,通过 SSH 连接到另一台 Mac 并运行 imsg rpc 的包装脚本)。
  1. 确保在此 Mac 上已登录”信息”。
  2. 配置 iMessage 并启动 Gateway 网关。

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

Section titled “专用机器人 macOS 用户(用于隔离身份)”

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

  1. 创建专用 Apple ID(例如:[email protected])。
    • Apple 可能需要电话号码进行验证 / 2FA。
  2. 创建 macOS 用户(例如:coderclawhome)并登录。
  3. 在该 macOS 用户中打开”信息”并使用机器人 Apple ID 登录 iMessage。
  4. 启用远程登录(系统设置 → 通用 → 共享 → 远程登录)。
  5. 安装 imsg
    • brew install steipete/tap/imsg
  6. 设置 SSH 使 ssh <bot-macos-user>@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 用户名:

#!/usr/bin/env bash
set -euo pipefail
# Run an interactive SSH once first to accept host keys:
# ssh <bot-macos-user>@localhost true
exec /usr/bin/ssh -o BatchMode=yes -o ConnectTimeout=5 -T <bot-macos-user>@localhost \
"/usr/local/bin/imsg" "$@"

示例配置:

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

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

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

示例包装脚本:

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

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

{
channels: {
imessage: {
cliPath: "~/imsg-ssh", // SSH wrapper to remote Mac
remoteHost: "user@gateway-host", // for SCP file transfer
includeAttachments: true,
},
},
}

如果未设置 remoteHost,CoderClaw 会尝试通过解析包装脚本中的 SSH 命令自动检测。建议显式配置以提高可靠性。

通过 Tailscale 连接远程 Mac(示例)

Section titled “通过 Tailscale 连接远程 Mac(示例)”

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

架构:

┌──────────────────────────────┐ SSH (imsg rpc) ┌──────────────────────────┐
│ Gateway host (Linux/VM) │──────────────────────────────────▶│ Mac with Messages + imsg │
│ - coderclaw gateway │ SCP (attachments) │ - Messages signed in │
│ - channels.imessage.cliPath │◀──────────────────────────────────│ - Remote Login enabled │
└──────────────────────────────┘ └──────────────────────────┘
│ Tailscale tailnet (hostname or 100.x.y.z)
user@gateway-host

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

{
channels: {
imessage: {
enabled: true,
cliPath: "~/.coderclaw/scripts/imsg-ssh",
remoteHost: "[email protected]",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}

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

#!/usr/bin/env bash
exec ssh -T [email protected] imsg "$@"

注意事项:

  • 确保 Mac 已登录”信息”,并已启用远程登录。
  • 使用 SSH 密钥使 ssh [email protected] 无需提示即可工作。
  • remoteHost 应与 SSH 目标匹配,以便 SCP 可以获取附件。

多账户支持:使用 channels.imessage.accounts 配置每个账户及可选的 name。参见 gateway/configuration 了解共享模式。不要提交 ~/.coderclaw/coderclaw.json(它通常包含令牌)。

私信:

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

群组:

  • channels.imessage.groupPolicy = open | allowlist | disabled
  • 设置 allowlist 时,channels.imessage.groupAllowFrom 控制谁可以在群组中触发。
  • 提及检测使用 agents.list[].groupChat.mentionPatterns(或 messages.groupChat.mentionPatterns),因为 iMessage 没有原生提及元数据。
  • 多智能体覆盖:在 agents.list[].groupChat.mentionPatterns 上设置每个智能体的模式。
  • imsg 流式传输消息事件;Gateway 网关将它们规范化为共享渠道信封。
  • 回复始终路由回相同的 chat id 或 handle。

某些 iMessage 会话可能有多个参与者,但根据”信息”存储聊天标识符的方式,仍以 is_group=false 到达。

如果你在 channels.imessage.groups 下显式配置了 chat_id,CoderClaw 会将该会话视为”群组”用于:

  • 会话隔离(独立的 agent:<agentId>:imessage:group:<chat_id> 会话键)
  • 群组允许列表 / 提及检测行为

示例:

{
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:...
  • 直接 handle:imessage:+1555 / sms:+1555 / [email protected]

列出聊天:

imsg chats --limit 20

完整配置:配置

提供商选项:

  • channels.imessage.enabled:启用/禁用渠道启动。
  • channels.imessage.cliPathimsg 路径。
  • channels.imessage.dbPath:“信息”数据库路径。
  • channels.imessage.remoteHost:当 cliPath 指向远程 Mac 时用于 SCP 附件传输的 SSH 主机(例如 user@gateway-host)。如未设置则从 SSH 包装脚本自动检测。
  • channels.imessage.serviceimessage | sms | auto
  • channels.imessage.region:短信区域。
  • channels.imessage.dmPolicypairing | allowlist | open | disabled(默认:pairing)。
  • channels.imessage.allowFrom:私信允许列表(handle、邮箱、E.164 号码或 chat_id:*)。open 需要 "*"。iMessage 没有用户名;使用 handle 或聊天目标。
  • channels.imessage.groupPolicyopen | allowlist | disabled(默认:allowlist)。
  • channels.imessage.groupAllowFrom:群组发送者允许列表。
  • channels.imessage.historyLimit / channels.imessage.accounts.*.historyLimit:作为上下文包含的最大群组消息数(0 禁用)。
  • channels.imessage.dmHistoryLimit:私信历史限制(用户轮次)。每用户覆盖: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