コンテンツにスキップ

BlueBubbles (macOS REST) を使った iMessage 連携の構築

  • BlueBubblesヘルパーアプリ(bluebubbles.app)を介して、macOS上で動作します。
  • 推奨環境はmacOS Sequoia (15)です。macOS Tahoe (26)でも動作しますが、現在は編集機能が制限されていたり、グループアイコンの更新が同期されないといった課題が確認されています。
  • OpenClawはREST API(GET /api/v1/ping, POST /message/text, POST /chat/:id/*)を使用して通信を行います。
  • メッセージの受信にはwebhookを使用し、送信、タイピングインジケーター、既読通知、タップバックなどはRESTコールで実行されます。
  • 添付ファイルやステッカーはインバウンドメディアとして取り込まれ、可能な限りエージェントに表示されます。
  • ペアリングや許可リストの設定は、他のチャンネルと同様にchannels.bluebubbles.allowFromとペアリングコードを使用して行います。
  • リアクションはSlackやTelegramと同じようにシステムイベントとして扱われるため、エージェントは返信する前にそれらに言及することが可能です。
  • 編集、送信取り消し、スレッド返信、メッセージエフェクト、グループ管理などの高度な機能も備えています。
  1. MacにBlueBubblesサーバーをインストールします(詳細は bluebubbles.app/install を参照してください)。

  2. BlueBubblesの設定でWeb APIを有効にし、パスワードを設定します。

  3. openclaw onboardを実行してBlueBubblesを選択するか、手動で設定を行います。

    {
    channels: {
    bluebubbles: {
    enabled: true,
    serverUrl: "http://192.168.1.100:1234",
    password: "example-password",
    webhookPath: "/bluebubbles-webhook",
    },
    },
    }
  4. BlueBubblesのwebhook送信先をGatewayに設定します(例:https://your-gateway-host:3000/bluebubbles-webhook?password=<password>)。

  5. Gatewayを起動すると、webhookハンドラーが登録され、ペアリングが開始されます。

セキュリティに関する注意点:

  • 必ずwebhookパスワードを設定してください。
  • webhookの認証は常に必須です。OpenClawは、channels.bluebubbles.passwordと一致するパスワードやGUID(例:?password=<password>やx-password)が含まれていないリクエストを、ネットワーク構成に関わらず拒否します。
  • パスワード認証は、webhookのボディ全体を読み込み・解析する前に行われます。

Messages.app の常時起動(VM / ヘッドレスト環境)

Section titled “Messages.app の常時起動(VM / ヘッドレスト環境)”

VMや常時稼働の環境では、Messages.appが「アイドル状態」になり、アプリをフォアグラウンドにするまでイベントが届かなくなることがあります。これを防ぐには、AppleScriptとLaunchAgentを使って5分ごとにMessages.appを叩くのが簡単で効果的な方法です。

以下の内容を ~/Scripts/poke-messages.scpt として保存します。

このスクリプトは非対話型で、フォーカスを奪うことはありません。

try
tell application "Messages"
if not running then
launch
end if
-- Touch the scripting interface to keep the process responsive.
set _chatCount to (count of chats)
end tell
on error
-- Ignore transient failures (first-run prompts, locked session, etc).
end try

以下の内容を ~/Library/LaunchAgents/com.user.poke-messages.plist として保存します。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.poke-messages</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-lc</string>
<string>/usr/bin/osascript &quot;$HOME/Scripts/poke-messages.scpt&quot;</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>300</integer>
<key>StandardOutPath</key>
<string>/tmp/poke-messages.log</string>
<key>StandardErrorPath</key>
<string>/tmp/poke-messages.err</string>
</dict>
</plist>

補足:

  • この設定により、300秒ごとおよびログイン時にスクリプトが実行されます。
  • 初回実行時にmacOSの「オートメーション」の許可を求めるプロンプトが表示される場合があります。LaunchAgentを実行するユーザーセッションで許可を与えてください。

設定を反映させるコマンド:

Terminal window
launchctl unload ~/Library/LaunchAgents/com.user.poke-messages.plist 2>/dev/null || true
launchctl load ~/Library/LaunchAgents/com.user.poke-messages.plist

BlueBubblesは、対話形式のオンボーディングで設定可能です。

openclaw onboard

ウィザードでは以下の項目を設定します。

  • Server URL(必須):BlueBubblesサーバーのアドレス(例:http://192.168.1.100:1234)
  • Password(必須):BlueBubblesサーバー設定のAPIパスワード
  • Webhook path(任意):デフォルトは /bluebubbles-webhook
  • DM policy:pairing, allowlist, open, disabledから選択
  • Allow list:電話番号、メールアドレス、またはチャットのターゲット

CLIから直接追加することも可能です。

openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>

AI Setup Assistant

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

Section titled “アクセス制御(DM とグループ)”

DM(ダイレクトメッセージ)の設定について説明します。

  • デフォルト設定: channels.bluebubbles.dmPolicy = "pairing"
  • 未知の送信者にはペアリングコードが送信され、承認されるまでメッセージは無視されます(コードの有効期限は1時間です)。
  • 承認方法:
    • openclaw pairing list bluebubbles
    • openclaw pairing approve bluebubbles <CODE>
  • ペアリングはデフォルトのトークン交換方式です。詳細は Pairing を参照してください。

グループ設定:

  • channels.bluebubbles.groupPolicy = open | allowlist | disabled(デフォルト: allowlist)
  • allowlist が設定されている場合、channels.bluebubbles.groupAllowFrom でグループ内でのトリガー権限を制御します。

連絡先名の補完(macOS、オプション)

Section titled “連絡先名の補完(macOS、オプション)”

BlueBubbles のグループ Webhook では、参加者のアドレスがそのまま送られてくることがよくあります。GroupMembers のコンテキストでローカルの連絡先名を表示したい場合は、macOS で連絡先補完機能を有効にできます。

  • channels.bluebubbles.enrichGroupParticipantsFromContacts = true でルックアップを有効にします(デフォルト: false)。
  • ルックアップは、グループアクセス、コマンド実行権限、メンションゲートのチェックを通過した後にのみ実行されます。
  • 名前が設定されていない電話番号の参加者のみが補完対象です。
  • ローカルに一致する情報がない場合は、元の電話番号がそのまま使用されます。
{
channels: {
bluebubbles: {
enrichGroupParticipantsFromContacts: true,
},
},
}

メンションゲート(グループ)

Section titled “メンションゲート(グループ)”

BlueBubbles はグループチャットでのメンションゲートをサポートしており、iMessage や WhatsApp と同様の動作が可能です。

  • agents.list[].groupChat.mentionPatterns(または messages.groupChat.mentionPatterns)を使用してメンションを検出します。
  • グループで requireMention が有効な場合、エージェントはメンションされた時のみ応答します。
  • 権限を持つ送信者からの制御コマンドは、メンションゲートをバイパスします。

グループごとの設定例:

{
channels: {
bluebubbles: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { requireMention: true }, // default for all groups
"iMessage;-;chat123": { requireMention: false }, // override for specific group
},
},
},
}
  • 制御コマンド(例: /config, /model)には実行権限が必要です。
  • allowFrom と groupAllowFrom を使用して、コマンドの実行権限を判断します。
  • 権限を持つ送信者は、グループ内でメンションしなくても制御コマンドを実行できます。

BlueBubbles のチャットは、トランスポート層を変更することなく、永続的な ACP ワークスペースに変換できます。

オペレーター向けのクイックフロー:

  • DM または許可されたグループチャット内で /acp spawn codex --bind here を実行します。
  • 以降、その BlueBubbles 会話でのメッセージは、生成された ACP セッションにルーティングされます。
  • /new や /reset を実行すると、バインドされた同じ ACP セッションがその場でリセットされます。
  • /acp close を実行すると、ACP セッションが終了し、バインディングが解除されます。

設定ファイルによる永続的なバインディングもサポートされています。トップレベルの bindings[] エントリで type: "acp" かつ match.channel: "bluebubbles" を指定します。

match.peer.id では、以下の BlueBubbles ターゲット形式を使用できます。

  • 正規化された DM ハンドル(例: +15555550123 や user@example.com)
  • chat_id:<id>
  • chat_guid:<guid>
  • chat_identifier:<identifier>

安定したグループバインディングには、chat_id:* または chat_identifier:* の使用を推奨します。

設定例:

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

共通の ACP バインディングの動作については ACP Agents を参照してください。

タイピングインジケーターと既読通知

Section titled “タイピングインジケーターと既読通知”
  • タイピングインジケーター: レスポンス生成の前後および生成中に自動的に送信されます。
  • 既読通知: channels.bluebubbles.sendReadReceipts で制御します(デフォルト: true)。
  • タイピングインジケーターの動作: OpenClaw がタイピング開始イベントを送信します。BlueBubbles は送信時またはタイムアウト時に自動的にタイピング状態をクリアします(DELETE による手動停止は動作が不安定なため)。
{
channels: {
bluebubbles: {
sendReadReceipts: false, // disable read receipts
},
},
}

設定で有効にすると、BlueBubbles で高度なメッセージアクションを利用できるようになります。

{
channels: {
bluebubbles: {
actions: {
reactions: true, // tapbacks (default: true)
edit: true, // edit sent messages (macOS 13+, broken on macOS 26 Tahoe)
unsend: true, // unsend messages (macOS 13+)
reply: true, // reply threading by message GUID
sendWithEffect: true, // message effects (slam, loud, etc.)
renameGroup: true, // rename group chats
setGroupIcon: true, // set group chat icon/photo (flaky on macOS 26 Tahoe)
addParticipant: true, // add participants to groups
removeParticipant: true, // remove participants from groups
leaveGroup: true, // leave group chats
sendAttachment: true, // send attachments/media
},
},
},
}

利用可能なアクション:

  • react: タップバック(リアクション)の追加・削除(messageId, emoji, remove)
  • edit: 送信済みメッセージの編集(messageId, text)
  • unsend: メッセージの送信取り消し(messageId)
  • reply: 特定のメッセージへの返信(messageId, text, to)
  • sendWithEffect: iMessage エフェクト付きで送信(text, to, effectId)
  • renameGroup: グループチャット名の変更(chatGuid, displayName)
  • setGroupIcon: グループチャットのアイコン/写真の設定(chatGuid, media) — macOS 26 Tahoe では不安定です(API が成功を返してもアイコンが同期されない場合があります)。
  • addParticipant: グループへの参加者追加(chatGuid, address)
  • removeParticipant: グループからの参加者削除(chatGuid, address)
  • leaveGroup: グループチャットからの退出(chatGuid)
  • upload-file: メディアやファイルの送信(to, buffer, filename, asVoice)
    • ボイスメモ: MP3 または CAF オーディオを使用して asVoice: true を設定すると、iMessage のボイスメッセージとして送信されます。BlueBubbles は送信時に MP3 を CAF に変換します。
  • レガシーエイリアス: sendAttachment も引き続き動作しますが、標準のアクション名は upload-file です。

メッセージ ID(短縮 ID とフル ID)

Section titled “メッセージ ID(短縮 ID とフル ID)”

OpenClaw では、トークンを節約するために短縮メッセージ ID(例: 1, 2)を表示することがあります。

  • MessageSid や ReplyToId は短縮 ID になる場合があります。
  • MessageSidFull や ReplyToIdFull には、プロバイダーのフル ID が含まれます。
  • 短縮 ID はメモリ内に保持されるため、再起動やキャッシュの破棄によって無効になることがあります。
  • アクションでは短縮 ID とフル ID の両方を受け付けますが、短縮 ID が無効になっている場合はエラーになります。

長期的な自動化やストレージへの保存にはフル ID を使用してください。

  • テンプレート: {{MessageSidFull}}, {{ReplyToIdFull}}
  • コンテキスト: インバウンドペイロード内の MessageSidFull / ReplyToIdFull

テンプレート変数については Configuration を参照してください。

レスポンスを1つのメッセージとしてまとめて送信するか、それともブロック単位でストリーミングするかを制御できます。デフォルトはオフになっていますが、ストリーミングを有効にすることで、よりリアルタイムに近いスムーズなレスポンス体験を提供できるのでおすすめです。

{
channels: {
bluebubbles: {
blockStreaming: true, // enable block streaming (off by default)
},
},
}

受信した添付ファイルは、自動的にダウンロードされてメディアキャッシュに保存される仕組みです。メディアの容量制限については channels.bluebubbles.mediaMaxMb で設定でき、デフォルトは 8 MB です。この制限は受信と送信の両方のメディアに適用されます。

送信するテキストが長すぎる場合には、channels.bluebubbles.textChunkLimit(デフォルト 4000 文字)の設定値に基づいて、自動的に分割して送信されます。文字数制限を調整したい場合は、この値を変更してください。

設定の全容については、こちらの Configuration を参照してください。

Provider のオプションは以下の通りです:

  • channels.bluebubbles.enabled: チャンネルの有効/無効を切り替えます。
  • channels.bluebubbles.serverUrl: BlueBubbles REST API のベース URL です。
  • channels.bluebubbles.password: API パスワードです。
  • channels.bluebubbles.webhookPath: Webhook エンドポイントのパスです(デフォルト:/bluebubbles-webhook)。
  • channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled から選択します(デフォルト:pairing)。
  • channels.bluebubbles.allowFrom: DM の許可リストです(ハンドル、メールアドレス、E.164 番号、chat_id:*、chat_guid:* が指定可能です)。
  • channels.bluebubbles.groupPolicy: open | allowlist | disabled から選択します(デフォルト:allowlist)。
  • channels.bluebubbles.groupAllowFrom: グループ送信者の許可リストです。
  • channels.bluebubbles.enrichGroupParticipantsFromContacts: macOS を使用している場合、ゲートを通過した後に、名前のないグループ参加者の情報をローカルの Contacts から補完するかどうかを設定します。デフォルトは false です。
  • channels.bluebubbles.groups: グループごとの設定(requireMention など)を行います。
  • channels.bluebubbles.sendReadReceipts: 既読確認を送信します(デフォルト:true)。
  • channels.bluebubbles.blockStreaming: ブロックストリーミングを有効にします(デフォルト:false。ストリーミング返信を利用する場合に必要です)。
  • channels.bluebubbles.textChunkLimit: 送信時のチャンクサイズを文字数で指定します(デフォルト:4000)。
  • channels.bluebubbles.chunkMode: length(デフォルト)は textChunkLimit を超えた場合のみ分割します。newline は、長さによる分割の前に、空行(段落の境界)で分割します。
  • channels.bluebubbles.mediaMaxMb: 送受信するメディアの容量制限を MB 単位で指定します(デフォルト:8)。
  • channels.bluebubbles.mediaLocalRoots: 送信用のローカルメディアパスとして許可する、絶対パスによるローカルディレクトリの明示的な許可リストです。設定されていない場合、ローカルパスによる送信はデフォルトで拒否されます。アカウントごとの上書きは channels.bluebubbles.accounts.<accountId>.mediaLocalRoots で行います。
  • channels.bluebubbles.historyLimit: コンテキストとして取得するグループメッセージの最大数です(0 で無効化)。
  • channels.bluebubbles.dmHistoryLimit: DM の履歴制限です。
  • channels.bluebubbles.actions: 特定のアクションの有効/無効を切り替えます。
  • channels.bluebubbles.accounts: マルチアカウント設定です。

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

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

アドレス指定と配信ターゲット

Section titled “アドレス指定と配信ターゲット”

安定したルーティングを行うために、chat_guid を使用するのがおすすめです。

  • chat_guid:iMessage;-;+15555550123 (グループチャットにはこちらが適しています)
  • chat_id:123
  • chat_identifier:...
  • 直接のハンドル: +15555550123, user@example.com
    • 直接のハンドルに対して既存の DM チャットが存在しない場合、OpenClaw は POST /api/v1/chat/new を使用してチャットを新規作成します。これを利用するには、BlueBubbles の Private API が有効になっている必要があります。
  • Webhookのリクエストは、guidやpasswordのクエリパラメータ、またはヘッダーをchannels.bluebubbles.passwordと比較することで認証されます。localhostからのリクエストも受け入れられます。
  • APIのパスワードとWebhookのエンドポイントは、機密情報(認証情報)として大切に管理してください。
  • Localhostを信頼するということは、同じホスト上で動作するリバースプロキシが意図せずパスワード認証をバイパスしてしまう可能性があることを意味します。Gatewayをプロキシ経由で利用する場合は、プロキシ側で認証を必須にし、gateway.trustedProxiesを設定しましょう。詳細はGateway securityを確認してください。
  • BlueBubblesサーバーをLANの外に公開する場合は、HTTPSを有効にし、ファイアウォールルールを設定するのがベストです。
  • タイピング中や既読のイベントが機能しなくなった場合は、BlueBubblesのWebhookログを確認し、Gatewayのパスがchannels.bluebubbles.webhookPathと一致しているかチェックしてみてください。
  • ペアリングコードの有効期限は1時間です。openclaw pairing list bluebubbles や openclaw pairing approve bluebubbles <code> を使用してください。
  • リアクション機能にはBlueBubblesのPrivate API(POST /api/v1/message/react)が必要です。サーバーのバージョンがこのAPIを公開しているか確認してください。
  • メッセージの編集や送信取り消しには、macOS 13以降と、それに対応したBlueBubblesサーバーのバージョンが必要です。macOS 26 (Tahoe) では、Private APIの変更により、現在編集機能が動作しません。
  • macOS 26 (Tahoe) では、グループアイコンの更新が不安定になることがあります。APIが成功を返しても、新しいアイコンが同期されない場合があります。
  • OpenClawは、BlueBubblesサーバーのmacOSバージョンに基づいて、動作しないことがわかっているアクションを自動的に非表示にします。もしmacOS 26 (Tahoe) で編集機能が表示されたままになっている場合は、channels.bluebubbles.actions.edit=false を設定して手動で無効化してください。
  • ステータスやヘルス情報の確認には、openclaw status --all または openclaw status --deep を実行しましょう。

一般的なチャネルのワークフローについては、Channels と Plugins ガイドを参照してください。

  • Channels Overview — サポートされているすべてのチャネル
  • Pairing — DMの認証とペアリングの流れ
  • Groups — グループチャットの動作とメンションによる制限
  • Channel Routing — メッセージのセッションルーティング
  • Security — アクセスモデルとセキュリティの強化
OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。