Files
whatsapp/WEBHOOK_ENDPOINTS.md
2026-06-09 16:44:39 -05:00

3.6 KiB

Webhook WhatsApp — Endpoints y Características

Endpoint principal

URL: /api/webhook.php

GET — Verificación de webhook

GET /api/webhook.php?hub.mode=subscribe&hub.verify_token=TOKEN&hub.challenge=CHALLENGE

Parámetros que envía Meta

Parámetro Valor esperado
hub.mode subscribe
hub.verify_token El token configurado en system_config.webhook_verify_token
hub.challenge Número aleatorio que debe devolverse tal cual

⚠️ Bug conocido

El código lee $_GET['hub_verify_token'] (con guión bajo), pero PHP convierte los puntos a guiones bajos automáticamente al parsear $_GET, por lo que funciona correctamente.

Respuesta exitosa

HTTP 200
Body: {challenge}

Respuesta fallida

HTTP 403
Body: {"error":"Token de verificación inválido"}

POST — Recepción de eventos

POST /api/webhook.php
Content-Type: application/json

Estructura del payload esperado (Meta Cloud API)

{
  "object": "whatsapp_business_account",
  "entry": [{
    "id": "WABA_ID",
    "changes": [{
      "field": "messages",
      "value": {
        "messaging_product": "whatsapp",
        "metadata": {
          "phone_number_id": "PHONE_NUMBER_ID"
        },
        "contacts": [{
          "wa_id": "573001234567",
          "profile": { "name": "Nombre Contacto" }
        }],
        "messages": [{
          "from": "573001234567",
          "id": "wamid.XXX",
          "timestamp": "1234567890",
          "type": "text",
          "text": { "body": "Hola" }
        }]
      }
    }]
  }]
}

Tipos de mensaje soportados

type Descripción
text Texto plano
image Imagen (con caption opcional)
audio Audio / nota de voz
video Video
document Documento / PDF
sticker Sticker
reaction Reacción emoji a otro mensaje
interactive Respuesta de lista o botón

El campo field del change puede ser

  • messages → mensajes entrantes y estados
  • conversations → alias aceptado también

Eventos de estado (statuses)

"statuses": [{
  "id": "wamid.XXX",
  "status": "sent|delivered|read|failed",
  "recipient_id": "573001234567"
}]

Respuesta exitosa

HTTP 200
Body: {"status":"success"}

Configuración necesaria en system_config (BD)

config_key Descripción
whatsapp_token Access Token de Meta
whatsapp_phone_number_id Phone Number ID de la línea
webhook_verify_token Token de verificación del webhook
whatsapp_api_url https://graph.facebook.com/v22.0/

Variables de entorno equivalentes (.env)

WHATSAPP_TOKEN=
WHATSAPP_PHONE_NUMBER_ID=
WEBHOOK_VERIFY_TOKEN=
WHATSAPP_API_URL=https://graph.facebook.com/v22.0/
DB_HOST=
DB_PORT=3306
DB_NAME=
DB_USER=
DB_PASS=

Tablas BD que usa el webhook

Tabla Uso
users Crea o busca usuario por phone_number
conversations Guarda cada mensaje (deduplicado por message_id)
webhook_logs Registra el payload crudo de cada POST
notifications Crea aviso de nuevo mensaje entrante
media_queue Encola media que no pudo descargarse en el momento
system_config Lee tokens y configuración

Seguridad — pendiente de implementar

  • No valida la firma X-Hub-Signature-256 en el POST.
  • Se recomienda agregar antes de procesar:
$signature = $_SERVER['HTTP_X_HUB_SIGNATURE_256'] ?? '';
$expected  = 'sha256=' . hash_hmac('sha256', $input, APP_SECRET);
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}