Files
taller_automotriz/docs/whatsapp.md
T
jpbeldomenico 15d6e8a2ee feat(whatsapp): webhook + envio por Graph API (F0)
Ultima fase del bot de reservas: conecta la maquina de conversacion ya
existente (whatsapp-bot.ts) con la WhatsApp Business Cloud API.

- src/lib/whatsapp.ts: traduce RespuestaBot -> payloads de Meta (texto e
  interactive/button, con los limites de 3 botones / 20 chars / 4096 chars),
  aplana el payload del webhook y valida X-Hub-Signature-256 en tiempo
  constante.
- src/app/api/whatsapp/webhook/route.ts: GET de verificacion y POST de
  mensajes. Valida la firma sobre el cuerpo crudo, deduplica por message id
  (Meta reintenta) y siempre devuelve 200 para no entrar en loop de retries.
- scripts/test-whatsapp-envio.ts (npm run test:envio): 30 asserts sobre la
  capa Meta con fetch stubbeado, sin DB ni credenciales.
- docs/whatsapp.md con el alta en el panel de Meta y las 4 env vars.

Falta solo cargar las credenciales de Meta en el .env de produccion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 09:55:47 -03:00

2.6 KiB

Bot de reservas por WhatsApp

Flujo: el cliente escribe al número del taller → el bot lo identifica por teléfono (verifica con el email registrado, o lo da de alta) → elige mecánico, trabajo y horario → confirma y se crea el Turno. Todo pasa dentro de la ventana de 24hs que abre el cliente, así que no hacen falta plantillas aprobadas ni tiene costo.

Piezas

Archivo Qué hace
src/lib/whatsapp-bot.ts Máquina de conversación. No sabe nada de Meta: devuelve RespuestaBot[]
src/lib/whatsapp.ts Traduce a/desde la Graph API de Meta y valida la firma del webhook
src/app/api/whatsapp/webhook/route.ts Endpoint: verificación (GET) y mensajes entrantes (POST)

Tests sin DB ni credenciales: npm run test:bot (conversación) y npm run test:envio (capa Meta).

Variables de entorno

WHATSAPP_PHONE_NUMBER_ID=   # id numérico del número, NO el teléfono
WHATSAPP_TOKEN=             # token permanente de System User
WHATSAPP_VERIFY_TOKEN=      # string inventado, el mismo acá y en el panel de Meta
WHATSAPP_APP_SECRET=        # App -> Settings -> Basic -> App Secret

Sin WHATSAPP_APP_SECRET el webhook rechaza todo con 403 (es a propósito: sin firma no se puede confiar en el payload).

Alta en Meta (una sola vez)

  1. Meta Business Suite con la cuenta de Facebook del taller.
  2. developers.facebook.com → crear App tipo Business → agregar producto WhatsApp.
  3. WhatsApp → API Setup: de ahí salen PHONE_NUMBER_ID y un token temporal (24hs). Para el token definitivo: Business Settings → System Users → crear usuario → Generate Token con permisos whatsapp_business_messaging y whatsapp_business_management.
  4. App → Settings → Basic → App Secret → WHATSAPP_APP_SECRET.
  5. Cargar las 4 variables en el .env de producción y redeployar.
  6. WhatsApp → Configuration → Webhook:
    • Callback URL: https://taller.beldo.duckdns.org/api/whatsapp/webhook
    • Verify token: el mismo WHATSAPP_VERIFY_TOKEN
    • Suscribir el campo messages (sin esto no llega nada).
  7. Probar con el número de prueba que da Meta gratis, antes de migrar el número real.

Notas:

  • El número del taller no puede estar activo en la app de WhatsApp normal/Business: hay que borrar esa cuenta antes de migrarlo a Cloud API.
  • Business Verification se saltea mientras estemos abajo de 1000 usuarios únicos/24hs; solo hace falta la aprobación del Display Name.
  • Meta permite 3 botones como máximo. Si hay más de 3 mecánicos activos, salen los 3 primeros como botón y el resto se elige respondiendo con el número (el bot acepta las dos formas).