Estado: listo para producción mediante WhatsApp Web (Baileys). Gateway gestiona las sesiones vinculadas.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.
Instalación (bajo demanda)
- La incorporación (
openclaw onboard) yopenclaw channels add --channel whatsappsolicitan instalar el Plugin de WhatsApp la primera vez que lo seleccionas. openclaw channels login --channel whatsapptambién ofrece el flujo de instalación cuando el Plugin aún no está presente.- Canal de desarrollo + checkout de git: usa de forma predeterminada la ruta local del Plugin.
- Stable/Beta: usa el paquete npm
@openclaw/whatsappen la etiqueta de versión oficial actual.
PATH durante la instalación de npm porque
una de sus dependencias de Baileys/libsignal se obtiene desde una URL de git. Instala
Git for Windows, luego reinicia la shell y vuelve a ejecutar la instalación:
bin está en PATH.
Emparejamiento
Solución de problemas de canal
Configuración de Gateway
Configuración rápida
Vincular WhatsApp (QR)
Patrones de despliegue
Número dedicado (recomendado)
Número dedicado (recomendado)
- identidad de WhatsApp separada para OpenClaw
- listas de permitidos de DM y límites de enrutamiento más claros
- menor probabilidad de confusión con chats contigo mismo
Alternativa con número personal
Alternativa con número personal
dmPolicy: "allowlist"allowFromincluye tu número personalselfChatMode: true
allowFrom.Alcance del canal solo para WhatsApp Web
Alcance del canal solo para WhatsApp Web
Baileys) en la arquitectura de canales actual de OpenClaw.No hay un canal de mensajería de Twilio WhatsApp separado en el registro integrado de canales de chat.Modelo de tiempo de ejecución
- Gateway gestiona el socket de WhatsApp y el bucle de reconexión.
- El vigilante de reconexión usa la actividad de transporte de WhatsApp Web, no solo el volumen de mensajes entrantes de la aplicación, por lo que una sesión silenciosa de dispositivo vinculado no se reinicia solo porque nadie haya enviado un mensaje recientemente. Un límite más largo de silencio de la aplicación sigue forzando una reconexión si los frames de transporte continúan llegando pero no se procesa ningún mensaje de aplicación durante la ventana del vigilante; después de una reconexión transitoria para una sesión activa recientemente, esa comprobación de silencio de la aplicación usa el tiempo de espera normal de mensajes para la primera ventana de recuperación.
- Los tiempos del socket de Baileys son explícitos bajo
web.whatsapp.*:keepAliveIntervalMscontrola los pings de aplicación de WhatsApp Web,connectTimeoutMscontrola el tiempo de espera del handshake de apertura ydefaultQueryTimeoutMscontrola los tiempos de espera de consultas de Baileys. - Los envíos salientes requieren un listener de WhatsApp activo para la cuenta de destino.
- Los envíos a grupos adjuntan metadatos nativos de mención para tokens
@+<digits>y@<digits>en texto y pies de medios cuando el token coincide con los metadatos actuales de participantes de WhatsApp, incluidos grupos respaldados por LID. - Los chats de estado y difusión se ignoran (
@status,@broadcast). - El vigilante de reconexión sigue la actividad de transporte de WhatsApp Web, no solo el volumen de mensajes entrantes de la aplicación: las sesiones silenciosas de dispositivo vinculado permanecen activas mientras continúen los frames de transporte, pero un bloqueo del transporte fuerza una reconexión mucho antes de la ruta posterior de desconexión remota.
- Los chats directos usan reglas de sesión de DM (
session.dmScope; el valor predeterminadomaincolapsa los DM en la sesión principal del agente). - Las sesiones de grupo están aisladas (
agent:<agentId>:whatsapp:group:<jid>). - Los canales/newsletters de WhatsApp pueden ser destinos salientes explícitos con su JID nativo
@newsletter. Los envíos salientes a newsletters usan metadatos de sesión de canal (agent:<agentId>:whatsapp:channel:<jid>) en lugar de semántica de sesión de DM. - El transporte de WhatsApp Web respeta las variables de entorno de proxy estándar en el host de Gateway (
HTTPS_PROXY,HTTP_PROXY,NO_PROXY/ variantes en minúsculas). Prefiere la configuración de proxy a nivel de host frente a ajustes de proxy de WhatsApp específicos del canal. - Cuando
messages.removeAckAfterReplyestá habilitado, OpenClaw borra la reacción de acuse de WhatsApp después de que se entrega una respuesta visible.
Hooks de Plugin y privacidad
Los mensajes entrantes de WhatsApp pueden contener contenido de mensajes personales, números de teléfono, identificadores de grupo, nombres de remitente y campos de correlación de sesión. Por ese motivo, WhatsApp no transmite cargas de hookmessage_received entrantes a plugins
a menos que lo habilites explícitamente:
Control de acceso y activación
- Política de DM
- Política de grupos + listas de permitidos
- Menciones + /activation
channels.whatsapp.dmPolicy controla el acceso a chats directos:pairing(predeterminado)allowlistopen(requiere queallowFromincluya"*")disabled
allowFrom acepta números con estilo E.164 (normalizados internamente).allowFrom es una lista de control de acceso de remitentes de DM. No controla envíos salientes explícitos a JID de grupos de WhatsApp ni a JID de canales @newsletter.Anulación multicuenta: channels.whatsapp.accounts.<id>.dmPolicy (y allowFrom) tienen prioridad sobre los valores predeterminados a nivel de canal para esa cuenta.Detalles del comportamiento en tiempo de ejecución:- los emparejamientos se conservan en el almacén de permitidos del canal y se combinan con
allowFromconfigurado - la automatización programada y el fallback de destinatario de Heartbeat usan destinos de entrega explícitos o
allowFromconfigurado; las aprobaciones de emparejamiento de DM no son destinatarios implícitos de cron ni de Heartbeat - si no hay una lista de permitidos configurada, el número propio vinculado se permite de forma predeterminada
- OpenClaw nunca empareja automáticamente DM salientes
fromMe(mensajes que te envías a ti mismo desde el dispositivo vinculado)
Comportamiento con número personal y chat contigo mismo
Cuando el número propio vinculado también está presente enallowFrom, se activan las salvaguardas de chat contigo mismo de WhatsApp:
- omitir confirmaciones de lectura para turnos de chat contigo mismo
- ignorar comportamiento de activación automática por mention-JID que de otro modo te haría ping a ti mismo
- si
messages.responsePrefixno está definido, las respuestas de chat contigo mismo usan de forma predeterminada[{identity.name}]o[openclaw]
Normalización de mensajes y contexto
Envoltorio entrante + contexto de respuesta
Envoltorio entrante + contexto de respuesta
ReplyToId, ReplyToBody, ReplyToSender, JID/E.164 del remitente).
Cuando el destino de la respuesta citada es un medio descargable, OpenClaw lo guarda mediante
el almacén normal de medios entrantes y lo expone como MediaPath/MediaType para que
el agente pueda inspeccionar la imagen referenciada en lugar de ver solo
<media:image>.Marcadores de posición de medios y extracción de ubicación/contacto
Marcadores de posición de medios y extracción de ubicación/contacto
<media:image><media:video><media:audio><media:document><media:sticker>
<media:audio>, por lo que decir la mención del bot en la nota de voz puede
activar la respuesta. Si la transcripción aún no menciona al bot, la
transcripción se conserva en el historial de grupo pendiente en lugar del marcador de posición sin procesar.Los cuerpos de ubicación usan texto de coordenadas conciso. Las etiquetas/comentarios de ubicación y los detalles de contacto/vCard se renderizan como metadatos no confiables delimitados, no como texto de prompt inline.Inyección de historial de grupo pendiente
Inyección de historial de grupo pendiente
- límite predeterminado:
50 - configuración:
channels.whatsapp.historyLimit - reserva:
messages.groupChat.historyLimit 0desactiva
[Mensajes de chat desde tu última respuesta - para contexto][Mensaje actual - responde a esto]
Confirmaciones de lectura
Confirmaciones de lectura
Entrega, fragmentación y multimedia
Fragmentación de texto
Fragmentación de texto
- límite de fragmento predeterminado:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"- el modo
newlineprefiere los límites de párrafo (líneas en blanco) y luego recurre a una fragmentación segura por longitud
Comportamiento de multimedia saliente
Comportamiento de multimedia saliente
- admite cargas de imagen, video, audio (nota de voz PTT) y documento
- el multimedia de audio se envía mediante la carga
audiode Baileys conptt: true, por lo que los clientes de WhatsApp lo muestran como una nota de voz push-to-talk - las cargas de respuesta conservan
audioAsVoice; la salida de nota de voz TTS para WhatsApp permanece en esta ruta PTT incluso cuando el proveedor devuelve MP3 o WebM - el audio nativo Ogg/Opus se envía como
audio/ogg; codecs=opuspara compatibilidad con notas de voz - el audio que no sea Ogg, incluida la salida MP3/WebM de Microsoft Edge TTS, se transcodifica con
ffmpega Ogg/Opus mono de 48 kHz antes de la entrega PTT /tts latestenvía la última respuesta del asistente como una nota de voz y suprime envíos repetidos de la misma respuesta;/tts chat on|off|defaultcontrola el TTS automático para el chat actual de WhatsApp- la reproducción de GIF animados es compatible mediante
gifPlayback: trueen envíos de video - los subtítulos se aplican al primer elemento multimedia al enviar cargas de respuesta con varios medios, salvo que las notas de voz PTT envían primero el audio y el texto visible por separado porque los clientes de WhatsApp no muestran los subtítulos de notas de voz de forma uniforme
- la fuente multimedia puede ser HTTP(S),
file://o rutas locales
Límites de tamaño de multimedia y comportamiento de reserva
Límites de tamaño de multimedia y comportamiento de reserva
- límite de guardado de multimedia entrante:
channels.whatsapp.mediaMaxMb(predeterminado50) - límite de envío de multimedia saliente:
channels.whatsapp.mediaMaxMb(predeterminado50) - las anulaciones por cuenta usan
channels.whatsapp.accounts.<accountId>.mediaMaxMb - las imágenes se optimizan automáticamente (barrido de redimensionamiento/calidad) para ajustarse a los límites
- ante un fallo de envío de multimedia, la reserva del primer elemento envía una advertencia de texto en lugar de descartar la respuesta silenciosamente
Citas en respuestas
WhatsApp admite citas nativas en respuestas, donde las respuestas salientes citan visiblemente el mensaje entrante. Contrólalo conchannels.whatsapp.replyToMode.
| Valor | Comportamiento |
|---|---|
"off" | No citar nunca; enviar como mensaje simple |
"first" | Citar solo el primer fragmento de respuesta saliente |
"all" | Citar cada fragmento de respuesta saliente |
"batched" | Citar respuestas agrupadas en cola y dejar sin cita las respuestas inmediatas |
"off". Las anulaciones por cuenta usan channels.whatsapp.accounts.<id>.replyToMode.
Nivel de reacción
channels.whatsapp.reactionLevel controla con qué amplitud el agente usa reacciones de emoji en WhatsApp:
| Nivel | Reacciones de acuse | Reacciones iniciadas por el agente | Descripción |
|---|---|---|---|
"off" | No | No | Sin reacciones en absoluto |
"ack" | Sí | No | Solo reacciones de acuse (confirmación previa a la respuesta) |
"minimal" | Sí | Sí (conservador) | Acuse + reacciones del agente con orientación conservadora |
"extensive" | Sí | Sí (recomendado) | Acuse + reacciones del agente con orientación recomendada |
"minimal".
Las anulaciones por cuenta usan channels.whatsapp.accounts.<id>.reactionLevel.
Reacciones de acuse
WhatsApp admite reacciones de acuse inmediatas al recibir mensajes entrantes mediantechannels.whatsapp.ackReaction.
Las reacciones de acuse están controladas por reactionLevel: se suprimen cuando reactionLevel es "off".
- se envían inmediatamente después de aceptar el mensaje entrante (antes de la respuesta)
- los fallos se registran, pero no bloquean la entrega normal de la respuesta
- el modo de grupo
mentionsreacciona en turnos activados por menciones; la activación de grupoalwaysactúa como omisión para esta comprobación - WhatsApp usa
channels.whatsapp.ackReaction(el valor heredadomessages.ackReactionno se usa aquí)
Varias cuentas y credenciales
Selección de cuenta y valores predeterminados
Selección de cuenta y valores predeterminados
- los ids de cuenta provienen de
channels.whatsapp.accounts - selección de cuenta predeterminada:
defaultsi está presente; de lo contrario, el primer id de cuenta configurado (ordenado) - los ids de cuenta se normalizan internamente para la búsqueda
Rutas de credenciales y compatibilidad heredada
Rutas de credenciales y compatibilidad heredada
- ruta de autenticación actual:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - archivo de copia de seguridad:
creds.json.bak - la autenticación predeterminada heredada en
~/.openclaw/credentials/todavía se reconoce/migra para flujos de cuenta predeterminada
Comportamiento de cierre de sesión
Comportamiento de cierre de sesión
openclaw channels logout --channel whatsapp [--account <id>] borra el estado de autenticación de WhatsApp para esa cuenta.Cuando hay un Gateway accesible, el cierre de sesión primero detiene el escuchador activo de WhatsApp para la cuenta seleccionada, de modo que la sesión vinculada no siga recibiendo mensajes hasta el siguiente reinicio. openclaw channels remove --channel whatsapp también detiene el escuchador activo antes de desactivar o eliminar la configuración de la cuenta.En directorios de autenticación heredados, oauth.json se conserva mientras se eliminan los archivos de autenticación de Baileys.Herramientas, acciones y escrituras de configuración
- La compatibilidad con herramientas del agente incluye la acción de reacción de WhatsApp (
react). - Controles de acciones:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- Las escrituras de configuración iniciadas por el canal están activadas de forma predeterminada (desactivar mediante
channels.whatsapp.configWrites=false).
Solución de problemas
No vinculado (se requiere QR)
No vinculado (se requiere QR)
Vinculado pero desconectado / bucle de reconexión
Vinculado pero desconectado / bucle de reconexión
status=408 Request Time-out Connection was lost repetido, ajusta
los tiempos del socket de Baileys bajo web.whatsapp. Empieza acortando
keepAliveIntervalMs por debajo del tiempo de espera por inactividad de tu red y aumentando
connectTimeoutMs en enlaces lentos o con pérdidas:~/.openclaw/logs/whatsapp-health.log dice Gateway inactive pero
openclaw gateway status y openclaw channels status --probe muestran que el
gateway y WhatsApp están sanos, ejecuta openclaw doctor. En Linux, doctor
advierte sobre entradas heredadas de crontab que todavía invocan
~/.openclaw/bin/ensure-whatsapp.sh; elimina esas entradas obsoletas con
crontab -e porque cron puede carecer del entorno de bus de usuario de systemd y
hacer que ese script antiguo informe incorrectamente el estado del gateway.Si es necesario, vuelve a vincular con channels login.El inicio de sesión por QR agota el tiempo detrás de un proxy
El inicio de sesión por QR agota el tiempo detrás de un proxy
openclaw channels login --channel whatsapp falla antes de mostrar un código QR utilizable con status=408 Request Time-out o una desconexión de socket TLS.El inicio de sesión de WhatsApp Web usa el entorno proxy estándar del host del gateway (HTTPS_PROXY, HTTP_PROXY, variantes en minúsculas y NO_PROXY). Verifica que el proceso del gateway herede el entorno proxy y que NO_PROXY no coincida con mmg.whatsapp.net.Sin escuchador activo al enviar
Sin escuchador activo al enviar
La respuesta aparece en la transcripción pero no en WhatsApp
La respuesta aparece en la transcripción pero no en WhatsApp
auto-reply delivery failed o auto-reply was not accepted by WhatsApp provider.Mensajes de grupo ignorados inesperadamente
Mensajes de grupo ignorados inesperadamente
groupPolicygroupAllowFrom/allowFrom- entradas de lista de permitidos de
groups - control por menciones (
requireMention+ patrones de mención) - claves duplicadas en
openclaw.json(JSON5): las entradas posteriores anulan las anteriores, así que mantén un sologroupPolicypor ámbito
Advertencia de runtime de Bun
Advertencia de runtime de Bun
Prompts del sistema
WhatsApp admite prompts del sistema de estilo Telegram para grupos y chats directos mediante los mapasgroups y direct.
Jerarquía de resolución para mensajes de grupo:
El mapa groups efectivo se determina primero: si la cuenta define sus propios groups, reemplaza completamente el mapa groups raíz (sin fusión profunda). La búsqueda de prompt se ejecuta entonces en el único mapa resultante:
- Prompt del sistema específico del grupo (
groups["<groupId>"].systemPrompt): se usa cuando la entrada específica del grupo existe en el mapa y su clavesystemPromptestá definida. SisystemPromptes una cadena vacía (""), se suprime el comodín y no se aplica ningún prompt del sistema. - Prompt del sistema comodín de grupo (
groups["*"].systemPrompt): se usa cuando la entrada específica del grupo está ausente por completo del mapa o cuando existe pero no define ninguna clavesystemPrompt.
direct efectivo se determina primero: si la cuenta define su propio direct, reemplaza completamente el mapa direct raíz (sin fusión profunda). La búsqueda de prompt se ejecuta entonces en el único mapa resultante:
- Prompt del sistema específico directo (
direct["<peerId>"].systemPrompt): se usa cuando la entrada del par específico existe en el mapa y su clavesystemPromptestá definida. SisystemPromptes una cadena vacía (""), el comodín se suprime y no se aplica ningún prompt del sistema. - Prompt del sistema comodín directo (
direct["*"].systemPrompt): se usa cuando la entrada del par específico está totalmente ausente del mapa, o cuando existe pero no define ninguna clavesystemPrompt.
dms sigue siendo el contenedor ligero de sobrescritura de historial por DM (dms.<id>.historyLimit). Las sobrescrituras de prompt residen bajo direct.groups se suprime intencionalmente para todas las cuentas en una configuración multicuenta, incluso para cuentas que no definen sus propios groups, para evitar que un bot reciba mensajes de grupos a los que no pertenece. WhatsApp no aplica esta protección: la raíz groups y la raíz direct siempre las heredan las cuentas que no definen ninguna sobrescritura a nivel de cuenta, independientemente de cuántas cuentas estén configuradas. En una configuración multicuenta de WhatsApp, si quieres prompts de grupo o directos por cuenta, define explícitamente el mapa completo bajo cada cuenta en lugar de depender de los valores predeterminados a nivel raíz.
Comportamiento importante:
channels.whatsapp.groupses tanto un mapa de configuración por grupo como la lista de permitidos de grupos a nivel de chat. En el ámbito raíz o de cuenta,groups["*"]significa “se admiten todos los grupos” para ese ámbito.- Añade un
systemPromptde grupo comodín solo cuando ya quieras que ese ámbito admita todos los grupos. Si aún quieres que solo sea apto un conjunto fijo de IDs de grupo, no usesgroups["*"]como valor predeterminado del prompt. En su lugar, repite el prompt en cada entrada de grupo incluida explícitamente en la lista de permitidos. - La admisión de grupos y la autorización de remitentes son comprobaciones separadas.
groups["*"]amplía el conjunto de grupos que pueden llegar al manejo de grupos, pero no autoriza por sí solo a todos los remitentes de esos grupos. El acceso de remitentes sigue controlándose por separado mediantechannels.whatsapp.groupPolicyychannels.whatsapp.groupAllowFrom. channels.whatsapp.directno tiene el mismo efecto secundario para los DM.direct["*"]solo proporciona una configuración predeterminada de chat directo después de que un DM ya haya sido admitido pordmPolicymásallowFromo por reglas del almacén de emparejamiento.
Punteros de referencia de configuración
Referencia principal: Campos de alta señal de WhatsApp:- acceso:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - entrega:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - multicuenta:
accounts.<id>.enabled,accounts.<id>.authDir, sobrescrituras a nivel de cuenta - operaciones:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.*,web.whatsapp.* - comportamiento de sesión:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit - prompts:
groups.<id>.systemPrompt,groups["*"].systemPrompt,direct.<id>.systemPrompt,direct["*"].systemPrompt