Pasar al contenido principal
osky
Cómo activar los hooks de retry/cache de Baileys en OpenClaw para mensajes grupales confiables
Tema OpenClaw + Baileys group reliability

El problema que resolvió el PR #94338 y por qué te importa

Si alguna vez has corrido un bot de WhatsApp con Baileys dentro de OpenClaw y te has encontrado con mensajes grupales que simplemente desaparecen — sin error, sin log, sin nada — ya encontraste tu culpable. El PR #94338 (fix(whatsapp): wire missing Baileys retry/cache hooks for group message reliability, relacionado con el issue #7433) cierra un hueco que existía desde hace rato: los hooks internos de retry y de cache de mensajes de Baileys no estaban conectados al pipeline de OpenClaw. El resultado era que en grupos con latencia alta o reconexiones frecuentes, los mensajes se perdían en el limbo sin posibilidad de reintento automático.

Consola de terminal mostrando logs de retry de mensajes de Baileys en OpenClaw

Este tutorial asume que ya tienes una instancia de OpenClaw corriendo (versión con el fix incluido, es decir, cualquier release posterior al PR #94338). Si no sabes qué versión tienes, revisa tu package.json o el output de openclaw --version antes de continuar.


Requisitos

  • Node.js 20 LTS o superior
  • OpenClaw actualizado al release que incluye el PR #94338 (verifica en github.com/openclaw/openclaw/releases)
  • Una sesión de Baileys ya autenticada (multi-device QR o pairing code)
  • Almacenamiento persistente para el cache de mensajes: puede ser Redis, SQLite, o el adaptador en memoria para desarrollo
  • Conocimiento básico de async/await en TypeScript o JavaScript

Paso 1: Actualiza OpenClaw

Antes de tocar configuración, asegúrate de estar en la versión correcta:

npm install openclaw@latest
# o si usas yarn
yarn add openclaw@latest

Confirma que el fix está presente:

npx openclaw --version
# Debe mostrar el build posterior al PR #94338

Paso 2: Configura el store de mensajes (cache)

El hook de cache necesita un store donde guardar los mensajes pendientes de retry. OpenClaw expone una interfaz MessageStore que puedes implementar con el adaptador que prefieras.

Opción A — En memoria (solo desarrollo):

import { createInMemoryMessageStore } from 'openclaw/stores';

const messageStore = createInMemoryMessageStore();

Opción B — Redis (recomendado en producción):

import { createRedisMessageStore } from 'openclaw/stores/redis';
import { createClient } from 'redis';

const redisClient = createClient({ url: process.env.REDIS_URL });
await redisClient.connect();

const messageStore = createRedisMessageStore({
  client: redisClient,
  keyPrefix: 'oc:msg:',
  ttlSeconds: 300, // mensajes pendientes expiran en 5 minutos
});

El TTL es importante: no quieres acumular mensajes zombies en Redis eternamente. Cinco minutos es un buen punto de partida para grupos activos.


Paso 3: Registra los hooks de retry y cache en tu instancia de OpenClaw

Aquí está el cambio central que introduce el PR #94338. Antes, estos hooks existían en Baileys pero OpenClaw no los pasaba al socket. Ahora hay una API explícita para conectarlos:

import { createOpenClawBot } from 'openclaw';
import { wireRetryAndCacheHooks } from 'openclaw/hooks/whatsapp';

const bot = await createOpenClawBot({
  sessionPath: './session',
  whatsapp: {
    multiDevice: true,
  },
});

// Este es el paso nuevo — sin esto, el fix del PR no aplica
wireRetryAndCacheHooks(bot.socket, {
  messageStore,
  maxRetries: 3,
  retryDelayMs: 1500,
  onRetryExhausted: async (msg, attempts) => {
    console.error(
      `[OpenClaw] Mensaje ${msg.key.id} falló después de ${attempts} intentos en grupo ${msg.key.remoteJid}`
    );
    // Aquí puedes alertar a un canal de Slack, guardar en BD, lo que necesites
  },
});

El parámetro maxRetries controla cuántas veces Baileys reintenta enviar un mensaje antes de darlo por muerto. retryDelayMs es el tiempo base entre intentos (se aplica backoff exponencial internamente, así que el tercer intento esperará más que el primero).


Paso 4: Verifica el comportamiento en grupos

Para confirmar que los hooks están activos, OpenClaw ahora emite eventos que puedes escuchar:

bot.on('whatsapp:message:retry', ({ messageId, attempt, jid }) => {
  console.log(`Reintentando mensaje ${messageId} (intento ${attempt}) en ${jid}`);
});

bot.on('whatsapp:message:cached', ({ messageId, jid }) => {
  console.log(`Mensaje ${messageId} cacheado para grupo ${jid}`);
});

Si ves estos logs durante una prueba con un grupo de WhatsApp, los hooks están correctamente conectados. Si no aparecen y los mensajes siguen perdiéndose, revisa que llamaste wireRetryAndCacheHooks antes de que el socket se conecte.


Paso 5: Manejo de reconexiones

El cache de mensajes pendientes no sirve de nada si al reconectar el bot no los procesa. Agrega este bloque para drenar el store al reconectar:

bot.on('whatsapp:connection:open', async () => {
  const pending = await messageStore.getPending();
  for (const msg of pending) {
    await bot.socket.relayMessage(msg.key.remoteJid, msg.message, {
      messageId: msg.key.id,
    });
  }
  console.log(`[OpenClaw] ${pending.length} mensajes pendientes reenviados tras reconexión`);
});

Advertencias de producción

No abuses del retry en grupos grandes. WhatsApp tiene límites de rate que no están documentados públicamente pero que sí aplican. Si tienes grupos de 500 personas y el bot reintenta agresivamente, puedes terminar baneado. Usa maxRetries: 2 o 3 como máximo y monitorea el evento onRetryExhausted.

El store de Redis debe ser persistente. Si usas Redis sin persistencia (sin AOF ni RDB habilitado), al reiniciar Redis pierdes el cache y el fix no sirve de nada. Configura al menos appendonly yes en tu redis.conf.

Sesiones corruptas anulan el fix. Si tu sesión de Baileys está en mal estado, los retries van a fallar de todas formas. Implementa un mecanismo de rotación de sesión o detecta el evento connection.update con qr para forzar re-autenticación automática.

Logs estructurados, no console.log. En producción usa pino o winston con contexto estructurado. Los mensajes de retry son ruidosos y necesitas poder filtrarlos por jid o messageId sin volverte loco.


Resumen rápido

  1. Actualiza OpenClaw al release post-PR #94338
  2. Elige e inicializa tu MessageStore (Redis en producción)
  3. Llama wireRetryAndCacheHooks antes de conectar el socket
  4. Escucha los eventos de retry/cache para monitoreo
  5. Drena el store al reconectar
  6. Configura límites sensatos de retry y alertas en onRetryExhausted

Con esto, tus mensajes grupales dejan de desaparecer en el limbo y el bot se comporta como adulto en producción.