imessage plugin を通じてのみ iMessage をサポートします。この plugin は JSON-RPC 経由で steipete/imsg を駆動し、BlueBubbles が持っていたものと同じ private API surface(react、edit、unsend、reply、sendWithEffect、ネイティブ投票、グループ管理、添付ファイル)に到達します。1 つの CLI バイナリが BlueBubbles サーバー + クライアントアプリ + webhook 配管を置き換えます。REST エンドポイントも webhook 認証もありません。
このガイドでは、古い channels.bluebubbles 設定を channels.imessage に移行します。他にサポートされる移行パスはありません。現在の OpenClaw では、残っている channels.bluebubbles ブロックは不活性で、runtime は読み取りません。
短い告知と運用者向け概要については、BlueBubbles の削除と imsg iMessage パスを参照してください。
移行チェックリスト
古い BlueBubbles 設定がすでに分かっている場合の、最短で安全な手順:- Messages.app を実行している Mac で
imsgを直接確認します(imsg chats、imsg history、imsg send、imsg rpc --help)。 - 挙動キーを
channels.bluebubblesからchannels.imessageにコピーします:dmPolicy、allowFrom、groupPolicy、groupAllowFrom、groups、includeAttachments、attachmentRoots、mediaMaxMb、textChunkLimit、coalesceSameSenderDms、actions。 - もう存在しない transport キーを削除します:
serverUrl、password、webhook URL、BlueBubbles サーバー設定。 - Gateway が Messages の Mac 上で実行されていない場合は、
channels.imessage.cliPathを SSH ラッパーに設定し、リモート添付ファイル取得用にremoteHostを設定します。 channels.imessageを有効化し、Gateway を再起動してから、openclaw channels status --probe --channel imessageを実行します。- DM を 1 件、許可されたグループを 1 件、添付ファイルが有効なら添付ファイルを、そして agent に使わせる予定のすべての private API アクションをテストします。
- iMessage パスが検証できたら、BlueBubbles サーバーと古い
channels.bluebubbles設定を削除します。
imsg の役割
imsg は Messages 用のローカル macOS CLI です。OpenClaw は imsg rpc を子プロセスとして起動し、stdin/stdout 経由で JSON-RPC をやり取りします。HTTP サーバー、webhook URL、バックグラウンドデーモン、launch agent、公開するポートはありません。
- 読み取りは、読み取り専用 SQLite ハンドルを使用して
~/Library/Messages/chat.dbから行われます。 - ライブ受信メッセージは
imsg watch/watch.subscribeから取得され、これはポーリング fallback 付きでchat.dbのファイルシステムイベントを追跡します。 - 送信は、通常のテキスト送信とファイル送信に Messages.app automation を使用します。
- 高度なアクションは、
imsg launchを使ってimsgヘルパーを Messages.app に注入します。これにより、開封確認、入力中インジケーター、リッチ送信、編集、送信取り消し、スレッド返信、tapback、投票、グループ管理が利用できるようになります。 - Linux ビルドではコピーした
chat.dbを検査できますが、送信、ライブ Mac データベースの watch、Messages.app の駆動はできません。OpenClaw iMessage では、サインイン済みの Mac 上、またはその Mac への SSH ラッパー経由でimsgを実行してください。
始める前に
-
Messages.app を実行している Mac に
imsgをインストールします:imsg chatsがunable to open database file、空の出力、またはauthorization deniedで失敗する場合は、imsgを起動するターミナル、エディタ、Node プロセス、Gateway サービス、または SSH 親プロセスにフルディスクアクセスを付与し、その親プロセスを開き直してください。 -
OpenClaw 設定を変更する前に、read、watch、send、RPC の surface を確認します:
42はimsg chatsから得た実際の chat id に置き換えてください。送信には Messages.app の Automation 権限が必要です。OpenClaw を SSH 経由で実行する場合は、OpenClaw が使用するのと同じ SSH ラッパーまたはユーザーコンテキストでこれらのコマンドを実行してください。読み取りは動作するが送信が AppleEvents-1743で失敗する場合は、Automation が/usr/libexec/sshd-keygen-wrapperに付与されていないか確認してください。SSH ラッパー送信が AppleEvents -1743 で失敗するを参照してください。 -
高度なアクションが必要な場合は、private API ブリッジを有効化します:
imsg launchには SIP の無効化が必要です(また、現代の macOS では library validation の緩和も必要です。imsg private API の有効化を参照してください)。基本的な送信、履歴、watch はimsg launchなしで動作しますが、高度なアクションは動作しません。 -
channels.imessageを有効化して Gateway を起動した後、OpenClaw 経由でブリッジを確認します:iMessage アカウントはworksを報告するはずです。--jsonでは、probe payload にprivateApi.available: trueが含まれます。falseが報告される場合は、まずそれを修正してください。Capability detectionを参照してください。probe には到達可能な Gateway が必要です(そうでない場合 CLI は config-only 出力に fallback します)。また、設定済みかつ有効なアカウントだけを probe します。 -
設定のスナップショットを取ります:
設定の変換
iMessage と BlueBubbles は、ほとんどの channel-level 挙動キーを共有します。変わるのは transport(REST サーバー vs ローカル CLI)と、グループレジストリのキー形式です。| BlueBubbles | 同梱 iMessage | 注記 |
|---|---|---|
channels.bluebubbles.enabled | channels.imessage.enabled | 同じセマンティクス(ブロックが存在するとデフォルトは true)。 |
channels.bluebubbles.serverUrl | (削除済み) | REST サーバーはありません。Plugin は stdio 経由で imsg rpc を起動します。 |
channels.bluebubbles.password | (削除済み) | Webhook 認証は不要です。 |
| (暗黙) | channels.imessage.cliPath | imsg へのパス(デフォルトは imsg)。SSH にはラッパースクリプトを使用します。 |
| (暗黙) | channels.imessage.dbPath | 任意の Messages.app chat.db オーバーライド。省略時は自動検出されます。 |
| (暗黙) | channels.imessage.remoteHost | host または user@host。cliPath が SSH ラッパーで、SCP による添付ファイル取得を使いたい場合にのみ必要です。 |
channels.bluebubbles.dmPolicy | channels.imessage.dmPolicy | 同じ値(pairing / allowlist / open / disabled)。デフォルトは pairing。 |
channels.bluebubbles.allowFrom | channels.imessage.allowFrom | 同じハンドル形式(+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。同梱 Plugin では、これはプライベート API プローブが稼働している場合にのみ発火します。 |
channels.bluebubbles.includeAttachments | channels.imessage.includeAttachments | 同じ形状で、同じくデフォルトはオフです。BlueBubbles で添付ファイルが流れていた場合は、これを明示的に設定してください。設定するまで、受信写真/メディアは黙って破棄されます(Inbound message ログ行は出ません)。 |
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 | channels.imessage.coalesceSameSenderDms | 同じオプトインです。DM のみで、グループはメッセージ単位のディスパッチを維持します。messages.inbound.byChannel.imessage またはグローバルの messages.inbound.debounceMs が設定されていない限り、デフォルトの受信デバウンスは 7000 ms に広がります。分割送信された DM の結合を参照してください。 |
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 Plugin は 2 つのグループゲートを連続して実行します。グループメッセージがエージェントに届くには、両方を通過する必要があります。- 送信者 / チャットターゲットの許可リスト(
channels.imessage.groupAllowFrom)— 送信者ハンドル、またはチャットターゲット(chat_id:,chat_guid:,chat_identifier:エントリ)に一致します。groupAllowFromが未設定の場合、このゲートはallowFromにフォールバックします。明示的なgroupAllowFrom: []はそのフォールバックを無効にし、groupPolicy: "allowlist"ではすべてのグループメッセージを破棄します。 - グループレジストリ(
channels.imessage.groups)— 数値の iMessagechat_idをキーにします。groupsブロックがない(または空の)場合: ゲート 1 に空でない実効送信者許可リストがある限り、グループはこのゲートを通過します。送信者フィルタリングがアクセスを管理し、全破棄の起動時警告は出ません。- エントリを持つ
groupsだが"*"がない場合: 一覧にあるchat_idキーのみが通過します。どれか 1 つのグループを列挙すると、groupPolicy: "open"であってもレジストリは許可リストになります。 groups: { "*": { ... } }: すべてのグループがこのゲートを通過します。
groups エントリをチャット GUID / チャット識別子でキー付けしていましたが、iMessage レジストリは数値の chat_id でキー付けします。グループごとのエントリをそのままコピーすると、キーが決して一致しない空ではないレジストリが作られるため、すべてのグループメッセージがゲート 2 で破棄されます。"*" ワイルドカードはそのままコピーし、特定グループのエントリは imsg chats の chat_id 値でキーを付け直してください。
どちらの破棄パスも、デフォルトのログレベルでは warn 行として表示されます。
- 起動時にアカウントごとに 1 回、
groupPolicy: "allowlist"が設定されていて、実効グループ送信者許可リストが空の場合:imessage: groupPolicy="allowlist" for account "<id>" but no group sender allowlist is configured ...。送信者を許可するにはgroupAllowFrom(またはallowFrom)を設定します。groupsだけを追加しても送信者ゲートは満たされません。 - 実行時に
chat_idごとに 1 回、レジストリがグループを破棄する場合:imessage: dropping group message from chat_id=<id> ... not in channels.imessage.groups allowlist。追加すべき正確なキーが示されます。
groupPolicy: "allowlist" を使う最小限の送信者スコープ設定:
requireMention などのチャットごとのオプションを設定する場合は、groups エントリを追加します。BlueBubbles の "*" エントリはそのままコピーしますが、特定のエントリは数値の iMessage chat_id 値でキーを付け直してください。
手順
-
config を移行します。編集中は新しいブロックを無効のままにしてください。古い
channels.bluebubblesブロックは現在の OpenClaw では無視されるため、参照用として並べて残しておけます。 -
切り替えてプローブします。
channels.imessage.enabled: trueを設定し、Gateway を再起動して、チャンネルが正常と報告されることを確認します。プローブには到達可能な Gateway が必要で、設定済みかつ有効なアカウントのみをプローブします。Mac 自体を検証するには、始める前に の直接のimsgコマンドを使用してください。 - DM を検証します。 エージェントにダイレクトメッセージを送信し、返信が届くことを確認します。
-
グループは別個に検証します。 DM とグループは異なるコードパスを通ります。DM の成功は、グループがルーティングされていることの証明にはなりません。許可済みのグループチャットでメッセージを送信し、返信が届くことを確認します。グループが沈黙する場合(エージェント返信なし、エラーなし)は、上記の「Group registry footgun」からの 2 つの
warn行を gateway ログで確認してください。起動時の警告は、有効な送信者許可リストが空であることを意味します。chat_idごとの警告は、入力済みのgroupsレジストリにそのチャットが含まれていないことを意味します。 -
アクション面を検証します。 ペアリング済み DM から、リアクション、編集、送信取り消し、返信、写真送信、そして(グループ内で)グループ名の変更または参加者の追加/削除をエージェントに依頼します。各アクションは Messages.app にネイティブに反映される必要があります。いずれかのアクションで
iMessage <action> requires the imsg private API bridgeが発生する場合は、imsg launchを再度実行し、openclaw channels status --probeで更新してください。 -
iMessage の DM、グループ、アクションが検証できたら、BlueBubbles サーバーと
channels.bluebubblesブロックを削除します。OpenClaw はchannels.bluebubblesを読み取りません。
アクションの対応状況の概要
| アクション | 従来の BlueBubbles | 同梱 iMessage |
|---|---|---|
| テキスト送信 / SMS フォールバック | ✅ | ✅ |
| メディア送信(写真、動画、ファイル、音声) | ✅ | ✅ |
スレッド返信(reply_to_guid) | ✅ | ✅(#51892 を解決) |
Tapback(react) | ✅ | ✅ |
| 編集 / 送信取り消し(macOS 13+ の受信者) | ✅ | ✅ |
| スクリーンエフェクト付き送信 | ✅ | ✅(#9394 の一部を解決) |
| リッチテキストの太字 / 斜体 / 下線 / 取り消し線 | ✅ | ✅(attributedBody による typed-run 書式設定) |
| ネイティブ Messages 投票(作成と投票) | ❌ | ✅(actions.polls。ネイティブ描画には受信者側に iOS/macOS 26+ が必要) |
| グループ名変更 / グループアイコン設定 | ✅ | ✅ |
| 参加者の追加 / 削除、グループ退出 | ✅ | ✅ |
| 開封確認と入力中インジケーター | ✅ | ✅(private API プローブにより制御) |
| 同一送信者 DM の結合 | ✅ | ✅(DM のみ。channels.imessage.coalesceSameSenderDms でオプトイン) |
| 再起動後の受信復旧 | ✅ | ✅(自動: since_rowid リプレイ + GUID 重複排除。local ではより広いウィンドウ) |
imsg watch.subscribe の since_rowid を介して最後に dispatch された rowid からリプレイし、GUID で重複排除し、古いバックログの年齢フェンスによって Push-flush の「backlog bomb」を抑制します。これは imsg RPC 接続上で実行されるため、リモート SSH cliPath 構成でも機能します。local 構成では chat.db を読み取れるため、より広い復旧ウィンドウが得られます。ブリッジまたは gateway 再起動後の受信復旧 を参照してください。
ペアリング、セッション、ACP バインディング
- 許可リストは handle で引き継がれます。
channels.imessage.allowFromは、BlueBubbles が使用していたものと同じ+15555550123/user@example.com文字列を認識します。そのままコピーしてください。 - pairing-store の承認は移行されません。 pairing store はチャンネルごとであり、古い BlueBubbles store を移行するものはありません。ペアリングのみで承認されていた送信者は、iMessage で再度ペアリングする必要があります。または、その handle を
allowFromに追加します。 - セッション はエージェント + チャットごとのスコープのままです。DM はデフォルトの
session.dmScope=mainのもとでエージェントのメインセッションに集約されます。グループセッションは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 を設定し、Gateway を再起動し、imsg のブロッカーを修正してから、切り替えを再試行してください。
返信キャッシュは SQLite Plugin state に保存されます。openclaw doctor --fix は、古い imessage/reply-cache.jsonl sidecar が存在する場合、それをインポートしてアーカイブします。
関連
- BlueBubbles の削除と imsg iMessage パス — 短い告知と運用者向け概要。
- iMessage —
imsg launchセットアップと capability 検出を含む、完全な iMessage チャンネルリファレンス。 /channels/bluebubbles— この移行ガイドへリダイレクトするレガシー URL。- ペアリング — DM 認証とペアリングフロー。
- チャンネルルーティング — gateway が送信返信用のチャンネルを選択する方法。