Flowise en WhatsApp por la API oficial, con ZapClaw
En resumen: ZapClaw entrega cada mensaje de WhatsApp a un pequeño script intermediario (el relay), que le pregunta a tu flujo de Flowise por la Prediction API, y la respuesta vuelve por ZapClaw. Los mensajes pasan por la Cloud API oficial de Meta, y el número sigue funcionando en la app de WhatsApp Business de tu celular. Funciona con chatflows y agentflows, y no necesitas una app de Meta propia.
Conecta tu número en minutos y dale a tu agente de Flowise el número de WhatsApp que tus clientes ya usan, en la nube o self-hosted.
Plan Business: US$ 29 al mes, con números ilimitados
Empieza gratis Ver el relayLo que necesitas para conectar
- La app de WhatsApp Business en el número, en la versión 2.24.17 o posterior, con uso habitual.
- Autenticación en dos pasos activada en la cuenta personal de Facebook que autoriza la conexión.
- El número fuera de cualquier otro proveedor. Si está conectado a otra plataforma, desconéctalo allí primero.
- Una computadora para hacer la conexión, con tu celular a la mano para confirmarla en la app.
No necesitas una empresa registrada ni un negocio verificado para conectar. La lista completa.
Por qué ZapClaw para un agente de Flowise en WhatsApp
- El número sigue en la app de WhatsApp Business. Con la Coexistencia, tu equipo sigue respondiendo en la app mientras Flowise trabaja con el mismo número.
- Sin una app de Meta propia. Conectas el número en la ventana de Embedded Signup de Meta, desde el panel de ZapClaw, y ZapClaw se encarga del lado de la Cloud API.
- Una memoria por cliente. El relay pasa al cliente como
sessionId, y Flowise mantiene una conversación separada para cada sesión, así que el agente recuerda lo que esa persona dijo antes. - Ninguna librería no oficial detrás de tu agente. Las integraciones que imitan WhatsApp Web van contra las condiciones de WhatsApp y ponen el número en riesgo. ZapClaw usa la Cloud API de Meta, y las políticas de Meta se aplican como a cualquier empresa en ella.
- Entregas que puedes comprobar. Cada evento va firmado con HMAC-SHA256 y tiene hasta 3 intentos de entrega si el relay no responde, y un evento fallido se puede reenviar desde el panel.
Por qué hay un relay en medio
Flowise ejecuta un flujo desde su Prediction API, con el mensaje en un campo question, y devuelve la respuesta en el cuerpo de la misma llamada HTTP. El webhook de ZapClaw trae su propio JSON y no lee el cuerpo de la respuesta, así que el relay hace de puente: convierte cada mensaje en una pregunta, y la respuesta en un envío por ZapClaw.
El relay de abajo tiene menos de 70 líneas de Node.js, sin nada que instalar. Si ya usas n8n, puede hacer de relay, como mostramos más abajo.
Configúralo en cuatro pasos
- En Flowise, guarda tu chatflow o agentflow y anota el ID del flujo. Si le asignaste una clave de API al flujo, anota esa clave también.
- En ZapClaw, conecta tu número, crea una clave de API y copia la Clave de firma en la página Webhook.
- Ejecuta el relay de abajo con esos valores en un servidor con una dirección HTTPS pública, y pega esa dirección en Webhook en ZapClaw. ZapClaw solo entrega en una dirección HTTPS pública.
- Haz clic en Enviar evento de prueba en ZapClaw: el relay responde
200y no le pregunta nada a Flowise. Luego envía un mensaje de WhatsApp a tu número desde otro celular: el flujo responde.
El relay, listo para ejecutar
Guárdalo como relay.mjs e inícialo con node relay.mjs en Node.js 18 o posterior. Lee su configuración del entorno: ZAPCLAW_API_KEY, ZAPCLAW_SECRET (la clave de firma), FLOWISE_URL (la dirección de tu Flowise), FLOW_ID, FLOWISE_API_KEY cuando el flujo tenga una, y PORT, el puerto en el que escucha el relay (8787 por defecto), al que tu proxy HTTPS reenvía.
// relay.mjs: ZapClaw webhook in, Flowise Prediction API, the answer out through ZapClaw.
// Node.js 18 or newer, nothing to install. Start it with: node relay.mjs
import { createServer } from 'node:http';
import { createHmac, timingSafeEqual } from 'node:crypto';
const ZAPCLAW_API_KEY = process.env.ZAPCLAW_API_KEY; // zc_live_...
const ZAPCLAW_SECRET = process.env.ZAPCLAW_SECRET; // the webhook signing secret
const FLOWISE_URL = process.env.FLOWISE_URL || 'http://localhost:3000'; // your Flowise address
const FLOW_ID = process.env.FLOW_ID; // the ID of your chatflow or agentflow
const FLOWISE_API_KEY = process.env.FLOWISE_API_KEY; // only when the flow has an API key
const queues = new Map(); // one message at a time per customer, in order
const isSigned = (raw, header = '') => {
const hmac = createHmac('sha256', ZAPCLAW_SECRET).update(raw).digest('hex');
const expected = Buffer.from(`sha256=${hmac}`);
const given = Buffer.from(String(header));
return given.length === expected.length && timingSafeEqual(given, expected);
};
const answer = async ({ data, account }) => {
// The customer is the session: Flowise keeps one conversation memory per sessionId.
const res = await fetch(new URL(`api/v1/prediction/${FLOW_ID}`, FLOWISE_URL), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...(FLOWISE_API_KEY && { Authorization: `Bearer ${FLOWISE_API_KEY}` }),
},
body: JSON.stringify({
question: data.text.body,
overrideConfig: { sessionId: data.user_id || data.from },
}),
});
if (!res.ok) throw new Error(`Flowise answered ${res.status}`);
const { text } = await res.json();
if (!text) return;
await fetch('https://api.zapclaw.app/api/v1/send/text', {
method: 'POST',
headers: { 'X-API-Key': ZAPCLAW_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({
from: account.display_phone_number || account.phone_number_id,
to: data.from || data.user_id,
text: text.slice(0, 4096),
}),
});
};
createServer((req, res) => {
const chunks = [];
req.on('data', (chunk) => chunks.push(chunk));
req.on('end', () => {
const raw = Buffer.concat(chunks);
if (!isSigned(raw, req.headers['x-zapclaw-signature'])) return res.writeHead(401).end();
res.writeHead(200).end(); // answer ZapClaw now: it waits 10 seconds, a flow can take longer
let event;
try {
event = JSON.parse(raw.toString('utf8'));
} catch {
return;
}
if (event.event !== 'message.received' || event.data?.type !== 'text') return;
const key = event.data.user_id || event.data.from;
const next = (queues.get(key) || Promise.resolve())
.then(() => answer(event))
.catch((err) => console.error(err));
queues.set(key, next);
});
}).listen(process.env.PORT || 8787);
Lo que hace: comprueba el encabezado X-ZapClaw-Signature, responde a ZapClaw de inmediato (ZapClaw espera 10 segundos, y un modelo puede tardar más) y le pregunta a Flowise un mensaje a la vez por cliente, para que las respuestas mantengan su orden. La respuesta del flujo vuelve en el campo text y sale como un mensaje de WhatsApp.
En un agentflow, deja el nodo Start en Chat Input: el relay envía el mensaje como question, y un inicio en Form Input espera un objeto form.
O usa n8n como relay
¿Ya usas n8n? Importa el flujo de nuestra página de n8n y agrega, entre el filtro y la respuesta, un nodo HTTP Request que envía a la Prediction API de tu flujo question igual a {{ $json.body.data.text.body }} y overrideConfig.sessionId igual a {{ $json.body.data.user_id || $json.body.data.from }}. Después de ese nodo, $json pasa a ser la respuesta de Flowise, así que en la respuesta usa {{ $json.text }} en text y haz que from y to lean el nodo del webhook: {{ $('ZapClaw webhook').item.json.body.account.display_phone_number || $('ZapClaw webhook').item.json.body.account.phone_number_id }} y {{ $('ZapClaw webhook').item.json.body.data.from || $('ZapClaw webhook').item.json.body.data.user_id }}.
Llamar a ZapClaw desde dentro de Flowise
Flowise también puede llamar a la API de ZapClaw por su cuenta: con el nodo HTTP de un agentflow, o con una Custom Tool que el agente decide usar, con un encabezado X-API-Key. Por ejemplo, una herramienta que avisa a un vendedor por WhatsApp cuando un cliente pide una cotización. Dentro de una Custom Tool, $flow.sessionId trae al cliente, porque el relay lo pasa como sesión, y una variable de Flowise leída con $vars puede guardar tu clave de ZapClaw. La llamada en sí, como comando curl:
curl -X POST https://api.zapclaw.app/api/v1/send/text \
-H "X-API-Key: zc_live_..." \
-H "Content-Type: application/json" \
-d '{ "from": "15551617409", "to": "15555550100", "text": "A customer asked for a quote" }'
from es tu número conectado, que el webhook trae en account.display_phone_number, y to es la persona a quien escribes. Un mensaje enviado responde 201. El texto libre funciona dentro de las 24 horas siguientes al último mensaje de esa persona a tu número; fuera de esa ventana, Meta solo acepta una plantilla aprobada, con POST /api/v1/send/template.
Lo que llega al relay
Cada mensaje llega como un evento message.received: el texto en data.text.body, el remitente en data.from (o data.user_id para un contacto que solo muestra su nombre de usuario), el nombre del contacto en data.contact_name y tu número en account.display_phone_number.
{
"event": "message.received",
"sequence": 1042,
"timestamp": "2026-10-15T14:00:00.000Z",
"data": {
"from": "15555550100",
"user_id": "US.1A2B3C4D5E6F7G8H9I0J",
"contact_name": "Maria Silva",
"message_id": "wamid.HBg...",
"type": "text",
"timestamp": "1792072800",
"text": { "body": "Do you deliver on Saturdays?" }
},
"account": {
"phone_number_id": "964283400112599",
"display_name": "My Business",
"display_phone_number": "+1 555 161-7409"
}
}
El relay solo pasa los mensajes de texto entrantes: el evento de prueba del panel y cualquier otro evento reciben un 200 y nada más. Un audio o una imagen trae una media_url que descargas con tu clave de API, si quieres pasársela a Flowise más adelante. Todos los eventos y campos están en la documentación (en inglés).
Cuánto cuesta
- Gratis: 500 mensajes al mes y 1 número, sin tarjeta y sin fecha de vencimiento. Al llegar al límite, el envío se pausa y los mensajes nuevos quedan retenidos hasta que te suscribas.
- Business: US$ 29 al mes, con 20,000 mensajes incluidos y números ilimitados.
- Agency: US$ 49 al mes para agencias, con 3 clientes y 60,000 mensajes incluidos y números ilimitados.
Meta te cobra directamente las tarifas de mensajes de WhatsApp, sin margen de ZapClaw. Todos los planes y precios.
Para quién es
Equipos que construyeron en Flowise un agente de IA, un asistente sobre sus propios documentos o un flujo de clasificación de consultas de soporte y quieren llevarlo al número de WhatsApp que sus clientes ya usan. Las agencias conectan los números de sus clientes en el plan Agency, cada cliente aislado de los demás. No sirve para envíos masivos.
Para ir más allá
- Typebot en WhatsApp, cuando un flujo guionizado con botones funciona mejor que un agente de IA.
- WhatsApp en n8n, con un flujo que importas en lugar de un script.
- Un webhook para tu propia IA, cuando las personas siguen respondiendo desde la app.
- Dify en WhatsApp, si construyes tus agentes en Dify.
- La referencia del webhook (en inglés), con cada evento y campo.
Fuentes
Documentación de Flowise, en inglés, consultada el 15 de octubre de 2026. Las funciones cambian, así que revisa cada fuente antes de construir.
- Flowise, Prediction: el endpoint, el campo
questiony una memoria porsessionId. - Referencia de la API de Flowise, Prediction: los campos de la solicitud y el
textde la respuesta. - Flowise, control de acceso a los flujos: la clave de API enviada como token Bearer.
- Flowise, Agentflow V2: las entradas del nodo Start y el nodo HTTP.
- Flowise, Custom Tool:
$flow.sessionIdy$vars. - Código fuente de Flowise en GitHub: cómo se lee el
sessionIdde una prediction. - ZapClaw: webhooks y verificación de la firma en la documentación, y lo que necesitas para conectar.
Pon tu agente de Flowise en WhatsApp hoy
Empieza en el plan gratuito: un número, sin tarjeta. Pasa al plan Business cuando necesites más números o más mensajes.
Empieza gratis Ver la documentación del webhook (en inglés)