RuniaRunia Docs

Recordatorios en el canvas

Programar avisos automáticos antes de un evento desde el canvas y disparar acciones cuando vencen

Los recordatorios sirven para que el agente le mande un aviso al cliente antes de un evento futuro. Por ejemplo: el cliente agenda un turno por Calendly, y querés que reciba un mensaje 24 horas antes y otro 1 hora antes. Esto se arma con tres piezas que viven en lugares distintos.

  1. El tipo se configura en el panel (Operación → Contactos → Recordatorios → Tipos). Define qué avisos manda el sistema (24 horas antes, 1 hora antes, lo que decida el cliente).
  2. El recordatorio concreto lo crea el canvas con el nodo create_reminder cada vez que pasa algo que merece programar avisos (una reserva, un cobro pendiente, lo que sea).
  3. El canvas que reacciona al vencimiento usa el trigger reminder_due y manda el mensaje al cliente cuando llega el momento.

La cancelación es la cuarta pieza, importante pero opcional: si el cliente cancela el turno, otro canvas escucha la cancelación y dispara cancel_reminder para que no le sigan llegando avisos.

Crear el tipo en el panel

Antes de tocar el canvas, el cliente (o vos, con acceso al panel) tiene que crear el tipo de recordatorio. Cada tipo define un nombre, los avisos que manda y la zona horaria.

La doc para clientes está en Recordatorios. Lo importante para vos: cuando el tipo se crea con nombre "Turno odontológico", el sistema le asigna un código interno tipo turno_odontologico. Ese código es el que vas a usar como kind_code en los nodos del canvas.

El kind_code tiene que existir en la empresa antes de publicar el canvas. Si el canvas referencia un código que no existe, los recordatorios nunca se van a programar y el flow va a fallar silencioso. Verificá la lista de tipos disponibles en el panel antes de armar el flujo.

Programar el recordatorio desde el canvas

Cuando el cliente agenda algo (típicamente con Calendly o Google Calendar), encadenás el nodo create_reminder después del nodo de integración que confirmó la reserva.

Nodo create_reminder configurado en el canvas, conectado después de un nodo de integración que agendó el turno
Nodo create_reminder configurado en el canvas, conectado después de un nodo de integración que agendó el turno

Los campos importantes del nodo son:

  • Tipo de recordatorio: el que creaste en el panel, por ejemplo "Turno odontológico".
  • Cuándo es el evento: la fecha y hora del turno. Lo más natural es referenciarla del nodo upstream, por ejemplo {{node.agendar_turno.start_time}}.
  • Teléfono: el número del cliente al que le va a llegar el aviso. Normalmente {{contact.phone}}.
  • Datos para personalizar (opcional): un cuadro donde guardás la información que vas a querer en el mensaje del aviso. Por ejemplo, nombre_doctor, sede, numero_paciente. Estos datos quedan disponibles en el canvas que reacciona al vencimiento.
  • Fuente y Referencia externa (opcionales pero recomendados): dos campos que sirven para poder cancelar el recordatorio después si el cliente cancela el turno. Si vienen de Calendly, ponés fuente = "calendly" y referencia externa = {{node.agendar_turno.event_id}}.

Fuente y referencia externa van juntas o ninguna. Si pasás una sin la otra, el nodo lo rechaza. Y si no las guardás al crear el recordatorio, después no vas a poder cancelarlo desde otro canvas. Reglá: si el evento puede cancelarse (siempre que venga de una integración externa), guardá las dos.

El nodo tiene dos salidas: out_success cuando programó todo bien, y out_error cuando algo falló (típico: el kind_code no existe, o la fecha está mal formada). Conectá la salida de error a algo, aunque sea un mensaje al cliente diciendo que hubo un problema o un traspaso a humano. Si la dejás sin conectar, el flow muere silencioso.

Reaccionar cuando vence un aviso

El aviso al cliente se manda desde un canvas separado, distinto al que agendó el turno. Ese canvas arranca con un trigger reminder_due y se dispara una vez por cada aviso configurado en el tipo.

Canvas con trigger reminder_due conectado a varios send_template, uno por aviso
Canvas con trigger reminder_due conectado a varios send_template, uno por aviso

En el config del trigger elegís el tipo de recordatorio. El trigger expone una salida por cada aviso del tipo: si el tipo tiene avisos a 24 horas, 4 horas y 1 hora, el nodo te muestra out_24h, out_4h, out_1h y un out_default de fallback.

Hay dos patrones para armar el flujo.

Una plantilla por aviso. Útil cuando querés que el copy cambie según cuán cerca está el evento (el de 24 horas dice "tu turno es mañana", el de 1 hora dice "tu turno es en una hora"):

[reminder_due]
  → out_24h → [send_template "recordatorio_turno_24h"] → [mark_reminder_notified]
  → out_4h  → [send_template "recordatorio_turno_4h"]  → [mark_reminder_notified]
  → out_1h  → [send_template "recordatorio_turno_1h"]  → [mark_reminder_notified]

Una sola plantilla con variable. Si todos los avisos dicen lo mismo y solo cambia el "cuánto falta", conectás todo a out_default y le pasás el código del aviso como parámetro de la plantilla:

[reminder_due]
  → out_default → [send_template con {{node.<id>.window_code}} en parámetros] → [mark_reminder_notified]

Cerrá siempre la rama con un nodo mark_reminder_notified. Sin él, el sistema deja el aviso como "en proceso" y, si pasa cierto tiempo sin marcarlo como enviado, lo reintenta y el cliente recibe el mensaje dos veces.

El nodo mark_reminder_notified necesita el reminder_id y el window_code, que vienen del trigger. Siempre pasalos como template: {{node.<id_del_trigger>.reminder_id}} y {{node.<id_del_trigger>.window_code}}. Hardcodearlos no funciona.

Si el envío de la plantilla falla (por ejemplo, la plantilla está rechazada por Meta), el send_template sale por su out_error. Conectá esa salida a algo accionable: un log para vos, una alerta al equipo de atención, o un fallback con texto plano.

Cancelar cuando el cliente cancela el turno

Si el cliente cancela el turno por Calendly antes de que llegue el aviso, no querés que le siga llegando. Para eso armás un canvas separado que escuche el evento de cancelación de la integración y dispare cancel_reminder.

[integration_event "calendly.invitee.canceled"]
  → [cancel_reminder fuente="calendly" referencia_externa="{{trigger.data.event_id}}"]

El nodo cancel_reminder tiene tres salidas:

  • out_success: encontró el recordatorio y lo canceló junto con todos sus avisos pendientes.
  • out_not_found: no encontró nada que cancelar (ya estaba cancelado, o nunca existió). No es un error: rutealo al mismo lugar que out_success o a un nodo final. Es esperable que pase.
  • out_error: algo falló de verdad (problema de red, datos mal pasados). Conectalo a un log o alerta.

Para cancelar tenés dos formas: por reminder_id directo (si lo guardaste en alguna variable) o por fuente + referencia externa. Si seguiste el patrón recomendado de guardar las dos al crear el recordatorio, esta es la opción natural.

Si pasás solo fuente o solo referencia externa, el validador lo rechaza al publicar. Van juntas o se usa reminder_id. No hay tercera opción.

Errores comunes

El canvas con reminder_due no se dispara nunca. Casi siempre es porque el kind_code configurado no coincide con el código real del tipo (un typo, un guion en vez de underscore, un acento). Verificá en el panel cómo quedó el código exacto y copialo tal cual.

Los recordatorios se programan pero los avisos llegan duplicados. El canvas no está cerrando con mark_reminder_notified. Mirá la rama: después del send_template, tiene que haber un mark_reminder_notified con reminder_id y window_code del trigger.

No se puede cancelar el recordatorio cuando el cliente cancela. El create_reminder original no guardó fuente + referencia externa. Sin esos campos, no hay forma de matchear el evento de cancelación con el recordatorio. Hay que volver al canvas que crea el recordatorio y agregarlos.

El out_default está sin conectar y un aviso nuevo no llega. Si el cliente del panel agrega un aviso nuevo al tipo (por ejemplo, suma uno de 30 minutos antes) y vos no actualizaste el canvas, ese aviso va a salir por out_default. Si esa salida está sin conectar, el flow muere en silencio. Conectá siempre out_default aunque sea a un fallback genérico, o avisale al cliente que cuando agregue un aviso nuevo el canvas necesita un ajuste.