← Blog

·

Chatbot con IA en la API oficial de WhatsApp: arquitectura y código

Actualizado el 29/10/2026

Para conectar un chatbot o agente de IA a WhatsApp por la API oficial, recibes cada mensaje por webhook, respondes 200 de inmediato, pones el evento en una cola y dejas que un worker arme el contexto, llame al modelo de lenguaje y envíe la respuesta por la API. La respuesta libre del bot solo puede salir dentro de la ventana de 24 horas que abrió el cliente, y la política de Meta exige un camino claro hacia la atención humana. Los términos de Meta también prohíben usar la plataforma para ofrecer asistentes de IA de uso general como producto principal, con excepciones en algunos países, entre ellos Brasil.

Esta guía muestra la arquitectura, las reglas que afectan al bot y un ejemplo funcional en Node.js con Vectalk, que transmite los mismos payloads y webhooks de Meta.

Arquitectura: webhook, cola, LLM y respuesta

Cliente en WhatsApp
      │
      ▼
Meta ──POST──▶ Vectalk ──POST──▶ /webhook (responde 200 y encola)
                                     │
                                     ▼
                                   Cola
                                     │
                                     ▼
                Worker: deduplica ▶ carga historial ▶ decide (bot o humano)
                                     │
                         ┌───────────┴───────────┐
                         ▼                       ▼
                   LLM genera respuesta     Agente humano
                         │
                         ▼
             POST /api/messages (Vectalk) ──▶ Meta ──▶ Cliente

Cada pieza tiene una función clara:

ComponenteResponsabilidadCuidado principal
WebhookRecibir el evento, validarlo y responder 200No llamar al LLM dentro de la solicitud
ColaDesacoplar la recepción del procesamientoGarantizar un reintento si el worker se cae
DeduplicaciónIgnorar eventos repetidos por su ID wamidGuardar los IDs procesados durante algunos días
HistorialArmar el contexto de la conversación por wa_idLimitar el tamaño para controlar costo y latencia
EnrutadorDecidir si responde el bot o si la conversación está con un humanoRespetar el estado de derivación
LLMGenerar la respuesta dentro del alcance del negocioPrompt con límites claros y tiempo máximo de respuesta
EnvíoLlamar a la API y guardar el ID del mensaje enviadoManejar errores y revisar la ventana de 24 horas

Por qué la cola es obligatoria

Un modelo de lenguaje puede tardar varios segundos en responder. Vectalk espera HTTP 200 en menos de 20 segundos y reenvía el evento si no lo recibe, según su documentación de webhooks. Si el endpoint espera al LLM, un pico de mensajes provoca reenvíos, respuestas duplicadas y el doble de costo. Con la cola, el webhook solo guarda el evento y responde.

El artículo sobre webhooks de la API de WhatsApp cubre el formato de los eventos, la deduplicación y el manejo de estados, y validar la firma del webhook muestra cómo revisar X-Hub-Signature-256 antes de encolar.

Marcar como leído y mostrar «escribiendo»

La Cloud API permite marcar el mensaje recibido como leído y mostrar el indicador de escritura en la misma llamada. Según la documentación de indicadores de escritura, el indicador desaparece cuando respondes o después de 25 segundos, lo que ocurra primero. Meta recomienda mostrarlo solo si realmente vas a responder.

{
  "messaging_product": "whatsapp",
  "status": "read",
  "message_id": "wamid.HBgLNTUx...",
  "typing_indicator": { "type": "text" }
}

En Vectalk, esta llamada va a POST /api/messages, el mismo endpoint documentado para marcar como leído.

La ventana de 24 horas define lo que el bot puede enviar

Cuando el cliente envía un mensaje, se abre una ventana de atención de 24 horas que se renueva con cada nuevo mensaje suyo. Dentro de ella, el bot puede responder con texto libre, multimedia y mensajes interactivos. Fuera de ella, solo con plantillas aprobadas (consulta la página de Meta sobre mensajes de servicio y la ventana de atención).

En la práctica, eso cambia el diseño del agente:

  • El bot es reactivo. Responde a lo que el cliente preguntó. Para retomar el contacto después de 24 horas, el sistema necesita una plantilla, no texto generado por el LLM.
  • Las respuestas lentas pueden perder la ventana. Si el bot depende de un proceso lento (análisis de un documento, consulta a otro sistema), registra la hora del último mensaje del cliente y revísala antes de enviar.
  • Los botones y las listas ayudan al LLM. En lugar de pedir que el cliente escriba «1» o «2», el bot puede enviar opciones para tocar. Mira mensajes interactivos en la API de WhatsApp.

El artículo sobre la ventana de 24 horas de WhatsApp detalla las reglas de apertura y renovación.

Cuánto cuesta cada respuesta del bot

Las respuestas libres dentro de la ventana son mensajes de servicio. Desde el 1/10/2026, cada número comercial tiene 1.000 mensajes de servicio gratuitos por mes, y Meta cobra a partir del 1.001, según la página de precios. Para destinatarios en Brasil, la tarifa de servicio es de R$ 0,0350 (reales brasileños) por mensaje entregado; las tarifas de otros mercados están en el precio de la API de WhatsApp por país. Un bot que responde en tres mensajes cortos cuesta tres veces más que uno que responde en uno solo, así que conviene juntar la respuesta.

A ese valor se suma el costo del propio modelo de lenguaje, que depende del proveedor y del tamaño del contexto.

¿Quieres probar mientras lees? Crea tu cuenta en Vectalk y envía el primer mensaje por la API oficial. Crear cuenta gratis →

Derivación a un humano

La Política de Mensajes de WhatsApp Business permite la automatización dentro de la ventana de 24 horas, pero exige caminos de escalamiento rápidos, claros y directos. Las opciones que enumera incluyen la transferencia a un agente humano en la conversación, un número de teléfono, correo, soporte en el sitio web, una visita a la tienda o un formulario de soporte.

Un bot de atención necesita, como mínimo, tres disparadores de derivación:

  1. Pedido explícito. El cliente escribe «agente», «hablar con una persona» o toca un botón de ayuda humana.
  2. Baja confianza. El LLM indica que no sabe responder o que el tema está fuera del alcance definido.
  3. Tema sensible. Un reclamo, una cancelación, un cobro impugnado o cualquier tema que la empresa decida tratar solo con personas.
Estado de la conversaciónQuién respondeCómo sale del estado
botAgente de IADisparador de derivación
esperando_humanoNadie responde automáticamente; el bot avisa el tiempo de espera una sola vezUn agente toma la conversación
humanoAgente, desde la herramienta de atenciónEl agente la cierra o la conversación queda inactiva

Si el número usa coexistencia, el agente puede responder desde la app WhatsApp Business en el celular. Los mensajes enviados desde la app llegan a tu sistema como eventos de eco, y el enrutador puede usarlos para pasar la conversación a humano automáticamente, sin que el bot responda encima. Para varios agentes en el mismo número, mira multiagente en WhatsApp con la API.

Lo que Meta permite para chatbots de IA

Los Términos de Meta para la Plataforma de WhatsApp Business, en la cláusula 4.7, tratan sobre los «Proveedores de IA»: proveedores y desarrolladores de tecnologías de inteligencia artificial o aprendizaje automático, como grandes modelos de lenguaje, plataformas de IA generativa y asistentes de IA de uso general, según lo determine Meta. Tienen prohibido usar la plataforma para ofrecer esas tecnologías cuando son la funcionalidad principal y no algo incidental o auxiliar.

Qué significa esto para quien construye bots:

  • Bot de atención de la propia empresa. Un agente que responde dudas sobre pedidos, agenda turnos o explica los productos de la empresa usa la IA como herramienta de atención. Meta decide cada caso, pero ese no es el uso al que apuntan los términos.
  • Asistente de uso general como producto. Ofrecer un «ChatGPT en WhatsApp» al público, donde conversar con la IA es el servicio en sí, es el caso prohibido, salvo en los países donde Meta está legalmente obligada a permitirlo.
  • Brasil. La página de precios para Proveedores de IA incluye a Brasil (+55) entre los mercados donde los Proveedores de IA pueden enviar mensajes de servicio desde el 11/03/2026, y Meta se los cobra según las tarifas publicadas. Entre los demás mercados listados están Italia y 29 mercados europeos, además de Turquía desde el 15/10/2026. En esos envíos, el webhook de estado trae la categoría de precio general_purpose_ai. Esta regla vale solo para Proveedores de IA; el precio para las demás empresas no cambia.
  • Datos para entrenamiento. Los términos prohíben usar datos de la plataforma para crear, desarrollar, entrenar o mejorar modelos de IA. Permiten usarlos para ajustar un modelo de uso exclusivo de la empresa, siempre que no sirvan para otros modelos. Revisa los términos de tu proveedor de LLM sobre retención y entrenamiento.

Los términos se actualizaron por última vez el 23/09/2026. Vuelve a leer la cláusula antes de lanzar un producto en el que la IA sea el centro de la oferta.

Ejemplo en Node.js

El ejemplo usa Express, una cola en memoria y la API de Vectalk. En producción, reemplaza la cola por un servicio persistente (Redis, SQS, RabbitMQ) y el Map por una base de datos. La función generarRespuesta es donde entra el SDK de tu proveedor de LLM. Para una versión paso a paso con la llamada real a un modelo, mira cómo conectar ChatGPT a la API oficial de WhatsApp.

import express from 'express';

const VECTALK = 'https://apis.vectalk.com.br/api/messages';
const TOKEN = process.env.VECTALK_TOKEN; // token de instancia
const VENTANA_MS = 24 * 60 * 60 * 1000;
const DISPARADORES_HUMANO = /\b(agente|humano|persona|reclamo|cancelar)\b/i;

const app = express();
app.use(express.json());

const cola = [];
const procesados = new Set();       // IDs wamid ya tratados
const conversaciones = new Map();   // wa_id -> { estado, historial, ultimaEntrada }

// 1. Webhook: valida, encola y responde 200
app.post('/webhook', (req, res) => {
  for (const entry of req.body.entry ?? []) {
    for (const change of entry.changes ?? []) {
      for (const msg of change.value?.messages ?? []) cola.push(msg);
    }
  }
  res.sendStatus(200);
});

// 2. Envío por Vectalk (mismo payload de Meta)
async function enviar(payload) {
  const r = await fetch(VECTALK, {
    method: 'POST',
    headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ messaging_product: 'whatsapp', ...payload }),
  });
  if (!r.ok) throw new Error(`Falla en el envío: ${r.status} ${await r.text()}`);
  return r.json();
}

// 3. Punto de integración con el LLM
async function generarRespuesta(historial) {
  // Llama aquí al SDK de tu proveedor, con un prompt de sistema que limite
  // el alcance a tu negocio y le pida responder "HANDOFF" cuando no sepa.
  throw new Error('Implementa la llamada al LLM');
}

// 4. Worker
async function procesar(msg) {
  if (procesados.has(msg.id)) return;
  procesados.add(msg.id);

  const c = conversaciones.get(msg.from) ?? { estado: 'bot', historial: [], ultimaEntrada: 0 };
  c.ultimaEntrada = Number(msg.timestamp) * 1000;
  conversaciones.set(msg.from, c);

  if (c.estado !== 'bot') return; // conversación con un humano: el bot se queda en silencio

  if (msg.type !== 'text') {
    await enviar({ to: msg.from, type: 'text', text: { body: 'Por ahora solo entiendo texto. ¿Puedes escribir tu consulta?' } });
    return;
  }

  const texto = msg.text.body;
  c.historial.push({ role: 'user', content: texto });
  c.historial = c.historial.slice(-20); // limita el contexto

  if (DISPARADORES_HUMANO.test(texto)) return derivar(msg.from, c);

  await enviar({ status: 'read', message_id: msg.id, typing_indicator: { type: 'text' } });

  const respuesta = await generarRespuesta(c.historial);
  if (respuesta.trim() === 'HANDOFF') return derivar(msg.from, c);

  if (Date.now() - c.ultimaEntrada > VENTANA_MS) return; // la ventana cerró: hace falta una plantilla

  await enviar({ to: msg.from, type: 'text', text: { body: respuesta } });
  c.historial.push({ role: 'assistant', content: respuesta });
}

async function derivar(waId, c) {
  c.estado = 'esperando_humano';
  await enviar({ to: waId, type: 'text', text: { body: 'Voy a llamar a una persona del equipo. En unos instantes alguien sigue por aquí.' } });
  // Notifica a tu herramienta de atención (cola de tickets, Slack, CRM).
}

setInterval(async () => {
  const msg = cola.shift();
  if (!msg) return;
  try { await procesar(msg); } catch (e) { console.error(e); }
}, 50);

app.listen(3000);

Lo que el ejemplo ya resuelve y lo que falta para producción:

  • Resuelve: respuesta inmediata al webhook, deduplicación por wamid, estado de derivación, límite de contexto, revisión de la ventana e indicador de escritura.
  • Falta: cola persistente con reintentos, base de datos para historial y estado, tiempo máximo en la llamada al LLM, registro de costos a partir del webhook de estado y un panel para que el agente tome la conversación y se la devuelva al bot. Vectalk no ofrece una bandeja de atención, así que ese panel es una herramienta propia o un CRM integrado con los webhooks.

Buenas prácticas para el agente

  • Alcance cerrado. El prompt de sistema debe decir qué hace el bot y qué no. Precios, plazos y políticas deben venir de los datos de tu sistema, no de la memoria del modelo.
  • Respuestas cortas. En WhatsApp, un mensaje de tres líneas funciona mejor que un texto largo. Eso también reduce la cantidad de mensajes cobrados.
  • Identifica al bot. Deja claro que el cliente está hablando con un asistente virtual y cómo llegar a una persona.
  • Registra todo. Guarda la pregunta, la respuesta, el modelo usado y el tiempo de respuesta. Sin eso no se puede auditar una respuesta equivocada.
  • Prueba con mensajes reales. Audios, fotos de comprobantes y stickers llegan todos los días. Decide qué hace el bot con cada tipo antes de pasar a producción.

Preguntas frecuentes

¿Puedo usar cualquier LLM con la API oficial?

La API de WhatsApp no restringe el modelo que usas en tu servidor. Lo que regulan los términos de Meta es el uso: la IA como apoyo a la atención de la empresa es distinto de ofrecer un asistente de uso general como producto principal.

¿El bot puede enviar el primer mensaje al cliente?

No con texto libre. Para iniciar el contacto o retomarlo después de 24 horas, hace falta una plantilla aprobada. Mira plantillas de la API de WhatsApp.

¿Cómo evito que el bot responda dos veces el mismo mensaje?

Guarda el ID wamid de cada mensaje procesado e ignora las repeticiones. Los reenvíos de webhook ocurren cada vez que el endpoint tarda o falla.

¿El bot puede responder audios?

El webhook entrega el ID del archivo multimedia, que descargas por la API de multimedia y transcribes con el servicio que prefieras. La transcripción y su costo corren por tu cuenta. Descargar multimedia del webhook muestra el paso de descarga.

¿Necesito algún registro especial en Meta para usar IA?

Para un bot de atención de la propia empresa, la documentación consultada no describe un registro adicional. Si tu producto es un asistente de IA de uso general, lee la cláusula 4.7 de los términos y la página de Proveedores de IA antes de empezar.

Empieza con Vectalk

Con Vectalk, tu bot recibe los mismos webhooks de Meta y envía con los mismos payloads, usando un token para todas las cuentas. No registras tarjeta en Meta: pagas una mensualidad y mantienes un saldo prepago, y cada mensaje entregado se descuenta de ese saldo. La coexistencia permite que el equipo humano siga usando la app. Crea tu cuenta en apps.vectalk.com.br/register y consulta la documentación.


Fuentes oficiales consultadas el 29/10/2026: Términos de Meta para la Plataforma de WhatsApp Business (actualizados el 23/09/2026), Política de Mensajes de WhatsApp Business, Precios para Proveedores de IA (actualizada el 15/10/2026), Precios de la plataforma de WhatsApp Business, Mensajes de servicio y ventana de atención, Indicadores de escritura, Webhooks en la documentación de Vectalk.

Pon a funcionar el WhatsApp oficial de tu empresa

Crea tu cuenta, conecta tu número a la API oficial (puedes mantener la app con coexistencia) y empieza a atender y enviar mensajes.