Mainstream messaging

BlueBubbles

Trạng thái: plugin kế thừa được đóng gói sẵn giao tiếp với máy chủ BlueBubbles trên macOS qua HTTP. Các thiết lập BlueBubbles hiện có vẫn tiếp tục hoạt động, nhưng các triển khai OpenClaw iMessage mới nên ưu tiên plugin iMessage gốc khi các yêu cầu của plugin này phù hợp với máy chủ của bạn.

Tổng quan

  • Chạy trên macOS thông qua ứng dụng trợ giúp BlueBubbles (bluebubbles.app).
  • Phương án dự phòng kế thừa cho các bản cài đặt đã phụ thuộc vào ID kênh BlueBubbles, trạng thái webhook, mục tiêu nhóm, phân phối cron, hoặc định tuyến workspace.
  • Được khuyến nghị/đã kiểm thử: macOS Sequoia (15). macOS Tahoe (26) hoạt động; chỉnh sửa hiện đang bị lỗi trên Tahoe, và cập nhật biểu tượng nhóm có thể báo thành công nhưng không đồng bộ.
  • OpenClaw giao tiếp với nó thông qua REST API (GET /api/v1/ping, POST /message/text, POST /chat/:id/*).
  • Tin nhắn đến đi qua webhooks; phản hồi gửi đi, chỉ báo đang nhập, xác nhận đã đọc, và tapbacks là các lệnh gọi REST.
  • Tệp đính kèm và nhãn dán được nạp dưới dạng phương tiện đầu vào (và được hiển thị cho agent khi có thể).
  • Phản hồi Auto-TTS tổng hợp âm thanh MP3 hoặc CAF được gửi dưới dạng bong bóng ghi âm iMessage thay vì tệp đính kèm thông thường.
  • Cơ chế ghép đôi/danh sách cho phép hoạt động giống các kênh khác (/channels/pairing v.v.) với channels.bluebubbles.allowFrom + mã ghép đôi.
  • Reactions được hiển thị dưới dạng sự kiện hệ thống giống như Slack/Telegram để agents có thể "nhắc đến" chúng trước khi trả lời.
  • Tính năng nâng cao: chỉnh sửa, thu hồi gửi, luồng trả lời, hiệu ứng tin nhắn, quản lý nhóm.

Bắt đầu nhanh

  • Install BlueBubbles

    Cài đặt máy chủ BlueBubbles trên máy Mac của bạn (làm theo hướng dẫn tại bluebubbles.app/install).

  • Enable the web API

    Trong cấu hình BlueBubbles, bật web API và đặt mật khẩu.

  • Configure OpenClaw

    Chạy openclaw onboard và chọn BlueBubbles, hoặc cấu hình thủ công:

    {
      channels: {
        bluebubbles: {
          enabled: true,
          serverUrl: "http://192.168.1.100:1234",
          password: "example-password",
          webhookPath: "/bluebubbles-webhook",
        },
      },
    }
    
  • Point webhooks at the gateway

    Trỏ webhooks của BlueBubbles tới Gateway của bạn (ví dụ: https://your-gateway-host:3000/bluebubbles-webhook?password=<password>).

  • Start the gateway

    Khởi động Gateway; nó sẽ đăng ký trình xử lý webhook và bắt đầu ghép đôi.

  • Giữ Messages.app hoạt động (thiết lập VM / headless)

    Một số thiết lập VM macOS / luôn bật có thể khiến Messages.app chuyển sang trạng thái "nhàn rỗi" (sự kiện đến dừng lại cho đến khi ứng dụng được mở/đưa lên trước). Cách khắc phục đơn giản là đánh thức Messages mỗi 5 phút bằng AppleScript + LaunchAgent.

  • Save the AppleScript

    Lưu nội dung này dưới dạng ~/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
    
  • Install a LaunchAgent

    Lưu nội dung này dưới dạng ~/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>
    

    Thao tác này chạy mỗi 300 giâykhi đăng nhập. Lần chạy đầu tiên có thể kích hoạt lời nhắc Automation của macOS (osascript → Messages). Phê duyệt chúng trong cùng phiên người dùng chạy LaunchAgent.

  • Load it

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

    BlueBubbles có trong quy trình onboarding tương tác:

    openclaw onboard
    

    Trình hướng dẫn yêu cầu:

    Server URLstringrequired

    Địa chỉ máy chủ BlueBubbles (ví dụ: http://192.168.1.100:1234).

    Passwordstringrequired

    Mật khẩu API từ phần cài đặt BlueBubbles Server.

    Webhook pathstring

    Đường dẫn endpoint webhook.

    DM policystring

    pairing, allowlist, open, hoặc disabled.

    Allow liststring[]

    Số điện thoại, email, hoặc mục tiêu chat.

    Bạn cũng có thể thêm BlueBubbles qua CLI:

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

    Kiểm soát truy cập (DMs + nhóm)

    DMs

    • Mặc định: channels.bluebubbles.dmPolicy = "pairing".
    • Người gửi không xác định nhận mã ghép đôi; tin nhắn bị bỏ qua cho đến khi được phê duyệt (mã hết hạn sau 1 giờ).
    • Phê duyệt qua:
      • openclaw pairing list bluebubbles
      • openclaw pairing approve bluebubbles &lt;CODE&gt;
    • Ghép đôi là cơ chế trao đổi token mặc định. Chi tiết: Ghép đôi

    Groups

    • channels.bluebubbles.groupPolicy = open | allowlist | disabled (mặc định: allowlist).
    • channels.bluebubbles.groupAllowFrom kiểm soát ai có thể kích hoạt trong nhóm khi allowlist được đặt.

    Bổ sung tên liên hệ (macOS, tùy chọn)

    Webhooks nhóm của BlueBubbles thường chỉ bao gồm địa chỉ người tham gia thô. Nếu bạn muốn ngữ cảnh GroupMembers hiển thị tên liên hệ cục bộ thay vào đó, bạn có thể chọn bật bổ sung từ Contacts cục bộ trên macOS:

    • channels.bluebubbles.enrichGroupParticipantsFromContacts = true bật tra cứu. Mặc định: false.
    • Tra cứu chỉ chạy sau khi quyền truy cập nhóm, ủy quyền lệnh, và chặn theo nhắc đến đã cho phép tin nhắn đi qua.
    • Chỉ người tham gia bằng số điện thoại chưa có tên mới được bổ sung.
    • Số điện thoại thô vẫn là phương án dự phòng khi không tìm thấy khớp cục bộ.
    {
      channels: {
        bluebubbles: {
          enrichGroupParticipantsFromContacts: true,
        },
      },
    }
    

    Chặn theo nhắc đến (nhóm)

    BlueBubbles hỗ trợ chặn theo nhắc đến cho chat nhóm, khớp với hành vi iMessage/WhatsApp:

    • Dùng agents.list[].groupChat.mentionPatterns (hoặc messages.groupChat.mentionPatterns) để phát hiện nhắc đến.
    • Khi requireMention được bật cho một nhóm, agent chỉ phản hồi khi được nhắc đến.
    • Lệnh điều khiển từ người gửi được ủy quyền bỏ qua chặn theo nhắc đến.

    Cấu hình theo nhóm:

    {
      channels: {
        bluebubbles: {
          groupPolicy: "allowlist",
          groupAllowFrom: ["+15555550123"],
          groups: {
            "*": { requireMention: true }, // default for all groups
            "iMessage;-;chat123": { requireMention: false }, // override for specific group
          },
        },
      },
    }
    

    Chặn lệnh

    • Lệnh điều khiển (ví dụ: /config, /model) yêu cầu ủy quyền.
    • Dùng allowFromgroupAllowFrom để xác định ủy quyền lệnh.
    • Người gửi được ủy quyền có thể chạy lệnh điều khiển ngay cả khi không nhắc đến trong nhóm.

    System prompt theo nhóm

    Mỗi mục dưới channels.bluebubbles.groups.* chấp nhận chuỗi systemPrompt tùy chọn. Giá trị này được đưa vào system prompt của agent ở mỗi lượt xử lý tin nhắn trong nhóm đó, vì vậy bạn có thể đặt persona hoặc quy tắc hành vi theo nhóm mà không cần chỉnh sửa prompt của agent:

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

    Khóa khớp với bất cứ gì BlueBubbles báo cáo là chatGuid / chatIdentifier / chatId dạng số cho nhóm, và mục wildcard "*" cung cấp mặc định cho mọi nhóm không có khớp chính xác (cùng mẫu được dùng bởi requireMention và chính sách công cụ theo nhóm). Khớp chính xác luôn thắng wildcard. DMs bỏ qua trường này; hãy dùng tùy chỉnh prompt ở cấp agent hoặc cấp tài khoản thay vào đó.

    Ví dụ hoàn chỉnh: trả lời theo luồng và phản ứng tapback (Private API)

    Khi bật BlueBubbles Private API, tin nhắn đầu vào đi kèm ID tin nhắn ngắn (ví dụ [[reply_to:5]]) và agent có thể gọi action=reply để trả lời theo luồng vào một tin nhắn cụ thể hoặc action=react để thả một tapback. systemPrompt theo nhóm là cách đáng tin cậy để giữ agent chọn đúng công cụ:

    {
      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.",
            },
          },
        },
      },
    }
    

    Phản ứng tapback và trả lời theo luồng đều yêu cầu BlueBubbles Private API; xem Hành động nâng caoID tin nhắn để biết cơ chế nền tảng.

    Liên kết cuộc trò chuyện ACP

    Chat BlueBubbles có thể được chuyển thành workspace ACP bền vững mà không thay đổi lớp truyền tải.

    Luồng thao tác nhanh:

    • Chạy /acp spawn codex --bind here bên trong DM hoặc chat nhóm được phép.
    • Các tin nhắn sau này trong cùng cuộc trò chuyện BlueBubbles đó sẽ định tuyến tới phiên ACP đã tạo.
    • /new/reset đặt lại cùng phiên ACP đã liên kết tại chỗ.
    • /acp close đóng phiên ACP và xóa liên kết.

    Liên kết liên tục được cấu hình cũng được hỗ trợ thông qua các mục bindings[] cấp cao nhất với type: "acp"match.channel: "bluebubbles".

    match.peer.id có thể dùng bất kỳ dạng mục tiêu BlueBubbles nào được hỗ trợ:

    • handle DM đã chuẩn hóa như +15555550123 hoặc [email protected]
    • chat_id:<id>
    • chat_guid:<guid>
    • chat_identifier:<identifier>

    Để có các liên kết nhóm ổn định, ưu tiên chat_id:* hoặc chat_identifier:*.

    Ví dụ:

    {
      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" },
        },
      ],
    }
    

    Xem Tác nhân ACP để biết hành vi liên kết ACP dùng chung.

    Đang nhập + biên nhận đã đọc

    • Chỉ báo đang nhập: Được gửi tự động trước và trong khi tạo phản hồi.
    • Biên nhận đã đọc: Được kiểm soát bởi channels.bluebubbles.sendReadReceipts (mặc định: true).
    • Chỉ báo đang nhập: OpenClaw gửi sự kiện bắt đầu nhập; BlueBubbles tự động xóa trạng thái đang nhập khi gửi hoặc hết thời gian chờ (dừng thủ công qua DELETE không đáng tin cậy).
    {
      channels: {
        bluebubbles: {
          sendReadReceipts: false, // disable read receipts
        },
      },
    }
    

    Hành động nâng cao

    BlueBubbles hỗ trợ các hành động tin nhắn nâng cao khi được bật trong cấu hình:

    {
      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
          },
        },
      },
    }
    
    Các hành động có sẵn
    • react: Thêm/xóa phản ứng tapback (messageId, emoji, remove). Bộ tapback gốc của iMessage là love, like, dislike, laugh, emphasizequestion. Khi tác nhân chọn một emoji ngoài bộ đó (ví dụ 👀), công cụ phản ứng sẽ chuyển về love để tapback vẫn hiển thị thay vì làm hỏng toàn bộ yêu cầu. Các phản ứng xác nhận đã cấu hình vẫn được xác thực nghiêm ngặt và báo lỗi với giá trị không xác định.
    • edit: Sửa một tin nhắn đã gửi (messageId, text).
    • unsend: Thu hồi một tin nhắn (messageId).
    • reply: Trả lời một tin nhắn cụ thể (messageId, text, to).
    • sendWithEffect: Gửi với hiệu ứng iMessage (text, to, effectId).
    • renameGroup: Đổi tên một cuộc trò chuyện nhóm (chatGuid, displayName).
    • setGroupIcon: Đặt biểu tượng/ảnh của cuộc trò chuyện nhóm (chatGuid, media) - không ổn định trên macOS 26 Tahoe (API có thể trả về thành công nhưng biểu tượng không đồng bộ).
    • addParticipant: Thêm ai đó vào một nhóm (chatGuid, address).
    • removeParticipant: Xóa ai đó khỏi một nhóm (chatGuid, address).
    • leaveGroup: Rời một cuộc trò chuyện nhóm (chatGuid).
    • upload-file: Gửi phương tiện/tệp (to, buffer, filename, asVoice).
      • Ghi âm thoại: đặt asVoice: true với âm thanh MP3 hoặc CAF để gửi dưới dạng tin nhắn thoại iMessage. BlueBubbles chuyển đổi MP3 → CAF khi gửi ghi âm thoại.
    • Bí danh cũ: sendAttachment vẫn hoạt động, nhưng upload-file là tên hành động chuẩn.

    ID tin nhắn (ngắn so với đầy đủ)

    OpenClaw có thể hiển thị ID tin nhắn ngắn (ví dụ 1, 2) để tiết kiệm token.

    • MessageSid / ReplyToId có thể là ID ngắn.
    • MessageSidFull / ReplyToIdFull chứa ID đầy đủ của nhà cung cấp.
    • ID ngắn nằm trong bộ nhớ; chúng có thể hết hạn khi khởi động lại hoặc khi bộ nhớ đệm bị loại bỏ.
    • Các hành động chấp nhận messageId ngắn hoặc đầy đủ, nhưng ID ngắn sẽ báo lỗi nếu không còn khả dụng.

    Dùng ID đầy đủ cho tự động hóa và lưu trữ bền vững:

    • Mẫu: {{MessageSidFull}}, {{ReplyToIdFull}}
    • Ngữ cảnh: MessageSidFull / ReplyToIdFull trong payload đến

    Xem Cấu hình để biết các biến mẫu.

    Gộp các DM gửi tách (lệnh + URL trong một lần soạn)

    Khi người dùng nhập cùng lúc một lệnh và một URL trong iMessage - ví dụ Dump https://example.com/article - Apple tách lần gửi thành hai lần gửi webhook riêng biệt:

    1. Một tin nhắn văn bản ("Dump").
    2. Một bong bóng xem trước URL ("https://...") với ảnh xem trước OG dưới dạng tệp đính kèm.

    Hai webhook đến OpenClaw cách nhau khoảng 0,8-2,0 giây trên hầu hết thiết lập. Nếu không gộp, tác nhân nhận riêng lệnh ở lượt 1, trả lời (thường là "gửi tôi URL"), và chỉ thấy URL ở lượt 2 - lúc đó ngữ cảnh lệnh đã bị mất.

    channels.bluebubbles.coalesceSameSenderDms chọn một DM để gộp các webhook liên tiếp từ cùng người gửi thành một lượt tác nhân duy nhất. Trò chuyện nhóm vẫn khóa theo từng tin nhắn để giữ nguyên cấu trúc lượt nhiều người dùng.

    Khi nào bật

    Bật khi:

    • Bạn cung cấp skills cần command + payload trong một tin nhắn (dump, paste, save, queue, v.v.).
    • Người dùng của bạn dán URL, hình ảnh hoặc nội dung dài kèm theo lệnh.
    • Bạn có thể chấp nhận độ trễ lượt DM tăng thêm (xem bên dưới).

    Để tắt khi:

    • Bạn cần độ trễ lệnh tối thiểu cho các kích hoạt DM một từ.
    • Tất cả luồng của bạn là lệnh một lần, không có payload theo sau.

    Bật

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

    Khi bật cờ này và không có messages.inbound.byChannel.bluebubbles rõ ràng, cửa sổ debounce mở rộng thành 2500 ms (mặc định cho trường hợp không gộp là 500 ms). Cửa sổ rộng hơn là bắt buộc - nhịp gửi tách của Apple 0,8-2,0 giây không vừa với mặc định chặt hơn.

    Để tự điều chỉnh cửa sổ:

    {
      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,
          },
        },
      },
    }
    

    Đánh đổi

    • Độ trễ tăng thêm cho các lệnh điều khiển DM. Khi bật cờ này, tin nhắn lệnh điều khiển DM (như Dump, Save, v.v.) hiện sẽ chờ tới cửa sổ debounce trước khi điều phối, phòng trường hợp một webhook payload đang đến. Lệnh trong trò chuyện nhóm vẫn được điều phối tức thì.
    • Đầu ra đã gộp có giới hạn - văn bản đã gộp bị giới hạn ở 4000 ký tự với dấu …[truncated] rõ ràng; tệp đính kèm bị giới hạn ở 20; mục nguồn bị giới hạn ở 10 (giữ lại mục đầu tiên cộng với các mục mới nhất sau giới hạn đó). Mỗi messageId nguồn vẫn đi tới bước chống trùng lặp đầu vào, nên lần phát lại MessagePoller sau này của bất kỳ sự kiện riêng lẻ nào cũng được nhận diện là trùng lặp.
    • Chọn bật, theo từng kênh. Các kênh khác (Telegram, WhatsApp, Slack, …) không bị ảnh hưởng.

    Tình huống và những gì tác nhân thấy

    Người dùng soạn Apple gửi Tắt cờ (mặc định) Bật cờ + cửa sổ 2500 ms
    Dump https://example.com (một lần gửi) 2 webhook cách nhau ~1 giây Hai lượt tác nhân: chỉ "Dump", rồi URL Một lượt: văn bản đã gộp Dump https://example.com
    Save this 📎image.jpg caption (tệp đính kèm + văn bản) 2 webhook Hai lượt Một lượt: văn bản + hình ảnh
    /status (lệnh độc lập) 1 webhook Điều phối tức thì Chờ tới cửa sổ, rồi điều phối
    Chỉ dán URL 1 webhook Điều phối tức thì Điều phối tức thì (chỉ một mục trong bucket)
    Văn bản + URL được gửi thành hai tin nhắn riêng có chủ ý, cách nhau vài phút 2 webhook ngoài cửa sổ Hai lượt Hai lượt (cửa sổ hết hạn giữa chúng)
    Gửi dồn nhanh (>10 DM nhỏ trong cửa sổ) N webhook N lượt Một lượt, đầu ra có giới hạn (áp dụng giới hạn đầu + mới nhất, văn bản/tệp đính kèm)

    Khắc phục sự cố gộp gửi tách

    Nếu cờ đã bật nhưng các lần gửi tách vẫn đến thành hai lượt, hãy kiểm tra từng lớp:

    Cấu hình thực sự đã tải
    grep coalesceSameSenderDms ~/.openclaw/openclaw.json
    

    Sau đó openclaw gateway restart - cờ được đọc khi tạo debouncer-registry.

    Cửa sổ debounce đủ rộng cho thiết lập của bạn

    Xem nhật ký máy chủ BlueBubbles tại ~/Library/Logs/bluebubbles-server/main.log:

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

    Đo khoảng cách giữa lần điều phối văn bản kiểu "Dump" và lần điều phối "https://..."; Attachments: theo sau. Tăng messages.inbound.byChannel.bluebubbles để bao phủ thoải mái khoảng cách đó.

    Dấu thời gian JSONL phiên ≠ thời điểm webhook đến

    Dấu thời gian sự kiện phiên (~/.openclaw/agents/<id>/sessions/*.jsonl) phản ánh lúc Gateway chuyển một tin nhắn cho tác nhân, không phải lúc webhook đến. Tin nhắn thứ hai trong hàng đợi được gắn [Queued messages while agent was busy] nghĩa là lượt đầu tiên vẫn đang chạy khi webhook thứ hai đến - bucket gộp đã được xả. Điều chỉnh cửa sổ theo nhật ký máy chủ BB, không phải nhật ký phiên.

    Áp lực bộ nhớ làm chậm điều phối trả lời

    Trên máy nhỏ hơn (8 GB), các lượt tác nhân có thể mất đủ lâu để bucket gộp xả trước khi phản hồi hoàn tất, và URL rơi vào một lượt thứ hai trong hàng đợi. Kiểm tra memory_pressureps -o rss -p $(pgrep openclaw-gateway); nếu Gateway vượt quá ~500 MB RSS và bộ nén đang hoạt động, hãy đóng các tiến trình nặng khác hoặc chuyển sang máy chủ lớn hơn.

    Lần gửi trích dẫn trả lời là một đường đi khác

    Nếu người dùng chạm vào Dump dưới dạng trả lời một bong bóng URL hiện có (iMessage hiển thị huy hiệu "1 Reply" trên bong bóng Dump), URL nằm trong replyToBody, không nằm trong webhook thứ hai. Việc gộp không áp dụng - đó là vấn đề skill/prompt, không phải vấn đề debouncer.

    Truyền phát theo khối

    Kiểm soát việc phản hồi được gửi dưới dạng một tin nhắn duy nhất hay được truyền phát theo các khối:

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

    Phương tiện + giới hạn

    • Tệp đính kèm đầu vào được tải xuống và lưu trong bộ nhớ đệm phương tiện.
    • Giới hạn phương tiện qua channels.bluebubbles.mediaMaxMb cho phương tiện đầu vào và đầu ra (mặc định: 8 MB).
    • Văn bản đầu ra được chia nhỏ theo channels.bluebubbles.textChunkLimit (mặc định: 4000 ký tự).

    Tham chiếu cấu hình

    Cấu hình đầy đủ: Cấu hình

    Kết nối và Webhook
    • channels.bluebubbles.enabled: Bật/tắt kênh.
    • channels.bluebubbles.serverUrl: URL cơ sở của BlueBubbles REST API.
    • channels.bluebubbles.password: Mật khẩu API.
    • channels.bluebubbles.webhookPath: Đường dẫn điểm cuối Webhook (mặc định: /bluebubbles-webhook).
    Chính sách truy cập
    • channels.bluebubbles.dmPolicy: pairing | allowlist | open | disabled (mặc định: pairing).
    • channels.bluebubbles.allowFrom: Danh sách cho phép DM (handle, email, số E.164, chat_id:*, chat_guid:*).
    • channels.bluebubbles.groupPolicy: open | allowlist | disabled (mặc định: allowlist).
    • channels.bluebubbles.groupAllowFrom: Danh sách cho phép người gửi trong nhóm.
    • channels.bluebubbles.enrichGroupParticipantsFromContacts: Trên macOS, tùy chọn bổ sung thông tin cho người tham gia nhóm chưa có tên từ Contacts cục bộ sau khi vượt qua kiểm soát truy cập. Mặc định: false.
    • channels.bluebubbles.groups: Cấu hình theo từng nhóm (requireMention, v.v.).
    Phân phối và chia đoạn
    • channels.bluebubbles.sendReadReceipts: Gửi xác nhận đã đọc (mặc định: true).
    • channels.bluebubbles.blockStreaming: Bật truyền trực tuyến theo khối (mặc định: false; bắt buộc để trả lời dạng streaming).
    • channels.bluebubbles.textChunkLimit: Kích thước đoạn gửi đi tính bằng ký tự (mặc định: 4000).
    • channels.bluebubbles.sendTimeoutMs: Thời gian chờ theo từng yêu cầu tính bằng ms cho việc gửi văn bản đi qua /api/v1/message/text (mặc định: 30000). Tăng giá trị này trên các thiết lập macOS 26 nơi việc gửi iMessage bằng Private API có thể bị kẹt hơn 60 giây bên trong framework iMessage; ví dụ 45000 hoặc 60000. Các phép thăm dò, tra cứu cuộc trò chuyện, phản ứng, chỉnh sửa và kiểm tra tình trạng hiện vẫn giữ mặc định 10 giây ngắn hơn; việc mở rộng phạm vi sang phản ứng và chỉnh sửa được lên kế hoạch cho bước tiếp theo. Ghi đè theo tài khoản: channels.bluebubbles.accounts.<accountId>.sendTimeoutMs.
    • channels.bluebubbles.chunkMode: length (mặc định) chỉ tách khi vượt quá textChunkLimit; newline tách theo dòng trống (ranh giới đoạn văn) trước khi chia đoạn theo độ dài.
    Phương tiện và lịch sử
    • channels.bluebubbles.mediaMaxMb: Giới hạn phương tiện vào/ra tính bằng MB (mặc định: 8).
    • channels.bluebubbles.mediaLocalRoots: Danh sách cho phép rõ ràng các thư mục cục bộ tuyệt đối được phép dùng cho đường dẫn phương tiện cục bộ gửi đi. Gửi bằng đường dẫn cục bộ bị từ chối theo mặc định trừ khi mục này được cấu hình. Ghi đè theo tài khoản: channels.bluebubbles.accounts.<accountId>.mediaLocalRoots.
    • channels.bluebubbles.coalesceSameSenderDms: Gộp các Webhook DM liên tiếp từ cùng một người gửi thành một lượt của agent để thao tác gửi tách văn bản+URL của Apple đến dưới dạng một tin nhắn duy nhất (mặc định: false). Xem Gộp các DM gửi tách để biết các kịch bản, tinh chỉnh cửa sổ và đánh đổi. Khi bật mà không có messages.inbound.byChannel.bluebubbles rõ ràng, mở rộng cửa sổ debounce mặc định cho tin nhắn đến từ 500 ms lên 2500 ms.
    • channels.bluebubbles.historyLimit: Số tin nhắn nhóm tối đa cho ngữ cảnh (0 để tắt).
    • channels.bluebubbles.dmHistoryLimit: Giới hạn lịch sử DM.
    • channels.bluebubbles.replyContextApiFallback: Khi một trả lời đến không có replyToBody/replyToSender và bộ đệm ngữ cảnh trả lời trong bộ nhớ bị miss, tìm nạp tin nhắn gốc từ BlueBubbles HTTP API như một phương án dự phòng nỗ lực tối đa (mặc định: false). Hữu ích cho triển khai nhiều phiên bản dùng chung một tài khoản BlueBubbles, sau khi tiến trình khởi động lại, hoặc sau khi mục trong bộ đệm TTL/LRU tồn tại lâu bị loại bỏ. Lần tìm nạp này được bảo vệ SSRF bằng cùng chính sách như mọi yêu cầu client BlueBubbles khác, không bao giờ throw và điền vào bộ đệm để các trả lời tiếp theo được phân bổ chi phí. Ghi đè theo tài khoản: channels.bluebubbles.accounts.<accountId>.replyContextApiFallback. Thiết lập cấp kênh được truyền sang các tài khoản không đặt cờ này.
    Hành động và tài khoản
    • channels.bluebubbles.actions: Bật/tắt các hành động cụ thể.
    • channels.bluebubbles.accounts: Cấu hình nhiều tài khoản.

    Các tùy chọn toàn cục liên quan:

    • agents.list[].groupChat.mentionPatterns (hoặc messages.groupChat.mentionPatterns).
    • messages.responsePrefix.

    Địa chỉ hóa / mục tiêu phân phối

    Ưu tiên chat_guid để định tuyến ổn định:

    • chat_guid:iMessage;-;+15555550123 (ưu tiên cho nhóm)
    • chat_id:123
    • chat_identifier:...
    • Handle trực tiếp: +15555550123, [email protected]
      • Nếu một handle trực tiếp chưa có cuộc trò chuyện DM hiện có, OpenClaw sẽ tạo một cuộc trò chuyện qua POST /api/v1/chat/new. Việc này yêu cầu bật BlueBubbles Private API.

    Định tuyến iMessage so với SMS

    Khi cùng một handle có cả cuộc trò chuyện iMessage và SMS trên Mac (ví dụ một số điện thoại đã đăng ký iMessage nhưng cũng đã nhận các dự phòng bong bóng xanh), OpenClaw ưu tiên cuộc trò chuyện iMessage và không bao giờ âm thầm hạ cấp xuống SMS. Để buộc dùng cuộc trò chuyện SMS, hãy dùng tiền tố mục tiêu sms: rõ ràng (ví dụ sms:+15555550123). Các handle không có cuộc trò chuyện iMessage khớp vẫn sẽ gửi qua bất kỳ cuộc trò chuyện nào BlueBubbles báo cáo.

    Bảo mật

    • Các yêu cầu Webhook được xác thực bằng cách so sánh tham số truy vấn hoặc header guid/password với channels.bluebubbles.password.
    • Giữ bí mật mật khẩu API và điểm cuối Webhook (xem chúng như thông tin xác thực).
    • Không có cơ chế bỏ qua xác thực BlueBubbles Webhook cho localhost. Nếu bạn proxy lưu lượng Webhook, hãy giữ mật khẩu BlueBubbles trên yêu cầu từ đầu đến cuối. gateway.trustedProxies không thay thế channels.bluebubbles.password ở đây. Xem Bảo mật Gateway.
    • Bật HTTPS + quy tắc tường lửa trên máy chủ BlueBubbles nếu để lộ nó ra ngoài LAN.

    Khắc phục sự cố

    • Nếu sự kiện nhập/xác nhận đọc ngừng hoạt động, hãy kiểm tra nhật ký Webhook của BlueBubbles và xác minh đường dẫn gateway khớp với channels.bluebubbles.webhookPath.
    • Mã ghép đôi hết hạn sau một giờ; dùng openclaw pairing list bluebubblesopenclaw pairing approve bluebubbles <code>.
    • Phản ứng yêu cầu BlueBubbles private API (POST /api/v1/message/react); hãy đảm bảo phiên bản máy chủ cung cấp API này.
    • Chỉnh sửa/thu hồi yêu cầu macOS 13+ và phiên bản máy chủ BlueBubbles tương thích. Trên macOS 26 (Tahoe), chỉnh sửa hiện bị hỏng do các thay đổi trong private API.
    • Cập nhật biểu tượng nhóm có thể không ổn định trên macOS 26 (Tahoe): API có thể trả về thành công nhưng biểu tượng mới không đồng bộ.
    • OpenClaw tự động ẩn các hành động đã biết là bị hỏng dựa trên phiên bản macOS của máy chủ BlueBubbles. Nếu chỉnh sửa vẫn xuất hiện trên macOS 26 (Tahoe), hãy tắt thủ công bằng channels.bluebubbles.actions.edit=false.
    • coalesceSameSenderDms đã bật nhưng các lượt gửi tách (ví dụ Dump + URL) vẫn đến thành hai lượt: xem danh sách kiểm tra khắc phục sự cố gộp lượt gửi tách - nguyên nhân phổ biến là cửa sổ debounce quá chặt, dấu thời gian nhật ký phiên bị đọc nhầm là thời điểm Webhook đến, hoặc một lần gửi trích dẫn trả lời (dùng replyToBody, không phải Webhook thứ hai).
    • Để xem thông tin trạng thái/tình trạng: openclaw status --all hoặc openclaw status --deep.

    Để tham khảo quy trình kênh chung, xem Kênh và hướng dẫn Plugins.

    Liên quan