iMessage (imsg)
Status: Externe CLI-Integration. Der Gateway startet imsg rpc (JSON-RPC über stdio).
Schnellstart (Einsteiger)
- Stelle sicher, dass Messages auf diesem Mac angemeldet ist.
- Installiere
imsg:brew install steipete/tap/imsg
- Konfiguriere OpenClaw mit
channels.imessage.cliPathundchannels.imessage.dbPath. - Starte den Gateway und bestätige alle macOS-Berechtigungsabfragen (Automation + Full Disk Access).
Minimale Konfiguration:
{
channels: {
imessage: {
enabled: true,
cliPath: "/usr/local/bin/imsg",
dbPath: "/Users/<you>/Library/Messages/chat.db",
},
},
}
Was ist das
- iMessage Channel basierend auf
imsgunter macOS. - Deterministisches Routing: Antworten gehen immer zurück zu iMessage.
- DMs teilen sich die Haupt-Session des Agents; Gruppen sind isoliert (
agent:<agentId>:imessage:group:<chat_id>). - Wenn ein Thread mit mehreren Teilnehmern mit
is_group=falseankommt, kannst du ihn trotzdem perchat_idüberchannels.imessage.groupsisolieren (siehe “Gruppenähnliche Threads” weiter unten).
Config-Schreibzugriff
Standardmäßig darf iMessage Config-Updates durchführen, die durch /config set|unset ausgelöst werden (erfordert commands.config: true).
Deaktivieren mit:
{
channels: { imessage: { configWrites: false } },
}
Voraussetzungen
- macOS mit angemeldetem Messages.
- Full Disk Access für OpenClaw +
imsg(Zugriff auf Messages-Datenbank). - Automation-Berechtigung beim Senden.
channels.imessage.cliPathkann auf jeden Befehl zeigen, der stdin/stdout weiterleitet (z. B. ein Wrapper-Script, das per SSH zu einem anderen Mac verbindet undimsg rpcausführt).
Setup (schneller Weg)
- Stelle sicher, dass Messages auf diesem Mac angemeldet ist.
- Konfiguriere iMessage und starte den Gateway.
Dedizierter Bot-macOS-Benutzer (für isolierte Identität)
Wenn der Bot von einer separaten iMessage-Identität senden soll (und deine persönlichen Messages sauber bleiben sollen), nutze eine dedizierte Apple ID + einen dedizierten macOS-Benutzer.
- Erstelle eine dedizierte Apple ID (Beispiel:
[email protected]).- Apple kann eine Telefonnummer für Verifizierung / 2FA verlangen.
- Erstelle einen macOS-Benutzer (Beispiel:
openclawhome) und melde dich dort an. - Öffne Messages in diesem macOS-Benutzer und melde dich mit der Bot-Apple-ID bei iMessage an.
- Aktiviere Remote Login (Systemeinstellungen → Allgemein → Freigaben → Remote-Anmeldung).
- Installiere
imsg:brew install steipete/tap/imsg
- Richte SSH so ein, dass
ssh <bot-macos-user>@localhost trueohne Passwort funktioniert. - Setze
channels.imessage.accounts.bot.cliPathauf einen SSH-Wrapper, derimsgals Bot-Benutzer ausführt.
Hinweis beim ersten Start: Senden/Empfangen kann GUI-Freigaben (Automation + Full Disk Access) im Bot-macOS-Benutzer erfordern. Falls imsg rpc hängt oder abbricht, melde dich bei diesem Benutzer an (Bildschirmfreigabe hilft), führe einmalig imsg chats --limit 1 / imsg send ... aus, bestätige die Abfragen und versuche es erneut.
Beispiel-Wrapper (chmod +x). Ersetze <bot-macos-user> durch deinen tatsächlichen macOS-Benutzernamen:
#!/usr/bin/env bash
set -euo pipefail
# Führe einmal interaktiv SSH aus, um Host-Keys zu akzeptieren:
# ssh <bot-macos-user>@localhost true
exec /usr/bin/ssh -o BatchMode=yes -o ConnectTimeout=5 -T <bot-macos-user>@localhost \
"/usr/local/bin/imsg" "$@"
Beispiel-Konfiguration:
{
channels: {
imessage: {
enabled: true,
accounts: {
bot: {
name: "Bot",
enabled: true,
cliPath: "/path/to/imsg-bot",
dbPath: "/Users/<bot-macos-user>/Library/Messages/chat.db",
},
},
},
},
}
Bei Single-Account-Setups nutze die flachen Optionen (channels.imessage.cliPath, channels.imessage.dbPath) statt der accounts-Map.
Remote/SSH-Variante (optional)
Wenn du iMessage auf einem anderen Mac nutzen willst, setze channels.imessage.cliPath auf einen Wrapper, der imsg auf dem Remote-macOS-Host über SSH ausführt. OpenClaw braucht nur stdio.
Beispiel-Wrapper:
#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"
Remote-Anhänge: Wenn cliPath über SSH auf einen Remote-Host zeigt, verweisen Anhangspfade in der Messages-Datenbank auf Dateien auf der Remote-Maschine. OpenClaw kann diese automatisch per SCP holen, wenn du channels.imessage.remoteHost setzt:
{
channels: {
imessage: {
cliPath: "~/imsg-ssh", // SSH-Wrapper zum Remote-Mac
remoteHost: "user@gateway-host", // für SCP-Dateitransfer
includeAttachments: true,
},
},
}
Falls remoteHost nicht gesetzt ist, versucht OpenClaw es automatisch zu erkennen, indem es den SSH-Befehl in deinem Wrapper-Script parst. Explizite Konfiguration wird für Zuverlässigkeit empfohlen.
Remote-Mac via Tailscale (Beispiel)
Wenn der Gateway auf einem Linux-Host/VM läuft, aber iMessage auf einem Mac laufen muss, ist Tailscale die einfachste Brücke: Der Gateway kommuniziert mit dem Mac über das Tailnet, führt imsg via SSH aus und holt Anhänge per SCP zurück.
Architektur:
┌──────────────────────────────┐ SSH (imsg rpc) ┌──────────────────────────┐
│ Gateway host (Linux/VM) │──────────────────────────────────▶│ Mac with Messages + imsg │
│ - openclaw gateway │ SCP (attachments) │ - Messages signed in │
│ - channels.imessage.cliPath │◀──────────────────────────────────│ - Remote Login enabled │
└──────────────────────────────┘ └──────────────────────────┘
▲
│ Tailscale tailnet (hostname or 100.x.y.z)
▼
user@gateway-host
Konkretes Konfigurations-Beispiel (Tailscale-Hostname):
{
channels: {
imessage: {
enabled: true,
cliPath: "~/.openclaw/scripts/imsg-ssh",
remoteHost: "[email protected]",
includeAttachments: true,
dbPath: "/Users/bot/Library/Messages/chat.db",
},
},
}
Beispiel-Wrapper (~/.openclaw/scripts/imsg-ssh):
#!/usr/bin/env bash
exec ssh -T [email protected] imsg "$@"
Hinweise:
- Stelle sicher, dass der Mac bei Messages angemeldet ist und Remote Login aktiviert ist.
- Nutze SSH-Keys, damit
ssh [email protected]ohne Abfragen funktioniert. remoteHostsollte zum SSH-Ziel passen, damit SCP Anhänge holen kann.
Multi-Account-Unterstützung: Nutze channels.imessage.accounts mit Account-spezifischer Config und optionalem name. Siehe gateway/configuration für das gemeinsame Pattern. Committe nicht ~/.openclaw/openclaw.json (enthält oft Tokens).
Zugriffskontrolle (DMs + Gruppen)
DMs:
- Standard:
channels.imessage.dmPolicy = "pairing". - Unbekannte Absender erhalten einen Pairing-Code; Nachrichten werden ignoriert, bis sie freigegeben sind (Codes laufen nach 1 Stunde ab).
- Freigabe via:
openclaw pairing list imessageopenclaw pairing approve imessage <CODE>
- Pairing ist der Standard-Token-Austausch für iMessage-DMs. Details: Pairing
Gruppen:
channels.imessage.groupPolicy = open | allowlist | disabled.channels.imessage.groupAllowFromsteuert, wer in Gruppen triggern kann, wennallowlistgesetzt ist.- Mention-Gating nutzt
agents.list[].groupChat.mentionPatterns(odermessages.groupChat.mentionPatterns), weil iMessage keine nativen Mention-Metadaten hat. - Multi-Agent-Override: Setze Agent-spezifische Patterns auf
agents.list[].groupChat.mentionPatterns.
Wie es funktioniert (Verhalten)
imsgstreamt Message-Events; der Gateway normalisiert sie in das gemeinsame Channel-Envelope.- Antworten werden immer zurück zur selben Chat-ID oder zum selben Handle geroutet.
Gruppenähnliche Threads (is_group=false)
Manche iMessage-Threads können mehrere Teilnehmer haben, kommen aber trotzdem mit is_group=false an, je nachdem wie Messages die Chat-ID speichert.
Wenn du explizit eine chat_id unter channels.imessage.groups konfigurierst, behandelt OpenClaw diesen Thread als “Gruppe” für:
- Session-Isolation (separater
agent:<agentId>:imessage:group:<chat_id>Session-Key) - Gruppen-Allowlisting / Mention-Gating-Verhalten
Beispiel:
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"42": { requireMention: false },
},
},
},
}
Das ist nützlich, wenn du eine isolierte Persönlichkeit/Modell für einen bestimmten Thread willst (siehe Multi-Agent Routing). Für Dateisystem-Isolation siehe Sandboxing.
Medien + Limits
- Optionale Anhang-Verarbeitung via
channels.imessage.includeAttachments. - Medien-Cap via
channels.imessage.mediaMaxMb.
Limits
- Ausgehender Text wird in Chunks von
channels.imessage.textChunkLimitaufgeteilt (Standard 4000). - Optionales Newline-Chunking: Setze
channels.imessage.chunkMode="newline", um bei Leerzeilen (Absatzgrenzen) zu splitten, bevor nach Länge gechunkt wird. - Medien-Uploads sind durch
channels.imessage.mediaMaxMbbegrenzt (Standard 16).
Adressierung / Zustellziele
Bevorzuge chat_id für stabiles Routing:
chat_id:123(bevorzugt)chat_guid:...chat_identifier:...- Direkte Handles:
imessage:+1555/sms:+1555/[email protected]
Chats auflisten:
imsg chats --limit 20
Konfigurationsreferenz (iMessage)
Vollständige Konfiguration: Configuration
Provider-Optionen:
channels.imessage.enabled: Channel-Start aktivieren/deaktivieren.channels.imessage.cliPath: Pfad zuimsg.channels.imessage.dbPath: Messages-DB-Pfad.channels.imessage.remoteHost: SSH-Host für SCP-Anhang-Transfer, wenncliPathauf einen Remote-Mac zeigt (z. B.user@gateway-host). Wird aus SSH-Wrapper automatisch erkannt, falls nicht gesetzt.channels.imessage.service:imessage | sms | auto.channels.imessage.region: SMS-Region.channels.imessage.dmPolicy:pairing | allowlist | open | disabled(Standard: pairing).channels.imessage.allowFrom: DM-Allowlist (Handles, E-Mails, E.164-Nummern oderchat_id:*).openerfordert"*". iMessage hat keine Benutzernamen; nutze Handles oder Chat-Ziele.channels.imessage.groupPolicy:open | allowlist | disabled(Standard: allowlist).channels.imessage.groupAllowFrom: Gruppen-Absender-Allowlist.channels.imessage.historyLimit/channels.imessage.accounts.*.historyLimit: Max. Gruppennachrichten als Context (0 deaktiviert).channels.imessage.dmHistoryLimit: DM-History-Limit in User-Turns. Pro-User-Overrides:channels.imessage.dms["<handle>"].historyLimit.channels.imessage.groups: Pro-Gruppen-Defaults + Allowlist (nutze"*"für globale Defaults).channels.imessage.includeAttachments: Anhänge in Context aufnehmen.channels.imessage.mediaMaxMb: Inbound/Outbound-Medien-Cap (MB).channels.imessage.textChunkLimit: Outbound-Chunk-Größe (Zeichen).channels.imessage.chunkMode:length(Standard) odernewline, um bei Leerzeilen (Absatzgrenzen) zu splitten, bevor nach Länge gechunkt wird.
Verwandte globale Optionen:
agents.list[].groupChat.mentionPatterns(odermessages.groupChat.mentionPatterns).messages.responsePrefix.