Módulo embebible

El WhatsApp, el SMS y el correo que tu producto manda, con registro de qué llegó.

Un motor de avisos para meter en lo tuyo: plantillas con variables, libreta de contactos con su consentimiento, credenciales de Meta y Twilio guardadas cifradas, y un registro por envío que dice encolado, enviado, entregado o leído. Con tus colores y en tu dominio.

Recordatorio de cita

Para Laura Medina

cita.recordatorio · v3

WhatsApp

Hola Laura, te recordamos tu cita en Clínica Norte el jueves 26 a las 11:30. Responde SÍ para confirmar o llámanos para moverla.

09:00

  1. Encolado09:00:02
  2. Enviado09:00:04
  3. Entregado09:00:05
  4. Leído09:14:31
Lo que un fetch a la API no hace

Mandar un mensaje es fácil. Poder demostrarlo después, no.

Llamar a Meta desde tu backend toma una tarde. Lo que toma meses es el consentimiento, el registro de qué llegó, los reintentos que no duplican y las llaves guardadas como se debe. Eso es lo que este módulo trae resuelto.

Lo que se mandó es lo que se aprobó

El cuerpo se arma al encolar y se guarda en el envío con la versión de la plantilla. Si alguien la edita mañana, el registro de hoy sigue diciendo exactamente qué le dijimos a ese cliente.

A quien dijo que no, no se le manda

La baja se guarda por canal, con fecha y motivo, y la comprueba la base de datos al encolar — no un `if` que una ruta nueva pueda olvidar. Si el cliente manda STOP, la baja se anota sola.

Tus llaves de Meta y Twilio no las lee nadie

Se cifran al guardarse y la tabla no tiene ni una política de lectura para usuarios: sólo el servidor las abre al despachar. El tablero muestra si están puestas y desde cuándo, nunca el secreto.

Cómo funciona

Tres pasos, y ninguno toca la API de Meta

01

Redactas la plantilla

Una por canal, porque un SMS de 160 caracteres y un correo con HTML no son el mismo texto. Con {{variables}} y una vista previa con datos reales antes de activarla.

02

Tu producto la encola

Desde el widget o con una llamada a la API: contacto, plantilla y variables. El módulo resuelve el canal, comprueba el consentimiento, renderiza y encola. Repetir la llamada no repite el mensaje.

03

El registro cuenta qué pasó

Enviado, entregado, leído o fallido con el error del proveedor traducido a español. Lo que se puede reintentar se reintenta solo; lo que necesita a una persona, se marca y se explica.

Qué trae

Tres canales y todo lo que hay alrededor

Cada canal con sus propias credenciales, guardadas por espacio de trabajo. Un envío es un canal: el texto aprobado en WhatsApp no es el correo, y reintentar por otro lado es un envío nuevo que alguien decide.

WhatsApp

Meta Cloud API

SMS

Twilio

Correo

Resend

Libreta de contactos con consentimiento

Nombre, correo, teléfono y WhatsApp, más los atributos que quieras. El consentimiento vive aparte, por canal: el mismo cliente puede querer la factura por correo y no querer WhatsApp.

Nunca dos veces el mismo aviso

Cada envío lleva una clave de deduplicación única por espacio. Un reintento de tu job o un doble clic devuelven el mismo envío, sin segunda fila ni segundo WhatsApp a las tres de la mañana.

Reintentos que saben cuándo parar

Un 5xx o la red caída reintentan solos con espera creciente. Un número inválido o una plantilla sin aprobar no: se marcan fallidos con el motivo, porque eso sólo lo arregla una persona.

Redactar, enviar y ver datos son tres permisos

El redactor escribe plantillas pero no dispara campañas a diez mil personas. Atención manda un mensaje suelto sin ver la libreta entera. El lector ve el registro y ningún dato personal.

Campañas a un segmento

Eliges la plantilla, filtras la libreta y el módulo encola un envío por contacto, saltando a quien se dio de baja. Cada uno con su estado y su error, no un «se mandó» global.

Una etiqueta, un archivo

El tablero entero —plantillas, libreta, envíos y ajustes— se embebe con una etiqueta HTML. Sin build, sin framework, aislado en Shadow DOM, con tus colores heredados por variables CSS.

Integrarlo

El tablero, con una etiqueta. Los envíos, con una llamada.

El token lo emite tu backend con tu llave secreta y dura quince minutos. La llave nunca llega al navegador, y las credenciales de Meta y Twilio nunca salen del servidor.

El tablero embebido

<script src="https://nexusnorth.dev/embed/v1/nexus-notificaciones.js" defer></script>

<nexus-notificaciones
  tenant-id="tu-tenant"
  workspace-id="tu-espacio"
  auth-token="token-efimero-de-tu-backend"
  style="--nexus-primary: #4f46e5; --nexus-radius: 0.75rem"
></nexus-notificaciones>

Un envío desde tu backend

POST /api/v1/notificaciones/messages
Authorization: Bearer <token>

{
  "contact_id": "c_8f3a…",
  "template_key": "cita.recordatorio",
  "vars": { "nombre": "Laura", "fecha": "jueves 26", "hora": "11:30" },
  "dedupe_key": "cita:4412:recordatorio-24h"
}
  • Tu módulo no aprende a hablar con Meta ni con Twilio: manda contacto, plantilla y variables, y ya.
  • El canal se elige al encolar: el que pidas, si no el de la plantilla, y sólo si el contacto tiene dirección, hay credencial y no se dio de baja.
  • La misma clave de deduplicación devuelve el mismo envío. Puedes reintentar tu llamada sin miedo.
  • Sin cookies de terceros: el token viaja en memoria, no en el navegador.
  • Aislado en Shadow DOM: tus estilos no lo tocan y los suyos no te tocan.
  • Un solo archivo, sin dependencias que choquen con las tuyas.
Preguntas

Lo que suelen preguntar antes de integrarlo

¿Manda desde mi número de WhatsApp o desde el de ustedes?

Desde el tuyo. Cada espacio de trabajo guarda sus propias credenciales de Meta, Twilio y correo, cifradas. Tus clientes ven tu nombre y tu número, no una marca ajena. Si todavía no tienes cuenta de Meta Business, te decimos cómo darla de alta.

¿Qué pasa si edito una plantilla que ya se usó?

Nada con lo ya mandado. Cada envío guarda el cuerpo tal como salió y la versión de la plantilla con la que se armó. La edición sube la versión y aplica a los envíos que vengan. Así «qué le dijimos a este cliente» siempre tiene respuesta.

¿Cómo evitan mandar a alguien que se dio de baja?

La baja se guarda por contacto y canal con fecha y motivo, y la comprueba la base de datos dentro de la función que encola: ninguna ruta puede saltársela. Si el destinatario contesta STOP por SMS, el proveedor lo avisa y la baja se anota sola. Volver a dar de alta sí pide una acción explícita.

¿Si falla WhatsApp, lo reintenta por correo?

No automáticamente, y es a propósito. El texto aprobado para WhatsApp no es el HTML del correo, y el consentimiento también es por canal. Reintentar por otro lado es un envío nuevo con otra plantilla, y alguien lo decide desde el registro con un clic.

¿Cómo sé si de verdad llegó?

Con los webhooks de Meta y Twilio: pasan el envío de «enviado» a «entregado» y a «leído». Sin webhook configurado, el envío se queda honestamente en «enviado», que es lo único que se sabe. El correo reporta entregado y rebotado.

¿Puede mi equipo redactar sin poder mandar campañas?

Sí. Redactar plantillas, ver contactos, mandar un mensaje suelto y disparar una campaña son permisos separados. El redactor escribe y mantiene la libreta; atención contesta a un cliente concreto sin ver la lista completa; sólo el dueño y el administrador lanzan campañas.

¿Dónde viven los datos de mis contactos?

En nuestra instancia por omisión, con aislamiento por espacio impuesto en la base. Si lo prefieres, pueden vivir en la tuya: el módulo apunta a donde le digas. Son datos personales de terceros y los tratamos como tales.

¿Tu producto necesita avisar a sus clientes?

Cuéntanos qué mandas hoy y por dónde, y te decimos si este módulo encaja — o si lo tuyo necesita otra cosa.

Hablemos