Files
whatsapp/modules/soporte/docs/tecnica/40-whatsapp-bot.md
Lizandro GuarnizoandClaude Opus 5 bc318db129 Documentación: menús y respuestas del bot, y manual de domicilios
El análisis de completitud cruzando roles contra módulos y tablas contra
documentos encontró dos huecos reales.

Manual de domicilios: recepcionista, lab_recepcion y lab_readonly tienen acceso
a la pantalla administrativa de domicilios, y la única página sobre el tema era
la del portal del enfermero, restringida a enfermeros. Son pantallas distintas
—una ve todo, la otra solo lo propio— y ahora cada una tiene su guía. Los
enfermeros pasan también a ver el manual de formularios, que su rol habilita.

Menús y respuestas automáticas del bot: había cuatro tablas en uso que ninguna
página explicaba. El bot responde solo las preguntas frecuentes mediante
autoresponses (7 configuradas) y ofrece un menú interactivo de 21 opciones en
dos niveles, todo configurable desde la base sin desplegar código. También
quedan documentados el estado de conversación, los envíos masivos y las
encuestas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 12:04:27 -05:00

3.5 KiB

WhatsApp y bot

El sistema nació como bot de WhatsApp y esa integración sigue siendo central.

Servicios

{{servicios}}

WhatsAppService

Envuelve la Cloud API de Meta. Se elige la línea al construirlo:

$wa = new WhatsAppService();           // principal
$wa = new WhatsAppService('turnero');  // turnero

Ambas líneas comparten cuenta (WABA) y token; lo único que cambia es el phone_number_id. Si un mensaje sale por la línea equivocada, casi siempre falta el argumento.

Métodos principales:

$wa->sendTextMessage($telefono, $texto, $meta);
$wa->sendTemplateMessage($telefono, $plantilla, $idioma, [], [], $componentes, $meta);

$meta acompaña el registro del mensaje: ['canal' => 'turnero', 'operator_id' => adminId()].

Plantillas

Fuera de la ventana de 24 horas hay que usar plantilla aprobada. message_templates guarda una copia local con sus components, pero la copia no manda: la versión real vive en Meta.

Consecuencia importante:

Las URL de los botones están en la plantilla, no en el código. Nuestro código solo envía los parámetros ({{1}}). Cambiar el código no altera el enlace que recibe el paciente.

Ejemplo — botón de consentimiento_turno_v2:

https://erp.laboratorioximenacaicedo.com/form_cliente.php?t={{1}}

Y así se arman los componentes al enviar:

$rawComps = [
    ['type' => 'body',   'parameters' => [['type' => 'text', 'text' => $codigo]]],
    ['type' => 'button', 'sub_type' => 'url', 'index' => '0',
     'parameters' => [['type' => 'text', 'text' => $token]]],
];

Respaldo

Si el envío por plantilla falla, se manda un texto plano con el enlace armado desde el dominio del servidor. Ese texto no pasa por Meta, así que su URL puede diferir de la del botón.

Contenido configurable

Buena parte de lo que responde el bot vive en la base, no en el código: respuestas automáticas por palabra clave y menús interactivos. Ver Menús y respuestas automáticas.

BotService

Decide qué hacer con cada mensaje entrante:

  1. ¿Aceptó los términos? Si no, se los pide y no avanza.
  2. ¿Está en horario? (BusinessHoursService)
  3. ¿La conversación la tomó un operador humano? El bot no interrumpe.
  4. Si no, responde según el estado de la conversación (ConversationStateService) y el menú (MenuService).

Términos y condiciones

Tabla Contenido
terms_versions Versión activa, URL del documento, mensajes
terms_acceptance Historial de aceptaciones
system_config.terms_message Texto de bienvenida, repite la URL dentro

Se vuelve a pedir la aceptación si nunca aceptó, si pasaron más de 6 meses, o si hay versión nueva con forzar_reenvio.

La URL del documento está en dos lugares. Cambiar solo uno deja al otro sirviendo un enlace viejo.

Configuración

Todo en system_config: whatsapp_token, whatsapp_api_url, whatsapp_business_account_id, whatsapp_phone_number_id, whatsapp_phone_number_id_turnero, webhook_verify_token.

Diagnóstico

Síntoma Dónde mirar
Sale por el número equivocado Falta 'turnero' en el constructor
Enlace roto en un botón La plantilla en Meta
No llega ninguna plantilla Estado de aprobación en WhatsApp Manager
Llega texto plano en vez de plantilla El respaldo actuó: la plantilla falló
El bot no responde webhook_logs, horario, estado de la conversación