Mensajes de grupo (canal web de WhatsApp)

Objetivo: permitir que Clawd participe en grupos de WhatsApp, se active solo cuando se le mencione, y mantenga ese hilo separado de la sesión personal de DM.

Nota: agents.list[].groupChat.mentionPatterns ahora también lo usan Telegram/Discord/Slack/iMessage; este documento se centra en el comportamiento específico de WhatsApp. Para configuraciones multi-agente, establece agents.list[].groupChat.mentionPatterns por agente (o usa messages.groupChat.mentionPatterns como respaldo global).

Qué está implementado (2025-12-03)

  • Modos de activación: mention (predeterminado) o always. mention requiere una mención (menciones reales de WhatsApp vía mentionedJids, patrones regex, o el E.164 del bot en cualquier parte del texto). always activa al agente con cada mensaje, pero debe responder solo cuando puede aportar valor; de lo contrario devuelve el token silencioso NO_REPLY. Los valores predeterminados se configuran en (channels.whatsapp.groups) y se pueden anular por grupo vía /activation. Cuando channels.whatsapp.groups está configurado, también actúa como lista de acceso de grupos (incluye "*" para permitir todos).
  • Política de grupo: channels.whatsapp.groupPolicy controla si se aceptan mensajes de grupo (open|disabled|allowlist). allowlist usa channels.whatsapp.groupAllowFrom (respaldo: channels.whatsapp.allowFrom explícito). El predeterminado es allowlist (bloqueado hasta que añadas remitentes).
  • Sesiones por grupo: las claves de sesión tienen la forma agent:<agentId>:whatsapp:group:<jid> por lo que comandos como /verbose on o /think high (enviados como mensajes independientes) aplican solo a ese grupo; el estado del DM personal no se altera. Los heartbeats se omiten para hilos de grupo.
  • Inyección de contexto: los mensajes de grupo pendientes (predeterminado 50) que no activaron una ejecución se añaden como prefijo bajo [Chat messages since your last reply - for context], con la línea que activó bajo [Current message - respond to this]. Los mensajes ya en la sesión no se reinyectan.
  • Identificación del remitente: cada lote de grupo termina con [from: Nombre del Remitente (+E164)] para que Pi sepa quién habla.
  • Efímeros/vista única: se desenvuelven antes de extraer texto/menciones, así que las menciones dentro de ellos siguen activando.
  • Prompt de sistema de grupo: en el primer turno de una sesión de grupo (y cuando /activation cambia el modo) se inyecta una breve introducción en el prompt de sistema como You are replying inside the WhatsApp group "<subject>". Group members: Alice (+44...), Bob (+43...), … Activation: trigger-only … Address the specific sender noted in the message context. Si los metadatos no están disponibles, igual se informa al agente que es un chat grupal.

Ejemplo de configuración (WhatsApp)

Añade un bloque groupChat a ~/.openclaw/openclaw.json para que las menciones por nombre funcionen incluso cuando WhatsApp elimina el @ visual en el cuerpo del texto:

{
  channels: {
    whatsapp: {
      groups: {
        "*": { requireMention: true },
      },
    },
  },
  agents: {
    list: [
      {
        id: "main",
        groupChat: {
          historyLimit: 50,
          mentionPatterns: ["@?openclaw", "\\+?15555550123"],
        },
      },
    ],
  },
}

Notas:

  • Los regex son insensibles a mayúsculas; cubren una mención por nombre como @openclaw y el número con o sin +/espacios.
  • WhatsApp sigue enviando menciones canónicas vía mentionedJids cuando alguien toca el contacto, así que el respaldo por número rara vez es necesario, pero es una red de seguridad útil.

Comando de activación (solo propietario)

Usa el comando de chat grupal:

  • /activation mention
  • /activation always

Solo el número propietario (de channels.whatsapp.allowFrom, o el E.164 propio del bot cuando no está configurado) puede cambiar esto. Envía /status como mensaje independiente en el grupo para ver el modo de activación actual.

Cómo usar

  1. Añade tu cuenta de WhatsApp (la que ejecuta OpenClaw) al grupo.
  2. Escribe @openclaw … (o incluye el número). Solo los remitentes en la lista de acceso pueden activarlo a menos que configures groupPolicy: "open".
  3. El prompt del agente incluirá contexto reciente del grupo más el marcador [from: …] para que pueda dirigirse a la persona correcta.
  4. Las directivas a nivel de sesión (/verbose on, /think high, /new o /reset, /compact) aplican solo a la sesión de ese grupo; envíalas como mensajes independientes para que se registren. Tu sesión personal de DM permanece independiente.

Pruebas / verificación

  • Prueba manual:
    • Envía un ping @openclaw en el grupo y confirma que la respuesta hace referencia al nombre del remitente.
    • Envía un segundo ping y verifica que el bloque de historial se incluye y luego se limpia en el siguiente turno.
  • Revisa los logs del gateway (ejecuta con --verbose) para ver entradas inbound web message que muestren from: <groupJid> y el sufijo [from: …].

Consideraciones conocidas

  • Los heartbeats se omiten intencionalmente para grupos para evitar broadcasts ruidosos.
  • La supresión de eco usa la cadena combinada del lote; si envías texto idéntico dos veces sin menciones, solo el primero obtendrá respuesta.
  • Las entradas del almacén de sesiones aparecerán como agent:<agentId>:whatsapp:group:<jid> en el almacén de sesiones (~/.openclaw/agents/<agentId>/sessions/sessions.json por defecto); una entrada faltante simplemente significa que el grupo aún no ha activado una ejecución.
  • Los indicadores de escritura en grupos siguen agents.defaults.typingMode (predeterminado: message cuando no se menciona).