Mainstream messaging
iMessage
Stato: integrazione CLI esterna nativa. Gateway avvia imsg rpc e comunica tramite JSON-RPC su stdio (nessun daemon/porta separati). Le azioni avanzate richiedono imsg launch e una verifica riuscita dell'API privata.
Risposte, tapback, effetti, allegati e gestione dei gruppi.
I DM iMessage usano per impostazione predefinita la modalità di associazione.
Usa un wrapper SSH quando il Gateway non è in esecuzione sul Mac di Messages.
Riferimento completo dei campi iMessage.
Configurazione rapida
Local Mac (fast path)
Install and verify imsg
brew install steipete/tap/imsgimsg rpc --helpimsg launchopenclaw channels status --probeConfigure OpenClaw
{channels: {imessage: {enabled: true,cliPath: "/usr/local/bin/imsg",dbPath: "/Users/user/Library/Messages/chat.db",},},}Start gateway
openclaw gatewayApprove first DM pairing (default dmPolicy)
openclaw pairing list imessageopenclaw pairing approve imessage <CODE>Le richieste di associazione scadono dopo 1 ora.
Remote Mac over SSH
OpenClaw richiede solo un cliPath compatibile con stdio, quindi puoi puntare cliPath a uno script wrapper che si connette via SSH a un Mac remoto ed esegue imsg.
#!/usr/bin/env bashexec ssh -T gateway-host imsg "$@"Configurazione consigliata quando gli allegati sono abilitati:
{channels: {imessage: { enabled: true, cliPath: "~/.openclaw/scripts/imsg-ssh", remoteHost: "user@gateway-host", // used for SCP attachment fetches includeAttachments: true, // Optional: override allowed attachment roots. // Defaults include /Users/*/Library/Messages/Attachments attachmentRoots: ["/Users/*/Library/Messages/Attachments"], remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"],},},}Se remoteHost non è impostato, OpenClaw tenta di rilevarlo automaticamente analizzando lo script wrapper SSH.
remoteHost deve essere host o user@host (senza spazi né opzioni SSH).
OpenClaw usa il controllo rigoroso della chiave host per SCP, quindi la chiave host del relay deve già esistere in ~/.ssh/known_hosts.
I percorsi degli allegati vengono convalidati rispetto alle radici consentite (attachmentRoots / remoteAttachmentRoots).
Requisiti e autorizzazioni (macOS)
- Messages deve avere l'accesso effettuato sul Mac che esegue
imsg. - È richiesto Accesso completo al disco per il contesto di processo che esegue OpenClaw/
imsg(accesso al DB di Messages). - È richiesta l'autorizzazione Automazione per inviare messaggi tramite Messages.app.
- Per le azioni avanzate (reazione / modifica / annullamento invio / risposta in thread / effetti / operazioni sui gruppi), System Integrity Protection deve essere disabilitata — vedi Abilitazione dell'API privata imsg sotto. L'invio/ricezione di testo e contenuti multimediali di base funziona senza.
Abilitazione dell'API privata imsg
imsg viene distribuito in due modalità operative:
- Modalità base (predefinita, non sono necessarie modifiche a SIP): testo e contenuti multimediali in uscita tramite
send, monitoraggio/cronologia in ingresso, elenco chat. È ciò che ottieni subito con una nuova installazionebrew install steipete/tap/imsgpiù le autorizzazioni macOS standard indicate sopra. - Modalità API privata:
imsginietta una dylib helper inMessages.appper chiamare funzioni interne diIMCore. Questo sbloccareact,edit,unsend,reply(in thread),sendWithEffect,renameGroup,setGroupIcon,addParticipant,removeParticipant,leaveGroup, oltre agli indicatori di digitazione e alle conferme di lettura.
Per accedere alla superficie di azioni avanzate documentata in questa pagina del canale, ti serve la modalità API privata. Il README di imsg è esplicito sul requisito:
Funzionalità avanzate come
read,typing,launch, invio avanzato basato su bridge, mutazione dei messaggi e gestione delle chat sono facoltative. Richiedono che SIP sia disabilitato e che una dylib helper venga iniettata inMessages.app.imsg launchrifiuta l'iniezione quando SIP è abilitato.
La tecnica di iniezione dell'helper usa la dylib di imsg per raggiungere le API private di Messages. Nel percorso iMessage di OpenClaw non c'è alcun server di terze parti o runtime BlueBubbles.
Configurazione
-
Installa (o aggiorna)
imsgsul Mac che esegue Messages.app:bash brew install steipete/tap/imsgimsg --versionimsg status --jsonL'output di
imsg status --jsonriportabridge_version,rpc_methodse iselectorsper metodo, così puoi vedere cosa supporta la build corrente prima di iniziare. -
Disabilita System Integrity Protection. Questo dipende dalla versione di macOS perché il requisito Apple sottostante dipende dal sistema operativo e dall'hardware:
- macOS 10.13–10.15 (Sierra–Catalina): disabilita Library Validation tramite Terminale, riavvia in Recovery Mode, esegui
csrutil disable, riavvia. - macOS 11+ (Big Sur e successivi), Intel: Recovery Mode (o Internet Recovery),
csrutil disable, riavvia. - macOS 11+, Apple Silicon: sequenza di avvio con il pulsante di accensione per entrare in Recovery; nelle versioni recenti di macOS tieni premuto il tasto Shift sinistro quando fai clic su Continua, poi
csrutil disable. Le configurazioni con macchine virtuali seguono un flusso separato — crea prima uno snapshot della VM. - macOS 26 / Tahoe: le policy di convalida delle librerie e i controlli di entitlement privati di
imagentsono stati ulteriormente irrigiditi;imsgpotrebbe richiedere una build aggiornata per restare compatibile. Se l'iniezione diimsg launchoselectorsspecifici iniziano a restituire false dopo un aggiornamento major di macOS, controlla le note di rilascio diimsgprima di presumere che il passaggio SIP sia riuscito.
Segui il flusso Recovery Mode di Apple per il tuo Mac per disabilitare SIP prima di eseguire
imsg launch. - macOS 10.13–10.15 (Sierra–Catalina): disabilita Library Validation tramite Terminale, riavvia in Recovery Mode, esegui
-
Inietta l'helper. Con SIP disabilitato e accesso effettuato in Messages.app:
bash imsg launchimsg launchrifiuta l'iniezione quando SIP è ancora abilitato, quindi funge anche da conferma che il passaggio 2 ha avuto effetto. -
Verifica il bridge da OpenClaw:
bash openclaw channels status --probeLa voce iMessage dovrebbe riportare
works, eimsg status --json | jq '.selectors'dovrebbe mostrareretractMessagePart: truepiù gli eventuali selettori di modifica / digitazione / lettura esposti dalla tua build macOS. Il gating per metodo del plugin OpenClaw inactions.tspubblicizza solo azioni il cui selettore sottostante ètrue, quindi la superficie di azioni che vedi nell'elenco strumenti dell'agente riflette ciò che il bridge può effettivamente fare su questo host.
Se openclaw channels status --probe riporta il canale come works ma azioni specifiche generano "iMessage <action> requires the imsg private API bridge" al momento del dispatch, esegui di nuovo imsg launch — l'helper può disattivarsi (riavvio di Messages.app, aggiornamento del sistema operativo, ecc.) e lo stato memorizzato nella cache available: true continuerà a pubblicizzare le azioni finché la prossima verifica non lo aggiorna.
Quando non puoi disabilitare SIP
Se SIP disabilitato non è accettabile per il tuo modello di minaccia:
imsgtorna alla modalità base — solo testo + contenuti multimediali + ricezione.- Il plugin OpenClaw continua a pubblicizzare l'invio di testo/media e il monitoraggio in ingresso; nasconde solo
react,edit,unsend,reply,sendWithEffecte le operazioni sui gruppi dalla superficie di azioni (secondo il gate di capacità per metodo). - Puoi eseguire un Mac non Apple Silicon separato (o un Mac dedicato al bot) con SIP disattivato per il carico iMessage, mantenendo SIP abilitato sui dispositivi principali. Vedi Utente macOS dedicato al bot (identità iMessage separata) sotto.
Controllo degli accessi e instradamento
DM policy
channels.imessage.dmPolicy controlla i messaggi diretti:
pairing(predefinito)allowlistopen(richiede cheallowFromincluda"*")disabled
Campo allowlist: channels.imessage.allowFrom.
Le voci allowlist devono identificare i mittenti: handle o gruppi di accesso mittente statici (accessGroup:<name>). Usa channels.imessage.groupAllowFrom per destinazioni chat come chat_id:*, chat_guid:* o chat_identifier:*; usa channels.imessage.groups per chiavi di registro numeriche chat_id.
Group policy + mentions
channels.imessage.groupPolicy controlla la gestione dei gruppi:
allowlist(predefinito quando configurato)opendisabled
Allowlist dei mittenti dei gruppi: channels.imessage.groupAllowFrom.
Le voci groupAllowFrom possono anche fare riferimento a gruppi di accesso mittente statici (accessGroup:<name>).
Fallback runtime: se groupAllowFrom non è impostato, i controlli dei mittenti dei gruppi iMessage usano allowFrom; imposta groupAllowFrom quando l'ammissione per DM e gruppi deve differire.
Nota runtime: se channels.imessage manca completamente, il runtime torna a groupPolicy="allowlist" e registra un avviso (anche se channels.defaults.groupPolicy è impostato).
Controllo delle menzioni per i gruppi:
- iMessage non dispone di metadati nativi per le menzioni
- il rilevamento delle menzioni usa pattern regex (
agents.list[].groupChat.mentionPatterns, fallbackmessages.groupChat.mentionPatterns) - senza pattern configurati, il controllo delle menzioni non può essere applicato
I comandi di controllo provenienti da mittenti autorizzati possono bypassare il controllo delle menzioni nei gruppi.
systemPrompt per gruppo:
Ogni voce sotto channels.imessage.groups.* accetta una stringa systemPrompt facoltativa. Il valore viene iniettato nel prompt di sistema dell'agente a ogni turno che gestisce un messaggio in quel gruppo. La risoluzione rispecchia la risoluzione del prompt per gruppo usata da channels.whatsapp.groups:
- Prompt di sistema specifico del gruppo (
groups["<chat_id>"].systemPrompt): usato quando la voce del gruppo specifico esiste nella mappa e la sua chiavesystemPromptè definita. SesystemPromptè una stringa vuota (""), il wildcard viene soppresso e a quel gruppo non viene applicato alcun prompt di sistema. - Prompt di sistema wildcard del gruppo (
groups["*"].systemPrompt): usato quando la voce del gruppo specifico è completamente assente dalla mappa, oppure quando esiste ma non definisce alcuna chiavesystemPrompt.
{ channels: { imessage: { groupPolicy: "allowlist", groupAllowFrom: ["+15555550123"], groups: { "*": { systemPrompt: "Use British spelling." }, "8421": { requireMention: true, systemPrompt: "This is the on-call rotation chat. Keep replies under 3 sentences.", }, "9907": { // explicit suppression: the wildcard "Use British spelling." does not apply here systemPrompt: "", }, }, }, },}I prompt per gruppo si applicano solo ai messaggi di gruppo: i messaggi diretti in questo canale non sono interessati.
Sessioni e risposte deterministiche
- I DM usano l'instradamento diretto; i gruppi usano l'instradamento di gruppo.
- Con
session.dmScope=mainpredefinito, i DM di iMessage confluiscono nella sessione principale dell'agente. - Le sessioni di gruppo sono isolate (
agent:<agentId>:imessage:group:<chat_id>). - Le risposte vengono reinstradate a iMessage usando i metadati del canale/target di origine.
Comportamento dei thread simili a gruppi:
Alcuni thread iMessage con più partecipanti possono arrivare con is_group=false.
Se quel chat_id è configurato esplicitamente sotto channels.imessage.groups, OpenClaw lo tratta come traffico di gruppo (controllo di gruppo + isolamento della sessione di gruppo).
Binding delle conversazioni ACP
Le chat iMessage legacy possono anche essere associate a sessioni ACP.
Flusso rapido per l'operatore:
- Esegui
/acp spawn codex --bind heredentro il DM o la chat di gruppo consentita. - I messaggi futuri nella stessa conversazione iMessage vengono instradati alla sessione ACP generata.
/newe/resetreimpostano la stessa sessione ACP associata sul posto./acp closechiude la sessione ACP e rimuove il binding.
I binding persistenti configurati sono supportati tramite voci bindings[] di primo livello con type: "acp" e match.channel: "imessage".
match.peer.id può usare:
- handle DM normalizzato come
+15555550123o[email protected] chat_id:<id>(consigliato per binding di gruppo stabili)chat_guid:<guid>chat_identifier:<identifier>
Esempio:
{ agents: { list: [ { id: "codex", runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent" }, }, }, ], }, bindings: [ { type: "acp", agentId: "codex", match: { channel: "imessage", accountId: "default", peer: { kind: "group", id: "chat_id:123" }, }, acp: { label: "codex-group" }, }, ],}Vedi Agenti ACP per il comportamento condiviso dei binding ACP.
Pattern di distribuzione
Utente macOS bot dedicato (identità iMessage separata)
Usa un Apple ID e un utente macOS dedicati in modo che il traffico del bot sia isolato dal tuo profilo personale di Messaggi.
Flusso tipico:
- Crea/accedi a un utente macOS dedicato.
- Accedi a Messaggi con l'Apple ID del bot in quell'utente.
- Installa
imsgin quell'utente. - Crea un wrapper SSH in modo che OpenClaw possa eseguire
imsgnel contesto di quell'utente. - Punta
channels.imessage.accounts.<id>.cliPathe.dbPatha quel profilo utente.
La prima esecuzione potrebbe richiedere approvazioni GUI (Automazione + Accesso completo al disco) nella sessione di quell'utente bot.
Mac remoto tramite Tailscale (esempio)
Topologia comune:
- il Gateway viene eseguito su Linux/VM
- iMessage +
imsgviene eseguito su un Mac nella tua tailnet - il wrapper
cliPathusa SSH per eseguireimsg remoteHostabilita il recupero degli allegati tramite SCP
Esempio:
{ channels: { imessage: { enabled: true, cliPath: "~/.openclaw/scripts/imsg-ssh", remoteHost: "[email protected]", includeAttachments: true, dbPath: "/Users/bot/Library/Messages/chat.db", }, },}#!/usr/bin/env bashexec ssh -T [email protected] imsg "$@"Usa chiavi SSH in modo che sia SSH sia SCP siano non interattivi.
Assicurati prima che la chiave host sia considerata attendibile (per esempio ssh [email protected]) così known_hosts viene popolato.
Pattern multi-account
iMessage supporta la configurazione per account sotto channels.imessage.accounts.
Ogni account può sovrascrivere campi come cliPath, dbPath, allowFrom, groupPolicy, mediaMaxMb, impostazioni della cronologia e allowlist delle radici degli allegati.
Media, suddivisione in blocchi e target di consegna
Allegati e media
- l'acquisizione degli allegati in ingresso è disattivata per impostazione predefinita: imposta
channels.imessage.includeAttachments: trueper inoltrare foto, memo vocali, video e altri allegati all'agente. Con questa opzione disabilitata, gli iMessage composti solo da allegati vengono scartati prima di raggiungere l'agente e potrebbero non produrre alcuna riga di logInbound message. - i percorsi degli allegati remoti possono essere recuperati tramite SCP quando
remoteHostè impostato - i percorsi degli allegati devono corrispondere alle radici consentite:
channels.imessage.attachmentRoots(locale)channels.imessage.remoteAttachmentRoots(modalità SCP remota)- pattern radice predefinito:
/Users/*/Library/Messages/Attachments
- SCP usa il controllo rigoroso della chiave host (
StrictHostKeyChecking=yes) - la dimensione dei media in uscita usa
channels.imessage.mediaMaxMb(predefinito 16 MB)
Suddivisione in blocchi in uscita
- limite dei blocchi di testo:
channels.imessage.textChunkLimit(predefinito 4000) - modalità di suddivisione in blocchi:
channels.imessage.chunkModelength(predefinita)newline(suddivisione che privilegia i paragrafi)
Formati di indirizzamento
Target espliciti preferiti:
chat_id:123(consigliato per un instradamento stabile)chat_guid:...chat_identifier:...
Sono supportati anche i target handle:
imessage:+1555...sms:+1555...[email protected]
imsg chats --limit 20Azioni API private
Quando imsg launch è in esecuzione e openclaw channels status --probe riporta privateApi.available: true, lo strumento di messaggistica può usare azioni native di iMessage oltre ai normali invii di testo.
{ channels: { imessage: { actions: { reactions: true, edit: true, unsend: true, reply: true, sendWithEffect: true, sendAttachment: true, renameGroup: true, setGroupIcon: true, addParticipant: true, removeParticipant: true, leaveGroup: true, }, }, },}Azioni disponibili
- react: aggiunge/rimuove tapback di iMessage (
messageId,emoji,remove). I tapback supportati mappano a amore, mi piace, non mi piace, risata, enfasi e domanda. - reply: invia una risposta in thread a un messaggio esistente (
messageId,textomessage, piùchatGuid,chatId,chatIdentifieroto). - sendWithEffect: invia testo con un effetto iMessage (
textomessage,effectoeffectId). - edit: modifica un messaggio inviato nelle versioni macOS/API private supportate (
messageId,textonewText). - unsend: ritira un messaggio inviato nelle versioni macOS/API private supportate (
messageId). - upload-file: invia media/file (
buffercome base64 o unmedia/path/filePathidratato,filename,asVoicefacoltativo). Alias legacy:sendAttachment. - renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup: gestiscono le chat di gruppo quando il target corrente è una conversazione di gruppo.
ID messaggio
Il contesto iMessage in ingresso include sia valori MessageSid brevi sia GUID messaggio completi quando disponibili. Gli ID brevi hanno ambito nella cache in memoria delle risposte recenti e vengono verificati rispetto alla chat corrente prima dell'uso. Se un ID breve è scaduto o appartiene a un'altra chat, riprova con il MessageSidFull completo.
Rilevamento delle capability
OpenClaw nasconde le azioni API private solo quando lo stato del probe in cache indica che il bridge non è disponibile. Se lo stato è sconosciuto, le azioni restano visibili ed eseguono i probe in modo lazy, così la prima azione può riuscire dopo imsg launch senza un aggiornamento manuale separato dello stato.
Conferme di lettura e digitazione
Quando il bridge API private è attivo, le chat in ingresso accettate vengono contrassegnate come lette prima del dispatch e viene mostrato un fumetto di digitazione al mittente mentre l'agente genera. Disabilita il contrassegno di lettura con:
{ channels: { imessage: { sendReadReceipts: false, }, },}Le build imsg più vecchie, precedenti all'elenco delle capability per metodo, disattiveranno silenziosamente digitazione/lettura; OpenClaw registra un avviso una tantum per riavvio così la conferma mancante è attribuibile.
Tapback in ingresso
OpenClaw sottoscrive i tapback di iMessage e instrada le reazioni accettate come eventi di sistema invece che come normale testo del messaggio, quindi un tapback dell'utente non attiva un normale ciclo di risposta.
La modalità di notifica è controllata da channels.imessage.reactionNotifications:
"own"(predefinito): notifica solo quando gli utenti reagiscono a messaggi creati dal bot."all": notifica per tutti i tapback in ingresso da mittenti autorizzati."off": ignora i tapback in ingresso.
Le sovrascritture per account usano channels.imessage.accounts.<id>.reactionNotifications.
Scritture di configurazione
iMessage consente per impostazione predefinita le scritture di configurazione avviate dal canale (per /config set|unset quando commands.config: true).
Disabilita:
{ channels: { imessage: { configWrites: false, }, },}Coalescing dei DM inviati in modo suddiviso (comando + URL in un'unica composizione)
Quando un utente digita insieme un comando e un URL, per esempio Dump https://example.com/article, l'app Messaggi di Apple divide l'invio in due righe chat.db separate:
- Un messaggio di testo (
"Dump"). - Un fumetto di anteprima URL (
"https://...") con immagini di anteprima OG come allegati.
Le due righe arrivano a OpenClaw a circa 0,8-2,0 s di distanza nella maggior parte delle configurazioni. Senza aggregazione, l'agente riceve il comando da solo al turno 1, risponde (spesso "mandami l'URL") e vede l'URL solo al turno 2, quando il contesto del comando è già perso. Questo dipende dalla pipeline di invio di Apple, non da qualcosa introdotto da OpenClaw o imsg.
channels.imessage.coalesceSameSenderDms fa sì che un DM unisca righe consecutive dello stesso mittente in un singolo turno dell'agente. Le chat di gruppo continuano a essere inviate per messaggio, così la struttura dei turni multiutente viene preservata.
When to enable
Abilita quando:
- Distribuisci skills che si aspettano
command + payloadin un solo messaggio (dump, paste, save, queue, ecc.). - I tuoi utenti incollano URL, immagini o contenuti lunghi insieme ai comandi.
- Puoi accettare la latenza aggiunta al turno DM (vedi sotto).
Lascia disabilitato quando:
- Ti serve la latenza minima dei comandi per trigger DM di una sola parola.
- Tutti i tuoi flussi sono comandi one-shot senza payload successivi.
Enabling
{ channels: { imessage: { coalesceSameSenderDms: true, // opt in (default: false) }, },}Con il flag attivo e senza un messages.inbound.byChannel.imessage esplicito, la finestra di debounce si allarga a 2500 ms (il valore predefinito legacy è 0 ms, cioè nessun debounce). La finestra più ampia è necessaria perché la cadenza split-send di Apple di 0,8-2,0 s non rientra in un valore predefinito più stretto.
Per regolare tu stesso la finestra:
{ 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). imessage: 2500, }, }, },}Trade-offs
- Latenza aggiunta per i messaggi DM. Con il flag attivo, ogni DM (inclusi i comandi di controllo autonomi e i follow-up con solo testo) attende fino alla finestra di debounce prima dell'invio, nel caso stia arrivando una riga di payload. I messaggi delle chat di gruppo mantengono l'invio immediato.
- L'output unito è limitato. Il testo unito è limitato a 4000 caratteri con un marcatore esplicito
…[truncated]; gli allegati sono limitati a 20; le voci sorgente sono limitate a 10 (oltre tale limite vengono conservate la prima e le più recenti). Ogni GUID sorgente viene tracciato incoalescedMessageGuidsper la telemetria a valle. - Solo DM. Le chat di gruppo passano all'invio per messaggio, così il bot rimane reattivo quando più persone stanno scrivendo.
- Opt-in, per canale. Gli altri canali (Telegram, WhatsApp, Slack, …) non sono interessati. Le configurazioni BlueBubbles legacy che impostano
channels.bluebubbles.coalesceSameSenderDmsdevono migrare quel valore achannels.imessage.coalesceSameSenderDms.
Scenari e cosa vede l'agente
| L'utente compone | chat.db produce |
Flag disattivo (predefinito) | Flag attivo + finestra di 2500 ms |
|---|---|---|---|
Dump https://example.com (un invio) |
2 righe a ~1 s di distanza | Due turni dell'agente: solo "Dump", poi URL | Un turno: testo unito Dump https://example.com |
Save this 📎image.jpg caption (allegato + testo) |
2 righe | Due turni (allegato scartato nell'unione) | Un turno: testo + immagine preservati |
/status (comando autonomo) |
1 riga | Invio immediato | Attende fino alla finestra, poi invia |
| URL incollato da solo | 1 riga | Invio immediato | Invio immediato (una sola voce nel bucket) |
| Testo + URL inviati come due messaggi separati intenzionali, a minuti di distanza | 2 righe fuori finestra | Due turni | Due turni (la finestra scade tra i due) |
| Raffica rapida (>10 piccoli DM dentro la finestra) | N righe | N turni | Un turno, output limitato (prima + più recenti, limiti testo/allegati applicati) |
| Due persone scrivono in una chat di gruppo | N righe da M mittenti | M+ turni (uno per bucket mittente) | M+ turni: le chat di gruppo non vengono aggregate |
Recupero dopo inattività del gateway
Quando il gateway è offline (crash, riavvio, sleep del Mac, macchina spenta), imsg watch riprende dallo stato corrente di chat.db quando il gateway torna attivo: qualsiasi cosa arrivata durante l'intervallo, per impostazione predefinita, non viene mai vista. Il recupero riproduce quei messaggi al successivo avvio, così l'agente non perde silenziosamente il traffico in ingresso.
Il recupero è disabilitato per impostazione predefinita. Abilitalo per canale:
channels: { imessage: { catchup: { enabled: true, // master switch (default: false) maxAgeMinutes: 120, // skip rows older than now - 2h (default: 120, clamp 1..720) perRunLimit: 50, // max rows replayed per startup (default: 50, clamp 1..500) firstRunLookbackMinutes: 30, // first run with no cursor: look back 30 min (default: 30) maxFailureRetries: 10, // give up on a wedged guid after 10 dispatch failures (default: 10) }, },}Come viene eseguito
Un passaggio per ogni avvio di monitorIMessageProvider, sequenziato come imsg launch pronto → watch.subscribe → performIMessageCatchup → ciclo di invio live. Il recupero usa chats.list + messages.history per chat tramite lo stesso client JSON-RPC usato da imsg watch. Tutto ciò che arriva durante il passaggio di recupero attraversa normalmente l'invio live; la cache di deduplicazione in ingresso esistente assorbe qualsiasi sovrapposizione con le righe riprodotte.
Ogni riga riprodotta viene inoltrata attraverso il percorso di invio live (evaluateIMessageInbound + dispatchInboundMessage), quindi allowlist, criteri di gruppo, debouncer, cache echo e conferme di lettura si comportano in modo identico sui messaggi riprodotti e live.
Semantica di cursore e tentativi
Il recupero mantiene un cursore per account in <openclawStateDir>/imessage/catchup/<account>__<hash>.json (la directory di stato di OpenClaw è ~/.openclaw per impostazione predefinita, sovrascrivibile con OPENCLAW_STATE_DIR):
{ "lastSeenMs": 1717900800000, "lastSeenRowid": 482910, "updatedAt": 1717900801234, "failureRetries": { "<guid>": 1 }}- Il cursore avanza a ogni invio riuscito e resta fermo quando l'invio di una riga genera un'eccezione: l'avvio successivo riprova la stessa riga dal cursore trattenuto.
- Dopo
maxFailureRetrieseccezioni consecutive sullo stessoguid, il recupero registra unwarne forza l'avanzamento del cursore oltre il messaggio bloccato, così gli avvii successivi possono progredire. - I guid già abbandonati vengono saltati a vista (senza tentativo di invio) nelle esecuzioni successive e conteggiati sotto
skippedGivenUpnel riepilogo dell'esecuzione.
Segnali visibili all'operatore
imessage catchup: replayed=N skippedFromMe=… skippedGivenUp=… failed=… givenUp=… fetchedCount=…imessage catchup: giving up on guid=<guid> after <N> failures; advancing cursor past itimessage catchup: fetched <X> rows across chats, capped to perRunLimit=<Y>Una riga WARN ... capped to perRunLimit significa che un singolo avvio non ha svuotato tutto il backlog. Aumenta perRunLimit (massimo 500) se i tuoi intervalli superano regolarmente il passaggio predefinito da 50 righe.
Quando lasciarlo disattivato
- Il Gateway viene eseguito continuamente con riavvio automatico tramite watchdog e gli intervalli sono sempre < pochi secondi: il valore predefinito disattivato va bene.
- Il volume DM è basso e i messaggi persi non cambierebbero il comportamento dell'agente: la finestra iniziale
firstRunLookbackMinutespuò inviare contesto vecchio inatteso alla prima abilitazione.
Quando attivi il recupero, il primo avvio senza cursore guarda indietro solo di firstRunLookbackMinutes (30 min per impostazione predefinita), non per l'intera finestra maxAgeMinutes: questo evita di riprodurre una lunga cronologia di messaggi precedenti all'abilitazione.
Risoluzione dei problemi
imsg not found or RPC unsupported
Convalida il binario e il supporto RPC:
imsg rpc --helpimsg status --jsonopenclaw channels status --probeSe il probe segnala che RPC non è supportato, aggiorna imsg. Se le azioni API private non sono disponibili, esegui imsg launch nella sessione dell'utente macOS con login effettuato e ripeti il probe. Se il Gateway non è in esecuzione su macOS, usa la configurazione Mac remoto via SSH sopra invece del percorso imsg locale predefinito.
Gateway is not running on macOS
Il valore predefinito cliPath: "imsg" deve essere eseguito sul Mac con accesso a Messaggi. Su Linux o Windows, imposta channels.imessage.cliPath su uno script wrapper che si connette via SSH a quel Mac ed esegue imsg "$@".
#!/usr/bin/env bashexec ssh -T messages-mac imsg "$@"Poi esegui:
openclaw channels status --probe --channel imessageDMs are ignored
Controlla:
channels.imessage.dmPolicychannels.imessage.allowFrom- approvazioni di pairing (
openclaw pairing list imessage)
Group messages are ignored
Controlla:
channels.imessage.groupPolicychannels.imessage.groupAllowFrom- comportamento allowlist di
channels.imessage.groups - configurazione del pattern di menzione (
agents.list[].groupChat.mentionPatterns)
Remote attachments fail
Controlla:
channels.imessage.remoteHostchannels.imessage.remoteAttachmentRoots- autenticazione con chiave SSH/SCP dall'host gateway
- la chiave host esiste in
~/.ssh/known_hostssull'host gateway - leggibilità del percorso remoto sul Mac che esegue Messaggi
macOS permission prompts were missed
Riesegui in un terminale GUI interattivo nello stesso contesto utente/sessione e approva i prompt:
imsg chats --limit 1imsg send <handle> "test"Conferma che Accesso completo al disco + Automazione siano concessi per il contesto del processo che esegue OpenClaw/imsg.
Riferimenti alla configurazione
Correlati
- Panoramica dei canali — tutti i canali supportati
- Rimozione di BlueBubbles e percorso iMessage con imsg — annuncio e riepilogo della migrazione
- Provenienza da BlueBubbles — tabella di traduzione della configurazione e passaggio guidato
- Pairing — autenticazione DM e flusso di pairing
- Gruppi — comportamento delle chat di gruppo e gating delle menzioni
- Routing dei canali — routing della sessione per i messaggi
- Sicurezza — modello di accesso e hardening