4dim / Notas

Token de página o de usuario: pasa al conectar, falla al enviar

Un token de usuario supera la comprobación inicial y falla al mandar el primer mensaje, días después. Tres identificadores que parecen iguales, la conexión fantasma, y cómo se guarda un token que escribe en nombre del negocio: GCM, clave fuera de la base, formato versionado.

El token que pasa la comprobación y falla al enviar

Si vas a conectar un CRM con Messenger, Instagram o WhatsApp, esta nota te dice dónde se rompen esas conexiones y por qué el fallo aparece tarde. Todo empieza por el token: la llave con la que Meta deja que un programa escriba en nombre de un negocio.

Hay dos tokens que se parecen. El del usuario que hizo la conexión y el de la página del negocio. El de usuario pasa la comprobación inicial: identifica a alguien, trae permisos, Meta responde 200. Y falla al mandar el primer mensaje, que puede ser días después, en otra pantalla, lejos del sitio donde se cometió el error.

Por eso el código exige token de página, y lo comprueba pidiéndole algo que solo un token de página puede hacer. Un error que se ve el día que se conecta es un error. Uno que se ve días después es una investigación.

Tres números largos que parecen iguales

Al configurar WhatsApp hay que copiar el identificador del número (phone_number_id) y el de la cuenta de WhatsApp Business (waba_id). En Instagram, el de la página y el de la cuenta de Instagram. Todos son cadenas largas de dígitos, indistinguibles a simple vista.

Confundirlos es el error más fácil de cometer y el más difícil de ver después. El que se pegó en el sitio equivocado también es un identificador válido de algo, así que nada parece raro.

No intentamos distinguirlos nosotros. Se lo preguntamos a Meta. Un token solo abre la cuenta a la que pertenece, así que la llamada de comprobación falla sola si el identificador no corresponde a ese token. Meta valida lo que Meta emitió.

Comprobar antes de guardar

La regla más importante del módulo de conexiones está escrita en su primera línea: se llama a Meta antes de escribir nada en la base. Guardar primero y comprobar después deja el canal en verde con credenciales que no sirven, «que es justo la mentira que este módulo existe para acabar: la que tranquiliza».

La comprobación trae además información. En WhatsApp, la calificación de calidad del número. En una página, sus datos y sus permisos. Así «conectada» pasa a ser un hecho comprobado con fecha, y no una casilla que alguien marcó una vez.

La conexión fantasma

Lo aprendimos por el camino largo. Hubo un flujo para «marcar a mano» un canal de Instagram o Messenger como conectado, sin comprobar nada ni guardar credenciales reales. Producía canales en verde que no podían enviar ni recibir nada. La cuenta de demostración tuvo uno así durante semanas. Era la misma mentira, en versión de producto: una pantalla que dice «conectado» porque alguien lo marcó.

Un estado que la pantalla afirma y el proveedor no confirma es una promesa que el sitio no cumple. Se descubre cuando un cliente escribe.

Cómo se guarda un token

Un token de WhatsApp escribe a los clientes en nombre del negocio. Basta una copia de seguridad que se filtra, un volcado para depurar un error o una consulta de más en una consola compartida para que alguien le hable a la clientela de un cliente. Por eso los tokens no se guardan en claro, aunque la base tenga bien puestos los permisos:

  • AES-256-GCM, no CBC. Son dos modos de cifrar. GCM autentica además de cifrar, así que un dato manipulado falla al descifrarse en vez de devolver basura que se acepta como token.
  • La clave vive en una variable de entorno del proceso, que es el único sitio que no viaja junto con los datos. Ni las copias de seguridad ni las exportaciones de la base la contienen.
  • Formato versionado, v1.iv.tag.texto. El día que haya que cambiar el algoritmo o la clave, lo viejo se sigue leyendo mientras lo nuevo ya se escribe. Sin ese número de versión, cambiar obliga a migrar todas las filas de golpe.
  • La clave se lee cada vez que se usa, no al cargar el módulo. Cargar los módulos es lo primero que hace Next al arrancar, y un fallo ahí tumba el proceso entero por una variable que quizá ninguna petición iba a necesitar. Además comprobamos que la clave tenga 32 bytes, con un mensaje que lo dice, en vez del error genérico de la librería de cifrado.
  • Las credenciales nunca llegan al navegador. Las funciones que llaman las páginas devuelven un sí o un no, «tiene credenciales», nunca el token. Un token que entra en el código que corre en el navegador puede acabar viajando hasta él.

Desconectar sin borrar

Desconectar un canal borra sus credenciales y conserva el registro. Se borran las credenciales porque un canal desconectado que guarda el token es un secreto que nadie usa ni renueva. Se conserva el registro porque las conversaciones existentes apuntan a él, y borrarlo las dejaría huérfanas, sin saber de dónde vinieron. Revocar no es borrar.

Y la versión de la API de Meta, la puerta por la que los programas le hablan, va en una variable de entorno y no escrita dentro del código. Meta jubila cada versión a los dos años. Escribirla en el código convierte esa jubilación en una caída de producción el día que toque.

Qué hacer entonces

  • Usar token de página para Messenger e Instagram, y una comprobación que solo un token de página pasa.
  • Dejar que Meta valide los identificadores. No adivinar cuál es cuál.
  • Comprobar contra el proveedor antes de guardar «conectado». Siempre.
  • Cifrar con GCM, con la clave fuera de la base, en formato versionado y leída solo al usarla.
  • Al desconectar, borrar el secreto y conservar la historia.
  • Poner la versión de la API en la configuración, con su fecha de jubilación anotada.

Esta nota sale de nuestro trabajo en AI-CRM Connection.

← todas las notas