Mainstream messaging
Migracja z BlueBubbles
Dołączony Plugin imessage sięga teraz do tego samego zakresu prywatnego API co BlueBubbles (react, edit, unsend, reply, sendWithEffect, zarządzanie grupami, załączniki), sterując steipete/imsg przez JSON-RPC. Jeśli masz już Maca z zainstalowanym imsg, możesz zrezygnować z serwera BlueBubbles i pozwolić Pluginowi komunikować się bezpośrednio z Messages.app.
Obsługa BlueBubbles została usunięta. OpenClaw obsługuje iMessage wyłącznie przez imsg. Ten przewodnik służy do migracji starych konfiguracji channels.bluebubbles do channels.imessage; nie ma innej obsługiwanej ścieżki migracji.
Lista kontrolna migracji
Użyj tej listy kontrolnej, jeśli znasz już swoją starą konfigurację BlueBubbles i chcesz wybrać najkrótszą bezpieczną ścieżkę:
- Zweryfikuj
imsgbezpośrednio na Macu, na którym działa Messages.app (imsg chats,imsg history,imsg sendiimsg rpc --help). - Skopiuj klucze zachowania z
channels.bluebubblesdochannels.imessage:dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,includeAttachments,attachmentRoots,mediaMaxMb,textChunkLimit,coalesceSameSenderDmsiactions. - Usuń klucze transportu, które już nie istnieją:
serverUrl,password, adresy URL Webhook oraz konfigurację serwera BlueBubbles. - Jeśli Gateway nie działa na Macu z Messages, ustaw
channels.imessage.cliPathna opakowanie SSH i ustawremoteHostdla zdalnego pobierania załączników. - Przy zatrzymanym Gateway włącz
channels.imessage, a następnie uruchomopenclaw channels status --probe --channel imessage. - Przetestuj jedną wiadomość DM, jedną dozwoloną grupę, załączniki, jeśli są włączone, oraz każdą akcję prywatnego API, której agent ma używać.
- Usuń serwer BlueBubbles i starą konfigurację
channels.bluebubblespo zweryfikowaniu ścieżki iMessage.
Kiedy ta migracja ma sens
- Masz już uruchomione
imsgna tym samym Macu (albo na dostępnym przez SSH), na którym Messages.app jest zalogowane. - Chcesz mieć o jeden element mniej do utrzymania — bez oddzielnego serwera BlueBubbles, bez punktu końcowego REST do uwierzytelniania, bez instalacji Webhook. Pojedynczy plik binarny CLI zamiast serwera + aplikacji klienckiej + pomocnika.
- Korzystasz z obsługiwanej wersji macOS / kompilacji
imsg, w której sonda prywatnego API zgłaszaavailable: true.
Co robi imsg
imsg to lokalne CLI macOS dla Messages. OpenClaw uruchamia imsg rpc jako proces potomny i komunikuje się przez JSON-RPC na stdin/stdout. Nie ma serwera HTTP, adresu URL Webhook, demona w tle, agenta uruchamiania ani portu do wystawienia.
- Odczyty pochodzą z
~/Library/Messages/chat.dbprzy użyciu uchwytu SQLite tylko do odczytu. - Przychodzące wiadomości na żywo pochodzą z
imsg watch/watch.subscribe, które śledzi zdarzenia systemu plikówchat.dbz awaryjnym odpytywaniem. - Wysyłanie używa automatyzacji Messages.app dla zwykłego tekstu i wysyłania plików.
- Zaawansowane akcje używają
imsg launch, aby wstrzyknąć pomocnikaimsgdo Messages.app. To odblokowuje potwierdzenia odczytu, wskaźniki pisania, bogate wysyłki, edycję, cofanie wysłania, odpowiedź w wątku, tapbacki i zarządzanie grupami. - Kompilacje dla Linux mogą sprawdzać skopiowany
chat.db, ale nie mogą wysyłać, obserwować aktywnej bazy danych Maca ani sterować Messages.app. Dla iMessage w OpenClaw uruchomimsgna zalogowanym Macu albo przez opakowanie SSH do tego Maca.
Zanim zaczniesz
-
Zainstaluj
imsgna Macu, na którym działa Messages.app:brew install steipete/tap/imsg imsg --version imsg chats --limit 3Jeśli
imsg chatskończy się błędemunable to open database file, pustym wyjściem alboauthorization denied, przyznaj pełny dostęp do dysku terminalowi, edytorowi, procesowi Node, usłudze Gateway albo procesowi nadrzędnemu SSH uruchamiającemuimsg, a następnie ponownie otwórz ten proces nadrzędny. -
Zweryfikuj odczyt, obserwowanie, wysyłanie i powierzchnie RPC przed zmianą konfiguracji OpenClaw:
imsg chats --limit 10 --json | jq -s imsg history --chat-id 42 --limit 10 --attachments --json | jq -s imsg watch --chat-id 42 --reactions --json imsg send --chat-id 42 --text "OpenClaw imsg test" imsg rpc --helpZastąp
42rzeczywistym identyfikatorem czatu zimsg chats. Wysyłanie wymaga uprawnienia automatyzacji dla Messages.app. Jeśli OpenClaw będzie działać przez SSH, uruchom te polecenia przez to samo opakowanie SSH lub w tym samym kontekście użytkownika, którego będzie używać OpenClaw. -
Włącz most prywatnego API, gdy potrzebujesz zaawansowanych akcji:
imsg launch imsg status --jsonimsg launchwymaga wyłączenia SIP. Podstawowe wysyłanie, historia i obserwowanie działają bezimsg launch; zaawansowane akcje nie działają. -
Po dodaniu włączonej konfiguracji
channels.imessagezweryfikuj most przez OpenClaw:openclaw channels status --probeOczekiwany wynik to
imessage.privateApi.available: true. Jeśli zgłaszafalse, najpierw to napraw — zobacz Wykrywanie możliwości.channels status --probesonduje tylko skonfigurowane, włączone konta. -
Utwórz migawkę konfiguracji:
cp ~/.openclaw/openclaw.json5 ~/.openclaw/openclaw.json5.bak
Tłumaczenie konfiguracji
iMessage i BlueBubbles współdzielą wiele konfiguracji na poziomie kanału. Klucze, które się zmieniają, dotyczą głównie transportu (serwer REST kontra lokalne CLI). Klucze zachowania (dmPolicy, groupPolicy, allowFrom itd.) zachowują to samo znaczenie.
| BlueBubbles | dołączony iMessage | Uwagi |
|---|---|---|
channels.bluebubbles.enabled |
channels.imessage.enabled |
Ta sama semantyka. |
channels.bluebubbles.serverUrl |
(usunięte) | Brak serwera REST — plugin uruchamia imsg rpc przez stdio. |
channels.bluebubbles.password |
(usunięte) | Uwierzytelnianie webhooka nie jest potrzebne. |
| (niejawne) | channels.imessage.cliPath |
Ścieżka do imsg (domyślnie imsg); dla SSH użyj skryptu opakowującego. |
| (niejawne) | channels.imessage.dbPath |
Opcjonalne nadpisanie chat.db z Messages.app; wykrywane automatycznie, gdy pominięte. |
| (niejawne) | channels.imessage.remoteHost |
host albo user@host — potrzebne tylko wtedy, gdy cliPath jest skryptem opakowującym SSH i chcesz pobierać załączniki przez SCP. |
channels.bluebubbles.dmPolicy |
channels.imessage.dmPolicy |
Te same wartości (pairing / allowlist / open / disabled). |
channels.bluebubbles.allowFrom |
channels.imessage.allowFrom |
Zatwierdzenia parowania są przenoszone według uchwytu, nie według tokena. |
channels.bluebubbles.groupPolicy |
channels.imessage.groupPolicy |
Te same wartości (allowlist / open / disabled). |
channels.bluebubbles.groupAllowFrom |
channels.imessage.groupAllowFrom |
Tak samo. |
channels.bluebubbles.groups |
channels.imessage.groups |
Skopiuj to dosłownie, łącznie z dowolnym wpisem wieloznacznym groups: { "*": { ... } }. Ustawienia dla grup requireMention, tools, toolsBySender są przenoszone. Przy groupPolicy: "allowlist" pusty lub brakujący blok groups po cichu odrzuca każdą wiadomość grupową — zobacz „Pułapka rejestru grup” poniżej. |
channels.bluebubbles.sendReadReceipts |
channels.imessage.sendReadReceipts |
Domyślnie true. W dołączonym pluginie działa to tylko wtedy, gdy działa sonda prywatnego API. |
channels.bluebubbles.includeAttachments |
channels.imessage.includeAttachments |
Ten sam kształt, tak samo domyślnie wyłączone. Jeśli w BlueBubbles załączniki były przesyłane, musisz jawnie ustawić to ponownie w bloku iMessage — nie jest przenoszone niejawnie, a przychodzące zdjęcia/media będą po cichu odrzucane bez wiersza dziennika Inbound message, dopóki tego nie zrobisz. |
channels.bluebubbles.attachmentRoots |
channels.imessage.attachmentRoots |
Lokalne katalogi główne; te same reguły wieloznaczne. |
| (nie dotyczy) | channels.imessage.remoteAttachmentRoots |
Używane tylko wtedy, gdy ustawiono remoteHost dla pobrań przez SCP. |
channels.bluebubbles.mediaMaxMb |
channels.imessage.mediaMaxMb |
Domyślnie 16 MB w iMessage (domyślna wartość BlueBubbles wynosiła 8 MB). Ustaw jawnie, jeśli chcesz zachować niższy limit. |
channels.bluebubbles.textChunkLimit |
channels.imessage.textChunkLimit |
Domyślnie 4000 w obu. |
channels.bluebubbles.coalesceSameSenderDms |
channels.imessage.coalesceSameSenderDms |
To samo ustawienie opt-in. Tylko dla DM — czaty grupowe zachowują natychmiastową wysyłkę każdej wiadomości w obu kanałach. Gdy włączone bez jawnego messages.inbound.byChannel.imessage, rozszerza domyślny debounce przychodzący do 2500 ms. Zobacz dokumentację iMessage § Scalanie dzielonych wysyłek DM. |
channels.bluebubbles.enrichGroupParticipantsFromContacts |
(nie dotyczy) | iMessage już odczytuje wyświetlane nazwy nadawców z chat.db. |
channels.bluebubbles.actions.* |
channels.imessage.actions.* |
Przełączniki dla poszczególnych akcji: reactions, edit, unsend, reply, sendWithEffect, renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup, sendAttachment. |
Konfiguracje wielu kont (channels.bluebubbles.accounts.*) tłumaczą się jeden do jednego na channels.imessage.accounts.*.
Pułapka rejestru grup
Dołączony plugin iMessage uruchamia dwie osobne bramki listy dozwolonych grup jedna po drugiej. Obie muszą przejść, aby wiadomość grupowa dotarła do agenta:
- Lista dozwolonych nadawców / celów czatu (
channels.imessage.groupAllowFrom) — sprawdzana przezisAllowedIMessageSender. Dopasowuje wiadomości przychodzące według uchwytu nadawcy,chat_guid,chat_identifieralbochat_id. Ten sam kształt co w BlueBubbles. - Rejestr grup (
channels.imessage.groups) — sprawdzany przezresolveChannelGroupPolicyzinbound-processing.ts:199. PrzygroupPolicy: "allowlist"ta bramka wymaga jednego z poniższych:- wpisu wieloznacznego
groups: { "*": { ... } }(ustawiaallowAll = true), albo - jawnego wpisu dla danego
chat_idwgroups.
- wpisu wieloznacznego
Jeśli bramka 1 przejdzie, ale bramka 2 nie, wiadomość zostaje odrzucona. Plugin emituje dwa sygnały na poziomie warn, więc nie jest to już ciche przy domyślnym poziomie logowania:
- Jednorazowe początkowe
warnna konto, gdy ustawionogroupPolicy: "allowlist", alechannels.imessage.groupsjest puste (brak wieloznacznika"*", brak wpisów dla poszczególnychchat_id) — uruchamiane zanim dotrą jakiekolwiek wiadomości. - Jednorazowe
warndla danegochat_idprzy pierwszym odrzuceniu konkretnej grupy w czasie działania, z nazwą chat_id i dokładnym kluczem do dodania wgroups, aby ją dopuścić.
DM nadal działają, ponieważ korzystają z innej ścieżki kodu.
To najczęstszy tryb awarii migracji BlueBubbles → dołączony iMessage: operatorzy kopiują groupAllowFrom i groupPolicy, ale pomijają blok groups, ponieważ groups: { "*": { "requireMention": true } } z BlueBubbles wygląda jak niepowiązane ustawienie wzmianki. W rzeczywistości jest kluczowe dla bramki rejestru.
Minimalna konfiguracja, aby wiadomości grupowe nadal przepływały po groupPolicy: "allowlist":
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123", "chat_guid:any;-;..."],
groups: {
"*": { requireMention: true },
},
},
},
}
requireMention: true pod * jest nieszkodliwe, gdy nie skonfigurowano wzorców wzmianek: runtime ustawia canDetectMention = false i pomija odrzucanie wzmianek w inbound-processing.ts:512. Po skonfigurowaniu wzorców wzmianek (agents.list[].groupChat.mentionPatterns) działa zgodnie z oczekiwaniami.
Jeśli logi gatewaya zawierają imessage: dropping group message from chat_id=<id> albo wiersz startowy imessage: groupPolicy="allowlist" but channels.imessage.groups is empty, odrzuca bramka 2 — dodaj blok groups.
Krok po kroku
-
Dodaj blok iMessage obok istniejącego bloku BlueBubbles. Pozostaw go wyłączonego, gdy Gateway nadal kieruje ruch BlueBubbles:
{ channels: { bluebubbles: { enabled: true, // ... existing config ... }, imessage: { enabled: false, cliPath: "/opt/homebrew/bin/imsg", dmPolicy: "pairing", allowFrom: ["+15555550123"], // copy from bluebubbles.allowFrom groupPolicy: "allowlist", groupAllowFrom: [], // copy from bluebubbles.groupAllowFrom groups: { "*": { requireMention: true } }, // copy from bluebubbles.groups — silently drops groups if missing, see "Group registry footgun" above actions: { reactions: true, edit: true, unsend: true, reply: true, sendWithEffect: true, sendAttachment: true, }, }, }, } -
Sprawdź sondą, zanim ruch będzie istotny — zatrzymaj Gateway, tymczasowo włącz blok iMessage i potwierdź z poziomu CLI, że iMessage zgłasza stan prawidłowy:
openclaw gateway stop # edit config: channels.imessage.enabled = true openclaw channels status --probe --channel imessage # expect imessage.privateApi.available: truechannels status --probesprawdza sondą tylko skonfigurowane, włączone konta. Nie restartuj Gateway z włączonymi jednocześnie BlueBubbles i iMessage, chyba że celowo chcesz uruchomić oba monitory kanałów. Jeśli nie przełączasz ruchu natychmiast, przed restartem Gateway ustawchannels.imessage.enabledz powrotem nafalse. Użyj bezpośrednich poleceńimsgz sekcji Zanim zaczniesz, aby zweryfikować Maca przed włączeniem ruchu OpenClaw. -
Przełącz ruch. Gdy włączone konto iMessage zgłasza stan prawidłowy, usuń konfigurację BlueBubbles i pozostaw iMessage włączone:
{ channels: { imessage: { enabled: true /* ... */ }, }, }Zrestartuj Gateway. Ruch przychodzący iMessage przepływa teraz przez dołączony Plugin.
-
Zweryfikuj wiadomości prywatne. Wyślij agentowi wiadomość bezpośrednią; potwierdź, że odpowiedź dochodzi.
-
Zweryfikuj grupy osobno. Wiadomości prywatne i grupy korzystają z różnych ścieżek kodu — powodzenie wiadomości prywatnych nie dowodzi, że grupy są routowane. Wyślij agentowi wiadomość w sparowanym czacie grupowym i potwierdź, że odpowiedź dochodzi. Jeśli grupa milknie (brak odpowiedzi agenta, brak błędu), sprawdź log gatewaya pod kątem
imessage: dropping group message from chat_id=<id>albo startowego wierszaimessage: groupPolicy="allowlist" but channels.imessage.groups is empty— oba pojawiają się na domyślnym poziomie logowania. Jeśli którykolwiek się pojawi, blokgroupsjest brakujący albo pusty — zobacz „Group registry footgun” powyżej. -
Zweryfikuj powierzchnię akcji — ze sparowanej wiadomości prywatnej poproś agenta o reakcję, edycję, cofnięcie wysłania, odpowiedź, wysłanie zdjęcia oraz (w grupie) zmianę nazwy grupy / dodanie albo usunięcie uczestnika. Każda akcja powinna natywnie pojawić się w Messages.app. Jeśli dowolna zgłasza „iMessage
<action>requires the imsg private API bridge”, uruchom ponownieimsg launchi odświeżchannels status --probe. -
Usuń serwer i konfigurację BlueBubbles, gdy wiadomości prywatne iMessage, grupy oraz akcje zostaną zweryfikowane. OpenClaw nie będzie używać
channels.bluebubbles.
Szybki przegląd parytetu akcji
| Akcja | starsze BlueBubbles | dołączone iMessage |
|---|---|---|
| Wysyłanie tekstu / awaryjne użycie SMS | ✅ | ✅ |
| Wysyłanie multimediów (zdjęcie, wideo, plik, głos) | ✅ | ✅ |
Odpowiedź w wątku (reply_to_guid) |
✅ | ✅ (zamyka #51892) |
Tapback (react) |
✅ | ✅ |
| Edycja / cofnięcie wysłania (odbiorcy macOS 13+) | ✅ | ✅ |
| Wysyłanie z efektem ekranowym | ✅ | ✅ (zamyka część #9394) |
| Tekst sformatowany: pogrubienie / kursywa / podkreślenie / przekreślenie | ✅ | ✅ (formatowanie przebiegów typograficznych przez attributedBody) |
| Zmiana nazwy grupy / ustawienie ikony grupy | ✅ | ✅ |
| Dodanie / usunięcie uczestnika, opuszczenie grupy | ✅ | ✅ |
| Potwierdzenia odczytu i wskaźnik pisania | ✅ | ✅ (uzależnione od sondy prywatnego API) |
| Scalanie wiadomości prywatnych od tego samego nadawcy | ✅ | ✅ (tylko wiadomości prywatne; opcjonalnie przez channels.imessage.coalesceSameSenderDms) |
| Nadrabianie wiadomości przychodzących odebranych, gdy gateway był wyłączony | ✅ (odtworzenie webhooka + pobranie historii) | ✅ (opcjonalnie przez channels.imessage.catchup.enabled; zamyka #78649) |
Nadrabianie zaległych wiadomości iMessage jest teraz dostępne jako funkcja opcjonalna w dołączonym Plugin. Przy starcie gatewaya, jeśli channels.imessage.catchup.enabled ma wartość true, gateway wykonuje jedno przejście chats.list + messages.history na czat wobec tego samego klienta JSON-RPC używanego przez imsg watch, odtwarza każdy pominięty wiersz przychodzący przez aktywną ścieżkę wysyłki (listy dozwolonych, politykę grup, debouncer, pamięć podręczną echo) i utrwala kursor per konto, aby kolejne uruchomienia zaczynały od miejsca, w którym poprzednio skończyły. Zobacz Nadrabianie po przestoju gatewaya, aby dostroić ustawienia.
Parowanie, sesje i powiązania ACP
- Zatwierdzenia parowania przenoszą się według uchwytu. Nie musisz ponownie zatwierdzać znanych nadawców —
channels.imessage.allowFromrozpoznaje te same ciągi+15555550123/user@example.com, których używało BlueBubbles. - Sesje pozostają zakresowane per agent + czat. Wiadomości prywatne zwijają się do głównej sesji agenta przy domyślnym
session.dmScope=main; sesje grup pozostają izolowane perchat_id. Klucze sesji różnią się (agent:<id>:imessage:group:<chat_id>kontra odpowiednik BlueBubbles) — stara historia rozmów pod kluczami sesji BlueBubbles nie przechodzi do sesji iMessage. - Powiązania ACP odwołujące się do
match.channel: "bluebubbles"trzeba zaktualizować do"imessage". Kształtymatch.peer.id(chat_id:,chat_guid:,chat_identifier:, sam uchwyt) są identyczne.
Brak kanału wycofania
Nie ma obsługiwanego runtime BlueBubbles, na który można się przełączyć z powrotem. Jeśli weryfikacja iMessage się nie powiedzie, ustaw channels.imessage.enabled: false, zrestartuj Gateway, napraw blokadę imsg i ponów przełączenie.
Pamięć podręczna odpowiedzi znajduje się w ~/.openclaw/state/imessage/reply-cache.jsonl (tryb 0600, katalog nadrzędny 0700). Można ją bezpiecznie usunąć, jeśli chcesz zacząć od czystego stanu.
Powiązane
- Usunięcie BlueBubbles i ścieżka iMessage przez imsg — krótkie ogłoszenie i podsumowanie dla operatora.
- iMessage — pełna dokumentacja kanału iMessage, w tym konfiguracja
imsg launchi wykrywanie możliwości. /channels/bluebubbles— starszy URL, który przekierowuje do tego przewodnika migracji.- Parowanie — uwierzytelnianie wiadomości prywatnych i przepływ parowania.
- Routing kanałów — jak gateway wybiera kanał dla odpowiedzi wychodzących.