Files
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

17 lines
799 B
Bash

DATABASE_URL="postgresql://taller:taller123@localhost:5432/taller_turnos"
NEXTAUTH_SECRET="cambia-esto-por-un-secret-seguro"
NEXTAUTH_URL="http://localhost:3000"
GMAIL_USER="tu-email@gmail.com"
GMAIL_APP_PASSWORD="xxxx xxxx xxxx xxxx"
MAGIC_LINK_BASE_URL="http://localhost:3000"
# Bot de reservas por WhatsApp (Meta Cloud API).
# PHONE_NUMBER_ID: panel de Meta -> WhatsApp -> API Setup (es un id numérico, NO el teléfono).
# TOKEN: token permanente de un System User con whatsapp_business_messaging + _management.
# VERIFY_TOKEN: string inventado por vos; el mismo va acá y en el panel al dar de alta el webhook.
# APP_SECRET: App -> Settings -> Basic -> App Secret. Sin esto el webhook rechaza todo.
WHATSAPP_PHONE_NUMBER_ID=""
WHATSAPP_TOKEN=""
WHATSAPP_VERIFY_TOKEN=""
WHATSAPP_APP_SECRET=""