Saltar al contenido principal

WhatsApp (canal web)

Estado: listo para producción mediante WhatsApp Web (Baileys). Gateway posee las sesiones vinculadas.

Instalación (bajo demanda)

  • La incorporación (openclaw onboard) y openclaw channels add --channel whatsapp solicitan instalar el plugin de WhatsApp la primera vez que lo seleccionas.
  • openclaw channels login --channel whatsapp tambié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 de forma predeterminada el paquete npm @openclaw/whatsapp.
La instalación manual sigue estando disponible:
openclaw plugins install @openclaw/whatsapp

Vinculación

La política predeterminada de mensajes directos es la vinculación para remitentes desconocidos.

Solución de problemas del canal

Diagnósticos multicanal y guías de reparación.

Configuración de Gateway

Patrones y ejemplos completos de configuración del canal.

Configuración rápida

1

Configurar la política de acceso de WhatsApp

{
  channels: {
    whatsapp: {
      dmPolicy: "pairing",
      allowFrom: ["+15551234567"],
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
    },
  },
}
2

Vincular WhatsApp (QR)

openclaw channels login --channel whatsapp
Para una cuenta específica:
openclaw channels login --channel whatsapp --account work
3

Iniciar Gateway

openclaw gateway
4

Aprobar la primera solicitud de vinculación (si usas el modo de vinculación)

openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
Las solicitudes de vinculación caducan después de 1 hora. Las solicitudes pendientes están limitadas a 3 por canal.
OpenClaw recomienda ejecutar WhatsApp en un número separado cuando sea posible. (Los metadatos del canal y el flujo de configuración están optimizados para esa configuración, pero también se admiten configuraciones con número personal).

Patrones de implementación

Este es el modo operativo más limpio:
  • identidad de WhatsApp separada para OpenClaw
  • listas de permitidos de mensajes directos y límites de enrutamiento más claros
  • menor probabilidad de confusión con el chat propio
Patrón de política mínimo:
{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],
    },
  },
}
La incorporación admite el modo de número personal y escribe una base compatible con chat propio:
  • dmPolicy: "allowlist"
  • allowFrom incluye tu número personal
  • selfChatMode: true
En tiempo de ejecución, las protecciones de chat propio se basan en el número propio vinculado y en allowFrom.
El canal de la plataforma de mensajería está basado en WhatsApp Web (Baileys) en la arquitectura actual de canales de OpenClaw.No hay un canal de mensajería de WhatsApp separado de Twilio en el registro integrado de canales de chat.

Modelo de tiempo de ejecución

  • Gateway posee el socket de WhatsApp y el bucle de reconexión.
  • Los envíos salientes requieren un listener activo de WhatsApp para la cuenta de destino.
  • Los chats de estado y difusión se ignoran (@status, @broadcast).
  • Los chats directos usan reglas de sesión de mensajes directos (session.dmScope; el valor predeterminado main colapsa los mensajes directos en la sesión principal del agente).
  • Las sesiones de grupo están aisladas (agent:<agentId>:whatsapp:group:<jid>).
  • 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 en lugar de ajustes de proxy de WhatsApp específicos del canal.

Control de acceso y activación

channels.whatsapp.dmPolicy controla el acceso a chats directos:
  • pairing (predeterminado)
  • allowlist
  • open (requiere que allowFrom incluya "*")
  • disabled
allowFrom acepta números con formato E.164 (normalizados internamente).Anulación para varias cuentas: channels.whatsapp.accounts.<id>.dmPolicy (y allowFrom) tienen prioridad sobre los valores predeterminados a nivel del canal para esa cuenta.Detalles del comportamiento en tiempo de ejecución:
  • las vinculaciones se conservan en el almacén de permitidos del canal y se combinan con allowFrom configurado
  • si no se configura ninguna lista de permitidos, el número propio vinculado se permite de forma predeterminada
  • los mensajes directos salientes fromMe nunca se vinculan automáticamente

Comportamiento de número personal y chat propio

Cuando el número propio vinculado también está presente en allowFrom, se activan las protecciones de chat propio de WhatsApp:
  • omitir confirmaciones de lectura para turnos de chat propio
  • ignorar el comportamiento de activación automática por mention-JID que de otro modo te mencionaría a ti mismo
  • si messages.responsePrefix no está definido, las respuestas de chat propio usan de forma predeterminada [{identity.name}] o [openclaw]

Normalización de mensajes y contexto

Los mensajes entrantes de WhatsApp se encapsulan en el sobre de entrada compartido.Si existe una respuesta citada, el contexto se agrega en esta forma:
[Respondiendo a <sender> id:<stanzaId>]
<cuerpo citado o marcador de posición de multimedia>
[/Respondiendo]
Los campos de metadatos de respuesta también se rellenan cuando están disponibles (ReplyToId, ReplyToBody, ReplyToSender, remitente JID/E.164).
Los mensajes entrantes que solo contienen multimedia se normalizan con marcadores de posición como:
  • <media:image>
  • <media:video>
  • <media:audio>
  • <media:document>
  • <media:sticker>
Las cargas de ubicación y contacto se normalizan en contexto textual antes del enrutamiento.
Para los grupos, los mensajes no procesados pueden almacenarse temporalmente e inyectarse como contexto cuando finalmente se activa el bot.
  • límite predeterminado: 50
  • configuración: channels.whatsapp.historyLimit
  • alternativa: messages.groupChat.historyLimit
  • 0 desactiva
Marcadores de inyección:
  • [Mensajes del chat desde tu última respuesta - para contexto]
  • [Mensaje actual - responde a este]
Las confirmaciones de lectura están habilitadas de forma predeterminada para los mensajes entrantes de WhatsApp aceptados.Desactivar globalmente:
{
  channels: {
    whatsapp: {
      sendReadReceipts: false,
    },
  },
}
Anulación por cuenta:
{
  channels: {
    whatsapp: {
      accounts: {
        work: {
          sendReadReceipts: false,
        },
      },
    },
  },
}
Los turnos de chat propio omiten las confirmaciones de lectura incluso cuando están habilitadas globalmente.

Entrega, fragmentación y multimedia

  • límite predeterminado de fragmento: channels.whatsapp.textChunkLimit = 4000
  • channels.whatsapp.chunkMode = "length" | "newline"
  • el modo newline prefiere límites de párrafo (líneas en blanco), y luego recurre a una fragmentación segura por longitud
  • admite cargas de imagen, video, audio (nota de voz PTT) y documento
  • audio/ogg se reescribe como audio/ogg; codecs=opus para compatibilidad con notas de voz
  • la reproducción de GIF animados se admite mediante gifPlayback: true en envíos de video
  • los subtítulos se aplican al primer elemento multimedia al enviar cargas de respuesta con varios elementos multimedia
  • el origen del multimedia puede ser HTTP(S), file:// o rutas locales
  • límite de guardado de multimedia entrante: channels.whatsapp.mediaMaxMb (predeterminado 50)
  • límite de envío de multimedia saliente: channels.whatsapp.mediaMaxMb (predeterminado 50)
  • las anulaciones por cuenta usan channels.whatsapp.accounts.<accountId>.mediaMaxMb
  • las imágenes se optimizan automáticamente (barrido de tamaño/calidad) para ajustarse a los límites
  • en caso de error al enviar multimedia, la alternativa del primer elemento envía una advertencia de texto en lugar de omitir la respuesta en silencio

Nivel de reacciones

channels.whatsapp.reactionLevel controla cuán ampliamente usa el agente las reacciones con emoji en WhatsApp:
NivelReacciones de acuseReacciones iniciadas por el agenteDescripción
"off"NoNoSin reacciones en absoluto
"ack"NoSolo reacciones de acuse (recepción previa a respuesta)
"minimal"Sí (conservadoras)Acuse + reacciones del agente con guía conservadora
"extensive"Sí (fomentadas)Acuse + reacciones del agente con guía fomentada
Predeterminado: "minimal". Las anulaciones por cuenta usan channels.whatsapp.accounts.<id>.reactionLevel.
{
  channels: {
    whatsapp: {
      reactionLevel: "ack",
    },
  },
}

Reacciones de acuse

WhatsApp admite reacciones de acuse inmediatas al recibir mensajes entrantes mediante channels.whatsapp.ackReaction. Las reacciones de acuse están controladas por reactionLevel: se suprimen cuando reactionLevel es "off".
{
  channels: {
    whatsapp: {
      ackReaction: {
        emoji: "👀",
        direct: true,
        group: "mentions", // always | mentions | never
      },
    },
  },
}
Notas sobre el comportamiento:
  • se envían inmediatamente después de que se acepta la entrada (antes de la respuesta)
  • los fallos se registran, pero no bloquean la entrega normal de respuestas
  • el modo de grupo mentions reacciona en turnos activados por mención; la activación de grupo always actúa como omisión de esta comprobación
  • WhatsApp usa channels.whatsapp.ackReaction (aquí no se usa el heredado messages.ackReaction)

Varias cuentas y credenciales

  • los ID de cuenta provienen de channels.whatsapp.accounts
  • selección de cuenta predeterminada: default si está presente; de lo contrario, el primer ID de cuenta configurado (ordenado)
  • los ID de cuenta se normalizan internamente para la búsqueda
  • ruta de autenticación actual: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json
  • archivo de respaldo: creds.json.bak
  • la autenticación heredada predeterminada en ~/.openclaw/credentials/ aún se reconoce/migra para los flujos de cuenta predeterminada
openclaw channels logout --channel whatsapp [--account <id>] borra el estado de autenticación de WhatsApp para esa cuenta.En los 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 de herramientas del agente incluye la acción de reacción de WhatsApp (react).
  • Restricciones de acciones:
    • channels.whatsapp.actions.reactions
    • channels.whatsapp.actions.polls
  • Las escrituras de configuración iniciadas por el canal están habilitadas de forma predeterminada (desactívalas mediante channels.whatsapp.configWrites=false).

Solución de problemas

Síntoma: el estado del canal indica que no está vinculado.Solución:
openclaw channels login --channel whatsapp
openclaw channels status
Síntoma: cuenta vinculada con desconexiones repetidas o intentos de reconexión.Solución:
openclaw doctor
openclaw logs --follow
Si es necesario, vuelve a vincular con channels login.
Los envíos salientes fallan rápidamente cuando no existe un listener activo de Gateway para la cuenta de destino.Asegúrate de que Gateway esté en ejecución y de que la cuenta esté vinculada.
Comprueba en este orden:
  • groupPolicy
  • groupAllowFrom / allowFrom
  • entradas de la lista de permitidos groups
  • restricción por mención (requireMention + patrones de mención)
  • claves duplicadas en openclaw.json (JSON5): las entradas posteriores reemplazan a las anteriores, así que mantén un único groupPolicy por alcance
El entorno de ejecución de Gateway para WhatsApp debe usar Node. Bun está marcado como incompatible para un funcionamiento estable de Gateway con WhatsApp/Telegram.

Punteros de referencia de configuración

Referencia principal: Campos de WhatsApp de alta relevancia:
  • acceso: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups
  • entrega: textChunkLimit, chunkMode, mediaMaxMb, sendReadReceipts, ackReaction, reactionLevel
  • varias cuentas: accounts.<id>.enabled, accounts.<id>.authDir, anulaciones a nivel de cuenta
  • operaciones: configWrites, debounceMs, web.enabled, web.heartbeatSeconds, web.reconnect.*
  • comportamiento de sesión: session.dmScope, historyLimit, dmHistoryLimit, dms.<id>.historyLimit

Relacionado