iMessage (imsg)

ステータス: 外部CLI統合。GatewayはJSON-RPC over stdioでimsg rpcを起動します。

クイックセットアップ(初心者向け)

  1. このMacでMessagesにサインインしていることを確認します。
  2. imsgをインストールします:
    • brew install steipete/tap/imsg
  3. channels.imessage.cliPathchannels.imessage.dbPathでOpenClawを設定します。
  4. Gatewayを起動し、macOSプロンプト(Automation + Full Disk Access)を承認します。

最小限の設定:

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

これは何か

  • macOS上のimsgによって支えられたiMessage Channel(チャンネル)。
  • 確定的なルーティング: 返信は常にiMessageに戻ります。
  • DMはエージェントのメインセッションを共有します。グループは分離されています(agent:<agentId>:imessage:group:<chat_id>)。
  • is_group=falseのマルチ参加者スレッドが到着した場合でも、channels.imessage.groupsを使用してchat_idで分離できます(以下の「グループ風スレッド」を参照)。

設定の書き込み

デフォルトでは、iMessageは/config set|unsetによってトリガーされる設定更新の書き込みが許可されています(commands.config: trueが必要)。

無効化するには:

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

要件

  • Messagesにサインインしているmacシステム。
  • OpenClaw + imsgのFull Disk Access(Messages DBアクセス)。
  • 送信時のAutomation権限。
  • channels.imessage.cliPathは、stdin/stdoutをプロキシする任意のコマンドを指すことができます(例: 別のMacにSSHしてimsg rpcを実行するラッパースクリプト)。

セットアップ(高速パス)

  1. このMacでMessagesにサインインしていることを確認します。
  2. iMessageを設定し、Gatewayを起動します。

専用botmacOSユーザー(分離されたアイデンティティ用)

Botに別のiMessageアイデンティティから送信させたい場合(個人のMessagesをクリーンに保つため)、専用のApple ID + 専用のmacOSユーザーを使用します。

  1. 専用のApple IDを作成します(例: [email protected])。
    • Appleは検証/2FAに電話番号を要求する場合があります。
  2. macOSユーザー(例: openclawhome)を作成してサインインします。
  3. そのmacOSユーザーでMessagesを開き、bot Apple IDを使用してiMessageにサインインします。
  4. Remote Login(リモートログイン)を有効にします(システム設定 → 一般 → 共有 → Remote Login)。
  5. imsgをインストールします:
    • brew install steipete/tap/imsg
  6. ssh <bot-macos-user>@localhost trueがパスワードなしで機能するようにSSHを設定します。
  7. channels.imessage.accounts.bot.cliPathを、botユーザーとしてimsgを実行するSSHラッパーに向けます。

初回実行の注意: 送受信にはbot macOSユーザーでのGUI承認(Automation + Full Disk Access)が必要な場合があります。imsg rpcがスタックまたは終了しているように見える場合は、そのユーザーにログイン(Screen Sharingが役立ちます)し、一度だけimsg chats --limit 1 / imsg send ...を実行し、プロンプトを承認してから再試行してください。

ラッパーの例(chmod +x)。<bot-macos-user>を実際のmacOSユーザー名に置き換えてください:

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

# ホストキーを受け入れるために最初に対話型SSHを一度実行します:
#   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"
        }
      }
    }
  }
}

シングルアカウントセットアップの場合は、accountsマップの代わりにフラットオプション(channels.imessage.cliPathchannels.imessage.dbPath)を使用します。

リモート/SSH変種(オプション)

別のMac上でiMessageを使用したい場合は、SSH経由でリモートmacOSホスト上でimsgを実行するラッパーにchannels.imessage.cliPathを設定します。OpenClawはstdioのみが必要です。

ラッパー例:

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

リモート添付ファイル: cliPathがSSH経由でリモートホストを指す場合、Messages databaseの添付ファイルパスはリモートマシン上のファイルを参照します。OpenClawはchannels.imessage.remoteHostを設定することで、SCP経由でこれらを自動的にフェッチできます:

{
  channels: {
    imessage: {
      cliPath: "~/imsg-ssh",                     // リモートMacへのSSHラッパー
      remoteHost: "user@gateway-host",           // SCPファイル転送用
      includeAttachments: true
    }
  }
}

remoteHostが設定されていない場合、OpenClawはラッパースクリプト内のSSHコマンドを解析して自動検出を試みます。信頼性のために明示的な設定が推奨されます。

Tailscale経由のリモートMac(例)

GatewayがLinuxホスト/VM上で実行されているが、iMessageがMac上で実行される必要がある場合、Tailscaleが最も簡単なブリッジです: GatewayはTailnet経由でMacと通信し、SSH経由でimsgを実行し、添付ファイルをSCPで返送します。

アーキテクチャ:

┌──────────────────────────────┐          SSH (imsg rpc)          ┌──────────────────────────┐
│ Gateway host (Linux/VM)      │──────────────────────────────────▶│ Mac with Messages + imsg │
│ - openclaw 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: "~/.openclaw/scripts/imsg-ssh",
      remoteHost: "[email protected]",
      includeAttachments: true,
      dbPath: "/Users/bot/Library/Messages/chat.db"
    }
  }
}

ラッパー例(~/.openclaw/scripts/imsg-ssh):

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

注:

  • MacがMessagesにサインインし、Remote Loginが有効になっていることを確認してください。
  • ssh [email protected]がプロンプトなしで機能するようにSSHキーを使用してください。
  • remoteHostはSCPが添付ファイルをフェッチできるようにSSHターゲットと一致させる必要があります。

複数アカウントサポート: channels.imessage.accountsをアカウントごとの設定とオプションのnameで使用します。共有パターンについてはgateway/configurationを参照してください。~/.openclaw/openclaw.jsonをコミットしないでください(多くの場合トークンが含まれています)。

アクセス制御(DM + グループ)

DM:

  • デフォルト: channels.imessage.dmPolicy = "pairing"
  • 未知の送信者はペアリングコードを受信します。承認されるまでメッセージは無視されます(コードは1時間後に期限切れになります)。
  • 承認するには:
    • openclaw pairing list imessage
    • openclaw pairing approve imessage <CODE>
  • ペアリングはiMessage DMのデフォルトのトークン交換です。詳細: Pairing

グループ:

  • channels.imessage.groupPolicy = open | allowlist | disabled
  • channels.imessage.groupAllowFromは、allowlistが設定されている場合にグループ内で誰がトリガーできるかを制御します。
  • メンションゲーティングはagents.list[].groupChat.mentionPatterns(またはmessages.groupChat.mentionPatterns)を使用します。iMessageにはネイティブメンションメタデータがないためです。
  • マルチエージェント上書き: agents.list[].groupChat.mentionPatternsでエージェントごとのパターンを設定します。

動作方法(動作)

  • imsgはメッセージイベントをストリームします。Gatewayはそれらを共有Channel(チャンネル)エンベロープに正規化します。
  • 返信は常に同じchat idまたはhandleにルーティングされます。

グループ風スレッド(is_group=false

一部のiMessageスレッドは複数の参加者を持つことができますが、Messagesがチャット識別子を保存する方法によっては、is_group=falseで到着する場合があります。

channels.imessage.groupsの下にchat_idを明示的に設定すると、OpenClawはそのスレッドを「グループ」として扱います:

  • セッション分離(別のagent:<agentId>:imessage:group:<chat_id>セッションキー)
  • グループ許可リスト/メンションゲーティング動作

例:

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

これは、特定のスレッドに対して分離されたパーソナリティ/モデルが必要な場合に便利です(Multi-agent routingを参照)。ファイルシステムの分離については、Sandboxingを参照してください。

メディア + 制限

  • 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 / [email protected]

チャットをリスト:

imsg chats --limit 20

設定リファレンス(iMessage)

完全な設定: Configuration

プロバイダーオプション:

  • channels.imessage.enabled: チャンネル起動の有効/無効化。
  • channels.imessage.cliPath: imsgへのパス。
  • channels.imessage.dbPath: Messages DBパス。
  • channels.imessage.remoteHost: cliPathがリモートMacを指す場合のSCP添付ファイル転送用のSSHホスト(例: user@gateway-host)。設定されていない場合はSSHラッパーから自動検出されます。
  • channels.imessage.service: imessage | sms | auto
  • channels.imessage.region: SMSリージョン。
  • channels.imessage.dmPolicy: pairing | allowlist | open | disabled(デフォルト: pairing)。
  • channels.imessage.allowFrom: DM許可リスト(ハンドル、メール、E.164番号、またはchat_id:*)。openには"*"が必要です。iMessageにはユーザー名がありません。ハンドルまたはチャットターゲットを使用してください。
  • channels.imessage.groupPolicy: open | 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.chunkMode: length(デフォルト)またはnewline(長さチャンク化の前に空白行(段落境界)で分割)。

関連するグローバルオプション:

  • agents.list[].groupChat.mentionPatterns(またはmessages.groupChat.mentionPatterns)。
  • messages.responsePrefix