Alertas de relaciones entre entidades
Las alertas de relaciones son la versión general del disparador de reposición de e-commerce, pero para cualquier entidad personalizada: asientos, vuelos, clases, espectáculos, citas o inventario B2B. La idea es sencilla:
Cuando cambia un registro de un catálogo, notifica a todos los contactos vinculados a ese registro mediante una segunda entidad relacionada.
Declaras una entidad principal - el catálogo cuyos registros cambian (por ejemplo,
concert_tickets o series) - y eliges cómo se encuentra la audiencia: una
lista de suscripción relacionada (una entidad de lista de espera / «seguir») o las personas que realizaron un
evento relevante (vieron / consultaron). Consulta Dos formas de definir la audiencia más abajo.
Cuando cambia el campo vigilado de un registro principal, Joryio resuelve esa audiencia y emite un evento por usuario que puedes usar como disparador de entrada de un recorrido o campaña, deduplicado por persona para que valores inestables no envíen spam a nadie.
¿Por qué dos entidades?
La función integrada de reposición de productos requiere un clic porque el catálogo de productos tiene una estructura conocida (un campo de stock y una lista de suscriptores). Las entidades personalizadas son libres: Joryio no puede adivinar qué campo significa «disponible» ni qué entidad contiene la lista de espera, por lo que lo declaras una vez en los ajustes de la entidad principal.
For most e-commerce stores the product catalog is still the easy path. Reach for relationship alerts when your catalog isn't products, or when the audience is an explicit list rather than inferred browsing intent.
Dos formas de definir la audiencia
Antes de configurar, la decisión clave es quién recibe la notificación:
- Comportamiento (
audienceSource: "event"): las personas que realizaron un evento de intención (por ejemplo,Watched Episode,Viewed Flight) que hace referencia al registro, dentro de una ventana retrospectiva. No hay registros de seguimiento/lista de espera que mantener: la audiencia es el comportamiento. Refleja cómo la reposición de productos crea su audiencia a partir de eventos de navegación. Es ideal para «notificar a todos los que vieron/consultaron». - Explícita (
audienceSource: "child_entity", predeterminado): las filas de una entidad de suscripción relacionada (una lista de espera «avísame» o una lista «seguir este espectáculo»). Es ideal cuando las personas se suscriben deliberadamente, independientemente de cualquier comportamiento.
No necesitas una entidad de seguimiento para el caso VOD; consulta el Ejemplo 2.
«Avísame» como evento frente a entidad de lista de espera
Una pregunta habitual: si un toque «Avísame» emite un evento (Notify Me con un
product_id), ¿sigues necesitando una entidad de lista de espera? Normalmente no: dirige a ella
el modo de evento (intentEvent: "Notify Me", intentRefProperty: "product_id") y
ya está.
Lo único que te hace volver a una entidad secundaria es la durabilidad. Una audiencia de eventos está limitada por dos factores:
- la ventana retrospectiva (
intentLookbackDays), y - la retención de eventos: el TTL de retención de datos del espacio de trabajo finalmente elimina el evento y, una vez eliminado, el modo de evento ya no puede verlo.
El momento de reposición es abierto: un artículo puede volver la semana siguiente o dentro de ocho meses. Si el evento «avísame» caducó cuando se repone, el modo de evento no alcanza a esa persona; una fila de lista de espera persiste hasta que la elimines. Por tanto:
- Horizonte corto y predecible (episodios nuevos, reposiciones rápidas) → modo de evento, sin entidad.
- Horizonte abierto, o si quieres una lista gestionable de «notificar una vez y eliminar» → entidad secundaria de lista de espera.
Configuración
Configura relationshipAlert en los ajustes de la entidad principal:
| Campo | Significado | Ejemplo |
|---|---|---|
enabled | Activa la alerta | true |
triggerMode | Qué cuenta como activación en field (ver abajo) | "restock" |
field | Campo principal cuya transición activa la alerta | "available" |
eventName | Evento por usuario que se emitirá | "back_in_stock" |
cooldownDays | Ventana de supresión por (persona, registro) (predeterminado: 7) | 7 |
audienceSource | "child_entity" (predeterminado) o "event" | "event" |
childEntity | (modo secundario) nombre interno de la entidad de lista de espera/seguimiento | "ticket_waitlist" |
childRefField | (modo secundario) campo en las filas secundarias que contiene el ID del registro principal | "ticketId" |
intentEvent | (modo de evento) evento de intención cuya audiencia se notificará | "Watched Episode" |
intentRefProperty | (modo de evento) propiedad del evento que contiene el ID del registro principal | "series_id" |
intentLookbackDays | (modo de evento) hasta qué punto mirar atrás (predeterminado: 90) | 90 |
Modos de disparador
restock: un número pasa de ≤ 0 a > 0 (vuelve a haber existencias). Predeterminado.increase: un número aumenta (por ejemplo, un recuento de episodios de 8 → 9).changed: un valor cambia a un valor nuevo no vacío (por ejemplo, un «ID de episodio más reciente»).
En el modo child-entity, la entidad secundaria debe declarar un enlace de usuario (qué
campo se asigna a un contacto, por ID de usuario / ID externo / email / teléfono / atributo):
así es como cada fila se resuelve en una persona. En el modo event, el
user_id del evento de intención es el contacto. Un valor anterior desconocido nunca activa nada (en los modos
numéricos), por lo que las primeras cargas no generan alertas falsas.
Ejemplo 1: entradas de concierto de nuevo disponibles
Objetivo: un espectáculo se agota; cuando vuelven a liberarse entradas, notifica a todos los que pidieron que se les avisara.
-
Entidad principal
concert_ticketscon un campo numéricoavailable. -
Entidad secundaria
ticket_waitlistcon los camposticketId(el espectáculo/registro al que hace referencia) yemail. Configura su enlace de usuario enemail. -
En
concert_tickets, configura:{
"relationshipAlert": {
"enabled": true,
"triggerMode": "restock",
"field": "available",
"childEntity": "ticket_waitlist",
"childRefField": "ticketId",
"eventName": "back_in_stock",
"cooldownDays": 30
}
} -
Cuando alguien toca «Avísame», tu app/sitio añade una fila a
ticket_waitlist:{ ticketId: "SHOW-A", email: "fan@example.com" }. -
Cuando
availabledeconcert_tickets/SHOW-Apasa de0 → 50, Joryio emite un eventoback_in_stockpara cada contacto en lista de espera.
Crea un recorrido de un paso (o una campaña activada) cuya entrada sea back_in_stock.
Personalízalo con los propios campos del registro, que viajan en el evento:
{{ event.name }} tickets are back! Grab yours before they sell out again.
El evento también incluye event.record_id, event.new_value (el nuevo stock) y
cualquier campo escalar del registro.
Ejemplo 2: episodio nuevo de una serie que alguien ve (VOD / estilo Netflix)
Objetivo: cuando se publica un episodio nuevo de una serie, avisa a todos los que han estado viendo esa serie.
¿Necesito una entidad «seguir» o puedo usar un evento de visualización? Puedes usar
el evento de visualización, y para VOD es la opción natural. Ya emites un evento
Watched Episode (o watch_series) cuando alguien reproduce un episodio; dirige
la alerta a ese evento y Joryio notificará a todos los que vieron la serie
recientemente. No hay registros de seguimiento que crear ni mantener. Usa una entidad de seguimiento solo
si quieres una lista explícita de suscripción «seguir este espectáculo» independiente de
la visualización.
¿Es igual que una reposición o es diferente? Aquí la parte de audiencia usa
comportamiento en vez de una lista de espera (esa es la opción audienceSource: "event"),
y el disparador también difiere: un episodio nuevo no es un cambio de stock 0 → >0,
es un recuento de episodios que aumenta (o un ID de «último episodio» que cambia). Es el mismo
motor, con dos controles distintos.
Lo que necesitas: una sola entidad:
-
Entidad principal
seriescon:- un campo de presentación como
title; - un campo numérico
episodeCount(o una cadenalatestEpisodeId); - ninguna entidad secundaria.
- un campo de presentación como
-
En
series, configura:{
"relationshipAlert": {
"enabled": true,
"triggerMode": "increase",
"field": "episodeCount",
"audienceSource": "event",
"intentEvent": "Watched Episode",
"intentRefProperty": "series_id",
"intentLookbackDays": 90,
"eventName": "new_episode",
"cooldownDays": 1
}
}(Prefer
"triggerMode": "changed"with"field": "latestEpisodeId"if you track the newest episode by id rather than a running count.) -
La conexión es la propiedad del evento. Tu reproductor ya envía, en cada reproducción, algo como:
{ "event": "Watched Episode", "series_id": "S-42", "episode": 12 }intentRefProperty: "series_id"es lo que vincula una visualización con el registroseries: debe coincidir con el ID del registro o el valor de clave principal (S-42). -
Cómo activar: cuando la ingesta de catálogo aumenta
episodeCountdeseries/S-42de8 → 9(una actualización normal de registro), Joryio consulta quién realizóWatched Episodeconseries_id = S-42durante los últimos 90 días y emite un eventonew_episodepara cada uno. -
Crea un recorrido/campaña cuya entrada sea
new_episode:Ya está disponible un episodio nuevo de {{ event.name }}. Retoma donde lo dejaste →
If you prefer an explicit follow list instead of watch behavior, keep
triggerMode: "increase" but use the child-entity audience: add a
series_follows entity (seriesId, userId, User Link → userId), set
audienceSource: "child_entity", childEntity: "series_follows",
childRefField: "seriesId", and add a follow row when someone taps Follow.
Reposición frente a episodio nuevo de un vistazo
| Reposición de concierto | Episodio nuevo (VOD) | |
|---|---|---|
| Entidades necesarias | principal + lista de espera secundaria | solo la principal |
| Audiencia | filas de ticket_waitlist (suscripción) | evento Watched Episode (comportamiento) |
audienceSource | child_entity | event |
| Campo vigilado | available (stock) | episodeCount / latestEpisodeId |
triggerMode | restock (0 → >0) | increase / changed |
| Evento emitido | back_in_stock | new_episode |
Excluir a las personas que ya actuaron
Si envías algo de tiempo después del lanzamiento, probablemente no quieras insistir a las personas que ya vieron el episodio nuevo (o ya compraron el artículo repuesto). Hay dos capas, y a menudo usarás ambas:
1. Omitirlas al activar: excludeEvent
La alerta puede eliminar de la audiencia a cualquiera que ya haya realizado un evento para el valor nuevo de esta transición. Para el ejemplo VOD, añade a la configuración:
{
"excludeEvent": "Watched Episode",
"excludeRefProperty": "series_id",
"excludeValueProperty": "episode",
"excludeLookbackDays": 30
}
Ahora, cuando se publica el episodio 9, Joryio notifica a quienes vieron la serie, pero
excluye a cualquiera que ya vio el episodio 9 (series_id = esta serie
y episode = el valor nuevo). excludeValueProperty lo vincula al
episodio nuevo específico. Para que coincida, el valor nuevo del campo debe coincidir con
el ID que lleva tu evento de visualización (esto es más limpio con triggerMode: "changed"
latestEpisodeId, o cuando los números de episodio son iguales al recuento). También sirve para reposición: configuraexcludeEventcomo tu evento de compra para omitir compradores recientes.
2. Volver a comprobar al enviar: la respuesta exacta para envíos retrasados
La exclusión al activar solo sabe quién vio algo hasta el momento en que se activa la alerta. Si deliberadamente esperas 2 días antes de enviar, las personas verán contenido durante esos dos días, y solo una comprobación al enviar puede detectarlas. Hazlo en el recorrido:
- Disparador de entrada:
new_episode. - Espera 2 días.
- Condición / bifurcación de comportamiento: NO ha realizado
Watched Episodedondeepisode={{ trigger.new_value }}durante los últimos 2 días → solo esta rama continúa al envío.
Esto vuelve a evaluar a cada persona justo antes de enviar, de modo que cualquiera que se haya puesto al día
durante la espera queda excluida. Usa excludeEvent (capa 1) para mantener ajustada la audiencia
inicial y la condición del recorrido (capa 2) para hacer exacto un envío retrasado.
Usar el evento de alerta
Independientemente de su nombre, eventName se comporta como cualquier otro evento de Joryio:
- Aparece en el selector de eventos como disparador de entrada de recorrido/campaña.
- Sus propiedades (
record_id,new_value,field, además de los campos escalares del registro y una etiquetaname) están disponibles comoevent.*en Liquid. - Los envíos siguen respetando el consentimiento, la supresión y las horas de silencio como cualquier otro envío de canal.
Cómo se activa internamente
La transición se detecta en la ruta de actualización de la entidad y se distribuye fuera de la
ruta crítica, por lo que una audiencia lenta nunca bloquea la escritura del registro. Las notificaciones se
deduplican por (contacto, registro) durante cooldownDays, y una fila secundaria solo
cuenta una vez incluso si varias filas se resuelven en el mismo contacto.
Importaciones masivas
Las importaciones masivas de registros no activan alertas de forma predeterminada, así que una primera carga nunca
avisa a todo el mundo. Actívalas por importación enviando triggerAlerts: true al endpoint
masivo. Cuando está activado y la entidad tiene una clave principal de negocio, la importación
hace upsert y diferencia: se actualizan los registros que ya existen y sus transiciones
se activan (por ejemplo, un feed nocturno de stock o episodeCount), mientras que las filas nuevas solo
activan alertas de modo changed (los modos numéricos necesitan un valor anterior desde el que cambiar).
Puesta en marcha
Hoy puedes conectar manualmente las dos entidades y la configuración relationshipAlert.
El asistente de IA también puede generar toda la estructura:
crear la entidad secundaria de seguimiento/lista de espera, configurar la alerta y construir
el recorrido de notificación a partir de una sola solicitud.