imessage uzyskuje teraz dostęp do tej samej powierzchni 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 rozmawiać 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.
Krótkie ogłoszenie i podsumowanie dla operatora znajdziesz w Usunięcie BlueBubbles i ścieżka imsg dla iMessage.
Lista kontrolna migracji
Użyj tej listy kontrolnej, gdy 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 sendorazimsg 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 wrapper 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 (lub na takim, do którego można dotrzeć przez SSH), na którym zalogowano Messages.app. - Chcesz mieć o jeden element mniej — bez osobnego serwera BlueBubbles, bez punktu końcowego REST do uwierzytelniania, bez instalacji Webhook. Jeden binarny plik CLI zamiast serwera + aplikacji klienckiej + pomocnika.
- Używasz obsługiwanej wersji macOS / kompilacji
imsg, w której sonda prywatnego API zwracaavailable: true.
Co robi imsg
imsg to lokalne CLI macOS dla Messages. OpenClaw uruchamia imsg rpc jako proces potomny i komunikuje się przez JSON-RPC po stdin/stdout. Nie ma serwera HTTP, adresu URL Webhook, demona w tle, agenta uruchomieniowego ani portu do wystawienia.
- Odczyty pochodzą z
~/Library/Messages/chat.dbprzy użyciu uchwytu SQLite tylko do odczytu. - Wiadomości przychodzące 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ę, cofnięcie wysłania, odpowiedź w wątku, tapbacki i zarządzanie grupami. - Kompilacje dla Linuksa mogą sprawdzać skopiowane
chat.db, ale nie mogą wysyłać, obserwować żywej bazy danych Maca ani sterować Messages.app. Dla iMessage w OpenClaw uruchamiajimsgna zalogowanym Macu albo przez wrapper SSH do tego Maca.
Zanim zaczniesz
-
Zainstaluj
imsgna Macu, na którym działa Messages.app:Jeśliimsg 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, który uruchamiaimsg, a następnie ponownie otwórz ten proces nadrzędny. -
Zweryfikuj powierzchnie odczytu, obserwacji, wysyłania i RPC przed zmianą konfiguracji OpenClaw:
Zastąp
42rzeczywistym identyfikatorem czatu zimsg chats. Wysyłanie wymaga uprawnienia Automation dla Messages.app. Jeśli OpenClaw będzie działać przez SSH, uruchom te polecenia przez ten sam wrapper SSH lub kontekst użytkownika, którego będzie używać OpenClaw. Jeśli odczyty/sondy działają, ale wysyłanie kończy się błędem AppleEvents-1743, sprawdź, czy Automation trafiło na/usr/libexec/sshd-keygen-wrapper; zobacz Wysyłanie przez wrapper SSH kończy się błędem AppleEvents -1743. -
Włącz most prywatnego API, gdy potrzebujesz zaawansowanych akcji:
imsg launchwymaga wyłączenia SIP. Podstawowe wysyłanie, historia i obserwacja działają bezimsg launch; zaawansowane akcje nie działają. -
Po dodaniu włączonej konfiguracji
channels.imessagezweryfikuj most przez OpenClaw:Oczekiwany wynik toimessage.privateApi.available: true. Jeśli zwracafalse, najpierw to napraw — zobacz Wykrywanie możliwości.channels status --probesprawdza tylko skonfigurowane, włączone konta. -
Zrób snapshot konfiguracji:
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ęto) | Brak serwera REST — Plugin uruchamia imsg rpc przez stdio. |
channels.bluebubbles.password | (usunięto) | Uwierzytelnianie webhooka nie jest potrzebne. |
| (domyślne) | channels.imessage.cliPath | Ścieżka do imsg (domyślnie imsg); użyj skryptu opakowującego dla SSH. |
| (domyślne) | channels.imessage.dbPath | Opcjonalne nadpisanie Messages.app chat.db; wykrywane automatycznie, gdy pominięte. |
| (domyślne) | channels.imessage.remoteHost | host lub 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 przenoszą się według uchwytu, nie według tokenu. |
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, w tym każdy wpis wieloznaczny groups: { "*": { ... } }. Ustawienia dla grup requireMention, tools, toolsBySender przenoszą się. 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 sonda prywatnego API jest uruchomiona. |
channels.bluebubbles.includeAttachments | channels.imessage.includeAttachments | Ten sam kształt, tak samo domyślnie wyłączone. Jeśli załączniki przepływały w BlueBubbles, musisz jawnie ustawić to ponownie w bloku iMessage — nie przenosi się to domyślnie, a przychodzące zdjęcia/multimedia 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 symboli wieloznacznych. |
| (nie dotyczy) | channels.imessage.remoteAttachmentRoots | Używane tylko wtedy, gdy ustawiono remoteHost na potrzeby pobierania przez SCP. |
channels.bluebubbles.mediaMaxMb | channels.imessage.mediaMaxMb | Domyślnie 16 MB w iMessage (domyślną wartością BlueBubbles było 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 opcjonalne. Tylko DM — czaty grupowe zachowują natychmiastowe wysyłanie każdej wiadomości w obu kanałach. Gdy włączone bez jawnego messages.inbound.byChannel.imessage lub globalnego messages.inbound.debounceMs, rozszerza domyślne opóźnienie przychodzące do 7000 ms. Zobacz dokumentację iMessage § Scalanie wiadomości DM wysyłanych w częściach. |
channels.bluebubbles.enrichGroupParticipantsFromContacts | (nie dotyczy) | iMessage już odczytuje nazwy wyświetlane 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. |
channels.bluebubbles.accounts.*) mapują 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ą przepuścić wiadomość, 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_identifierlubchat_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), lub - jawnego wpisu dla danego
chat_idwgroups.
- wpisu wieloznacznego
warn, więc na domyślnym poziomie dziennika nie jest to już ciche:
- Jednorazowy startowy sygnał
warndla każdego konta, gdy ustawionogroupPolicy: "allowlist", alechannels.imessage.groupsjest puste (brak symbolu wieloznacznego"*", brak wpisów dla poszczególnychchat_id) — wyzwalany przed nadejściem jakichkolwiek wiadomości. - Jednorazowy sygnał
warndla każdegochat_id, gdy konkretna grupa zostaje odrzucona po raz pierwszy w czasie działania, z nazwąchat_idi dokładnym kluczem, który trzeba dodać dogroups, aby ją dopuścić.
groupAllowFrom i groupPolicy, ale pomijają blok groups, ponieważ groups: { "*": { "requireMention": true } } w BlueBubbles wygląda jak niepowiązane ustawienie wzmianki. W rzeczywistości jest kluczowy dla bramki rejestru.
Minimalna konfiguracja, aby wiadomości grupowe nadal przepływały po groupPolicy: "allowlist":
requireMention: true pod * jest nieszkodliwe, gdy nie skonfigurowano wzorców wzmianek: runtime ustawia canDetectMention = false i skraca odrzucanie wzmianki w inbound-processing.ts:512. Ze skonfigurowanymi wzorcami wzmianek (agents.list[].groupChat.mentionPatterns) działa zgodnie z oczekiwaniami.
Jeśli logi Gateway pokazują 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, dopóki Gateway nadal kieruje ruch BlueBubbles:
-
Sprawdź, zanim ruch zacznie mieć znaczenie — zatrzymaj Gateway, tymczasowo włącz blok iMessage i potwierdź z CLI, że iMessage zgłasza stan zdrowy:
channels status --probesprawdza tylko skonfigurowane, włączone konta. Nie uruchamiaj ponownie Gateway z jednocześnie włączonymi BlueBubbles i iMessage, chyba że celowo chcesz, aby działały oba monitory kanałów. Jeśli nie przełączasz się natychmiast, ustawchannels.imessage.enabledz powrotem nafalseprzed ponownym uruchomieniem Gateway. Użyj bezpośrednich poleceńimsgz sekcji Zanim zaczniesz, aby zweryfikować Maca przed włączeniem ruchu OpenClaw. -
Przełącz. Gdy włączone konto iMessage zgłasza stan zdrowy, usuń konfigurację BlueBubbles i pozostaw iMessage włączony:
Uruchom ponownie gateway. Ruch przychodzący iMessage przepływa teraz przez wbudowany plugin.
- Zweryfikuj DM-y. Wyślij agentowi wiadomość bezpośrednią; potwierdź, że odpowiedź dotarła.
-
Zweryfikuj grupy osobno. DM-y i grupy korzystają z różnych ścieżek kodu — powodzenie DM nie dowodzi, że grupy są routowane. Wyślij agentowi wiadomość w sparowanym czacie grupowym i potwierdź, że odpowiedź dotarła. Jeśli grupa zamilknie (brak odpowiedzi agenta, brak błędu), sprawdź log Gateway pod kątem
imessage: dropping group message from chat_id=<id>albo wiersza startowegoimessage: groupPolicy="allowlist" but channels.imessage.groups is empty— oba pojawiają się na domyślnym poziomie logowania. Jeśli pojawi się którykolwiek, brakuje blokugroupsalbo jest pusty — zobacz „Pułapka rejestru grup” powyżej. -
Zweryfikuj powierzchnię akcji — ze sparowanego DM poproś agenta, aby zareagował, edytował, cofnął wysłanie, odpowiedział, wysłał zdjęcie oraz (w grupie) zmienił nazwę grupy / dodał lub usunął uczestnika. Każda akcja powinna trafić natywnie do Messages.app. Jeśli jakakolwiek zgłosi „iMessage
<action>requires the imsg private API bridge”, uruchom ponownieimsg launchi odświeżchannels status --probe. -
Usuń serwer i konfigurację BlueBubbles, gdy DM-y, grupy i akcje iMessage zostaną zweryfikowane. OpenClaw nie użyje
channels.bluebubbles.
Szybki przegląd zgodności akcji
| Akcja | starszy BlueBubbles | wbudowany iMessage |
|---|---|---|
| Wysyłanie tekstu / fallback 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 typed-run przez attributedBody) |
| Zmiana nazwy grupy / ustawienie ikony grupy | ✅ | ✅ |
| Dodanie / usunięcie uczestnika, opuszczenie grupy | ✅ | ✅ |
| Potwierdzenia odczytu i wskaźnik pisania | ✅ | ✅ (bramkowane sprawdzeniem prywatnego API) |
| Scalanie DM od tego samego nadawcy | ✅ | ✅ (tylko DM; opt-in przez channels.imessage.coalesceSameSenderDms) |
| Odzyskiwanie przychodzących po restarcie | ✅ (powtórka Webhook + pobieranie historii) | ✅ (automatyczne: powtórka pominiętych przez since_rowid + dedupe; szersze okno lokalnie) |
imsg watch.subscribe since_rowid i deduplikuje po GUID, a ograniczenie wieku starych zaległości tłumi „bombę zaległości” Push-flush. Działa to przez połączenie RPC imsg, więc działa również dla zdalnych konfiguracji SSH cliPath; konfiguracje lokalne dostają szersze okno odzyskiwania, ponieważ mogą czytać chat.db. Zobacz Odzyskiwanie przychodzących po restarcie mostka lub gateway.
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ł BlueBubbles. - Sesje pozostają zakresowane według agent + czat. DM-y zwijają się do głównej sesji agenta przy domyślnym
session.dmScope=main; sesje grupowe pozostają izolowane wedługchat_id. Klucze sesji różnią się (agent:<id>:imessage:group:<chat_id>vs odpowiednik BlueBubbles) — stara historia rozmów pod kluczami sesji BlueBubbles nie przenosi się 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:, goły 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, ustawchannels.imessage.enabled: false, uruchom ponownie Gateway, napraw blokadę imsg i ponów przełączenie.
Pamięć podręczna odpowiedzi znajduje się w stanie pluginu SQLite. openclaw doctor --fix importuje i archiwizuje stary sidecar imessage/reply-cache.jsonl, gdy jest obecny.
Powiązane
- Usunięcie BlueBubbles i ścieżka imsg iMessage — krótki komunikat i podsumowanie dla operatora.
- iMessage — pełne odniesienie 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 DM i przepływ parowania.
- Routing kanałów — jak gateway wybiera kanał dla odpowiedzi wychodzących.