Stato: pronto per la produzione tramite WhatsApp Web (Baileys). Il Gateway gestisce le sessioni collegate.Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
Installazione (su richiesta)
- Onboarding (
openclaw onboard) eopenclaw channels add --channel whatsappchiedono di installare il plugin WhatsApp la prima volta che lo selezioni. - Anche
openclaw channels login --channel whatsappoffre il flusso di installazione quando il plugin non è ancora presente. - Canale dev + checkout git: usa per impostazione predefinita il percorso del plugin locale.
- Stable/Beta: usa il pacchetto npm
@openclaw/whatsappsul tag di rilascio ufficiale corrente.
PATH durante l’installazione npm perché
una delle sue dipendenze Baileys/libsignal viene recuperata da un URL git. Installa
Git for Windows, quindi riavvia la shell ed esegui di nuovo l’installazione:
bin è in PATH.
Associazione
Risoluzione dei problemi del canale
Configurazione del Gateway
Configurazione rapida
Collega WhatsApp (QR)
Pattern di distribuzione
Numero dedicato (consigliato)
Numero dedicato (consigliato)
- identità WhatsApp separata per OpenClaw
- allowlist DM e confini di routing più chiari
- minore probabilità di confusione con le chat con sé stessi
Fallback con numero personale
Fallback con numero personale
dmPolicy: "allowlist"allowFrominclude il tuo numero personaleselfChatMode: true
allowFrom.Ambito del canale solo WhatsApp Web
Ambito del canale solo WhatsApp Web
Baileys) nell’architettura dei canali OpenClaw corrente.Non esiste un canale di messaggistica Twilio WhatsApp separato nel registro integrato dei canali chat.Modello runtime
- Il Gateway gestisce il socket WhatsApp e il ciclo di riconnessione.
- Il watchdog di riconnessione usa l’attività del trasporto WhatsApp Web, non solo il volume dei messaggi app in ingresso, quindi una sessione silenziosa di un dispositivo collegato non viene riavviata solo perché nessuno ha inviato messaggi di recente. Un limite più lungo di silenzio dell’applicazione forza comunque una riconnessione se i frame di trasporto continuano ad arrivare ma non vengono gestiti messaggi dell’applicazione durante la finestra del watchdog; dopo una riconnessione transitoria per una sessione attiva di recente, quel controllo del silenzio dell’applicazione usa il timeout normale dei messaggi per la prima finestra di recupero.
- I timing del socket Baileys sono espliciti sotto
web.whatsapp.*:keepAliveIntervalMscontrolla i ping dell’applicazione WhatsApp Web,connectTimeoutMscontrolla il timeout dell’handshake di apertura edefaultQueryTimeoutMscontrolla i timeout delle query Baileys. - Gli invii in uscita richiedono un listener WhatsApp attivo per l’account di destinazione.
- Gli invii ai gruppi allegano metadati di menzione nativi per i token
@+<digits>e@<digits>nel testo e nelle didascalie dei media quando il token corrisponde ai metadati correnti dei partecipanti WhatsApp, inclusi i gruppi basati su LID. - Le chat di stato e broadcast vengono ignorate (
@status,@broadcast). - Il watchdog di riconnessione segue l’attività del trasporto WhatsApp Web, non solo il volume dei messaggi app in ingresso: le sessioni silenziose dei dispositivi collegati restano attive mentre i frame di trasporto continuano, ma uno stallo del trasporto forza la riconnessione molto prima del percorso successivo di disconnessione remota.
- Le chat dirette usano le regole di sessione DM (
session.dmScope; il valore predefinitomaincollassa i DM nella sessione principale dell’agente). - Le sessioni di gruppo sono isolate (
agent:<agentId>:whatsapp:group:<jid>). - WhatsApp Channels/Newsletters possono essere destinazioni in uscita esplicite con il loro JID nativo
@newsletter. Gli invii in uscita alle newsletter usano i metadati di sessione del canale (agent:<agentId>:whatsapp:channel:<jid>) invece della semantica delle sessioni DM. - Il trasporto WhatsApp Web rispetta le variabili d’ambiente proxy standard sull’host del Gateway (
HTTPS_PROXY,HTTP_PROXY,NO_PROXY/ varianti minuscole). Preferisci la configurazione proxy a livello host rispetto alle impostazioni proxy WhatsApp specifiche del canale. - Quando
messages.removeAckAfterReplyè abilitato, OpenClaw cancella la reazione di ack WhatsApp dopo la consegna di una risposta visibile.
Hook dei plugin e privacy
I messaggi WhatsApp in ingresso possono contenere contenuto di messaggi personali, numeri di telefono, identificatori di gruppo, nomi dei mittenti e campi di correlazione della sessione. Per questo motivo, WhatsApp non trasmette i payload degli hookmessage_received in ingresso ai plugin
a meno che tu non faccia opt-in esplicitamente:
Controllo degli accessi e attivazione
- Policy DM
- Policy dei gruppi + allowlist
- Menzioni + /activation
channels.whatsapp.dmPolicy controlla l’accesso alle chat dirette:pairing(predefinito)allowlistopen(richiede cheallowFromincluda"*")disabled
allowFrom accetta numeri in stile E.164 (normalizzati internamente).allowFrom è una lista di controllo degli accessi per mittenti DM. Non limita gli invii in uscita espliciti verso JID di gruppi WhatsApp o JID di canali @newsletter.Override multi-account: channels.whatsapp.accounts.<id>.dmPolicy (e allowFrom) hanno la precedenza sui valori predefiniti a livello di canale per quell’account.Dettagli del comportamento runtime:- le associazioni vengono persistite nell’allow-store del canale e unite con
allowFromconfigurato - l’automazione pianificata e il fallback dei destinatari Heartbeat usano destinazioni di consegna esplicite o
allowFromconfigurato; le approvazioni di associazione DM non sono destinatari Cron o Heartbeat impliciti - se non è configurata alcuna allowlist, il numero personale collegato è consentito per impostazione predefinita
- OpenClaw non associa mai automaticamente i DM in uscita
fromMe(messaggi che invii a te stesso dal dispositivo collegato)
Comportamento con numero personale e chat con sé stessi
Quando il numero personale collegato è presente anche inallowFrom, si attivano le salvaguardie WhatsApp per la chat con sé stessi:
- salta le conferme di lettura per i turni di chat con sé stessi
- ignora il comportamento di attivazione automatica mention-JID che altrimenti ti pingherebbe
- se
messages.responsePrefixnon è impostato, le risposte nella chat con sé stessi usano per impostazione predefinita[{identity.name}]o[openclaw]
Normalizzazione dei messaggi e contesto
Envelope in ingresso + contesto della risposta
Envelope in ingresso + contesto della risposta
ReplyToId, ReplyToBody, ReplyToSender, JID/E.164 del mittente).
Quando il target della risposta citata è un media scaricabile, OpenClaw lo salva tramite
il normale store dei media in ingresso e lo espone come MediaPath/MediaType in modo che
l’agente possa ispezionare l’immagine referenziata invece di vedere solo
<media:image>.Placeholder dei media ed estrazione di posizione/contatti
Placeholder dei media ed estrazione di posizione/contatti
<media:image><media:video><media:audio><media:document><media:sticker>
<media:audio>, quindi pronunciare la menzione del bot nella nota vocale può
attivare la risposta. Se la trascrizione continua a non menzionare il bot, la
trascrizione viene mantenuta nella cronologia di gruppo in sospeso invece del placeholder grezzo.I corpi delle posizioni usano testo conciso con coordinate. Etichette/commenti delle posizioni e dettagli di contatti/vCard vengono resi come metadati non attendibili in blocchi fenced, non come testo inline del prompt.Iniezione della cronologia di gruppo in sospeso
Iniezione della cronologia di gruppo in sospeso
- limite predefinito:
50 - configurazione:
channels.whatsapp.historyLimit - ripiego:
messages.groupChat.historyLimit 0disabilita
[Chat messages since your last reply - for context][Current message - respond to this]
Conferme di lettura
Conferme di lettura
Consegna, suddivisione in blocchi e media
Suddivisione del testo in blocchi
Suddivisione del testo in blocchi
- limite predefinito del blocco:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"- la modalità
newlinepreferisce i confini di paragrafo (righe vuote), poi ricorre alla suddivisione in blocchi sicura per lunghezza
Comportamento dei media in uscita
Comportamento dei media in uscita
- supporta payload di immagini, video, audio (nota vocale PTT) e documenti
- i media audio vengono inviati tramite il payload
audiodi Baileys conptt: true, quindi i client WhatsApp li mostrano come note vocali push-to-talk - i payload di risposta preservano
audioAsVoice; l’output di note vocali TTS per WhatsApp rimane su questo percorso PTT anche quando il provider restituisce MP3 o WebM - l’audio Ogg/Opus nativo viene inviato come
audio/ogg; codecs=opusper la compatibilità con le note vocali - l’audio non Ogg, incluso l’output MP3/WebM di Microsoft Edge TTS, viene transcodificato con
ffmpegin Ogg/Opus mono a 48 kHz prima della consegna PTT /tts latestinvia l’ultima risposta dell’assistente come una singola nota vocale e sopprime gli invii ripetuti per la stessa risposta;/tts chat on|off|defaultcontrolla il TTS automatico per la chat WhatsApp corrente- la riproduzione delle GIF animate è supportata tramite
gifPlayback: truenegli invii video - le didascalie vengono applicate al primo elemento multimediale quando si inviano payload di risposta con più media, tranne che le note vocali PTT inviano prima l’audio e il testo visibile separatamente perché i client WhatsApp non mostrano le didascalie delle note vocali in modo coerente
- la sorgente multimediale può essere HTTP(S),
file://o percorsi locali
Limiti di dimensione dei media e comportamento di ripiego
Limiti di dimensione dei media e comportamento di ripiego
- limite di salvataggio dei media in ingresso:
channels.whatsapp.mediaMaxMb(predefinito50) - limite di invio dei media in uscita:
channels.whatsapp.mediaMaxMb(predefinito50) - gli override per account usano
channels.whatsapp.accounts.<accountId>.mediaMaxMb - le immagini vengono ottimizzate automaticamente (ridimensionamento/verifica della qualità) per rientrare nei limiti
- in caso di errore nell’invio dei media, il ripiego del primo elemento invia un avviso testuale invece di eliminare silenziosamente la risposta
Citazione nelle risposte
WhatsApp supporta la citazione nativa nelle risposte, in cui le risposte in uscita citano visibilmente il messaggio in ingresso. Controllala conchannels.whatsapp.replyToMode.
| Valore | Comportamento |
|---|---|
"off" | Non citare mai; invia come messaggio semplice |
"first" | Cita solo il primo blocco di risposta in uscita |
"all" | Cita ogni blocco di risposta in uscita |
"batched" | Cita le risposte accodate in batch lasciando non citate quelle immediate |
"off". Gli override per account usano channels.whatsapp.accounts.<id>.replyToMode.
Livello di reazione
channels.whatsapp.reactionLevel controlla quanto ampiamente l’agente usa le reazioni emoji su WhatsApp:
| Livello | Reazioni di conferma | Reazioni avviate dall’agente | Descrizione |
|---|---|---|---|
"off" | No | No | Nessuna reazione |
"ack" | Sì | No | Solo reazioni di conferma (ricevuta prima della risposta) |
"minimal" | Sì | Sì (conservative) | Conferma + reazioni dell’agente con guida prudente |
"extensive" | Sì | Sì (incoraggiate) | Conferma + reazioni dell’agente con guida incoraggiata |
"minimal".
Gli override per account usano channels.whatsapp.accounts.<id>.reactionLevel.
Reazioni di conferma
WhatsApp supporta reazioni di conferma immediate alla ricezione in ingresso tramitechannels.whatsapp.ackReaction.
Le reazioni di conferma sono controllate da reactionLevel: vengono soppresse quando reactionLevel è "off".
- inviate immediatamente dopo l’accettazione del messaggio in ingresso (prima della risposta)
- gli errori vengono registrati ma non bloccano la normale consegna della risposta
- la modalità gruppo
mentionsreagisce ai turni attivati da menzioni; l’attivazione del gruppoalwayspermette di saltare questo controllo - WhatsApp usa
channels.whatsapp.ackReaction(il valore legacymessages.ackReactionnon viene usato qui)
Multi-account e credenziali
Selezione dell'account e valori predefiniti
Selezione dell'account e valori predefiniti
- gli ID account provengono da
channels.whatsapp.accounts - selezione dell’account predefinito:
defaultse presente, altrimenti il primo ID account configurato (ordinato) - gli ID account vengono normalizzati internamente per la ricerca
Percorsi delle credenziali e compatibilità legacy
Percorsi delle credenziali e compatibilità legacy
- percorso di autenticazione corrente:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - file di backup:
creds.json.bak - l’autenticazione predefinita legacy in
~/.openclaw/credentials/è ancora riconosciuta/migrata per i flussi dell’account predefinito
Comportamento di logout
Comportamento di logout
openclaw channels logout --channel whatsapp [--account <id>] cancella lo stato di autenticazione WhatsApp per quell’account.Quando un Gateway è raggiungibile, il logout prima arresta il listener WhatsApp attivo per l’account selezionato, così la sessione collegata non continua a ricevere messaggi fino al riavvio successivo. Anche openclaw channels remove --channel whatsapp arresta il listener attivo prima di disabilitare o eliminare la configurazione dell’account.Nelle directory di autenticazione legacy, oauth.json viene preservato mentre i file di autenticazione Baileys vengono rimossi.Strumenti, azioni e scritture di configurazione
- Il supporto agli strumenti dell’agente include l’azione di reazione WhatsApp (
react). - Gate delle azioni:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Le scritture di configurazione avviate dal canale sono abilitate per impostazione predefinita (disabilita tramite
channels.whatsapp.configWrites=false).
Risoluzione dei problemi
Non collegato (QR richiesto)
Non collegato (QR richiesto)
Collegato ma disconnesso / ciclo di riconnessione
Collegato ma disconnesso / ciclo di riconnessione
status=408 Request Time-out Connection was lost, regola
i tempi del socket Baileys sotto web.whatsapp. Inizia accorciando
keepAliveIntervalMs sotto il timeout di inattività della tua rete e aumentando
connectTimeoutMs su collegamenti lenti o con perdita di pacchetti:~/.openclaw/logs/whatsapp-health.log dice Gateway inactive ma
openclaw gateway status e openclaw channels status --probe mostrano che il
Gateway e WhatsApp sono in salute, esegui openclaw doctor. Su Linux, doctor
avvisa delle voci crontab legacy che invocano ancora
~/.openclaw/bin/ensure-whatsapp.sh; rimuovi quelle voci obsolete con
crontab -e perché cron può non avere l’ambiente del bus utente systemd e
far sì che quel vecchio script segnali erroneamente lo stato del Gateway.Se necessario, ricollega con channels login.Il login QR va in timeout dietro un proxy
Il login QR va in timeout dietro un proxy
openclaw channels login --channel whatsapp fallisce prima di mostrare un codice QR utilizzabile con status=408 Request Time-out o una disconnessione del socket TLS.Il login WhatsApp Web usa l’ambiente proxy standard dell’host del Gateway (HTTPS_PROXY, HTTP_PROXY, varianti minuscole e NO_PROXY). Verifica che il processo del Gateway erediti l’ambiente proxy e che NO_PROXY non corrisponda a mmg.whatsapp.net.Nessun listener attivo durante l'invio
Nessun listener attivo durante l'invio
La risposta appare nella trascrizione ma non in WhatsApp
La risposta appare nella trascrizione ma non in WhatsApp
auto-reply delivery failed o auto-reply was not accepted by WhatsApp provider.Messaggi di gruppo ignorati inaspettatamente
Messaggi di gruppo ignorati inaspettatamente
groupPolicygroupAllowFrom/allowFrom- voci della lista consentiti
groups - gate basato su menzioni (
requireMention+ pattern di menzione) - chiavi duplicate in
openclaw.json(JSON5): le voci successive sovrascrivono quelle precedenti, quindi mantieni un sologroupPolicyper ambito
Avviso del runtime Bun
Avviso del runtime Bun
Prompt di sistema
WhatsApp supporta prompt di sistema in stile Telegram per gruppi e chat dirette tramite le mappegroups e direct.
Gerarchia di risoluzione per i messaggi di gruppo:
La mappa groups effettiva viene determinata per prima: se l’account definisce i propri groups, sostituisce completamente la mappa groups radice (nessun deep merge). La ricerca del prompt viene quindi eseguita sulla singola mappa risultante:
- Prompt di sistema specifico del gruppo (
groups["<groupId>"].systemPrompt): usato quando la voce del gruppo specifico esiste nella mappa e la sua chiavesystemPromptè definita. SesystemPromptè una stringa vuota (""), il carattere jolly viene soppresso e non viene applicato alcun prompt di sistema. - Prompt di sistema jolly del gruppo (
groups["*"].systemPrompt): usato quando la voce del gruppo specifico è del tutto assente dalla mappa oppure quando esiste ma non definisce alcuna chiavesystemPrompt.
direct effettiva viene determinata per prima: se l’account definisce la propria direct, sostituisce completamente la mappa direct radice (nessun deep merge). La ricerca del prompt viene quindi eseguita sulla singola mappa risultante:
- Prompt di sistema specifico per chat diretta (
direct["<peerId>"].systemPrompt): usato quando la voce del peer specifico esiste nella mappa e la sua chiavesystemPromptè definita. SesystemPromptè una stringa vuota (""), il jolly viene soppresso e non viene applicato alcun prompt di sistema. - Prompt di sistema jolly per chat diretta (
direct["*"].systemPrompt): usato quando la voce del peer specifico è completamente assente dalla mappa, oppure quando esiste ma non definisce alcuna chiavesystemPrompt.
dms rimane il contenitore leggero di override della cronologia per DM (dms.<id>.historyLimit). Gli override dei prompt risiedono sotto direct.groups a livello radice viene intenzionalmente soppresso per tutti gli account in una configurazione con più account, anche per gli account che non definiscono propri groups, per impedire a un bot di ricevere messaggi di gruppo per gruppi a cui non appartiene. WhatsApp non applica questa protezione: groups a livello radice e direct a livello radice vengono sempre ereditati dagli account che non definiscono override a livello di account, indipendentemente da quanti account siano configurati. In una configurazione WhatsApp con più account, se vuoi prompt di gruppo o diretti per account, definisci esplicitamente la mappa completa sotto ciascun account invece di affidarti ai valori predefiniti a livello radice.
Comportamento importante:
channels.whatsapp.groupsè sia una mappa di configurazione per gruppo sia la allowlist dei gruppi a livello di chat. A livello radice o di account,groups["*"]significa “tutti i gruppi sono ammessi” per quell’ambito.- Aggiungi un
systemPromptdi gruppo jolly solo quando vuoi già che quell’ambito ammetta tutti i gruppi. Se vuoi comunque che sia idoneo solo un insieme fisso di ID gruppo, non usaregroups["*"]per il valore predefinito del prompt. Ripeti invece il prompt su ogni voce di gruppo esplicitamente inclusa nella allowlist. - L’ammissione del gruppo e l’autorizzazione del mittente sono controlli separati.
groups["*"]amplia l’insieme dei gruppi che possono raggiungere la gestione dei gruppi, ma da solo non autorizza ogni mittente in quei gruppi. L’accesso del mittente è comunque controllato separatamente dachannels.whatsapp.groupPolicyechannels.whatsapp.groupAllowFrom. channels.whatsapp.directnon ha lo stesso effetto collaterale per i DM.direct["*"]fornisce solo una configurazione predefinita per le chat dirette dopo che un DM è già stato ammesso dadmPolicypiùallowFromo dalle regole dell’archivio di associazione.
Puntatori di riferimento per la configurazione
Riferimento principale: Campi WhatsApp ad alto segnale:- accesso:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - recapito:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - più account:
accounts.<id>.enabled,accounts.<id>.authDir, override a livello di account - operazioni:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.*,web.whatsapp.* - comportamento della sessione:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit - prompt:
groups.<id>.systemPrompt,groups["*"].systemPrompt,direct.<id>.systemPrompt,direct["*"].systemPrompt