WhatsApp (web channel)
Status: WhatsApp Web über Baileys. Gateway verwaltet die Session(s).
Schnellstart (Einsteiger)
- Verwende wenn möglich eine separate Telefonnummer (empfohlen).
- Konfiguriere WhatsApp in
~/.openclaw/openclaw.json. - Führe
openclaw channels loginaus, um den QR-Code zu scannen (Verknüpfte Geräte). - Starte das Gateway.
Minimale Konfiguration:
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
Ziele
- Mehrere WhatsApp-Accounts (Multi-Account) in einem Gateway-Prozess.
- Deterministisches Routing: Antworten gehen zurück zu WhatsApp, kein Model-Routing.
- Model sieht genug Context, um zitierte Antworten zu verstehen.
Config-Schreibzugriff
Standardmäßig darf WhatsApp Config-Updates schreiben, die durch /config set|unset ausgelöst werden (erfordert commands.config: true).
Deaktivieren mit:
{
channels: { whatsapp: { configWrites: false } },
}
Architektur (wer verwaltet was)
- Gateway verwaltet den Baileys-Socket und die Inbox-Schleife.
- CLI / macOS-App kommunizieren mit dem Gateway; keine direkte Baileys-Nutzung.
- Aktiver Listener ist erforderlich für ausgehende Nachrichten; sonst schlägt das Senden sofort fehl.
Telefonnummer besorgen (zwei Modi)
WhatsApp benötigt eine echte Mobilnummer zur Verifizierung. VoIP- und virtuelle Nummern werden meist blockiert. Es gibt zwei unterstützte Wege, OpenClaw mit WhatsApp zu nutzen:
Dedizierte Nummer (empfohlen)
Verwende eine separate Telefonnummer für OpenClaw. Beste User Experience, sauberes Routing, keine Self-Chat-Eigenheiten. Ideales Setup: altes/Ersatz-Android-Handy + eSIM. Lass es am WLAN und Strom und verknüpfe es per QR-Code.
WhatsApp Business: Du kannst WhatsApp Business auf demselben Gerät mit einer anderen Nummer nutzen. Perfekt, um dein persönliches WhatsApp getrennt zu halten — installiere WhatsApp Business und registriere dort die OpenClaw-Nummer.
Beispiel-Config (dedizierte Nummer, Single-User-Allowlist):
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
Pairing-Modus (optional):
Wenn du Pairing statt Allowlist möchtest, setze channels.whatsapp.dmPolicy auf pairing. Unbekannte Absender erhalten einen Pairing-Code; freigeben mit:
openclaw pairing approve whatsapp <code>
Persönliche Nummer (Fallback)
Schneller Fallback: Nutze OpenClaw mit deiner eigenen Nummer. Schreib dir selbst (WhatsApp “Nachricht an mich selbst”) zum Testen, damit du keine Kontakte zuspammst. Rechne damit, Verifizierungscodes auf deinem Haupthandy während Setup und Experimenten zu lesen. Self-Chat-Modus muss aktiviert sein. Wenn der Wizard nach deiner persönlichen WhatsApp-Nummer fragt, gib die Nummer ein, von der du Nachrichten sendest (Owner/Sender), nicht die Assistenten-Nummer.
Beispiel-Config (persönliche Nummer, Self-Chat):
{
"whatsapp": {
"selfChatMode": true,
"dmPolicy": "allowlist",
"allowFrom": ["+15551234567"]
}
}
Self-Chat-Antworten verwenden standardmäßig [{identity.name}] wenn gesetzt (sonst [openclaw]),
falls messages.responsePrefix nicht gesetzt ist. Setze es explizit, um das Präfix anzupassen oder zu deaktivieren
(verwende "", um es zu entfernen).
Tipps zur Nummernbeschaffung
- Lokale eSIM von deinem Mobilfunkanbieter (am zuverlässigsten)
- Prepaid-SIM — günstig, muss nur eine SMS zur Verifizierung empfangen
Vermeide: TextNow, Google Voice, die meisten “kostenlosen SMS”-Dienste — WhatsApp blockiert diese aggressiv.
Tipp: Die Nummer muss nur eine Verifizierungs-SMS empfangen. Danach bleiben WhatsApp-Web-Sessions über creds.json bestehen.
Warum nicht Twilio?
- Frühe OpenClaw-Versionen unterstützten Twilios WhatsApp-Business-Integration.
- WhatsApp-Business-Nummern passen schlecht zu einem persönlichen Assistenten.
- Meta erzwingt ein 24-Stunden-Antwortfenster; wenn du in den letzten 24 Stunden nicht geantwortet hast, kann die Business-Nummer keine neuen Nachrichten initiieren.
- High-Volume- oder “geschwätzige” Nutzung löst aggressive Blockierungen aus, weil Business-Accounts nicht für dutzende persönliche Assistenten-Nachrichten gedacht sind.
- Ergebnis: unzuverlässige Zustellung und häufige Blockierungen, daher wurde der Support entfernt.
Login + Credentials
- Login-Befehl:
openclaw channels login(QR-Code über Verknüpfte Geräte). - Multi-Account-Login:
openclaw channels login --account <id>(<id>=accountId). - Standard-Account (wenn
--accountweggelassen wird):defaultfalls vorhanden, sonst die erste konfigurierte Account-ID (sortiert). - Credentials gespeichert in
~/.openclaw/credentials/whatsapp/<accountId>/creds.json. - Backup-Kopie unter
creds.json.bak(wird bei Korruption wiederhergestellt). - Legacy-Kompatibilität: ältere Installationen speicherten Baileys-Dateien direkt in
~/.openclaw/credentials/. - Logout:
openclaw channels logout(oder--account <id>) löscht WhatsApp-Auth-State (behält aber gemeinsamesoauth.json). - Ausgeloggter Socket => Fehler fordert erneutes Verknüpfen.
Eingehender Flow (DM + Gruppe)
- WhatsApp-Events kommen von
messages.upsert(Baileys). - Inbox-Listener werden beim Herunterfahren getrennt, um Anhäufung von Event-Handlern bei Tests/Neustarts zu vermeiden.
- Status-/Broadcast-Chats werden ignoriert.
- Direkte Chats verwenden E.164; Gruppen verwenden Gruppen-JID.
- DM-Policy:
channels.whatsapp.dmPolicykontrolliert Direktchat-Zugriff (Standard:pairing).- Pairing: Unbekannte Absender erhalten einen Pairing-Code (freigeben mit
openclaw pairing approve whatsapp <code>; Codes laufen nach 1 Stunde ab). - Open: erfordert
channels.whatsapp.allowFrommit"*". - Deine verknüpfte WhatsApp-Nummer ist implizit vertrauenswürdig, daher überspringen Self-Messages die
channels.whatsapp.dmPolicy- undchannels.whatsapp.allowFrom-Prüfungen.
- Pairing: Unbekannte Absender erhalten einen Pairing-Code (freigeben mit
Persönliche-Nummer-Modus (Fallback)
Wenn du OpenClaw mit deiner persönlichen WhatsApp-Nummer nutzt, aktiviere channels.whatsapp.selfChatMode (siehe Beispiel oben).
Verhalten:
- Ausgehende DMs lösen nie Pairing-Antworten aus (verhindert Spam an Kontakte).
- Eingehende unbekannte Absender folgen weiterhin
channels.whatsapp.dmPolicy. - Self-Chat-Modus (allowFrom enthält deine Nummer) vermeidet automatische Lesebestätigungen und ignoriert Erwähnungs-JIDs.
- Lesebestätigungen werden für Nicht-Self-Chat-DMs gesendet.
Lesebestätigungen
Standardmäßig markiert das Gateway eingehende WhatsApp-Nachrichten als gelesen (blaue Häkchen), sobald sie akzeptiert werden.
Global deaktivieren:
{
channels: { whatsapp: { sendReadReceipts: false } },
}
Pro Account deaktivieren:
{
channels: {
whatsapp: {
accounts: {
personal: { sendReadReceipts: false },
},
},
},
}
Hinweise:
- Self-Chat-Modus überspringt immer Lesebestätigungen.
WhatsApp FAQ: Nachrichten senden + Pairing
Wird OpenClaw zufällige Kontakte anschreiben, wenn ich WhatsApp verknüpfe? Nein. Die Standard-DM-Policy ist pairing, daher erhalten unbekannte Absender nur einen Pairing-Code und ihre Nachricht wird nicht verarbeitet. OpenClaw antwortet nur auf Chats, die es empfängt, oder auf Sends, die du explizit auslöst (Agent/CLI).
Wie funktioniert Pairing auf WhatsApp? Pairing ist ein DM-Gate für unbekannte Absender:
- Erste DM von einem neuen Absender gibt einen kurzen Code zurück (Nachricht wird nicht verarbeitet).
- Freigeben mit:
openclaw pairing approve whatsapp <code>(auflisten mitopenclaw pairing list whatsapp). - Codes laufen nach 1 Stunde ab; ausstehende Anfragen sind auf 3 pro Channel begrenzt.
Können mehrere Personen verschiedene OpenClaw-Instanzen mit einer WhatsApp-Nummer nutzen?
Ja, indem du jeden Absender über bindings zu einem anderen Agent routest (Peer kind: "dm", Sender E.164 wie +15551234567). Antworten kommen trotzdem vom selben WhatsApp-Account, und Direktchats kollabieren zur Haupt-Session jedes Agents, also verwende einen Agent pro Person. DM-Zugriffskontrolle (dmPolicy/allowFrom) ist global pro WhatsApp-Account. Siehe Multi-Agent Routing.
Warum fragt der Wizard nach meiner Telefonnummer?
Der Wizard nutzt sie, um deine Allowlist/Owner zu setzen, damit deine eigenen DMs erlaubt sind. Sie wird nicht für automatisches Senden verwendet. Wenn du OpenClaw mit deiner persönlichen WhatsApp-Nummer nutzt, verwende dieselbe Nummer und aktiviere channels.whatsapp.selfChatMode.
Nachrichten-Normalisierung (was das Model sieht)
Bodyist der aktuelle Nachrichtentext mit Envelope.- Zitierter Antwort-Context wird immer angehängt:
[Replying to +1555 id:ABC123] <quoted text or <media:...>> [/Replying] - Antwort-Metadaten werden ebenfalls gesetzt:
ReplyToId= stanzaIdReplyToBody= zitierter Text oder Medien-PlatzhalterReplyToSender= E.164 wenn bekannt
- Nur-Medien-Nachrichten verwenden Platzhalter:
<media:image|video|audio|document|sticker>
Gruppen
- Gruppen werden auf
agent:<agentId>:whatsapp:group:<jid>Sessions gemappt. - Gruppen-Policy:
channels.whatsapp.groupPolicy = open|disabled|allowlist(Standardallowlist). - Aktivierungsmodi:
mention(Standard): erfordert @Erwähnung oder Regex-Match.always: triggert immer.
/activation mention|alwaysist nur für Owner und muss als eigenständige Nachricht gesendet werden.- Owner =
channels.whatsapp.allowFrom(oder Self-E.164 falls nicht gesetzt). - History-Injection (nur ausstehend):
- Kürzliche unverarbeitete Nachrichten (Standard 50) eingefügt unter:
[Chat messages since your last reply - for context](Nachrichten, die bereits in der Session sind, werden nicht erneut eingefügt) - Aktuelle Nachricht unter:
[Current message - respond to this] - Absender-Suffix angehängt:
[from: Name (+E164)]
- Kürzliche unverarbeitete Nachrichten (Standard 50) eingefügt unter:
- Gruppen-Metadaten werden 5 Min. gecacht (Betreff + Teilnehmer).
Antwort-Zustellung (Threading)
- WhatsApp Web sendet Standard-Nachrichten (kein zitiertes Antwort-Threading im aktuellen Gateway).
- Reply-Tags werden auf diesem Channel ignoriert.
Acknowledgment-Reactions (Auto-React bei Empfang)
WhatsApp kann automatisch Emoji-Reactions auf eingehende Nachrichten senden, sofort nach Empfang, bevor der Bot eine Antwort generiert. Das gibt Nutzern sofortiges Feedback, dass ihre Nachricht empfangen wurde.
Konfiguration:
{
"whatsapp": {
"ackReaction": {
"emoji": "👀",
"direct": true,
"group": "mentions"
}
}
}
Optionen:
emoji(string): Emoji für Acknowledgment (z.B. ”👀”, ”✅”, ”📨”). Leer oder weggelassen = Feature deaktiviert.direct(boolean, Standard:true): Reactions in Direkt-/DM-Chats senden.group(string, Standard:"mentions"): Gruppenchat-Verhalten:"always": Auf alle Gruppennachrichten reagieren (auch ohne @Erwähnung)"mentions": Nur reagieren, wenn Bot @erwähnt wird"never": Nie in Gruppen reagieren
Pro-Account-Override:
{
"whatsapp": {
"accounts": {
"work": {
"ackReaction": {
"emoji": "✅",
"direct": false,
"group": "always"
}
}
}
}
}
Verhaltenshinweise:
- Reactions werden sofort nach Nachrichtenempfang gesendet, vor Tipp-Indikatoren oder Bot-Antworten.
- In Gruppen mit
requireMention: false(Aktivierung: always) reagiertgroup: "mentions"auf alle Nachrichten (nicht nur @Erwähnungen). - Fire-and-forget: Reaction-Fehler werden geloggt, verhindern aber nicht die Bot-Antwort.
- Teilnehmer-JID wird automatisch für Gruppen-Reactions eingefügt.
- WhatsApp ignoriert
messages.ackReaction; verwende stattdessenchannels.whatsapp.ackReaction.
Agent-Tool (Reactions)
- Tool:
whatsappmitreact-Action (chatJid,messageId,emoji, optionalremove). - Optional:
participant(Gruppen-Sender),fromMe(auf eigene Nachricht reagieren),accountId(Multi-Account). - Reaction-Entfernungs-Semantik: siehe /tools/reactions.
- Tool-Gating:
channels.whatsapp.actions.reactions(Standard: aktiviert).
Limits
- Ausgehender Text wird in Chunks von
channels.whatsapp.textChunkLimitaufgeteilt (Standard 4000). - Optionales Newline-Chunking: setze
channels.whatsapp.chunkMode="newline", um an Leerzeilen (Absatzgrenzen) vor Längen-Chunking zu splitten. - Eingehende Medien-Speicherungen sind begrenzt durch
channels.whatsapp.mediaMaxMb(Standard 50 MB). - Ausgehende Medien-Items sind begrenzt durch
agents.defaults.mediaMaxMb(Standard 5 MB).
Ausgehende Sends (Text + Medien)
- Verwendet aktiven Web-Listener; Fehler wenn Gateway nicht läuft.
- Text-Chunking: 4k max pro Nachricht (konfigurierbar über
channels.whatsapp.textChunkLimit, optionalchannels.whatsapp.chunkMode). - Medien:
- Image/Video/Audio/Document unterstützt.
- Audio wird als PTT gesendet;
audio/ogg=>audio/ogg; codecs=opus. - Caption nur beim ersten Medien-Item.
- Medien-Fetch unterstützt HTTP(S) und lokale Pfade.
- Animierte GIFs: WhatsApp erwartet MP4 mit
gifPlayback: truefür Inline-Looping.- CLI:
openclaw message send --media <mp4> --gif-playback - Gateway:
send-Params enthaltengifPlayback: true
- CLI:
Sprachnachrichten (PTT-Audio)
WhatsApp sendet Audio als Sprachnachrichten (PTT-Bubble).
- Beste Ergebnisse: OGG/Opus. OpenClaw schreibt
audio/oggum zuaudio/ogg; codecs=opus. [[audio_as_voice]]wird für WhatsApp ignoriert (Audio wird bereits als Sprachnachricht versendet).
Medien-Limits + Optimierung
- Standard-Ausgangs-Cap: 5 MB (pro Medien-Item).
- Override:
agents.defaults.mediaMaxMb. - Bilder werden automatisch zu JPEG unter Cap optimiert (Resize + Quality-Sweep).
- Übergroße Medien => Fehler; Medien-Antwort fällt zurück auf Text-Warnung.
Heartbeats
- Gateway-Heartbeat loggt Verbindungsgesundheit (
web.heartbeatSeconds, Standard 60s). - Agent-Heartbeat kann pro Agent konfiguriert werden (
agents.list[].heartbeat) oder global überagents.defaults.heartbeat(Fallback wenn keine Pro-Agent-Einträge gesetzt sind).- Verwendet den konfigurierten Heartbeat-Prompt (Standard:
Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.) +HEARTBEAT_OK-Skip-Verhalten. - Zustellung standardmäßig zum zuletzt verwendeten Channel (oder konfiguriertem Target).
- Verwendet den konfigurierten Heartbeat-Prompt (Standard:
Reconnect-Verhalten
- Backoff-Policy:
web.reconnect:initialMs,maxMs,factor,jitter,maxAttempts.
- Wenn maxAttempts erreicht, stoppt Web-Monitoring (degraded).
- Ausgeloggt => stoppen und erneutes Verknüpfen erforderlich.
Config-Schnellübersicht
channels.whatsapp.dmPolicy(DM-Policy: pairing/allowlist/open/disabled).channels.whatsapp.selfChatMode(Same-Phone-Setup; Bot nutzt deine persönliche WhatsApp-Nummer).channels.whatsapp.allowFrom(DM-Allowlist). WhatsApp verwendet E.164-Telefonnummern (keine Benutzernamen).channels.whatsapp.mediaMaxMb(Eingehende Medien-Speicher-Cap).channels.whatsapp.ackReaction(Auto-Reaction bei Nachrichtenempfang:{emoji, direct, group}).channels.whatsapp.accounts.<accountId>.*(Pro-Account-Einstellungen + optionalesauthDir).channels.whatsapp.accounts.<accountId>.mediaMaxMb(Pro-Account eingehende Medien-Cap).channels.whatsapp.accounts.<accountId>.ackReaction(Pro-Account Ack-Reaction-Override).channels.whatsapp.groupAllowFrom(Gruppen-Sender-Allowlist).channels.whatsapp.groupPolicy(Gruppen-Policy).channels.whatsapp.historyLimit/channels.whatsapp.accounts.<accountId>.historyLimit(Gruppen-History-Context;0deaktiviert).channels.whatsapp.dmHistoryLimit(DM-History-Limit in User-Turns). Pro-User-Overrides:channels.whatsapp.dms["<phone>"].historyLimit.channels.whatsapp.groups(Gruppen-Allowlist + Mention-Gating-Defaults; verwende"*"um alle zu erlauben)channels.whatsapp.actions.reactions(Gate WhatsApp-Tool-Reactions).agents.list[].groupChat.mentionPatterns(odermessages.groupChat.mentionPatterns)messages.groupChat.historyLimitchannels.whatsapp.messagePrefix(Eingehender Prefix; pro Account:channels.whatsapp.accounts.<accountId>.messagePrefix; deprecated:messages.messagePrefix)messages.responsePrefix(Ausgehender Prefix)agents.defaults.mediaMaxMbagents.defaults.heartbeat.everyagents.defaults.heartbeat.model(optionaler Override)agents.defaults.heartbeat.targetagents.defaults.heartbeat.toagents.defaults.heartbeat.sessionagents.list[].heartbeat.*(Pro-Agent-Overrides)session.*(scope, idle, store, mainKey)web.enabled(Channel-Startup deaktivieren wenn false)web.heartbeatSecondsweb.reconnect.*
Logs + Troubleshooting
- Subsysteme:
whatsapp/inbound,whatsapp/outbound,web-heartbeat,web-reconnect. - Log-Datei:
/tmp/openclaw/openclaw-YYYY-MM-DD.log(konfigurierbar). - Troubleshooting-Guide: Gateway Troubleshooting.
Troubleshooting (Schnell)
Nicht verknüpft / QR-Login erforderlich
- Symptom:
channels statuszeigtlinked: falseoder warnt “Not linked”. - Fix: Führe
openclaw channels loginauf dem Gateway-Host aus und scanne den QR-Code (WhatsApp → Einstellungen → Verknüpfte Geräte).
Verknüpft aber getrennt / Reconnect-Loop
- Symptom:
channels statuszeigtrunning, disconnectedoder warnt “Linked but disconnected”. - Fix:
openclaw doctor(oder Gateway neu starten). Falls es weiterhin besteht, erneut verknüpfen mitchannels loginundopenclaw logs --followprüfen.
Bun-Runtime
- Bun ist nicht empfohlen. WhatsApp (Baileys) und Telegram sind unzuverlässig auf Bun. Führe das Gateway mit Node aus. (Siehe Getting Started Runtime-Hinweis.)