Mainstream messaging

BlueBubbles

Status:內建的舊版 Plugin,透過 HTTP 與 BlueBubbles macOS 伺服器通訊。現有 BlueBubbles 設定會繼續運作,但新的 OpenClaw iMessage 部署在需求符合主機條件時,應優先使用原生 iMessage Plugin。

概觀

  • 透過 BlueBubbles 輔助應用程式在 macOS 上執行(bluebubbles.app)。
  • 適用於已依賴 BlueBubbles 頻道 ID、webhook 狀態、群組目標、cron 傳遞或工作區路由的安裝,作為舊版備援。
  • 建議/已測試:macOS Sequoia (15)。macOS Tahoe (26) 可運作;目前 Tahoe 上的編輯功能已損壞,群組圖示更新可能回報成功但未同步。
  • OpenClaw 透過其 REST API 與它通訊(GET /api/v1/pingPOST /message/textPOST /chat/:id/*)。
  • 傳入訊息會透過 webhooks 抵達;傳出回覆、輸入中指示、已讀回條與 tapbacks 都是 REST 呼叫。
  • 附件與貼圖會作為傳入媒體擷取(並在可行時呈現給代理)。
  • 會合成 MP3 或 CAF 音訊的自動 TTS 回覆,會以 iMessage 語音備忘錄泡泡傳遞,而不是一般檔案附件。
  • 配對/允許清單的運作方式與其他頻道相同(/channels/pairing 等),搭配 channels.bluebubbles.allowFrom + 配對碼。
  • 反應會像 Slack/Telegram 一樣以系統事件呈現,讓代理可在回覆前「提及」它們。
  • 進階功能:編輯、收回、回覆串接、訊息效果、群組管理。

快速開始

  • 安裝 BlueBubbles

    在你的 Mac 上安裝 BlueBubbles 伺服器(依照 bluebubbles.app/install 的指示)。

  • 啟用 Web API

    在 BlueBubbles 設定中啟用 Web API 並設定密碼。

  • 設定 OpenClaw

    執行 openclaw onboard 並選取 BlueBubbles,或手動設定:

    {
      channels: {
        bluebubbles: {
          enabled: true,
          serverUrl: "http://192.168.1.100:1234",
          password: "example-password",
          webhookPath: "/bluebubbles-webhook",
        },
      },
    }
    
  • 將 webhooks 指向 gateway

    將 BlueBubbles webhooks 指向你的 gateway(範例:https://your-gateway-host:3000/bluebubbles-webhook?password=<password>)。

  • 啟動 gateway

    啟動 gateway;它會註冊 webhook 處理常式並開始配對。

  • 讓 Messages.app 保持運作(VM / 無頭設定)

    某些 macOS VM / 常時開機設定可能會讓 Messages.app 進入「閒置」狀態(傳入事件會停止,直到應用程式被開啟/帶到前景)。一個簡單的解法是使用 AppleScript + LaunchAgent 每 5 分鐘 poke Messages 一次

  • 儲存 AppleScript

    將以下內容儲存為 ~/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
    
  • 安裝 LaunchAgent

    將以下內容儲存為 ~/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 自動化提示(osascript → Messages)。請在執行 LaunchAgent 的同一個使用者工作階段中核准。

  • 載入它

    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
    

    精靈會提示輸入:

    伺服器 URLstringrequired

    BlueBubbles 伺服器位址(例如 http://192.168.1.100:1234)。

    密碼stringrequired

    來自 BlueBubbles Server 設定的 API 密碼。

    Webhook 路徑string

    Webhook 端點路徑。

    DM 政策string

    pairingallowlistopendisabled

    允許清單string[]

    電話號碼、電子郵件或聊天目標。

    你也可以透過 CLI 新增 BlueBubbles:

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

    存取控制(DM + 群組)

    DM

    • 預設:channels.bluebubbles.dmPolicy = "pairing"
    • 未知寄件者會收到配對碼;訊息在核准前會被忽略(代碼會在 1 小時後過期)。
    • 透過以下方式核准:
      • openclaw pairing list bluebubbles
      • openclaw pairing approve bluebubbles &lt;CODE&gt;
    • 配對是預設的權杖交換。詳細資訊:配對

    群組

    • channels.bluebubbles.groupPolicy = open | allowlist | disabled(預設:allowlist)。
    • 設定 allowlist 時,channels.bluebubbles.groupAllowFrom 控制誰可以在群組中觸發。

    聯絡人名稱補充(macOS,選用)

    BlueBubbles 群組 webhooks 通常只包含原始參與者位址。如果你希望 GroupMembers context 改為顯示本機聯絡人名稱,可以在 macOS 上選擇啟用本機聯絡人補充:

    • channels.bluebubbles.enrichGroupParticipantsFromContacts = true 會啟用查詢。預設:false
    • 查詢只會在群組存取、命令授權與提及門控允許訊息通過後執行。
    • 只會補充未命名的電話參與者。
    • 找不到本機相符項目時,原始電話號碼仍會作為備援。
    {
      channels: {
        bluebubbles: {
          enrichGroupParticipantsFromContacts: true,
        },
      },
    }
    

    提及門控(群組)

    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)需要授權。
    • 使用 allowFromgroupAllowFrom 判斷命令授權。
    • 授權寄件者即使未在群組中提及,也可以執行控制命令。

    每群組系統提示

    channels.bluebubbles.groups.* 底下的每個項目都接受選用的 systemPrompt 字串。該值會在處理該群組訊息的每一輪注入代理的系統提示,因此你可以設定每群組 persona 或行為規則,而不用編輯代理提示:

    {
      channels: {
        bluebubbles: {
          groups: {
            "iMessage;-;chat123": {
              systemPrompt: "Keep responses under 3 sentences. Mirror the group's casual tone.",
            },
          },
        },
      },
    }
    

    鍵會對應 BlueBubbles 回報給該群組的 chatGuid / chatIdentifier / 數字 chatId,而 "*" 萬用字元項目會為每個沒有精確相符項目的群組提供預設值(與 requireMention 以及每群組工具政策使用相同模式)。精確相符一律優先於萬用字元。DM 會忽略此欄位;請改用代理層級或帳號層級的提示自訂。

    實例:串接回覆與 tapback 反應(私有 API)

    啟用 BlueBubbles 私有 API 後,傳入訊息會帶有短訊息 ID(例如 [[reply_to:5]]),且代理可以呼叫 action=reply 來串接到特定訊息,或呼叫 action=react 放置 tapback。每群組 systemPrompt 是讓代理選擇正確工具的可靠方式:

    {
      channels: {
        bluebubbles: {
          groups: {
            "iMessage;+;chat-family": {
              systemPrompt: "When replying in this group, always call action=reply with the [[reply_to:N]] messageId from context so your response threads under the triggering message. Never send a new unlinked message. For short acknowledgements ('ok', 'got it', 'on it'), use action=react with an appropriate tapback emoji (❤️, 👍, 😂, ‼️, ❓) instead of sending a text reply.",
            },
          },
        },
      },
    }
    

    Tapback 反應與串接回覆都需要 BlueBubbles 私有 API;底層機制請參閱進階動作訊息 ID

    ACP 對話繫結

    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[email protected]
    • 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 繫結行為。

    輸入中 + 已讀回執

    • 輸入中指示器:在回應產生前及期間自動傳送。
    • 已讀回執:由 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:新增/移除 Tapback 反應(messageIdemojiremove)。iMessage 的原生 Tapback 集合是 lovelikedislikelaughemphasizequestion。當代理程式選擇該集合以外的表情符號(例如 👀)時,反應工具會退回到 love,讓 Tapback 仍可呈現,而不是讓整個請求失敗。已設定的確認反應仍會嚴格驗證,並在值未知時報錯。
    • edit:編輯已傳送的訊息(messageIdtext)。
    • unsend:收回訊息(messageId)。
    • reply:回覆特定訊息(messageIdtextto)。
    • sendWithEffect:使用 iMessage 效果傳送(texttoeffectId)。
    • renameGroup:重新命名群組聊天(chatGuiddisplayName)。
    • setGroupIcon:設定群組聊天的圖示/照片(chatGuidmedia)- 在 macOS 26 Tahoe 上不穩定(API 可能回傳成功,但圖示不會同步)。
    • addParticipant:將某人加入群組(chatGuidaddress)。
    • removeParticipant:從群組移除某人(chatGuidaddress)。
    • leaveGroup:離開群組聊天(chatGuid)。
    • upload-file:傳送媒體/檔案(tobufferfilenameasVoice)。
      • 語音備忘錄:設定 asVoice: true,搭配 MP3CAF 音訊,以 iMessage 語音訊息傳送。BlueBubbles 會在傳送語音備忘錄時將 MP3 → CAF。
    • 舊版別名:sendAttachment 仍可使用,但 upload-file 是正式動作名稱。

    訊息 ID(短版與完整)

    為節省 token,OpenClaw 可能會顯示_短版_訊息 ID(例如 12)。

    • MessageSid / ReplyToId 可以是短 ID。
    • MessageSidFull / ReplyToIdFull 包含提供者完整 ID。
    • 短 ID 存於記憶體中;重新啟動或快取淘汰時可能會過期。
    • 動作接受短版或完整 messageId,但若短 ID 已無法取得會報錯。

    若要用於持久的自動化和儲存,請使用完整 ID:

    • 範本:{{MessageSidFull}}{{ReplyToIdFull}}
    • 脈絡:傳入酬載中的 MessageSidFull / ReplyToIdFull

    請參閱設定了解範本變數。

    合併分割傳送的 DM(同一段撰寫中的命令 + URL)

    當使用者在 iMessage 中把命令和 URL 一起輸入時,例如 Dump https://example.com/article,Apple 會將傳送拆成兩個獨立的 Webhook 傳遞

    1. 一則文字訊息("Dump")。
    2. 一個 URL 預覽泡泡("https://..."),並以附件附上 OG 預覽圖片。

    在多數環境中,兩個 Webhook 抵達 OpenClaw 的間隔約為 0.8-2.0 秒。若未合併,代理程式會在第 1 輪只收到命令並回覆(通常是「把 URL 傳給我」),到第 2 輪才看到 URL,此時命令脈絡已經遺失。

    channels.bluebubbles.coalesceSameSenderDms 讓 DM 選擇將連續且同一傳送者的 Webhook 合併為單一代理程式輪次。群組聊天仍會以每則訊息作為鍵,因此保留多使用者輪次結構。

    啟用時機

    在以下情況啟用:

    • 你提供預期 command + payload 位於同一則訊息中的 Skills(傾印、貼上、儲存、排入佇列等)。
    • 你的使用者會把 URL、圖片或長內容與命令一起貼上。
    • 你可以接受額外的 DM 輪次延遲(見下方)。

    在以下情況保持停用:

    • 你需要單字 DM 觸發詞的最低命令延遲。
    • 你的所有流程都是沒有後續酬載的一次性命令。

    啟用

    {
      channels: {
        bluebubbles: {
          coalesceSameSenderDms: true, // opt in (default: false)
        },
      },
    }
    

    旗標開啟且沒有明確設定 messages.inbound.byChannel.bluebubbles 時,防彈跳視窗會加寬到 2500 ms(非合併模式預設為 500 ms)。較寬的視窗是必要的,因為 Apple 的分割傳送節奏為 0.8-2.0 秒,無法放入較緊的預設值。

    若要自行調整視窗:

    {
      messages: {
        inbound: {
          byChannel: {
            // 2500 ms works for most setups; raise to 4000 ms if your Mac is slow
            // or under memory pressure (observed gap can stretch past 2 s then).
            bluebubbles: 2500,
          },
        },
      },
    }
    

    取捨

    • DM 控制命令的額外延遲。 旗標開啟時,DM 控制命令訊息(如 DumpSave 等)現在會最多等待到防彈跳視窗結束才派送,以防酬載 Webhook 即將抵達。群組聊天命令維持即時派送。
    • 合併輸出有界 - 合併文字上限為 4000 字元,並帶有明確的 …[truncated] 標記;附件上限為 20;來源項目上限為 10(超過後保留第一筆加最新項目)。每個來源 messageId 仍會到達傳入去重,因此之後 MessagePoller 重播任何個別事件時,會被辨識為重複。
    • 選擇加入、按頻道設定。 其他頻道(Telegram、WhatsApp、Slack、…)不受影響。

    情境以及代理程式看到的內容

    使用者撰寫 Apple 傳遞 旗標關閉(預設) 旗標開啟 + 2500 ms 視窗
    Dump https://example.com(一次傳送) 2 個 Webhook,間隔約 1 秒 兩個代理程式輪次:只有「Dump」,然後是 URL 一個輪次:合併文字 Dump https://example.com
    Save this 📎image.jpg caption(附件 + 文字) 2 個 Webhook 兩個輪次 一個輪次:文字 + 圖片
    /status(獨立命令) 1 個 Webhook 即時派送 最多等待到視窗結束,然後派送
    只貼上 URL 1 個 Webhook 即時派送 即時派送(儲存桶中只有一筆項目)
    文字 + URL 作為兩則刻意分開的訊息傳送,相隔數分鐘 2 個 Webhook,位於視窗之外 兩個輪次 兩個輪次(視窗在兩者之間到期)
    快速大量訊息(視窗內 >10 則小型 DM) N 個 Webhook N 個輪次 一個輪次,有界輸出(套用第一筆 + 最新,以及文字/附件上限)

    分割傳送合併疑難排解

    如果旗標已開啟,但分割傳送仍以兩個輪次抵達,請逐層檢查:

    設定確實已載入
    grep coalesceSameSenderDms ~/.openclaw/openclaw.json
    

    接著執行 openclaw gateway restart - 此旗標會在建立防彈跳登錄表時讀取。

    防彈跳視窗對你的環境足夠寬

    查看 ~/Library/Logs/bluebubbles-server/main.log 下的 BlueBubbles 伺服器記錄:

    grep -E "Dispatching event to webhook" main.log | tail -20
    

    測量 "Dump" 這類文字派送與其後 "https://..."; Attachments: 派送之間的間隔。將 messages.inbound.byChannel.bluebubbles 提高到足以涵蓋該間隔。

    工作階段 JSONL 時間戳 ≠ Webhook 抵達時間

    工作階段事件時間戳(~/.openclaw/agents/<id>/sessions/*.jsonl)反映的是 Gateway 將訊息交給代理程式的時間,不是 Webhook 抵達的時間。標記為 [Queued messages while agent was busy] 的排隊第二則訊息,表示第二個 Webhook 抵達時第一個輪次仍在執行,合併儲存桶已經送出並清空。請依據 BB 伺服器記錄調整視窗,而不是依據工作階段記錄。

    記憶體壓力拖慢回覆派送

    在較小的主機(8 GB)上,代理程式輪次可能耗時足以讓合併儲存桶在回覆完成前就送出並清空,URL 會落入排隊的第二個輪次。檢查 memory_pressureps -o rss -p $(pgrep openclaw-gateway);如果 Gateway 超過約 500 MB RSS 且壓縮器作用中,請關閉其他繁重處理程序,或升級到較大的主機。

    引用回覆傳送是不同路徑

    如果使用者是點選 Dump 作為現有 URL 泡泡的回覆(iMessage 會在 Dump 泡泡上顯示「1 則回覆」徽章),URL 會位於 replyToBody,而不是第二個 Webhook。合併不適用 - 這是 Skills/提示詞層面的問題,不是防彈跳器層面的問題。

    區塊串流

    控制回應是作為單一訊息傳送,還是以區塊串流傳送:

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

    媒體 + 限制

    • 傳入附件會下載並儲存在媒體快取中。
    • 透過 channels.bluebubbles.mediaMaxMb 設定傳入與傳出媒體的媒體上限(預設:8 MB)。
    • 傳出文字會依 channels.bluebubbles.textChunkLimit 分塊(預設:4000 字元)。

    設定參考

    完整設定:設定

    連線與 Webhook
    • channels.bluebubbles.enabled:啟用/停用此頻道。
    • channels.bluebubbles.serverUrl:BlueBubbles REST API 基底 URL。
    • channels.bluebubbles.password:API 密碼。
    • channels.bluebubbles.webhookPath:Webhook 端點路徑(預設:/bluebubbles-webhook)。
    存取政策
    • channels.bluebubbles.dmPolicypairing | allowlist | open | disabled(預設:pairing)。
    • channels.bluebubbles.allowFrom:DM 允許清單(帳號代稱、電子郵件、E.164 號碼、chat_id:*chat_guid:*)。
    • channels.bluebubbles.groupPolicyopen | allowlist | disabled(預設:allowlist)。
    • channels.bluebubbles.groupAllowFrom:群組寄件者允許清單。
    • channels.bluebubbles.enrichGroupParticipantsFromContacts:在 macOS 上,可選擇在通過閘門檢查後,從本機「聯絡人」補充未命名的群組參與者。預設:false
    • channels.bluebubbles.groups:每個群組的設定(requireMention 等)。
    傳送與分段
    • channels.bluebubbles.sendReadReceipts:傳送讀取回條(預設:true)。
    • channels.bluebubbles.blockStreaming:啟用區塊串流(預設:false;串流回覆需要此設定)。
    • channels.bluebubbles.textChunkLimit:傳出分段大小,以字元計(預設:4000)。
    • channels.bluebubbles.sendTimeoutMs:透過 /api/v1/message/text 傳送傳出文字時,每個請求的逾時時間,以毫秒計(預設:30000)。在 macOS 26 設定中,Private API iMessage 傳送可能在 iMessage framework 內停滯 60 秒以上;此時請提高此值,例如 4500060000。探測、聊天查詢、反應、編輯和健康檢查目前仍保留較短的 10 秒預設值;後續計畫將涵蓋範圍擴展到反應和編輯。每個帳號的覆寫:channels.bluebubbles.accounts.<accountId>.sendTimeoutMs
    • channels.bluebubbles.chunkModelength(預設)只會在超過 textChunkLimit 時分割;newline 會先依空白行(段落邊界)分割,再依長度分段。
    媒體與歷史記錄
    • channels.bluebubbles.mediaMaxMb:傳入/傳出媒體大小上限,以 MB 計(預設:8)。
    • channels.bluebubbles.mediaLocalRoots:明確允許用於傳出本機媒體路徑的絕對本機目錄清單。除非已設定此項,否則預設拒絕傳送本機路徑。每個帳號的覆寫:channels.bluebubbles.accounts.<accountId>.mediaLocalRoots
    • channels.bluebubbles.coalesceSameSenderDms:將連續的同寄件者 DM Webhook 合併為一次代理程式回合,讓 Apple 的文字+URL 分開傳送能以單一訊息抵達(預設:false)。如需情境、視窗調整與取捨,請參閱合併分開傳送的 DM。啟用且未明確設定 messages.inbound.byChannel.bluebubbles 時,會將預設傳入防抖視窗從 500 毫秒放寬為 2500 毫秒。
    • channels.bluebubbles.historyLimit:用於上下文的群組訊息數量上限(0 表示停用)。
    • channels.bluebubbles.dmHistoryLimit:DM 歷史記錄限制。
    • channels.bluebubbles.replyContextApiFallback:當傳入回覆缺少 replyToBody/replyToSender,且記憶體中的回覆上下文快取未命中時,以盡力而為的後備方式從 BlueBubbles HTTP API 擷取原始訊息(預設:false)。適用於共用同一個 BlueBubbles 帳號的多執行個體部署、程序重新啟動後,或長時間存活的 TTL/LRU 快取遭逐出後。此擷取受與所有其他 BlueBubbles 用戶端請求相同的 SSRF 防護政策保護,絕不會擲出錯誤,並會填入快取,讓後續回覆分攤成本。每個帳號的覆寫:channels.bluebubbles.accounts.<accountId>.replyContextApiFallback。頻道層級設定會傳播到省略此旗標的帳號。
    動作與帳號
    • channels.bluebubbles.actions:啟用/停用特定動作。
    • channels.bluebubbles.accounts:多帳號設定。

    相關全域選項:

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

    定址 / 傳送目標

    偏好使用 chat_guid 以取得穩定路由:

    • chat_guid:iMessage;-;+15555550123(群組建議使用)
    • chat_id:123
    • chat_identifier:...
    • 直接帳號代稱:+15555550123[email protected]
      • 如果直接帳號代稱沒有現有的 DM 聊天,OpenClaw 會透過 POST /api/v1/chat/new 建立一個。這需要啟用 BlueBubbles Private API。

    iMessage 與 SMS 路由

    當同一個帳號代稱在 Mac 上同時有 iMessage 和 SMS 聊天時(例如某個電話號碼已註冊 iMessage,但也曾收到綠色泡泡後備訊息),OpenClaw 會偏好 iMessage 聊天,且絕不會無聲降級到 SMS。若要強制使用 SMS 聊天,請使用明確的 sms: 目標前綴(例如 sms:+15555550123)。沒有相符 iMessage 聊天的帳號代稱,仍會透過 BlueBubbles 回報的任何聊天傳送。

    安全性

    • Webhook 請求會透過比對 guid/password 查詢參數或標頭與 channels.bluebubbles.password 進行驗證。
    • 請保密 API 密碼和 Webhook 端點(將它們視為憑證)。
    • BlueBubbles Webhook 驗證沒有 localhost 旁路。如果你代理 Webhook 流量,請讓 BlueBubbles 密碼在請求端到端保留。gateway.trustedProxies 在此不會取代 channels.bluebubbles.password。請參閱 Gateway 安全性
    • 如果將 BlueBubbles 伺服器暴露到 LAN 之外,請啟用 HTTPS 與防火牆規則。

    疑難排解

    • 如果輸入/讀取事件停止運作,請檢查 BlueBubbles Webhook 記錄,並確認 Gateway 路徑符合 channels.bluebubbles.webhookPath
    • 配對碼會在一小時後到期;請使用 openclaw pairing list bluebubblesopenclaw pairing approve bluebubbles <code>
    • 反應需要 BlueBubbles Private API(POST /api/v1/message/react);請確認伺服器版本有公開它。
    • 編輯/收回需要 macOS 13+ 和相容的 BlueBubbles 伺服器版本。在 macOS 26(Tahoe)上,編輯目前因 Private API 變更而無法運作。
    • 群組圖示更新在 macOS 26(Tahoe)上可能不穩定:API 可能回傳成功,但新圖示不會同步。
    • OpenClaw 會根據 BlueBubbles 伺服器的 macOS 版本自動隱藏已知無法運作的動作。如果編輯仍出現在 macOS 26(Tahoe)上,請用 channels.bluebubbles.actions.edit=false 手動停用。
    • 已啟用 coalesceSameSenderDms,但分開傳送(例如 Dump + URL)仍以兩個回合抵達:請參閱分開傳送合併疑難排解檢查清單 - 常見原因包括防抖視窗太緊、工作階段記錄時間戳記被誤讀為 Webhook 抵達時間,或傳送的是回覆引用(它使用 replyToBody,不是第二個 Webhook)。
    • 如需狀態/健康資訊:openclaw status --allopenclaw status --deep

    如需一般頻道工作流程參考,請參閱頻道Plugins 指南。

    相關