Commit Graph
40 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Opus 5 2b1f08b03f Evitar teléfonos falsos en la historia clínica, y pedir el número a quien lo oculta
El arreglo anterior dejó un defecto: obtenerOCrearDesdeWhatsapp() copiaba
users.phone_number al teléfono de la ficha, y para quien oculta su número ahí
va el BSUID. normalizarTelefono() le quitaba el punto y las letras, así que
"CO.1761088155094242" quedaba guardado como "1761088155094242": un número de
16 dígitos, falso, con apariencia de real, dentro de una historia clínica y
sin que nadie lo notara. Ahora esa ficha se crea sin teléfono, que es la
verdad: no lo tenemos.

- esBsuid() queda definido una sola vez, en config.php, que es donde lo ven
  tanto el servicio de WhatsApp como las clases del laboratorio.
- La lista y el detalle de pacientes dicen "Solo por WhatsApp" en vez de
  mostrar el identificador crudo: recepción necesita entender por qué no
  puede llamar, no ver un código.
- Al crear la ficha desde una conversación se le pide el número con el botón
  de Meta, una sola vez (users.contacto_pedido_at). El texto es editable
  desde configuración. Solo se marca como pedido si Meta aceptó el envío,
  para poder reintentar si falló.
- tests/test_bsuid.php: 30 verificaciones sobre identidad, envío, vinculación
  y creación de fichas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 20:26:31 -05:00
Lizandro GuarnizoandClaude Opus 5 26025a6399 Reconocer por BSUID a quien oculta su teléfono, y poder pedírselo
Meta no permite averiguar el teléfono a partir del BSUID: no hay endpoint de
consulta inversa, cada empresa debe llevar su propia equivalencia. Pero el
BSUID llega en TODOS los webhooks de mensaje, también en los que aún traen
teléfono, así que la equivalencia se puede ir guardando sola mientras la
persona todavía muestra su número.

- users.bsuid guarda esa equivalencia, y el webhook la anota en cada mensaje.
  Cuando alguien oculte su número, se le seguirá reconociendo y respondiendo
  a su teléfono de siempre.
- Va en columna aparte y no en phone_number porque el teléfono además cruza
  con el paciente y el turnero; mezclarlos rompería esos cruces.
- Para quien nunca escribió mostrando el número queda pedirle el contacto:
  pedirContacto() manda el botón request_contact_info, y el webhook atiende
  el mensaje `contacts` que llega si acepta.
- Al vincular puede aparecer un segundo registro de la misma persona. No se
  fusionan: una fusión mal hecha mezcla dos historias clínicas. Gana el que
  tiene el teléfono, el otro queda anotado en el log para revisarlo a mano.
- scripts/backfill_bsuid.php carga las equivalencias del histórico (6.423),
  con --simular para verlas sin escribir.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 20:07:52 -05:00
Lizandro GuarnizoandClaude Opus 5 92179af56a Atender a quien oculta su teléfono en WhatsApp (BSUID)
Meta desplegó los nombres de usuario: quien oculta su teléfono llega al
webhook sin `from` ni `wa_id`, identificado solo por su BSUID con la forma
"CO.1761088155094242". El webhook exigía teléfono y descartaba el mensaje
en silencio, sin guardarlo ni dejar rastro: 221 mensajes de 65 personas
ignorados por completo, ya el 3-6% de lo que entra cada día y subiendo.

- webhook.php lee `from_user_id` cuando no llega el teléfono, y rescata el
  nombre del contacto indexando también por `user_id`.
- WhatsAppService responde por BSUID: Meta exige el campo `recipient` en
  lugar de `to`. Se traduce en sendMessage(), el punto por donde pasan todos
  los envíos, en vez de en los diez métodos que arman payloads.
- formatPhoneNumber() devuelve el BSUID intacto; antes le quitaba el punto
  y las letras y lo dejaba en un destinatario inexistente.
- Las cuatro columnas del flujo pasan a varchar(32): los BSUID de Meta
  llegan a 23 caracteres y se truncaban en silencio en varchar(20).

De estas personas no tendremos el teléfono; si un flujo lo necesita, hay
que identificarlas por documento.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 19:41:10 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4b054c5afc fix: meta ignorado en sendTemplateMessage con rawComponents
Cuando se usaban rawComponents, el parámetro $meta no se agregaba
al payload, causando que los mensajes del turnero se guardaran con
canal='bot' y aparecieran en conversations.php.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-28 01:14:53 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 3d6147bf0d fix(template): send parameter_name for named-variable templates
WhatsApp API returns "(#100) Invalid parameter — Parameter name is
missing or empty" for templates that use named variables.

- chat.php sendTemplate(): collect params as [{name, value}] objects
  using data-var-index as the parameter name
- WhatsAppService::sendTemplateMessage(): handle {name, value} objects
  in the indexed-array path by emitting {type, parameter_name, text}
  (backward-compatible — plain strings still work as positional params)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 15:04:31 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 a8380ddc81 debug(template): expose Meta error subcode/details, add canal meta
- WhatsAppService::makeRequest: include error_subcode and error_data.details
  in the thrown exception message to surface the real reason for #100 errors
- chat_send_message: log template name/lang/params before sending;
  pass canal+operator_id meta so outgoing templates are tagged correctly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 14:54:10 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 4d04fea1de fix(turnero): save outgoing messages with canal='turnero' so they appear in chat
saveOutgoingMessage() now reads __app_meta.canal and stores it in conversations.
sendMediaById() accepts a $meta param and forwards it to saveOutgoingMessage.
chat_upload_media.php passes $extra (canal=turnero) to sendMediaById.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:32:23 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 5acd46df5a fix(turnero): route incoming messages by phone_number_id and fix WhatsAppService canal
- WhatsAppService($canal): when 'turnero', swaps phoneNumberId to whatsapp_phone_number_id_turnero
  so outgoing messages actually go from the turnero number (not the main bot)
- webhook.php: reads metadata.phone_number_id from the payload and compares it to
  whatsapp_phone_number_id_turnero; if it matches, saves canal='turnero' and skips bot processing
- Previously all incoming messages had canal=NULL/bot so Chat Turnero never saw them,
  and all outgoing messages from Chat Turnero were sent via the wrong (main bot) number

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-03 08:26:11 -05:00
Lizandro Guarnizo a716cd187a Update WhatsAppService.php 2026-02-21 12:02:15 -05:00
Lizandro Guarnizo 51f1b04293 up 2026-02-21 11:45:32 -05:00
Lizandro Guarnizo e00c96c614 Update WhatsAppService.php 2026-02-21 11:39:25 -05:00
Lizandro Guarnizo 0aa450be67 up 2026-02-21 11:33:56 -05:00
Lizandro Guarnizo 5dd48ba5c2 up 2026-02-21 11:24:15 -05:00
Lizandro Guarnizo f6cf4bace1 up 2026-02-21 08:58:22 -05:00
Lizandro Guarnizo 38cd62eb0e up 2026-02-21 08:51:38 -05:00
Lizandro Guarnizo 2f73ee2a1a up 2026-02-20 11:46:29 -05:00
Lizandro Guarnizo 421a5a4d7c up 2026-02-20 09:07:37 -05:00
Lizandro Guarnizo 276af13387 up 2026-02-06 09:38:36 -05:00
Lizandro Guarnizo 40bc8d15e7 Update WhatsAppService.php 2026-01-28 13:10:54 -05:00
Lizandro Guarnizo 7997ecb830 up 2026-01-28 13:05:36 -05:00
Lizandro Guarnizo 1f224044f7 up 2026-01-27 14:51:41 -05:00
Lizandro Guarnizo f1ee63bd77 Revert "ip"
This reverts commit eca0c919a4.
2026-01-25 21:09:38 -05:00
Lizandro Guarnizo eca0c919a4 ip 2026-01-25 21:08:09 -05:00
Lizandro Guarnizo 606fd887c5 Update WhatsAppService.php 2026-01-24 12:24:24 -05:00
Lizandro Guarnizo 9204220d40 Update WhatsAppService.php 2026-01-24 12:13:29 -05:00
Lizandro Guarnizo c01639afd2 Update WhatsAppService.php 2026-01-24 12:06:56 -05:00
Lizandro Guarnizo 3d45d54f0c up 2026-01-24 01:01:12 -05:00
Lizandro Guarnizo 2aed2c428c up 2026-01-22 14:10:03 -05:00
Lizandro Guarnizo 31dbc8aa86 up 2026-01-21 22:11:12 -05:00
lizandrogd 75b8f469f4 up 2026-01-21 15:08:18 -05:00
lizandrogd 86347914e0 Update WhatsAppService.php 2026-01-21 09:37:01 -05:00
lizandrogd 45a11032f5 mejoras 2026-01-21 08:28:54 -05:00
lizandrogd b1961f0116 up 2026-01-21 02:22:29 -05:00
lizandrogd 87b89b52a5 up 2026-01-21 01:02:17 -05:00
lizandrogd 4e3e02111b up 2026-01-20 23:55:00 -05:00
lizandrogd 81708fbb22 up
up
2026-01-20 23:29:06 -05:00
lizandrogd ccea8adefa up 2026-01-13 02:12:18 -05:00
lizandrogd 83fcabe36f full 2026-01-13 00:48:57 -05:00
lizandrogd 50fc690b1b funcional 2026-01-12 15:54:04 -05:00
lizandrogd ce12ac2cce w 2025-11-18 20:26:36 -05:00