Mainstream messaging
Se provieni da BlueBubbles
Il Plugin imessage incluso ora raggiunge la stessa superficie API privata di BlueBubbles (react, edit, unsend, reply, sendWithEffect, gestione dei gruppi, allegati) pilotando steipete/imsg tramite JSON-RPC. Se esegui già un Mac con imsg installato, puoi eliminare il server BlueBubbles e lasciare che il Plugin comunichi direttamente con Messages.app.
Il supporto per BlueBubbles è stato rimosso. OpenClaw supporta iMessage solo tramite imsg. Questa guida serve per migrare le vecchie configurazioni channels.bluebubbles a channels.imessage; non esiste un altro percorso di migrazione supportato.
Checklist di migrazione
Usa questa checklist quando conosci già la tua vecchia configurazione BlueBubbles e vuoi il percorso sicuro più breve:
- Verifica
imsgdirettamente sul Mac che esegue Messages.app (imsg chats,imsg history,imsg sendeimsg rpc --help). - Copia le chiavi di comportamento da
channels.bluebubblesachannels.imessage:dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups,includeAttachments,attachmentRoots,mediaMaxMb,textChunkLimit,coalesceSameSenderDmseactions. - Elimina le chiavi di trasporto che non esistono più:
serverUrl,password, URL dei webhook e configurazione del server BlueBubbles. - Se il Gateway non è in esecuzione sul Mac di Messages, imposta
channels.imessage.cliPathsu un wrapper SSH e impostaremoteHostper il recupero remoto degli allegati. - Con il Gateway arrestato, abilita
channels.imessage, quindi eseguiopenclaw channels status --probe --channel imessage. - Testa un DM, un gruppo consentito, gli allegati se abilitati e ogni azione API privata che ti aspetti che l'agente usi.
- Elimina il server BlueBubbles e la vecchia configurazione
channels.bluebubblesdopo aver verificato il percorso iMessage.
Quando questa migrazione ha senso
- Esegui già
imsgsullo stesso Mac (o su uno raggiungibile tramite SSH) in cui Messages.app ha effettuato l'accesso. - Vuoi un componente in meno da gestire: nessun server BlueBubbles separato, nessun endpoint REST da autenticare, nessun cablaggio di webhook. Un singolo binario CLI invece di server + app client + helper.
- Usi una build macOS /
imsgsupportata in cui il probe dell'API privata segnalaavailable: true.
Cosa fa imsg
imsg è una CLI locale per macOS dedicata a Messages. OpenClaw avvia imsg rpc come processo figlio e comunica tramite JSON-RPC su stdin/stdout. Non ci sono server HTTP, URL webhook, demoni in background, agenti di avvio o porte da esporre.
- Le letture provengono da
~/Library/Messages/chat.dbusando un handle SQLite di sola lettura. - I messaggi in ingresso live provengono da
imsg watch/watch.subscribe, che segue gli eventi del filesystem dichat.dbcon un fallback basato su polling. - Gli invii usano l'automazione di Messages.app per i normali invii di testo e file.
- Le azioni avanzate usano
imsg launchper iniettare l'helperimsgin Messages.app. Questo sblocca conferme di lettura, indicatori di digitazione, invii avanzati, modifica, annullamento dell'invio, risposta in thread, tapback e gestione dei gruppi. - Le build Linux possono ispezionare un
chat.dbcopiato, ma non possono inviare, osservare il database live del Mac o controllare Messages.app. Per OpenClaw iMessage, eseguiimsgsul Mac con accesso effettuato o tramite un wrapper SSH verso quel Mac.
Prima di iniziare
-
Installa
imsgsul Mac che esegue Messages.app:brew install steipete/tap/imsg imsg --version imsg chats --limit 3Se
imsg chatsfallisce conunable to open database file, output vuoto oauthorization denied, concedi Accesso completo al disco al terminale, all'editor, al processo Node, al servizio Gateway o al processo padre SSH che avviaimsg, quindi riapri quel processo padre. -
Verifica le superfici di lettura, osservazione, invio e RPC prima di modificare la configurazione di 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 --helpSostituisci
42con un ID chat reale daimsg chats. L'invio richiede l'autorizzazione Automazione per Messages.app. Se OpenClaw verrà eseguito tramite SSH, esegui questi comandi tramite lo stesso wrapper SSH o contesto utente che userà OpenClaw. -
Abilita il bridge API privata quando ti servono azioni avanzate:
imsg launch imsg status --jsonimsg launchrichiede che SIP sia disabilitato. Invio di base, cronologia e osservazione funzionano senzaimsg launch; le azioni avanzate no. -
Dopo aver aggiunto una configurazione
channels.imessageabilitata, verifica il bridge tramite OpenClaw:openclaw channels status --probeDevi ottenere
imessage.privateApi.available: true. Se segnalafalse, correggi prima questo aspetto: consulta Rilevamento delle capacità.channels status --probeesegue il probe solo degli account configurati e abilitati. -
Crea uno snapshot della configurazione:
cp ~/.openclaw/openclaw.json5 ~/.openclaw/openclaw.json5.bak
Traduzione della configurazione
iMessage e BlueBubbles condividono molta configurazione a livello di canale. Le chiavi che cambiano sono principalmente quelle di trasporto (server REST rispetto a CLI locale). Le chiavi di comportamento (dmPolicy, groupPolicy, allowFrom e così via) mantengono lo stesso significato.
| BlueBubbles | iMessage incluso | Note |
|---|---|---|
channels.bluebubbles.enabled |
channels.imessage.enabled |
Stessa semantica. |
channels.bluebubbles.serverUrl |
(rimosso) | Nessun server REST: il Plugin avvia imsg rpc su stdio. |
channels.bluebubbles.password |
(rimosso) | Nessuna autenticazione Webhook necessaria. |
| (implicito) | channels.imessage.cliPath |
Percorso di imsg (predefinito imsg); usa uno script wrapper per SSH. |
| (implicito) | channels.imessage.dbPath |
Override facoltativo di Messages.app chat.db; rilevato automaticamente se omesso. |
| (implicito) | channels.imessage.remoteHost |
host o user@host: necessario solo quando cliPath è un wrapper SSH e vuoi recuperare allegati tramite SCP. |
channels.bluebubbles.dmPolicy |
channels.imessage.dmPolicy |
Stessi valori (pairing / allowlist / open / disabled). |
channels.bluebubbles.allowFrom |
channels.imessage.allowFrom |
Le approvazioni di abbinamento vengono trasferite per handle, non per token. |
channels.bluebubbles.groupPolicy |
channels.imessage.groupPolicy |
Stessi valori (allowlist / open / disabled). |
channels.bluebubbles.groupAllowFrom |
channels.imessage.groupAllowFrom |
Uguale. |
channels.bluebubbles.groups |
channels.imessage.groups |
Copia questo alla lettera, inclusa qualsiasi voce wildcard groups: { "*": { ... } }. Le impostazioni per gruppo requireMention, tools, toolsBySender vengono trasferite. Con groupPolicy: "allowlist", un blocco groups vuoto o mancante elimina silenziosamente ogni messaggio di gruppo: vedi "Trappola del registro dei gruppi" sotto. |
channels.bluebubbles.sendReadReceipts |
channels.imessage.sendReadReceipts |
Predefinito true. Con il Plugin incluso questo si attiva solo quando il probe dell'API privata è attivo. |
channels.bluebubbles.includeAttachments |
channels.imessage.includeAttachments |
Stessa forma, stesso disattivo per impostazione predefinita. Se su BlueBubbles gli allegati venivano trasmessi, devi reimpostarlo esplicitamente nel blocco iMessage: non viene trasferito implicitamente, e foto/media in ingresso verranno eliminati silenziosamente senza riga di log Inbound message finché non lo fai. |
channels.bluebubbles.attachmentRoots |
channels.imessage.attachmentRoots |
Radici locali; stesse regole wildcard. |
| (N/D) | channels.imessage.remoteAttachmentRoots |
Usato solo quando remoteHost è impostato per recuperi SCP. |
channels.bluebubbles.mediaMaxMb |
channels.imessage.mediaMaxMb |
Predefinito 16 MB su iMessage (il valore predefinito di BlueBubbles era 8 MB). Impostalo esplicitamente se vuoi mantenere il limite più basso. |
channels.bluebubbles.textChunkLimit |
channels.imessage.textChunkLimit |
Predefinito 4000 su entrambi. |
channels.bluebubbles.coalesceSameSenderDms |
channels.imessage.coalesceSameSenderDms |
Stessa attivazione esplicita. Solo per DM: le chat di gruppo mantengono l'invio immediato per messaggio su entrambi i canali. Quando abilitato senza un messages.inbound.byChannel.imessage esplicito, amplia il debounce in ingresso predefinito a 2500 ms. Vedi documentazione iMessage § Accorpamento dei DM split-send. |
channels.bluebubbles.enrichGroupParticipantsFromContacts |
(N/D) | iMessage legge già i nomi visualizzati dei mittenti da chat.db. |
channels.bluebubbles.actions.* |
channels.imessage.actions.* |
Attivazioni per azione: reactions, edit, unsend, reply, sendWithEffect, renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup, sendAttachment. |
Le configurazioni multi-account (channels.bluebubbles.accounts.*) si traducono uno a uno in channels.imessage.accounts.*.
Trappola del registro dei gruppi
Il Plugin iMessage incluso esegue due gate di allowlist dei gruppi separati, uno dopo l'altro. Entrambi devono passare perché un messaggio di gruppo raggiunga l'agente:
- Allowlist del mittente / destinatario chat (
channels.imessage.groupAllowFrom): controllata daisAllowedIMessageSender. Abbina i messaggi in ingresso per handle del mittente,chat_guid,chat_identifierochat_id. Stessa forma di BlueBubbles. - Registro dei gruppi (
channels.imessage.groups): controllato daresolveChannelGroupPolicydainbound-processing.ts:199. CongroupPolicy: "allowlist", questo gate richiede:- una voce wildcard
groups: { "*": { ... } }(impostaallowAll = true), oppure - una voce esplicita per
chat_idsottogroups.
- una voce wildcard
Se il gate 1 passa ma il gate 2 fallisce, il messaggio viene eliminato. Il Plugin emette due segnali di livello warn, quindi questo non è più silenzioso al livello di log predefinito:
- Un
warndi avvio una tantum per account quandogroupPolicy: "allowlist"è impostato machannels.imessage.groupsè vuoto (nessuna wildcard"*", nessuna voce perchat_id): attivato prima che arrivi qualsiasi messaggio. - Un
warnuna tantum perchat_idla prima volta che uno specifico gruppo viene eliminato a runtime, indicando il chat_id e la chiave esatta da aggiungere agroupsper consentirlo.
I DM continuano a funzionare perché seguono un percorso di codice diverso.
Questa è la modalità di errore più comune nella migrazione BlueBubbles → iMessage incluso: gli operatori copiano groupAllowFrom e groupPolicy ma saltano il blocco groups, perché groups: { "*": { "requireMention": true } } di BlueBubbles sembra un'impostazione di menzione non correlata. In realtà è essenziale per il gate del registro.
La configurazione minima per mantenere attivi i messaggi di gruppo dopo groupPolicy: "allowlist":
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123", "chat_guid:any;-;..."],
groups: {
"*": { requireMention: true },
},
},
},
}
requireMention: true sotto * è innocuo quando non sono configurati pattern di mention: il runtime imposta canDetectMention = false e interrompe subito lo scarto della mention in inbound-processing.ts:512. Con i pattern di mention configurati (agents.list[].groupChat.mentionPatterns), funziona come previsto.
Se i log del Gateway mostrano imessage: dropping group message from chat_id=<id> o la riga di avvio imessage: groupPolicy="allowlist" but channels.imessage.groups is empty, il gate 2 sta scartando: aggiungi il blocco groups.
Passo dopo passo
-
Aggiungi un blocco iMessage accanto al blocco BlueBubbles esistente. Mantienilo disabilitato mentre il Gateway sta ancora instradando il traffico 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, }, }, }, } -
Esegui un probe prima che il traffico conti — arresta il Gateway, abilita temporaneamente il blocco iMessage e conferma dalla CLI che iMessage risulti integro:
openclaw gateway stop # edit config: channels.imessage.enabled = true openclaw channels status --probe --channel imessage # expect imessage.privateApi.available: truechannels status --probeesegue il probe solo degli account configurati e abilitati. Non riavviare il Gateway con BlueBubbles e iMessage entrambi abilitati, a meno che tu non voglia intenzionalmente eseguire entrambi i monitor di canale. Se non stai effettuando subito il passaggio, reimpostachannels.imessage.enabledsufalseprima di riavviare il Gateway. Usa i comandi direttiimsgin Prima di iniziare per validare il Mac prima di abilitare il traffico OpenClaw. -
Effettua il passaggio. Quando l'account iMessage abilitato risulta integro, rimuovi la configurazione BlueBubbles e mantieni iMessage abilitato:
{ channels: { imessage: { enabled: true /* ... */ }, }, }Riavvia il Gateway. Il traffico iMessage in ingresso ora passa attraverso il Plugin incluso.
-
Verifica i DM. Invia all'agente un messaggio diretto; conferma che la risposta arrivi.
-
Verifica i gruppi separatamente. DM e gruppi seguono percorsi di codice diversi: il successo dei DM non prova che i gruppi siano instradati. Invia all'agente un messaggio in una chat di gruppo associata e conferma che la risposta arrivi. Se il gruppo diventa silenzioso (nessuna risposta dell'agente, nessun errore), controlla nel log del Gateway la presenza di
imessage: dropping group message from chat_id=<id>o della riga di avvioimessage: groupPolicy="allowlist" but channels.imessage.groups is empty: entrambe vengono emesse al livello di log predefinito. Se compare una delle due, il bloccogroupsè mancante o vuoto: vedi "Group registry footgun" sopra. -
Verifica la superficie delle azioni — da un DM associato, chiedi all'agente di reagire, modificare, annullare l'invio, rispondere, inviare una foto e (in un gruppo) rinominare il gruppo / aggiungere o rimuovere un partecipante. Ogni azione dovrebbe arrivare nativamente in Messages.app. Se una qualsiasi restituisce "iMessage
<action>requires the imsg private API bridge", esegui di nuovoimsg launche aggiornachannels status --probe. -
Rimuovi il server e la configurazione BlueBubbles dopo aver verificato DM, gruppi e azioni di iMessage. OpenClaw non userà
channels.bluebubbles.
Parità delle azioni in sintesi
| Azione | BlueBubbles legacy | iMessage incluso |
|---|---|---|
| Invio di testo / fallback SMS | ✅ | ✅ |
| Invio di media (foto, video, file, voce) | ✅ | ✅ |
Risposta in thread (reply_to_guid) |
✅ | ✅ (chiude #51892) |
Tapback (react) |
✅ | ✅ |
| Modifica / annullamento invio (destinatari macOS 13+) | ✅ | ✅ |
| Invio con effetto schermo | ✅ | ✅ (chiude parte di #9394) |
| Testo ricco grassetto / corsivo / sottolineato / barrato | ✅ | ✅ (formattazione typed-run tramite attributedBody) |
| Rinomina gruppo / imposta icona gruppo | ✅ | ✅ |
| Aggiungi / rimuovi partecipante, lascia gruppo | ✅ | ✅ |
| Conferme di lettura e indicatore di scrittura | ✅ | ✅ (controllato dal probe dell'API privata) |
| Coalescing DM dello stesso mittente | ✅ | ✅ (solo DM; opt-in tramite channels.imessage.coalesceSameSenderDms) |
| Recupero dei messaggi in ingresso ricevuti mentre il Gateway è inattivo | ✅ (replay Webhook + recupero cronologia) | ✅ (opt-in tramite channels.imessage.catchup.enabled; chiude #78649) |
Il recupero iMessage è ora disponibile come funzionalità opt-in nel Plugin incluso. All'avvio del Gateway, se channels.imessage.catchup.enabled è true, il Gateway esegue un passaggio chats.list + messages.history per chat sullo stesso client JSON-RPC usato da imsg watch, riproduce ogni riga in ingresso persa attraverso il percorso di dispatch live (allowlist, policy di gruppo, debouncer, cache echo) e persiste un cursore per account in modo che gli avvii successivi riprendano da dove erano rimasti. Vedi Recupero dopo inattività del Gateway per la regolazione.
Associazione, sessioni e binding ACP
- Le approvazioni di associazione vengono trasferite per handle. Non devi riapprovare i mittenti noti:
channels.imessage.allowFromriconosce le stesse stringhe+15555550123/user@example.comusate da BlueBubbles. - Le sessioni restano limitate per agente + chat. I DM confluiscono nella sessione principale dell'agente con il valore predefinito
session.dmScope=main; le sessioni di gruppo restano isolate perchat_id. Le chiavi di sessione differiscono (agent:<id>:imessage:group:<chat_id>rispetto all'equivalente BlueBubbles): la vecchia cronologia delle conversazioni sotto le chiavi di sessione BlueBubbles non viene trasferita nelle sessioni iMessage. - I binding ACP che fanno riferimento a
match.channel: "bluebubbles"devono essere aggiornati a"imessage". Le forme dimatch.peer.id(chat_id:,chat_guid:,chat_identifier:, handle semplice) sono identiche.
Nessun canale di rollback
Non esiste un runtime BlueBubbles supportato a cui tornare. Se la verifica di iMessage fallisce, imposta channels.imessage.enabled: false, riavvia il Gateway, correggi il blocco di imsg e riprova il passaggio.
La cache delle risposte si trova in ~/.openclaw/state/imessage/reply-cache.jsonl (modalità 0600, directory padre 0700). Può essere eliminata se vuoi ripartire da zero.
Correlati
- Rimozione di BlueBubbles e percorso iMessage imsg — breve annuncio e riepilogo per gli operatori.
- iMessage — riferimento completo del canale iMessage, inclusi configurazione
imsg launche rilevamento delle capacità. /channels/bluebubbles— URL legacy che reindirizza a questa guida di migrazione.- Associazione — autenticazione DM e flusso di associazione.
- Instradamento dei canali — come il Gateway sceglie un canale per le risposte in uscita.