Statut : prêt pour la production via WhatsApp Web (Baileys). Le Gateway possède les sessions liées.
Installer (à la demande)
Section intitulée « Installer (à la demande) »- L’intégration (
openclaw onboard) etopenclaw channels add --channel whatsappvous invitent à installer le plugin WhatsApp la première fois que vous le sélectionnez. openclaw channels login --channel whatsapppropose également le flux d’installation lorsque le plugin n’est pas encore présent.- Canal Dev + git checkout : par défaut, le chemin du plugin local.
- Stable/Bêta : installe le plugin officiel
@openclaw/whatsappdepuis ClawHub en premier, avec npm comme solution de repli. - Le runtime WhatsApp est distribué en dehors du package npm principal d’OpenClaw afin que les dépendances d’exécution spécifiques à WhatsApp restent avec le plugin externe.
L’installation manuelle reste disponible :
openclaw plugins install clawhub:@openclaw/whatsappUtilisez le package nu npm (@openclaw/whatsapp) uniquement lorsque vous avez besoin du registre
de repli. Épinglez une version exacte uniquement lorsque vous avez besoin d’une installation reproductible.
La stratégie de DM par défaut est l’appariement pour les expéditeurs inconnus.
Playbooks de diagnostic et de réparation multi-canaux.
Modèles et exemples complets de configuration de canal.
Configuration rapide
Section intitulée « Configuration rapide »Configurer la stratégie d'accès WhatsApp
{channels: {whatsapp: {dmPolicy: "pairing",allowFrom: ["+15551234567"],groupPolicy: "allowlist",groupAllowFrom: ["+15551234567"],},},}Lier WhatsApp (QR)
Fenêtre de terminal openclaw channels login --channel whatsappLa connexion actuelle est basée sur QR. Dans les environnements distants ou sans interface graphique, assurez-vousd'avoir un chemin fiable pour transmettre le code QR en direct au téléphone qui va le scanneravant de démarrer la connexion.Pour un compte spécifique :Fenêtre de terminal openclaw channels login --channel whatsapp --account workPour attacher un répertoire d'authentification WhatsApp Web existant/personnalisé avant la connexion :Fenêtre de terminal openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-authopenclaw channels login --channel whatsapp --account workDémarrer la passerelle
Fenêtre de terminal openclaw gatewayApprouver la première demande d'appariement (si vous utilisez le mode d'appariement)
Fenêtre de terminal openclaw pairing list whatsappopenclaw pairing approve whatsappLes demandes d'appariement expirent après 1 heure. Les demandes en attente sont limitées à 3 par channel.
Modèles de déploiement
Section intitulée « Modèles de déploiement »Numéro dédié (recommandé)
C’est le mode opérationnel le plus propre :
- identité WhatsApp séparée pour OpenClaw
- listes d’autorisation DM et limites de routage plus claires
- risque réduit de confusion avec les auto-discussions
Modèle de stratégie minimal :
{ channels: { whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15551234567"], }, },}Mode de repli avec numéro personnel
Onboarding prend en charge le mode numéro personnel et écrit une ligne de base adaptée aux auto-discussions :
dmPolicy: "allowlist"allowFrominclut votre numéro personnelselfChatMode: true
Au runtime, les protections de l’auto-discussion se basent sur le numéro auto lié et allowFrom.
Périmètre du channel WhatsApp Web uniquement
Le channel de la plateforme de messagerie est basé sur WhatsApp Web (Baileys) dans l’architecture actuelle des channels OpenClaw.
Il n’y a pas de channel de messagerie WhatsApp Twilio séparé dans le registre des channels de chat intégrés.
Modèle d’exécution
Section intitulée « Modèle d’exécution »- Le Gateway possède le socket WhatsApp et la boucle de reconnexion.
- Le chien de garde de reconnexion utilise l’activité de transport WhatsApp Web, et pas seulement le volume des messages entrants de l’application ; ainsi, une session d’appareil lié silencieuse n’est pas redémarrée uniquement parce que personne n’a envoyé de message récemment. Un plafond de silence d’application plus long force toujours une reconnexion si les trames de transport continuent d’arriver mais qu’aucun message d’application n’est géré pendant la fenêtre du chien de garde ; après une reconnexion transitoire pour une session récemment active, cette vérification de silence d’application utilise le délai d’expiration normal des messages pour la première fenêtre de récupération.
- Les timings du socket Baileys sont explicites sous
web.whatsapp.*:keepAliveIntervalMscontrôle les pings d’application WhatsApp Web,connectTimeoutMscontrôle le délai d’expiration de la poignée de main d’ouverture, etdefaultQueryTimeoutMscontrôle les délais d’expiration des requêtes Baileys. - Les envois sortants nécessitent un écouteur WhatsApp actif pour le compte cible.
- Les envois de groupe attachent des métadonnées de mention natives pour les jetons
@+<digits>et@<digits>dans le texte et les légendes des médias lorsque le jeton correspond aux métadonnées du participant WhatsApp actuel, y compris les groupes pris en charge par LID. - Les discussions de statut et de diffusion sont ignorées (
@status,@broadcast). - Le chien de garde de reconnexion suit l’activité de transport WhatsApp Web, et pas seulement le volume des messages entrants de l’application : les sessions d’appareil lié silencieuses restent actives tant que les trames de transport continuent, mais un arrêt du transport force une reconnexion bien avant le chemin de déconnexion distant ultérieur.
- Les discussions directes utilisent les règles de session DM (
session.dmScope; par défaut,mainréduit les DMs à la session principale de l’agent). - Les sessions de groupe sont isolées (
agent:<agentId>:whatsapp:group:<jid>). - Les chaînes/lettres d’information WhatsApp peuvent être des cibles sortantes explicites avec leur JID natif
@newsletter. Les envois de lettres d’information sortants utilisent les métadonnées de session de chaîne (agent:<agentId>:whatsapp:channel:<jid>) plutôt que la sémantique de session DM. - Le transport WhatsApp Web respecte les variables d’environnement de proxy standard sur l’hôte de la passerelle (WhatsApp
HTTPS_PROXY,HTTP_PROXY,NO_PROXYWhatsApp / variantes en minuscules). Préférez la configuration proxy au niveau de l’hôte aux paramètres de proxy WhatsApp spécifiques au canal. - Lorsque
messages.removeAckAfterReplyOpenClawWhatsApp est activé, OpenClaw efface la réaction d’accusé de réception (ack) WhatsApp une fois qu’une réponse visible est délivrée.
Prompts d’approbation
Section intitulée « Prompts d’approbation »WhatsApp peut afficher les prompts d’approbation d’exécution et de plugin avec des réactions 👍 / 👎. La livraison est
contrôlée par la configuration de transfert d’approbation de premier niveau :
{ approvals: { exec: { enabled: true, mode: "session", }, plugin: { enabled: true, mode: "targets", targets: [{ channel: "whatsapp", to: "+15551234567" }], }, },}approvals.exec et approvals.plugin sont indépendants. L’activation de WhatsApp en tant que channel ne fait que lier
le transport ; elle n’envoie pas de invites d’approbation, sauf si la famille d’approbation correspondante est activée
et routée vers WhatsApp. Le mode session délivre des approbations par emoji natives uniquement pour les approbations
qui proviennent de WhatsApp. Le mode cible utilise le pipeline de transfert partagé pour les cibles WhatsApp
explicites et ne crée pas de ventilateur de DM d’approbateur séparé.
Les réactions d’approbation WhatsApp nécessitent des approbateurs WhatsApp explicites provenant de allowFrom ou "*".
defaultTo contrôle les cibles de message par défaut ordinaires ; ce n’est pas un approbateur d’approbation. Les commandes manuelles
/approve passent toujours par le chemin d’autorisation d’envoi WhatsApp normal avant
la résolution de l’approbation.
Crochets de plugin et confidentialité
Section intitulée « Crochets de plugin et confidentialité »Les messages entrants WhatsApp peuvent contenir du contenu de message personnel, des numéros de téléphone,
des identifiants de groupe, des noms d’expéditeur et des champs de corrélation de session. Pour cette raison,
WhatsApp ne diffuse pas les charges utiles de hook message_received entrantes aux plugins
sauf si vous optez explicitement pour :
{ channels: { whatsapp: { pluginHooks: { messageReceived: true, }, }, },}Vous pouvez limiter l’opt-in à un seul compte :
{ channels: { whatsapp: { accounts: { work: { pluginHooks: { messageReceived: true, }, }, }, }, },}N’activez cela que pour les plugins auxquels vous faites confiance pour recevoir le contenu et les identifiants des messages WhatsApp entrants.
Contrôle d’accès et activation
Section intitulée « Contrôle d’accès et activation »channels.whatsapp.dmPolicy contrôle l’accès aux discussions directes :
pairing(par défaut)allowlistopen(nécessite queallowFrominclue"*")disabled
allowFrom accepte les numéros au format E.164 (normalisés en interne).
allowFrom est une liste de contrôle d’accès des expéditeurs de DM. Elle ne bloque pas les envois sortants explicites vers les JID de groupe WhatsApp ou les JID de channel @newsletter.
Substitution multi-compte : `channels.whatsapp.accounts.
.dmPolicy(etallowFrom`) priment sur les paramètres par défaut au niveau du channel pour ce compte.
Détails du comportement à l'exécution :
- les appariements sont conservés dans le magasin d'autorisation de channel et fusionnés avec `allowFrom` configuré- l'automatisation planifiée et le destinataire de secours du heartbeat utilisent des cibles de livraison explicites ou `allowFrom` configuré ; les approbations d'appariement DM ne sont pas des destinataires implicites pour le cron ou le heartbeat- si aucune liste d'autorisation n'est configurée, le numéro personnel lié est autorisé par défaut- OpenClaw n'apparie jamais automatiquement les DM sortants `fromMe` (messages que vous vous envoyez depuis l'appareil lié)L’accès aux groupes comporte deux niveaux :
-
Liste d’autorisation d’appartenance au groupe (
channels.whatsapp.groups)- si
groupsest omis, tous les groupes sont éligibles - si
groupsest présent, il agit comme une liste d’autorisation de groupe ("*"autorisés)
- si
-
Stratégie d’expéditeur de groupe (
channels.whatsapp.groupPolicy+groupAllowFrom)open: liste d’autorisation de l’expéditeur contournéeallowlist: l’expéditeur doit correspondre àgroupAllowFrom(ou*)disabled: bloquer tout le trafic entrant du groupe
Repli de la liste d’autorisation de l’expéditeur :
- si
groupAllowFromn’est pas défini, le moteur d’exécution (runtime) revient àallowFromsi disponible - les listes d’autorisation des expéditeurs sont évaluées avant l’activation par mention/réponse
Remarque : si aucun bloc channels.whatsapp n’existe du tout, le repli de la stratégie de groupe du runtime est allowlist (avec un journal d’avertissement), même si channels.defaults.groupPolicy est défini.
Les réponses de groupe nécessitent une mention par défaut.
La détection de mention comprend :
- les mentions explicites WhatsApp de l’identité du bot
- les motifs regex de mention configurés (
agents.list[].groupChat.mentionPatterns, replimessages.groupChat.mentionPatterns) - les transcriptions de notes vocales entrantes pour les messages de groupe autorisés
- la détection implicite de réponse au bot (l’expéditeur de la réponse correspond à l’identité du bot)
Note de sécurité :
- la citation/réponse satisfait uniquement le filtrage par mention ; elle n’accorde pas l’autorisation de l’expéditeur
- avec
groupPolicy: "allowlist", les expéditeurs non autorisés sont toujours bloqués même s’ils répondent à un message d’un utilisateur autorisé
Commande d’activation au niveau de la session :
/activation mention/activation always
activation met à jour l’état de la session (pas la configuration globale). Il est restreint au propriétaire.
Comportement du numéro personnel et de l’auto-discussion
Section intitulée « Comportement du numéro personnel et de l’auto-discussion »Lorsque le numéro personnel lié est également présent dans allowFromWhatsApp, les sauvegardes d’auto-discussion WhatsApp s’activent :
- ignorer les accusés de lecture pour les tours de chat avec soi-même
- ignorer le comportement de déclenchement automatique de mention-JID qui vous ferait autrement vous pinguer vous-même
- si
messages.responsePrefixn’est pas défini, les réponses de chat avec soi-même correspondent par défaut à[{identity.name}]ou[openclaw]
Normalisation des messages et contexte
Section intitulée « Normalisation des messages et contexte »Enveloppe entrante + contexte de réponse
Les messages WhatsApp entrants sont enveloppés dans l’enveloppe entrante partagée.
Si une réponse citée existe, le contexte est ajouté sous cette forme :
[Replying toid:
]
[/Replying]
Les champs de métadonnées de réponse sont également renseignés lorsque disponibles (`ReplyToId`, `ReplyToBody`, `ReplyToSender`, JID de l'expéditeur/E.164).Lorsque la cible de la réponse citée est un média téléchargeable, OpenClaw l'enregistre viale magasin de médias entrant normal et l'expose en tant que `MediaPath`/`MediaType` afinque l'agent puisse inspecter l'image référencée au lieu de ne voir que``.
Espaces réservés pour les médias et extraction de localisation/contact
Les messages entrants contenant uniquement des médias sont normalisés avec des espaces réservés tels que :
- `
-
-
-
-
`
Les notes vocales autorisées des groupes sont transcrites avant le filtrage par mention lorsque lecorps est uniquement ``, de sorte que prononcer la mention du bot dans la note vocale peut déclencher la réponse. Si la transcription ne mentionne toujours pas le bot, la transcription est conservée dans l’historique des groupes en attente au lieu de l’espace réservé brut.
Les corps de localisation utilisent un texte de coordonnées concis. Les étiquettes/commentaires de localisation et les détails de contact/vCard sont rendus en tant que métadonnées non fiables clôturées, et non en tant que texte d'invite en ligne.Injection de l'historique de groupe en attente
Pour les groupes, les messages non traités peuvent être mis en tampon et injectés en contexte lorsque le bot est finalement déclenché.
- limite par défaut :
50 - configuration :
channels.whatsapp.historyLimit - repli :
messages.groupChat.historyLimit 0désactive
Marqueurs d’injection :
[Chat messages since your last reply - for context][Current message - respond to this]
Accusés de réception
Les accusés de réception sont activés par défaut pour les messages WhatsApp entrants acceptés.
Désactiver globalement :
{ channels: { whatsapp: { sendReadReceipts: false, }, },}Remplacement par compte :
{ channels: { whatsapp: { accounts: { work: { sendReadReceipts: false, }, }, }, },}Les tours de dialogue avec soi-même ignorent les accusés de réception même s’ils sont activés globalement.
Livraison, découpage et médias
Section intitulée « Livraison, découpage et médias »Découpage du texte
- limite de découpage par défaut :
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"- le mode
newlinepréfère les limites de paragraphe (lignes vides), puis revient au découpage sécurisé en termes de longueur
Comportement des médias sortants
- prend en charge les charges utiles d’image, vidéo, audio (note vocale PTT) et de document
- les médias audio sont envoyés via la charge utile
audiode Baileys avecptt: true, de sorte que les clients WhatsApp l’affichent comme une note vocale appuyer-parler (push-to-talk) - les charges utiles de réponse préservent
audioAsVoice; la sortie de note vocale TTS pour WhatsApp reste sur ce chemin PTT même lorsque le provider renvoie du MP3 ou WebM - l’audio Ogg/Opus natif est envoyé sous forme de
audio/ogg; codecs=opuspour la compatibilité des notes vocales - l’audio non-Ogg, y compris la sortie MP3/WebM du TTS Microsoft Edge, est transcodé avec
ffmpegen Ogg/Opus mono 48 kHz avant la livraison PTT /tts latestenvoie la dernière réponse de l’assistant en une seule note vocale et supprime les envois répétés pour la même réponse;/tts chat on|off|defaultcontrôle le TTS automatique pour la discussion WhatsApp actuelle- la lecture des GIF animés est prise en charge via
gifPlayback: truelors de l’envoi de vidéos forceDocument/asDocumentenvoie les images, GIF et vidéos sortants via la charge utile de document Baileys pour éviter la compression des médias WhatsApp tout en préservant le nom de fichier résolu et le type MIME- les légendes sont appliquées au premier élément multimédia lors de l’envoi de charges utiles de réponse multimédia, sauf que les notes vocales PTT envoient d’abord l’audio puis le texte visible séparément, car les clients WhatsApp n’affichent pas les légendes de notes vocales de manière cohérente
- la source multimédia peut être HTTP(S),
file://, ou des chemins locaux
Limites de taille des médias et comportement de repli
- limite d’enregistrement des médias entrants :
channels.whatsapp.mediaMaxMb(par défaut50) - limite d’envoi des médias sortants :
channels.whatsapp.mediaMaxMb(par défaut50) - les remplacements par compte utilisent `channels.whatsapp.accounts.
.mediaMaxMb - les images sont automatiquement optimisées (redimensionnement/ajustement de la qualité) pour respecter les limites, sauf siforceDocument/asDocument` demande une livraison de document
- en cas d’échec de l’envoi d’un média, le repli du premier élément envoie un avertissement texte au lieu d’abandonner silencieusement la réponse
Citation de réponse
Section intitulée « Citation de réponse »WhatsApp prend en charge la citation de réponse native, où les réponses sortantes citent visuellement le message entrant. Contrôlez cela avec channels.whatsapp.replyToMode.
| Valeur | Comportement |
|---|---|
"off" | Ne jamais citer ; envoyer comme un message simple |
"first" | Citer uniquement le premier bloc de réponse sortant |
"all" | Citer chaque bloc de réponse sortant |
"batched" | Citer les réponses groupées en file d’attente tout en laissant les réponses immédiates sans citation |
La valeur par défaut est "off". Les remplacements par compte utilisent channels.whatsapp.accounts.<id>.replyToMode.
{ channels: { whatsapp: { replyToMode: "first", }, },}Niveau de réaction
Section intitulée « Niveau de réaction »channels.whatsapp.reactionLevel contrôle la manière dont l’agent utilise les réactions emoji sur WhatsApp :
| Niveau | Réactions d’accusé de réception | Réactions initiées par l’agent | Description |
|---|---|---|---|
"off" | Non | Non | Aucune réaction |
"ack" | Oui | Non | Réactions d’accusé de réception uniquement (accusé de réception avant réponse) |
"minimal" | Oui | Oui (conservateur) | Accusé de réception + réactions de l’agent avec directives conservatrices |
"extensive" | Oui | Oui (encouragé) | Accusé de réception + réactions de l’agent avec directives encourageantes |
Par défaut : "minimal".
Les remplacements par compte utilisent channels.whatsapp.accounts.<id>.reactionLevel.
{ channels: { whatsapp: { reactionLevel: "ack", }, },}Réactions d’accusé de réception
Section intitulée « Réactions d’accusé de réception »WhatsApp prend en charge les réactions d’accusé de réception immédiats sur la réception entrante via WhatsAppchannels.whatsapp.ackReaction.
Les réactions d’accusé de réception sont contrôlées par reactionLevel — elles sont supprimées lorsque reactionLevel est "off".
{ channels: { whatsapp: { ackReaction: { emoji: "👀", direct: true, group: "mentions", // always | mentions | never }, }, },}Notes de comportement :
- envoyé immédiatement après acceptation de l’entrant (pré-réponse)
- si
ackReactionest présent sansemoji, WhatsApp utilise l’émoji d’identité de l’agent acheminé, par défaut « 👀 » ; omettezackReactionou définissezemoji: ""pour n’envoyer aucune réaction d’accusé de réception - les échecs sont enregistrés mais ne bloquent pas la livraison des réponses normales
- le mode de groupe
mentionsréagit aux tours déclenchés par des mentions ; l’activation de groupealwaysagit comme une dérogation pour cette vérification - WhatsApp utilise
channels.whatsapp.ackReaction(l’ancienmessages.ackReactionn’est pas utilisé ici)
Réactions de statut du cycle de vie
Section intitulée « Réactions de statut du cycle de vie »Définissez messages.statusReactions.enabled: true pour permettre à WhatsApp de remplacer la réaction d’accusé de réception pendant un tour au lieu de laisser un émoji de reçu statique. Lorsqu’elle est activée, OpenClaw utilise le même emplacement de réaction aux messages entrants pour les états du cycle de vie tels que mis en file d’attente, réflexion, activité de l’outil, compactage, terminé et erreur.
{ messages: { statusReactions: { enabled: true, emojis: { deploy: "🛫", build: "🏗️", concierge: "💁", }, }, },}Notes sur le comportement :
channels.whatsapp.ackReactioncontrôle toujours si les réactions de statut sont éligibles pour les messages directs et les groupes.- La réaction de statut mis en file d’attente utilise le même émoji d’accusé de réception effectif que les réactions d’accusé de réception simples.
- WhatsApp dispose d’un seul emplacement de réaction de bot par message, les mises à jour du cycle de vie remplacent donc la réaction actuelle sur place.
messages.removeAckAfterReply: trueefface la réaction de statut finale après la pause configurée pour terminé/erreur.- Les catégories d’émojis d’outils incluent
tool,coding,web,deploy,buildetconcierge.
Multi-compte et identifiants
Section intitulée « Multi-compte et identifiants »Sélection de compte et valeurs par défaut
- les identifiants de compte proviennent de
channels.whatsapp.accounts - sélection du compte par défaut :
defaultsi présent, sinon le premier identifiant de compte configuré (trié) - les identifiants de compte sont normalisés en interne pour la recherche
Chemins d'accès aux identifiants et compatibilité avec l'ancien système
- chemin d’authentification actuel : `~/.openclaw/credentials/whatsapp/
/creds.json - fichier de sauvegarde :creds.json.bak - l'authentification par défaut héritée dans~/.openclaw/credentials/` est toujours reconnue/migrée pour les flux de comptes par défaut
Comportement de déconnexion
`openclaw channels logout —channel whatsapp [—account
]`WhatsAppGatewayWhatsApp efface l’état d’authentification WhatsApp pour ce compte.
Lorsqu'un Gateway est accessible, la déconnexion arrête d'abord l'écouteur WhatsApp en direct pour le compte sélectionné afin que la session liée ne continue pas à recevoir des messages jusqu'au prochain redémarrage. `openclaw channels remove --channel whatsapp` arrête également l'écouteur en direct avant de désactiver ou de supprimer la configuration du compte.
Dans les répertoires d'authentification hérités, `oauth.json`Baileys est conservé tandis que les fichiers d'authentification Baileys sont supprimés.Outils, actions et écritures de configuration
Section intitulée « Outils, actions et écritures de configuration »- La prise en charge des outils de l’agent inclut l’action de réaction WhatsApp (WhatsApp
react). - Portes d’action (Action gates) :
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Les écritures de configuration initiées par le canal sont activées par défaut (désactiver via
channels.whatsapp.configWrites=false).
Dépannage
Section intitulée « Dépannage »Non lié (QR requis)
Symptôme : l’état du canal indique non lié.
Correction :
openclaw channels login --channel whatsappopenclaw channels statusLinked but disconnected / reconnect loop
Symptôme : compte lié avec des déconnexions répétées ou des tentatives de reconnexion.
Les comptes inactifs peuvent rester connectés au-delà du délai d’expiration normal des messages ; le watchdog redémarre lorsque l’activité de transport de WhatsApp Web s’arrête, que la socket se ferme ou que l’activité au niveau de l’application reste silencieuse au-delà de la fenêtre de sécurité étendue.
Si les journaux montrent des status=408 Request Time-out Connection was lostBaileys répétés, ajustez les timings de socket de Baileys sous web.whatsapp. Commencez par raccourcir keepAliveIntervalMs en dessous du délai d’inactivité de votre réseau et en augmentant connectTimeoutMs sur les liaisons lentes ou perturbées :
{ web: { whatsapp: { keepAliveIntervalMs: 15000, connectTimeoutMs: 60000, defaultQueryTimeoutMs: 60000, }, },}Correction :
openclaw channels status --probeopenclaw doctoropenclaw logs --followopenclaw gateway statusSi la boucle persiste après la correction de la connectivité de l’hôte et des timings, sauvegardez le répertoire d’authentification du compte et reliez ce compte :
cp -a ~/.openclaw/credentials/whatsapp/
~/.openclaw/credentials/whatsapp/
.bak openclaw channels logout —channel whatsapp —account
openclaw channels login —channel whatsapp —account
Si `~/.openclaw/logs/whatsapp-health.log` indique `Gateway inactive` mais que `openclaw gateway status` et `openclaw channels status --probe`WhatsApp montrent que la passerelle et WhatsApp sont en bonne santé, exécutez `openclaw doctor`Linux. Sur Linux, le docteur avertit concernant les entrées crontab héritées qui appellent encore `~/.openclaw/bin/ensure-whatsapp.sh` ; supprimez ces entrées obsolètes avec `crontab -e` car cron peut manquer de l'environnement utilisateur de systemd et faire rapporter de manière incorrecte l'état de la passerelle par cet ancien script.
Si nécessaire, reliez avec `channels login`.QR login times out behind a proxy
Symptôme : openclaw channels login --channel whatsapp échoue avant d’afficher un code QR utilisable avec status=408 Request Time-outWhatsApp ou une déconnexion de socket TLS.
La connexion WhatsApp Web utilise l’environnement proxy standard de l’hôte de la passerelle (HTTPS_PROXY, HTTP_PROXY, variantes en minuscules et NO_PROXY). Vérifiez que le processus de la passerelle hérite de l’environnement proxy et que NO_PROXY ne correspond pas à mmg.whatsapp.net.
No active listener when sending
Les envois sortants échouent rapidement lorsqu’aucun écouteur de passerelle actif n’existe pour le compte cible.
Assurez-vous que la passerelle est en cours d’exécution et que le compte est lié.
<Accordion title=“WhatsAppReply appears in transcript but not in WhatsApp”WhatsAppOpenClawBaileysWhatsApp> Les lignes de la transcription enregistrent ce que l’agent a généré. La livraison WhatsApp est vérifiée séparément : OpenClaw ne considère une réponse automatique comme envoyée qu’après que Baileys a renvoyé un ID de message sortant pour au moins un envoi de texte ou de média visible.
Les réactions d'accusé de réception sont des reçus indépendants précédant la réponse. Une réaction réussie ne prouve pas que la réponse textuelle ou média ultérieure a été acceptée par WhatsApp.
Vérifiez les journaux de la passerelle pour `auto-reply delivery failed` ou `auto-reply was not accepted by WhatsApp provider`.Group messages unexpectedly ignored
Vérifiez dans cet ordre :
groupPolicygroupAllowFrom/allowFrom- entrées de la liste d’autorisation
groups - filtrage par mentions (
requireMention+ modèles de mentions) - clés en double dans
openclaw.json(JSON5) : les entrées ultérieures écrasent les précédentes, gardez donc un seulgroupPolicypar portée
Si channels.whatsapp.groupsWhatsAppOpenClaw est présent, WhatsApp peut toujours observer les messages d’autres groupes, mais OpenClaw les ignore avant le routage de session. Ajoutez le JID du groupe à channels.whatsapp.groups ou ajoutez groups["*"] pour admettre tous les groupes tout en maintenant l’autorisation de l’expéditeur sous groupPolicy et groupAllowFrom.
<Accordion title=“BunBun runtime warning”WhatsAppBunWhatsAppTelegram> L’exécution de la passerelle WhatsApp doit utiliser Node. Bun est signalé comme incompatible pour le fonctionnement stable des passerelles WhatsApp/Telegram.
Invites du système
Section intitulée « Invites du système »WhatsApp prend en charge les invites du système de style Telegram pour les groupes et les discussions directes via les cartes groups et direct.
Hiérarchie de résolution pour les messages de groupe :
La carte groups effective est déterminée en premier : si le compte définit sa propre groups, elle remplace entièrement la carte groups racine (pas de fusion profonde). La recherche d’invite s’exécute ensuite sur la carte unique résultante :
- Invite du système spécifique au groupe (
groups["<groupId>"].systemPrompt) : utilisée lorsque l’entrée spécifique au groupe existe dans la carte et que sa clésystemPromptest définie. SisystemPromptest une chaîne vide (""), le caractère générique est supprimé et aucune invite du système n’est appliquée. - Invite du système générique pour les groupes (
groups["*"].systemPrompt) : utilisée lorsque l’entrée spécifique au groupe est totalement absente de la carte, ou lorsqu’elle existe mais ne définit aucune clésystemPrompt.
Hiérarchie de résolution pour les messages directs :
La carte direct effective est déterminée en premier : si le compte définit sa propre direct, elle remplace entièrement la carte direct racine (pas de fusion profonde). La recherche d’invite s’exécute ensuite sur la carte unique résultante :
- Invite du système spécifique au direct (
direct["<peerId>"].systemPrompt) : utilisée lorsque l’entrée spécifique au pair existe dans la carte et que sa clésystemPromptest définie. SisystemPromptest une chaîne vide (""), le caractère générique est supprimé et aucune invite du système n’est appliquée. - Invite du système générique pour les directs (
direct["*"].systemPrompt) : utilisée lorsque l’entrée spécifique au pair est totalement absente de la carte, ou lorsqu’elle existe mais ne définit aucune clésystemPrompt.
Différence avec le comportement multi-compte Telegram : Sur Telegram, le TelegramTelegramgroups racine est intentionnellement supprimé pour tous les comptes dans une configuration multi-compte — même les comptes qui ne définissent pas leur propre groupsWhatsApp — pour empêcher un bot de recevoir des messages de groupe pour les groupes auxquels il n’appartient pas. WhatsApp n’applique pas cette garde : le groups racine et le directWhatsApp racine sont toujours hérités par les comptes qui ne définissent pas de substitution au niveau du compte, quel que soit le nombre de comptes configurés. Dans une configuration WhatsApp multi-compte, si vous souhaitez des invites de groupe ou directes par compte, définissez la carte complète sous chaque compte explicitement plutôt que de vous fier aux valeurs par défaut au niveau racine.
Comportement important :
channels.whatsapp.groupsest à la fois une carte de configuration par groupe et la liste d’autorisation de groupe au niveau du chat. Soit au niveau racine soit au niveau du compte,groups["*"]signifie « tous les groupes sont admis » pour cette portée.- N’ajoutez un groupe générique
systemPromptque lorsque vous souhaitez déjà que cette portée admette tous les groupes. Si vous souhaitez toujours qu’un ensemble fixe d’ID de groupe soient éligibles, n’utilisez pasgroups["*"]pour l’invite par défaut. À la place, répétez l’invite sur chaque entrée de groupe explicitement autorisée. - L’admission de groupe et l’autorisation de l’expéditeur sont des contrôles distincts.
groups["*"]élargit l’ensemble des groupes qui peuvent atteindre la gestion de groupe, mais il n’autorise pas par lui-même chaque expéditeur dans ces groupes. L’accès de l’expéditeur est toujours contrôlé séparément parchannels.whatsapp.groupPolicyetchannels.whatsapp.groupAllowFrom. channels.whatsapp.directn’a pas le même effet secondaire pour les DMs.direct["*"]fournit uniquement une configuration de chat direct par défaut après qu’un DM a déjà été admis pardmPolicyplusallowFromou les règles du magasin d’appairage.
Exemple :
{ channels: { whatsapp: { groups: { // Use only if all groups should be admitted at the root scope. // Applies to all accounts that do not define their own groups map. "*": { systemPrompt: "Default prompt for all groups." }, }, direct: { // Applies to all accounts that do not define their own direct map. "*": { systemPrompt: "Default prompt for all direct chats." }, }, accounts: { work: { groups: { // This account defines its own groups, so root groups are fully // replaced. To keep a wildcard, define "*" explicitly here too. requireMention: false, systemPrompt: "Focus on project management.", }, // Use only if all groups should be admitted in this account. "*": { systemPrompt: "Default prompt for work groups." }, }, direct: { // This account defines its own direct map, so root direct entries are // fully replaced. To keep a wildcard, define "*" explicitly here too. "+15551234567": { systemPrompt: "Prompt for a specific work direct chat." }, "*": { systemPrompt: "Default prompt for work direct chats." }, }, }, }, }, },}Pointeurs vers la référence de configuration
Section intitulée « Pointeurs vers la référence de configuration »Référence principale :
Champs WhatsApp à fort signal :
- accès :
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - livraison :
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - multi-compte :
accounts.<id>.enabled,accounts.<id>.authDir, substitutions au niveau du compte - opérations :
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.*,web.whatsapp.* - comportement de la session :
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit - invites :
groups.<id>.systemPrompt,groups["*"].systemPrompt,direct.<id>.systemPrompt,direct["*"].systemPrompt