Verificando acceso interno...
WhatsApp — configuración técnica
Tenemos tres formas de conectar WhatsApp y cada una tiene su sitio: Meta Cloud API (la oficial, para clientes de verdad), Twilio WhatsApp (atajo cuando ya tenemos número Twilio), y Local Agent (modo experimental sobre número personal, sólo PoCs). Esta guía explica cuándo usar cada una y cómo dejarla operativa.
- Las 3 opciones (cuándo usar cada una)
- Meta Cloud API · alta y configuración
- Meta · webhook entrante y firma
- Meta · envío de mensajes y plantillas
- Twilio WhatsApp · cuándo y cómo
- Local Agent · modo experimental
- Pipeline IA y memoria conversacional
- Enlace con asistente de voz (ElevenLabs)
- Checklist de alta de un cliente nuevo
1. Las 3 opciones (cuándo usar cada una)
| Opción | Cuándo | Pro | Contra |
|---|---|---|---|
| Meta Cloud API | Cliente de verdad que va a producción. | Oficial, escalable, sin coste por mensaje en sesión 24h, soporta plantillas multimedia. | Requiere número dedicado + verificación Meta Business + el cliente no puede usar ese número en su WhatsApp normal. |
| Twilio WhatsApp | Cliente que ya nos compra teléfono y queremos un único proveedor. | Mismo dashboard que la voz, factura única, alta más rápida. | Coste por mensaje más alto, plantillas más rígidas, depende de Twilio para todo. |
| Local Agent | PoCs internas, demos rápidas, números personales. | Funciona sobre número personal sin pedir nada a Meta. 0 € de alta. | Inestable, no oficial, riesgo de baneo del número. Nunca producción cliente. |
Regla del equipo: ofrecer Meta Cloud API por defecto. Twilio sólo si el cliente ya tiene Twilio. Local Agent sólo para nuestras pruebas.
2. Meta Cloud API · alta y configuración
Pasos en Meta Business Suite → WhatsApp → Configuración API:
- Crear/usar un Meta Business verificado (NIF + dominio).
- Añadir un número de teléfono dedicado a WhatsApp (no tiene que ser nuevo, pero sale del WhatsApp normal del cliente).
- Verificar el número (SMS o llamada).
- Crear una App Meta tipo Business y añadirle el producto WhatsApp.
- Generar un Permanent Access Token con permisos
whatsapp_business_messagingywhatsapp_business_management. - Anotar el Phone Number ID y el WhatsApp Business Account ID (WABA).
- Apuntar el Callback URL a
https://cadences.app/api/webhooks/whatsappcon el verify token que decidamos. - Suscribirse a los webhook fields:
messages,message_status,message_template_status_update.
Secretos a guardar (Pages project cadences):
| Secret | Para qué |
|---|---|
WHATSAPP_ACCESS_TOKEN (alias META_WHATSAPP_TOKEN) | Token permanente para llamar a la API de envío. |
WHATSAPP_PHONE_NUMBER_ID (alias META_PHONE_NUMBER_ID) | ID del número dedicado. |
META_APP_SECRET | Para verificar la firma X-Hub-Signature-256 del webhook. |
WHATSAPP_VERIFY_TOKEN | String que inventamos y que Meta nos manda en el handshake GET. |
Para multi-tenant, WHATSAPP_PHONE_NUMBER_ID y access token viven
en voice_connectors.credentialsEncrypted por cliente; el global
es sólo fallback.
3. Meta · webhook entrante y firma
Endpoint único: functions/api/webhooks/whatsapp.js. Maneja dos
verbos:
- GET (handshake al alta): Meta nos manda
?hub.mode=subscribe&hub.verify_token=X&hub.challenge=Y. ComparamosXconWHATSAPP_VERIFY_TOKENy devolvemosYen texto plano. - POST (mensajes y eventos): JSON con
entry[].changes[].value.messagesystatuses. Antes de procesar, verificamos la firmaX-Hub-Signature-256converifyMetaSignature()usandoMETA_APP_SECRET(HMAC-SHA256 sobre el body crudo).
El procesamiento del POST hace, en orden:
- Identificar el tenant por
WABA ID+phone_number_id. - Insertar en
incoming_whatsapp_messagesel raw + parsed. - Crear o actualizar el
conversation_thread(tablaconversation_threads, migración 0059). - Disparar el SmartPipeline (sección 7) que decide cómo responder.
- Si llega
statuses(entregado/leído/fallido), actualizar el outbound correspondiente enwhatsapp_messages.
4. Meta · envío de mensajes y plantillas
Reglas de oro de WhatsApp Business:
- Ventana de 24h: si el cliente nos escribió en las últimas 24h, podemos contestar libremente con texto/imagen/audio. Fuera de esa ventana, sólo plantillas pre-aprobadas (HSM).
- Plantillas: hay que crearlas en Meta Business Suite y que las aprueben (24-48h normalmente). Categoría
UTILITYes la más fácil;MARKETINGexige opt-in y se cobra más caro. - Coste: en sesión 24h iniciada por el cliente = gratis. Plantilla iniciada por nosotros = ~ 0,03–0,06 €/mensaje en España (depende de categoría).
Endpoints nuestros para envío:
POST /api/whatsapp/send— Mensaje libre (sólo válido en ventana 24h). Body:{ tenant_id, to, type, content }.POST /api/whatsapp/send-template— Plantilla aprobada. Body:{ tenant_id, to, template_name, language, components }.POST /api/whatsapp/upload-media— Sube imagen/audio/PDF y devuelvemedia_idreusable.
Todo lo que sale queda en whatsapp_messages con status
que se actualiza desde el webhook (queued → sent →
delivered → read o failed).
5. Twilio WhatsApp · cuándo y cómo
Twilio nos da WhatsApp encima del mismo proyecto Twilio que usamos para voz. Útil cuando el cliente ya está con nosotros con número de teléfono y no quiere otro proveedor más.
- El mismo webhook (
/api/webhooks/whatsapp) detecta proveedor por la cabeceraX-Twilio-Signature(ausente = Meta). - Verificación:
verifyTwilioSignature(), HMAC-SHA1 sobre URL + parámetros POST ordenados, secret =TWILIO_AUTH_TOKEN. - Envío:
functions/api/twilio/send-whatsapp.js. Cobra ~ 0,005 € + lo de Meta por mensaje (más caro que Meta directo).
Aviso: Twilio no soporta todas las features nuevas de Meta (carouseles, flows interactivos). Si el cliente quiere algo avanzado, ir a Meta Cloud API directo.
6. Local Agent · modo experimental
Bridge sobre whatsapp-web.js (no oficial) que se conecta con un
número personal vía QR, como WhatsApp Web. Vive en
functions/api/whatsapp-local/ y la pieza central es
SmartPipelineService.js.
Útil para:
- Demos a clientes sin esperar verificación Meta.
- Probar el pipeline IA antes de pagar el alta oficial.
- Nuestro propio uso interno (responder consultas con IA).
Riesgos: Meta puede banear el número en cualquier momento. Nunca prometer SLA. Nunca facturar por uso. Nunca números de cliente final.
7. Pipeline IA y memoria conversacional
Cuando entra un mensaje y el tenant tiene auto-respond activo, el SmartPipeline decide cómo responder en 4 pasos:
- Clasificar intención (LLM corto): consulta_producto, consulta_pedido, queja, charla, spam.
- Recuperar contexto: hilo previo de
conversation_threads+ RAG de la knowledge base del tenant + facts del cliente (voice_customer_facts). - Generar respuesta (LLM principal, normalmente GPT-4o-mini con system prompt del tenant).
- Decidir acción adicional: si la intención es queja grave → marcar
escalate; si es pedido → ofrecer link Stripe; si es info → solo responder.
Todo el historial entra en whatsapp_local_messages /
conversation_threads para que el siguiente mensaje conserve memoria.
La memoria es cross-canal: si el cliente llamó por teléfono,
el thread está unificado por customer_phone y el bot lo recuerda.
8. Enlace con asistente de voz (ElevenLabs)
WhatsApp y voz no son silos. Hay 3 puntos de contacto importantes:
- Tool
send_whatsapp: el agente de voz puede mandar un WhatsApp durante la llamada (link de pago, foto del producto, mapa) — ver ElevenLabs · tools. - Escalación: si la llamada va mal y el agente decide
escalate_to_human, mandamos WhatsApp al staff con el resumen + transcripción para que retomen el contexto. - Memoria compartida: el thread
conversation_threadsagrupa mensajes WhatsApp + llamadas porcustomer_phone. Cuando entra un WhatsApp, el SmartPipeline ve también las últimas 3 llamadas resumidas.
9. Checklist de alta de un cliente nuevo
- Decidir proveedor (Meta vs Twilio) — sección 1.
- Si Meta: alta en Meta Business + número dedicado + access token + Phone Number ID.
- Insertar en
voice_connectorsconconnectorType='whatsapp_meta'(owhatsapp_twilio) y credenciales cifradas. - Configurar webhook callback en Meta apuntando a
https://cadences.app/api/webhooks/whatsappcon el verify token. - Suscribirse a fields
messages+message_status. - Crear las plantillas iniciales del cliente (utilidad: confirmación de pedido, recordatorio de cita, post-llamada). Esperar aprobación Meta.
- Activar
auto_respond=1envoice_assistants+ indexar knowledge base en Vectorize. - Test: mandar un WhatsApp al número, comprobar que llega al webhook (logs Cloudflare), que se inserta en
incoming_whatsapp_messages, que el bot responde. - Pasar al cliente acceso al panel para que vea conversaciones y pueda intervenir.