Mainstream messaging
iMessage
Status: native externe CLI-integratie. Gateway start imsg rpc en communiceert via JSON-RPC over stdio (geen afzonderlijke daemon/poort). Geavanceerde acties vereisen imsg launch en een geslaagde private API-probe.
Antwoorden, tapbacks, effecten, peilingen, bijlagen en groepsbeheer.
iMessage-DM's gebruiken standaard de koppelingsmodus.
Gebruik een SSH-wrapper wanneer de Gateway niet op de Messages-Mac draait.
Volledige referentie voor iMessage-velden.
Snelle setup
Lokale Mac (snel pad)
Installeer en verifieer imsg
brew install steipete/tap/imsgimsg rpc --helpimsg launchopenclaw channels status --probeConfigureer OpenClaw
{channels: {imessage: {enabled: true,cliPath: "/usr/local/bin/imsg",dbPath: "/Users/user/Library/Messages/chat.db",},},}Start gateway
openclaw gatewayKeur eerste DM-koppeling goed (standaard dmPolicy)
openclaw pairing list imessageopenclaw pairing approve imessage <CODE>Koppelingsverzoeken verlopen na 1 uur.
Externe Mac via SSH
OpenClaw vereist alleen een stdio-compatibele cliPath, dus je kunt cliPath laten wijzen naar een wrapperscript dat via SSH verbinding maakt met een externe Mac en imsg uitvoert.
#!/usr/bin/env bashexec ssh -T gateway-host imsg "$@"Aanbevolen configuratie wanneer bijlagen zijn ingeschakeld:
{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"],},},}Als remoteHost niet is ingesteld, probeert OpenClaw dit automatisch te detecteren door het SSH-wrapperscript te parsen.
remoteHost moet host of user@host zijn (geen spaties of SSH-opties).
OpenClaw gebruikt strikte host-key-controle voor SCP, dus de hostsleutel van de relayhost moet al bestaan in ~/.ssh/known_hosts.
Bijlagepaden worden gevalideerd tegen toegestane roots (attachmentRoots / remoteAttachmentRoots).
Vereisten en machtigingen (macOS)
- Messages moet zijn ingelogd op de Mac waarop
imsgdraait. - Full Disk Access is vereist voor de procescontext waarin OpenClaw/
imsgdraait (toegang tot de Messages-database). - Automatiseringsmachtiging is vereist om berichten via Messages.app te verzenden.
- Voor geavanceerde acties (reageren / bewerken / verzenden ongedaan maken / antwoord in thread / effecten / peilingen / groepsbewerkingen) moet System Integrity Protection zijn uitgeschakeld — zie De imsg private API inschakelen hieronder. Basisfunctionaliteit voor tekst en media verzenden/ontvangen werkt zonder dit.
SSH-wrapperverzendingen mislukken met AppleEvents -1743
Een remote-SSH-setup kan chats lezen, channels status --probe doorstaan en inkomende berichten verwerken terwijl uitgaande verzendingen nog steeds mislukken met een AppleEvents-autorisatiefout:
Not authorized to send Apple events to Messages. (-1743)Controleer de TCC-database van de ingelogde Mac-gebruiker of System Settings > Privacy & Security > Automation. Als de Automation-vermelding is vastgelegd voor /usr/libexec/sshd-keygen-wrapper in plaats van voor het imsg- of lokale shellproces, toont macOS mogelijk geen bruikbare Messages-schakelaar voor die server-side SSH-client:
kTCCServiceAppleEvents | /usr/libexec/sshd-keygen-wrapper | auth_value=0 | com.apple.MobileSMSIn die toestand kan het blijven mislukken om tccutil reset AppleEvents te herhalen of imsg send opnieuw via dezelfde SSH-wrapper uit te voeren, omdat de procescontext die Messages Automation nodig heeft de SSH-wrapper is, niet een app waaraan de UI toegang kan verlenen.
Gebruik in plaats daarvan een van de ondersteunde imsg-procescontexten:
- Draai de Gateway, of ten minste de
imsg-bridge, in de lokale sessie van de ingelogde Messages-gebruiker. - Start de Gateway met een LaunchAgent voor die gebruiker nadat Full Disk Access en Automation vanuit dezelfde sessie zijn verleend.
- Als je de SSH-topologie met twee gebruikers behoudt, verifieer dan dat een echte uitgaande
imsg sendvia exact dezelfde wrapper slaagt voordat je het kanaal inschakelt. Als Automation niet kan worden verleend, configureer dan opnieuw naar eenimsg-setup met één gebruiker in plaats van voor verzendingen op de SSH-wrapper te vertrouwen.
De imsg private API inschakelen
imsg wordt geleverd in twee operationele modi:
- Basismodus (standaard, geen SIP-wijzigingen nodig): uitgaande tekst en media via
send, inkomende watch/history, chatlijst. Dit krijg je direct na een nieuwebrew install steipete/tap/imsgplus de standaard macOS-machtigingen hierboven. - Private API-modus:
imsginjecteert een helper-dylib inMessages.appom interneIMCore-functies aan te roepen. Dit ontgrendeltreact,edit,unsend,reply(threaded),sendWithEffect,pollenpoll-vote(native Messages-peilingen),renameGroup,setGroupIcon,addParticipant,removeParticipant,leaveGroup, plus type-indicatoren en leesbevestigingen.
Om het geavanceerde actieoppervlak te bereiken dat deze kanaalpagina documenteert, heb je Private API-modus nodig. De imsg README is expliciet over de vereiste:
Geavanceerde functies zoals
read,typing,launch, bridge-backed rijke verzending, berichtmutatie en chatbeheer zijn opt-in. Ze vereisen dat SIP is uitgeschakeld en dat een helper-dylib inMessages.appwordt geïnjecteerd.imsg launchweigert te injecteren wanneer SIP is ingeschakeld.
De helper-injectietechniek gebruikt de eigen dylib van imsg om Messages private APIs te bereiken. Er is geen externe server of BlueBubbles-runtime in het OpenClaw iMessage-pad.
Setup
-
Installeer (of upgrade)
imsgop de Mac waarop Messages.app draait:bash brew install steipete/tap/imsgimsg --versionimsg status --jsonDe uitvoer van
imsg status --jsonrapporteertbridge_version,rpc_methodsen per methodeselectors, zodat je kunt zien wat de huidige build ondersteunt voordat je begint. -
Schakel System Integrity Protection uit, en (op moderne macOS) Library Validation. Het injecteren van een niet-Apple helper-dylib in de door Apple ondertekende
Messages.appvereist dat SIP uit staat en dat library validation is versoepeld. De SIP-stap in Recovery-modus is macOS-versiespecifiek:- macOS 10.13-10.15 (Sierra-Catalina): schakel Library Validation uit via Terminal, herstart naar Recovery Mode, voer
csrutil disableuit, herstart. - macOS 11+ (Big Sur en later), Intel: Recovery Mode (of Internet Recovery),
csrutil disable, herstart. - macOS 11+, Apple Silicon: opstartreeks met de aan/uit-knop om Recovery te openen; houd op recente macOS-versies de Left Shift-toets ingedrukt wanneer je op Continue klikt, daarna
csrutil disable. Virtual-machine-setups volgen een aparte flow, dus maak eerst een VM-snapshot.
Op macOS 11 en later is alleen
csrutil disablemeestal niet genoeg. Apple handhaaft library validation nog steeds tegenMessages.appals platform binary, waardoor een adhoc-ondertekende helper wordt geweigerd (Library Validation failed: ... platform binary, but mapped file is not), zelfs met SIP uit. Schakel na het uitschakelen van SIP ook library validation uit en herstart:bash sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool truemacOS 26 (Tahoe), geverifieerd op 26.5.1: SIP uit plus de bovenstaande
DisableLibraryValidation-opdracht is voldoende om de helper te injecteren in 26.0 tot en met 26.5.x. Er zijn geen boot-args vereist. De plist is de doorslaggevende factor en de meest voorkomende ontbrekende stap wanneer injectie mislukt op Tahoe:- Met de plist:
imsg launchinjecteert enimsg statusrapporteertadvanced_features: true. - Zonder de plist (zelfs met SIP uit):
imsg launchmislukt metFailed to launch: Timeout waiting for Messages.app to initialize. AMFI weigert de adhoc-helper bij het laden, waardoor de bridge nooit gereed wordt en de launch time-out. Die time-out is het symptoom dat de meeste mensen op Tahoe tegenkomen, en de oplossing is de plist hierboven, niet iets ingrijpenders.
Dit is bevestigd met een gecontroleerde voor/na-test op macOS 26.5.1 (Apple Silicon): met de plist wordt de dylib in
Messages.appgemapt en komt de bridge op; verwijder de plist en herstart, enimsg launchproduceert de bovenstaande time-outfout zonder dat de dylib wordt gemapt.Als
imsg launch-injectie of specifiekeselectorsna een macOS-upgrade false beginnen terug te geven, is deze gate meestal de oorzaak. Controleer je SIP- en library-validation-status voordat je aanneemt dat de SIP-stap zelf is mislukt. Als die instellingen correct zijn en de bridge nog steeds niet kan injecteren, verzamel danimsg status --jsonplus de uitvoer vanimsg launchen meld dit aan hetimsg-project in plaats van extra systeembrede beveiligingsmaatregelen te verzwakken.Volg Apple's Recovery-mode-flow voor je Mac om SIP uit te schakelen voordat je
imsg launchuitvoert. - macOS 10.13-10.15 (Sierra-Catalina): schakel Library Validation uit via Terminal, herstart naar Recovery Mode, voer
-
Injecteer de helper. Met SIP uitgeschakeld en Messages.app aangemeld:
bash imsg launchimsg launchweigert te injecteren wanneer SIP nog steeds is ingeschakeld, dus dit dient ook als bevestiging dat stap 2 is gelukt. -
Verifieer de bridge vanuit OpenClaw:
bash openclaw channels status --probeDe iMessage-vermelding zou
worksmoeten rapporteren, enimsg status --json | jq '{rpc_methods, selectors}'zou de mogelijkheden moeten tonen die door je macOS-build worden blootgesteld. Poll-aanmaak vereistselectors.pollPayloadMessage; stemmen vereist zowelselectors.pollVoteMessageals depoll.vote-RPC-methode. De OpenClaw-Plugin adverteert alleen acties die worden ondersteund door de gecachte probe, terwijl een lege cache optimistisch blijft en bij de eerste dispatch probet.
Als openclaw channels status --probe het kanaal als works rapporteert maar specifieke acties tijdens dispatch "iMessage <action> requires the imsg private API bridge" gooien, voer dan imsg launch opnieuw uit — de helper kan wegvallen (herstart van Messages.app, OS-update, enz.) en de gecachte available: true-status blijft acties adverteren totdat de volgende probe wordt vernieuwd.
Wanneer je SIP niet kunt uitschakelen
Als SIP-uitgeschakeld niet acceptabel is voor je dreigingsmodel:
imsgvalt terug naar basismodus — alleen tekst + media + ontvangen.- De OpenClaw-Plugin adverteert nog steeds tekst/media verzenden en inkomende monitoring; hij verbergt alleen
react,edit,unsend,reply,sendWithEffecten groepsbewerkingen uit het actieoppervlak (volgens de capability-gate per methode). - Je kunt een aparte niet-Apple-Silicon Mac (of een dedicated bot-Mac) met SIP uit gebruiken voor de iMessage-workload, terwijl SIP op je primaire apparaten ingeschakeld blijft. Zie Dedicated bot macOS user (separate iMessage identity) hieronder.
Toegangscontrole en routering
DM policy
channels.imessage.dmPolicy beheert directe berichten:
pairing(standaard)allowlistopen(vereist datallowFrom"*"bevat)disabled
Allowlist-veld: channels.imessage.allowFrom.
Allowlist-vermeldingen moeten afzenders identificeren: handles of statische toegangsroepen voor afzenders (accessGroup:<name>). Gebruik channels.imessage.groupAllowFrom voor chatdoelen zoals chat_id:*, chat_guid:* of chat_identifier:*; gebruik channels.imessage.groups voor numerieke chat_id-registersleutels.
Group policy + mentions
channels.imessage.groupPolicy beheert groepsafhandeling:
allowlist(standaard wanneer geconfigureerd)opendisabled
Allowlist voor groepsafzenders: channels.imessage.groupAllowFrom.
groupAllowFrom-vermeldingen kunnen ook verwijzen naar statische toegangsroepen voor afzenders (accessGroup:<name>).
Runtime-terugval: als groupAllowFrom niet is ingesteld, gebruiken controles van iMessage-groepsafzenders allowFrom; stel groupAllowFrom in wanneer toelating voor DM's en groepen moet verschillen.
Runtime-opmerking: als channels.imessage volledig ontbreekt, valt runtime terug naar groupPolicy="allowlist" en logt een waarschuwing (zelfs als channels.defaults.groupPolicy is ingesteld).
Vermeldings-gating voor groepen:
- iMessage heeft geen native vermeldingsmetadata
- detectie van vermeldingen gebruikt regex-patronen (
agents.list[].groupChat.mentionPatterns, terugvalmessages.groupChat.mentionPatterns) - zonder geconfigureerde patronen kan vermeldings-gating niet worden afgedwongen
Besturingscommando's van geautoriseerde afzenders kunnen vermeldings-gating in groepen omzeilen.
systemPrompt per groep:
Elke vermelding onder channels.imessage.groups.* accepteert een optionele systemPrompt-string. De waarde wordt geïnjecteerd in de systeemprompt van de agent bij elke turn die een bericht in die groep afhandelt. Resolutie weerspiegelt de promptresolutie per groep die door channels.whatsapp.groups wordt gebruikt:
- Groepsspecifieke systeemprompt (
groups["<chat_id>"].systemPrompt): gebruikt wanneer de specifieke groepsvermelding in de map bestaat en de sleutelsystemPromptis gedefinieerd. AlssystemPrompteen lege string ("") is, wordt de wildcard onderdrukt en wordt er geen systeemprompt op die groep toegepast. - Wildcard-systeemprompt voor groepen (
groups["*"].systemPrompt): gebruikt wanneer de specifieke groepsvermelding volledig ontbreekt in de map, of wanneer deze bestaat maar geensystemPrompt-sleutel definieert.
{ 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: "", }, }, }, },}Prompts per groep zijn alleen van toepassing op groepsberichten — directe berichten in dit kanaal blijven onaangetast.
Sessions and deterministic replies
- DM's gebruiken directe routering; groepen gebruiken groepsroutering.
- Met de standaard
session.dmScope=mainworden iMessage-DM's samengevoegd in de hoofdsessie van de agent. - Groepssessies zijn geïsoleerd (
agent:<agentId>:imessage:group:<chat_id>). - Antwoorden worden terug naar iMessage gerouteerd met metadata van het oorspronkelijke kanaal/doel.
Groepsachtig threadgedrag:
Sommige iMessage-threads met meerdere deelnemers kunnen binnenkomen met is_group=false.
Als die chat_id expliciet is geconfigureerd onder channels.imessage.groups, behandelt OpenClaw dit als groepsverkeer (groeps-gating + isolatie van groepssessies).
ACP-gespreksbindingen
Verouderde iMessage-chats kunnen ook aan ACP-sessies worden gebonden.
Snelle operatorflow:
- Voer
/acp spawn codex --bind hereuit binnen de DM of toegestane groepschat. - Toekomstige berichten in datzelfde iMessage-gesprek worden naar de gespawnde ACP-sessie gerouteerd.
/newen/resetresetten dezelfde gebonden ACP-sessie ter plekke./acp closesluit de ACP-sessie en verwijdert de binding.
Geconfigureerde persistente bindingen worden ondersteund via top-level bindings[]-vermeldingen met type: "acp" en match.channel: "imessage".
match.peer.id kan het volgende gebruiken:
- genormaliseerde DM-handle zoals
+15555550123ofuser@example.com chat_id:<id>(aanbevolen voor stabiele groepsbindingen)chat_guid:<guid>chat_identifier:<identifier>
Voorbeeld:
{ 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" }, }, ],}Zie ACP-agenten voor gedeeld gedrag van ACP-bindingen.
Deploymentpatronen
Dedicated bot macOS user (separate iMessage identity)
Gebruik een dedicated Apple ID en macOS-gebruiker zodat botverkeer is geïsoleerd van je persoonlijke Messages-profiel.
Typische flow:
- Maak een dedicated macOS-gebruiker aan of meld je daarmee aan.
- Meld je in Messages aan met de Apple ID van de bot in die gebruiker.
- Installeer
imsgin die gebruiker. - Maak een SSH-wrapper zodat OpenClaw
imsgin die gebruikerscontext kan uitvoeren. - Wijs
channels.imessage.accounts.<id>.cliPathen.dbPathnaar dat gebruikersprofiel.
De eerste uitvoering kan GUI-goedkeuringen vereisen (Automation + Full Disk Access) in die botgebruikerssessie.
Remote Mac over Tailscale (example)
Veelvoorkomende topologie:
- Gateway draait op Linux/VM
- iMessage +
imsgdraait op een Mac in je tailnet cliPath-wrapper gebruikt SSH omimsguit te voerenremoteHostschakelt SCP-ophalen van bijlagen in
Voorbeeld:
{ channels: { imessage: { enabled: true, cliPath: "~/.openclaw/scripts/imsg-ssh", remoteHost: "bot@mac-mini.tailnet-1234.ts.net", includeAttachments: true, dbPath: "/Users/bot/Library/Messages/chat.db", }, },}#!/usr/bin/env bashexec ssh -T bot@mac-mini.tailnet-1234.ts.net imsg "$@"Gebruik SSH-sleutels zodat zowel SSH als SCP niet-interactief zijn.
Zorg dat de hostsleutel eerst wordt vertrouwd (bijvoorbeeld ssh bot@mac-mini.tailnet-1234.ts.net) zodat known_hosts wordt gevuld.
Multi-account pattern
iMessage ondersteunt configuratie per account onder channels.imessage.accounts.
Elk account kan velden overschrijven zoals cliPath, dbPath, allowFrom, groupPolicy, mediaMaxMb, geschiedenisinstellingen en allowlists voor hoofdlocaties van bijlagen.
Direct-message history
Stel channels.imessage.dmHistoryLimit in om nieuwe direct-message-sessies te seeden met recente gedecodeerde imsg-geschiedenis voor dat gesprek. Gebruik channels.imessage.dms["<sender>"].historyLimit voor overrides per afzender, inclusief 0 om geschiedenis voor een afzender uit te schakelen.
iMessage-DM-geschiedenis wordt on demand opgehaald uit imsg. Als dmHistoryLimit niet is ingesteld, wordt globale seeding van DM-geschiedenis uitgeschakeld, maar een positieve per-afzender channels.imessage.dms["<sender>"].historyLimit schakelt seeding voor die afzender nog steeds in.
Media, chunking en bezorgdoelen
Bijlagen en media
- opname van inkomende bijlagen is standaard uitgeschakeld — stel
channels.imessage.includeAttachments: truein om foto's, spraakmemo's, video en andere bijlagen door te sturen naar de agent. Als dit is uitgeschakeld, worden iMessages die alleen uit bijlagen bestaan verwijderd voordat ze de agent bereiken en produceren ze mogelijk helemaal geenInbound message-logregel. - externe bijlagepaden kunnen via SCP worden opgehaald wanneer
remoteHostis ingesteld - bijlagepaden moeten overeenkomen met toegestane roots:
channels.imessage.attachmentRoots(lokaal)channels.imessage.remoteAttachmentRoots(externe SCP-modus)- standaard rootpatroon:
/Users/*/Library/Messages/Attachments
- SCP gebruikt strikte hostkeycontrole (
StrictHostKeyChecking=yes) - grootte van uitgaande media gebruikt
channels.imessage.mediaMaxMb(standaard 16 MB)
Uitgaande chunking
- limiet voor tekstchunks:
channels.imessage.textChunkLimit(standaard 4000) - chunkmodus:
channels.imessage.chunkModelength(standaard)newline(splitsing waarbij alinea's eerst worden gebruikt)
Adresseringsindelingen
Voorkeur voor expliciete doelen:
chat_id:123(aanbevolen voor stabiele routering)chat_guid:...chat_identifier:...
Handledoelen worden ook ondersteund:
imessage:+1555...sms:+1555...user@example.com
imsg chats --limit 20Acties voor private API
Wanneer imsg launch actief is en openclaw channels status --probe privateApi.available: true meldt, kan de berichtentool naast normale tekstverzending ook iMessage-native acties gebruiken.
{ 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, polls: true, }, }, },}Beschikbare acties
- react: Voeg iMessage-tapbacks toe of verwijder ze (
messageId,emoji,remove). Ondersteunde tapbacks worden gekoppeld aan liefde, leuk, niet leuk, lachen, benadrukken en vraag. - reply: Stuur een threaded antwoord op een bestaand bericht (
messageId,textofmessage, pluschatGuid,chatId,chatIdentifierofto). - sendWithEffect: Stuur tekst met een iMessage-effect (
textofmessage,effectofeffectId). - edit: Bewerk een verzonden bericht op ondersteunde macOS-/private API-versies (
messageId,textofnewText). - unsend: Trek een verzonden bericht in op ondersteunde macOS-/private API-versies (
messageId). - upload-file: Stuur media/bestanden (
bufferals base64 of een gehydrateerdemedia/path/filePath,filename, optioneelasVoice). Legacy-alias:sendAttachment. - renameGroup, setGroupIcon, addParticipant, removeParticipant, leaveGroup: Beheer groepschats wanneer het huidige doel een groepsgesprek is.
- poll: Maak een native Apple Messages-peiling (
pollQuestion,pollOption2 tot 12 keer herhaald, pluschatGuid,chatId,chatIdentifierofto). Ontvangers op iOS/iPadOS/macOS 26+ zien deze native en stemmen native; oudere OS-versies krijgen een tekstfallback "Sent a poll". Vereistselectors.pollPayloadMessage. - poll-vote: Stem op een bestaande peiling (
pollIdofmessageId, plus precies één vanpollOptionIndex,pollOptionIdofpollOptionText). Vereistselectors.pollVoteMessageen de RPC-methodepoll.vote.
Geaccepteerde inkomende peilingen worden voor de agent weergegeven met de vraag, genummerde optielabels, stemtotalen en de bericht-ID van de peiling die nodig is voor poll-vote.
Bericht-ID's
Inkomende iMessage-context bevat zowel korte MessageSid-waarden als volledige bericht-GUID's wanneer beschikbaar. Korte ID's zijn beperkt tot de recente SQLite-backed antwoordcache en worden vóór gebruik gecontroleerd tegen de huidige chat. Als een korte ID is verlopen of bij een andere chat hoort, probeer het dan opnieuw met de volledige MessageSidFull.
Detectie van mogelijkheden
OpenClaw verbergt private API-acties alleen wanneer de gecachte probestatus zegt dat de bridge niet beschikbaar is. Als de status onbekend is, blijven acties zichtbaar en voeren dispatches probes lazy uit, zodat de eerste actie kan slagen na imsg launch zonder afzonderlijke handmatige statusvernieuwing.
Leesbevestigingen en typen
Wanneer de private API-bridge actief is, worden geaccepteerde inkomende chats als gelezen gemarkeerd en tonen directe chats een typballon zodra de turn is geaccepteerd, terwijl de agent context voorbereidt en genereert. Schakel leesmarkering uit met:
{ channels: { imessage: { sendReadReceipts: false, }, },}Oudere imsg-builds van vóór de mogelijkhedenlijst per methode schakelen typen/lezen stilzwijgend uit; OpenClaw logt één waarschuwing per herstart zodat de ontbrekende bevestiging herleidbaar is.
Inkomende tapbacks
OpenClaw abonneert zich op iMessage-tapbacks en routeert geaccepteerde reacties als systeemgebeurtenissen in plaats van normale berichttekst, zodat een tapback van een gebruiker geen gewone antwoordlus activeert.
Meldingsmodus wordt geregeld door channels.imessage.reactionNotifications:
"own"(standaard): meld alleen wanneer gebruikers reageren op berichten die door de bot zijn geschreven."all": meld alle inkomende tapbacks van geautoriseerde afzenders."off": negeer inkomende tapbacks.
Overrides per account gebruiken channels.imessage.accounts.<id>.reactionNotifications.
Goedkeuringsreacties (👍 / 👎)
Wanneer approvals.exec.enabled of approvals.plugin.enabled true is en de aanvraag naar iMessage wordt gerouteerd, levert de gateway native een goedkeuringsprompt en accepteert die een tapback om deze op te lossen:
👍(Like-tapback) →allow-once👎(Dislike-tapback) →denyallow-alwaysblijft een handmatige fallback: stuur/approve <id> allow-alwaysals normaal antwoord.
Reactieverwerking vereist dat de handle van de reagerende gebruiker een expliciete goedkeurder is. De lijst met goedkeurders wordt gelezen uit channels.imessage.allowFrom (of channels.imessage.accounts.<id>.allowFrom); voeg het telefoonnummer van de gebruiker toe in E.164-vorm of diens Apple ID-e-mailadres. De wildcardvermelding "*" wordt gehonoreerd, maar staat elke afzender toe om goed te keuren. De reactiesnelkoppeling omzeilt bewust reactionNotifications, dmPolicy en groupAllowFrom, omdat de expliciete allowlist voor goedkeurders de enige gate is die ertoe doet voor het oplossen van goedkeuringen.
Gedragswijziging in deze release: Wanneer channels.imessage.allowFrom niet leeg is, wordt de tekstcommand /approve <id> <decision> nu geautoriseerd tegen die lijst met goedkeurders (niet tegen de bredere DM-allowlist). Afzenders die wel op de DM-allowlist staan maar niet in allowFrom, krijgen een expliciete weigering. Voeg elke operator die via /approve (en via reacties) moet kunnen goedkeuren toe aan allowFrom om het eerdere gedrag te behouden. Wanneer allowFrom leeg is, blijft de legacy "same-chat fallback" van kracht en blijft /approve iedereen autoriseren die door de DM-allowlist wordt toegestaan.
Operatornotities:
- De reactiebinding wordt zowel in het geheugen opgeslagen (met een TTL die overeenkomt met de vervaltijd van de goedkeuring) als in de persistente keyed store van de gateway, zodat een tapback die kort na een herstart van de gateway binnenkomt de goedkeuring nog steeds oplost.
- Cross-device
is_from_me=true-tapbacks (de eigen reactie van de operator op een gekoppeld Apple-apparaat) worden bewust genegeerd, zodat de bot zichzelf niet kan goedkeuren. - Legacy tekststijl-tapbacks (
Liked "…"platte tekst van zeer oude Apple-clients) kunnen geen goedkeuringen oplossen omdat ze geen bericht-GUID dragen; reactieoplossing vereist de gestructureerde tapbackmetadata die huidige macOS-/iOS-clients uitsturen.
Configuratieschrijfacties
iMessage staat standaard door het kanaal geïnitieerde configuratieschrijfacties toe (voor /config set|unset wanneer commands.config: true).
Uitschakelen:
{ channels: { imessage: { configWrites: false, }, },}Split-send-DM's samenvoegen (command + URL in één compositie)
Wanneer een gebruiker een command en een URL samen typt — bijvoorbeeld Dump https://example.com/article — splitst Apple's Messages-app de verzending in twee afzonderlijke chat.db-rijen:
- Een tekstbericht (
"Dump"). - Een URL-previewballon (
"https://...") met OG-previewafbeeldingen als bijlagen.
De twee rijen komen op de meeste setups ~0,8-2,0 s na elkaar bij OpenClaw aan. Zonder samenvoeging ontvangt de agent alleen het command in turn 1, antwoordt hij (vaak "stuur me de URL") en ziet hij de URL pas in turn 2 — op dat punt is de commandcontext al verloren. Dit is Apple's verzendpipeline, niet iets wat OpenClaw of imsg introduceert.
channels.imessage.coalesceSameSenderDms laat een DM opeenvolgende rijen van dezelfde afzender bufferen. Wanneer imsg de structurele URL-previewmarkering balloon_bundle_id: "com.apple.messages.URLBalloonProvider" op een van de bronrijen blootlegt, voegt OpenClaw alleen die echte split-send samen en houdt het alle andere gebufferde rijen als afzonderlijke turns. Op oudere imsg-builds die helemaal geen ballonmetadata uitsturen, kan OpenClaw een split-send niet onderscheiden van afzonderlijke verzendingen, dus valt het terug op het samenvoegen van de bucket. Dat behoudt het gedrag van vóór metadata in plaats van Dump <url>-split-sends te laten regresseren naar twee turns. Groepschats blijven per bericht dispatchen zodat de turnstructuur met meerdere gebruikers behouden blijft.
Wanneer inschakelen
Schakel dit in wanneer:
- Je skills levert die
command + payloadin één bericht verwachten (dump, paste, save, queue, enz.). - Je gebruikers URL's naast commands plakken.
- Je de extra DM-turnlatentie kunt accepteren (zie hieronder).
Laat uitgeschakeld wanneer:
- Je minimale commandlatentie nodig hebt voor DM-triggers van één woord.
- Al je flows eenmalige commands zijn zonder payload-follow-ups.
Inschakelen
{ channels: { imessage: { coalesceSameSenderDms: true, // opt in (default: false) }, },}Met de flag aan en zonder expliciete messages.inbound.byChannel.imessage of globale messages.inbound.debounceMs wordt het debouncevenster verbreed naar 7000 ms (de legacy-standaard is 0 ms — geen debouncing). Het bredere venster is vereist omdat Apple's URL-preview-split-send-cadans kan oplopen tot meerdere seconden terwijl Messages.app de previewrij uitstuurd.
Om het venster zelf af te stemmen:
{ messages: { inbound: { byChannel: { // 7000 ms covers observed Messages.app URL-preview delays. imessage: 7000, }, }, },}Trade-offs
- Voor precies samenvoegen is actuele
imsg-payloadmetadata nodig. Wanneer de URL-rijballoon_bundle_idbevat, wordt alleen die echte gesplitste verzending samengevoegd en blijven andere gebufferde rijen apart. Op oudereimsg-builds die geen balloon-metadata blootstellen, valt OpenClaw terug op het samenvoegen van de gebufferde bucket, zodat gesplitste verzendingen vanDump <url>niet terugvallen naar twee beurten (tijdelijke achterwaartse compatibiliteit, verwijderd zodraimsggesplitste verzendingen upstream samenvoegt). - Extra latentie voor DM-berichten. Met de vlag ingeschakeld wacht elke DM (inclusief losse besturingsopdrachten en vervolgen met alleen tekst) maximaal tot het debouncevenster voordat deze wordt verzonden, voor het geval er een URL-previewrij aankomt. Groepschatberichten blijven direct verzonden.
- Samengevoegde uitvoer is begrensd. Samengevoegde tekst is begrensd op 4000 tekens met een expliciete markering
…[truncated]; bijlagen zijn begrensd op 20; bronvermeldingen zijn begrensd op 10 (eerste-plus-nieuwste blijven daarna behouden). Elke bron-GUID wordt bijgehouden incoalescedMessageGuidsvoor downstream-telemetrie. - Alleen DM. Groepschats vallen terug op verzending per bericht, zodat de bot responsief blijft wanneer meerdere mensen typen.
- Opt-in, per kanaal. Andere kanalen (Telegram, WhatsApp, Slack, …) worden niet beïnvloed. Verouderde BlueBubbles-configuraties die
channels.bluebubbles.coalesceSameSenderDmsinstellen, moeten die waarde migreren naarchannels.imessage.coalesceSameSenderDms.
Scenario's en wat de agent ziet
De kolom "Vlag aan" toont gedrag op een imsg-build die balloon_bundle_id uitstuurt. Op oudere imsg-builds die helemaal geen balloon-metadata uitsturen, vallen de rijen hieronder die zijn gemarkeerd als "Twee beurten" / "N beurten" in plaats daarvan terug op een verouderde samenvoeging (één beurt): OpenClaw kan een gesplitste verzending structureel niet onderscheiden van aparte verzendingen, dus behoudt het de samenvoeging van vóór de metadata. Precieze scheiding wordt actief zodra de build balloon-metadata uitstuurt.
| Gebruiker stelt op | chat.db produceert |
Vlag uit (standaard) | Vlag aan + venster (imsg stuurt balloon-metadata uit) |
|---|---|---|---|
Dump https://example.com (één verzending) |
2 rijen met ~1 s ertussen | Twee agentbeurten: alleen "Dump", daarna URL | Eén beurt: samengevoegde tekst Dump https://example.com |
Save this 📎image.jpg caption (bijlage + tekst) |
2 rijen zonder URL-balloonmetadata | Twee beurten | Twee beurten nadat metadata is waargenomen; één samengevoegde beurt in oude/pre-latch sessies zonder metadata |
/status (losse opdracht) |
1 rij | Directe verzending | Wacht maximaal tot het venster, verzend daarna |
| Alleen URL geplakt | 1 rij | Directe verzending | Wacht maximaal tot het venster, verzend daarna |
| Tekst + URL verzonden als twee bewuste aparte berichten, minuten uit elkaar | 2 rijen buiten venster | Twee beurten | Twee beurten (venster verloopt ertussen) |
| Snelle vloed (>10 kleine DM's binnen venster) | N rijen zonder URL-balloonmetadata | N beurten | N beurten nadat metadata is waargenomen; één begrensde samengevoegde beurt in oude/pre-latch sessies zonder metadata |
| Twee mensen typen in een groepschat | N rijen van M afzenders | M+ beurten (één per afzenderbucket) | M+ beurten — groepschats worden niet samengevoegd |
Inbound-herstel na een herstart van bridge of Gateway
iMessage herstelt berichten die zijn gemist terwijl de Gateway offline was, en onderdrukt tegelijk de oude "backlogbom" die Apple na een Push-herstel kan doorspoelen. Het standaardgedrag staat altijd aan en is gebouwd op de inbound-dedupe.
- Replay-dedupe. Elk verzonden inbound-bericht wordt met zijn Apple-GUID vastgelegd in persistente Plugin-status (
imessage.inbound-dedupe), geclaimd bij ingestie en vastgelegd na verwerking (vrijgegeven bij een tijdelijke fout zodat het opnieuw kan proberen). Alles wat al is verwerkt, wordt weggegooid in plaats van twee keer verzonden. Hierdoor kan herstel agressief opnieuw afspelen zonder administratie per bericht. - Downtime-herstel. Bij het opstarten onthoudt de monitor de laatst verzonden
chat.db-rowid (een persistente cursor per account) en geeft die door aanimsg watch.subscribealssince_rowid, zodatimsgde rijen opnieuw afspeelt die binnenkwamen terwijl de Gateway offline was, en daarna live volgt. Replay is begrensd tot de meest recente rijen en tot berichten van maximaal ~2 uur oud, en de dedupe verwijdert alles wat al is verwerkt. - Leeftijdsgrens voor oude backlog. Rijen boven de opstartgrens zijn echt live; een rij waarvan de verzenddatum meer dan ~15 minuten ouder is dan de aankomsttijd, is de Push-flush-backlog en wordt onderdrukt. Opnieuw afgespeelde rijen (op of onder de grens) gebruiken in plaats daarvan het bredere herstelvenster, zodat een recent gemist bericht wordt afgeleverd terwijl oude geschiedenis dat niet wordt.
Herstel werkt met zowel lokale als externe cliPath-setups, omdat since_rowid-replay via dezelfde imsg-RPC-verbinding loopt. Het verschil is het venster: wanneer de Gateway chat.db kan lezen (lokaal), verankert deze de opstart-rowid-grens, begrenst de replay-spanne en levert gemiste berichten tot een paar uur oud af. Via een externe SSH-cliPath kan deze de database niet lezen, dus is replay onbeperkt en gebruikt elke rij de live-leeftijdsgrens — het herstelt nog steeds recent gemiste berichten en onderdrukt nog steeds oude backlog, alleen met het smallere livevenster. Voer de Gateway uit op de Messages-Mac voor het bredere herstelvenster.
Operator-zichtbaar signaal
Onderdrukte backlog wordt op het standaardniveau gelogd, nooit stilzwijgend weggegooid (de vlag recovery toont welk venster is toegepast):
imessage: suppressed stale inbound backlog account=<id> sent=<iso> recovery=<bool> (<N> suppressed since start)Migratie
channels.imessage.catchup.* is verouderd — downtime-herstel is nu automatisch en vereist geen configuratie voor nieuwe setups. Bestaande configuraties met catchup.enabled: true blijven gehonoreerd als compatibiliteitsprofiel voor het herstel-replayvenster. Uitgeschakelde catchup-blokken (enabled: false of geen enabled: true) zijn uitgefaseerd; openclaw doctor --fix verwijdert die.
Probleemoplossing
imsg not found or RPC unsupported
Valideer de binary en RPC-ondersteuning:
imsg rpc --helpimsg status --jsonopenclaw channels status --probeAls de probe meldt dat RPC niet wordt ondersteund, werk imsg bij. Als private-API-acties niet beschikbaar zijn, voer imsg launch uit in de ingelogde macOS-gebruikerssessie en voer de probe opnieuw uit. Als de Gateway niet op macOS draait, gebruik dan de setup Externe Mac via SSH hierboven in plaats van het standaard lokale imsg-pad.
Messages send but inbound iMessages do not arrive
Bewijs eerst of het bericht de lokale Mac heeft bereikt. Als chat.db niet verandert, kan OpenClaw het bericht niet ontvangen, zelfs niet wanneer imsg status --json een gezonde bridge meldt.
imsg chats --limit 10 --jsonimsg watch --chat-id <chat-id> --jsonsqlite3 ~/Library/Messages/chat.db \"select datetime(max(date)/1000000000 + 978307200, 'unixepoch', 'localtime'), max(ROWID) from message;"Als vanaf de telefoon verzonden berichten geen nieuwe rijen maken, herstel dan de macOS Messages- en Apple Push-laag voordat je de OpenClaw-configuratie wijzigt. Een eenmalige serviceverversing is vaak genoeg:
launchctl kickstart -k system/com.apple.apsdlaunchctl kickstart -k gui/$(id -u)/com.apple.CommCenterlaunchctl kickstart -k gui/$(id -u)/com.apple.identityservicesdlaunchctl kickstart -k gui/$(id -u)/com.apple.imagentimsg launchopenclaw gateway restartVerzend een nieuwe iMessage vanaf de telefoon en bevestig een nieuwe chat.db-rij of imsg watch-event voordat je OpenClaw-sessies debugt. Voer dit niet uit als een periodieke bridge-herstartlus; herhaald imsg launch plus Gateway-herstarts tijdens actief werk kunnen afleveringen onderbreken en lopende kanaalruns laten vastlopen.
Gateway is not running on macOS
De standaard cliPath: "imsg" moet draaien op de Mac die bij Messages is aangemeld. Stel op Linux of Windows channels.imessage.cliPath in op een wrapperscript dat via SSH naar die Mac gaat en imsg "$@" uitvoert.
#!/usr/bin/env bashexec ssh -T messages-mac imsg "$@"Voer daarna uit:
openclaw channels status --probe --channel imessageDMs are ignored
Controleer:
channels.imessage.dmPolicychannels.imessage.allowFrom- koppelingsgoedkeuringen (
openclaw pairing list imessage)
Group messages are ignored
Controleer:
channels.imessage.groupPolicychannels.imessage.groupAllowFrom- allowlist-gedrag van
channels.imessage.groups - configuratie van vermeldingspatronen (
agents.list[].groupChat.mentionPatterns)
Remote attachments fail
Controleer:
channels.imessage.remoteHostchannels.imessage.remoteAttachmentRoots- SSH/SCP-sleutelauthenticatie vanaf de Gateway-host
- hostsleutel bestaat in
~/.ssh/known_hostsop de Gateway-host - leesbaarheid van externe paden op de Mac waarop Messages draait
macOS permission prompts were missed
Voer opnieuw uit in een interactieve GUI-terminal in dezelfde gebruikers-/sessiecontext en keur prompts goed:
imsg chats --limit 1imsg send <handle> "test"Bevestig dat Full Disk Access + Automation zijn toegekend voor de procescontext die OpenClaw/imsg uitvoert.
Verwijzingen naar configuratiereferentie
Gerelateerd
- Kanalenoverzicht — alle ondersteunde kanalen
- BlueBubbles-verwijdering en het imsg iMessage-pad — aankondiging en migratiesamenvatting
- Overstappen vanaf BlueBubbles — configuratievertaaltabel en stapsgewijze overstap
- Koppeling — DM-authenticatie en koppelingsflow
- Groepen — groepschatgedrag en vermeldingspoort
- Kanaalroutering — sessieroutering voor berichten
- Beveiliging — toegangsmodel en hardening