Reglas, segmentos y scoring¶
Reglas¶
Una regla es metadata + condition + actions. Se ejecuta en la misma petición que recibe el evento, sobre el
perfil en memoria; las reglas que coinciden se determinan antes de ejecutar cualquier acción.
Formato (API POST /cxs/rules)¶
{
"metadata": {"id": "compras-contador", "name": "purchase enriquece el perfil", "description": ""},
"condition": {"type": "eventTypeCondition", "parameterValues": {"eventTypeId": "purchase"}},
"actions": [
{"type": "incrementPropertyAction", "parameterValues": {"propertyName": "totalPurchases"}},
{"type": "setPropertyAction", "parameterValues": {"setPropertyName": "properties(lastPurchaseDate)", "setPropertyValueCurrentEventTimestamp": true, "setPropertyStrategy": "alwaysSet"}},
{"type": "setPropertyAction", "parameterValues": {"setPropertyName": "properties(lastOrderId)", "setPropertyValue": "eventProperty::properties(orderId)", "setPropertyStrategy": "alwaysSet"}}
]
}
En Inoyu → Rules → nueva: nombre, descripción y prioridad en el formulario; en "Condition JSON" pegar solo la
condición ({"type": ..., "parameterValues": ...}); cada acción en su propio bloque "Add Action". Inoyu genera el
id. No pegar el objeto completo (metadata + condition + actions) en los editores: da "Missing property type".
Guardar dos veces crea dos reglas iguales y los contadores suben de a dos.
Condiciones disponibles (las más usadas)¶
| Tipo | Parámetros | Uso |
|---|---|---|
eventTypeCondition |
eventTypeId |
El evento es de ese tipo |
eventPropertyCondition |
propertyName (properties.categoria), comparisonOperator, propertyValue / propertyValueInteger / propertyValueDate |
Propiedad del evento |
profilePropertyCondition |
ídem sobre properties.x del perfil |
Propiedad del perfil (también en reglas: se evalúa sobre el perfil antes de las acciones) |
booleanCondition |
operator (and/or), subConditions[] |
Combinar |
notCondition |
subCondition |
Negar |
pastEventCondition |
eventCondition, numberOfDays, minimumEventCount, maximumEventCount |
"Hizo X en los últimos N días" (en segmentos; Unomi crea reglas ocultas con contadores en systemProperties.pastEvents) |
profileSegmentCondition |
segments[], matchType (in/notIn) |
Pertenencia a otro segmento |
sessionPropertyCondition, sourceEventPropertyCondition, newVisitorCondition, returningVisitorCondition |
Casos específicos |
Operadores: equals, notEquals, greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo,
exists, missing, contains, startsWith, endsWith, in, notIn, between, matchesRegex.
Acciones disponibles (las más usadas)¶
| Tipo | Parámetros | Efecto |
|---|---|---|
setPropertyAction |
setPropertyName (properties(x)), setPropertyValue / setPropertyValueInteger / setPropertyValueBoolean / setPropertyValueCurrentEventTimestamp, setPropertyStrategy (alwaysSet, setIfMissing, addValue, remove) |
Fija una propiedad del perfil. El valor admite referencias dinámicas: eventProperty::properties(orderId), eventProperty::target.properties(email), profileProperty::x, sessionProperty::x |
incrementPropertyAction |
propertyName; opcional propertyTarget (campo de target.properties a sumar, solo enteros de 32 bits) |
Suma 1, o el valor del target |
copyPropertiesAction |
singleValueStrategy (alwaysSet), opcional rootProperty |
Copia event.properties y target.properties al perfil |
eventToProfilePropertyAction |
eventPropertyName, profilePropertyName |
Copia una propiedad |
mergeProfilesOnPropertyAction |
mergeProfilePropertyName, mergeProfilePropertyValue (eventProperty::target.properties(email)), forceEventProfileAsMaster |
Fusión de identidad (ver identidad) |
sendEventAction, evaluateProfileSegmentsAction, modifyConsentAction, updatePropertiesAction |
Casos específicos |
Lista completa de tipos instalados: GET /cxs/definitions/conditions y GET /cxs/definitions/actions (Inoyu →
Condition Types / Action Types).
Limitaciones que condicionan el diseño de reglas¶
- Sin fórmulas ni agregaciones. Un atributo calculado es una regla que reacciona a cada evento. Suma de
enteros con
incrementPropertyAction(propertyTargettomatarget.properties.<campo>; por encima de 2.147.483.647 acumulados falla: enviar importes en miles si hace falta). Promedios, decimales u otras fórmulas requieren una acción Groovy (/cxs/groovyActions; funciona en 3.0.0 aunque la pantalla de Inoyu no lista) o un proceso externo que escriba la propiedad por API. - Sin contadores por valor dinámico. "Tercer
productViewde la misma categoría" no se expresa de forma genérica: hace falta un par de reglas por categoría (una incrementavistasElectronica, otra dispara cuandovistasElectronica >= 2en un evento de esa categoría), o unapastEventConditiondentro de la regla (consulta a Elasticsearch, con hasta 5 s de retraso). - Sin reprocesar el pasado. El contador vale desde que existe la regla.
- Las estadísticas de reglas (
executionCount) se sincronizan cada 10 s.
Segmentos¶
Un segmento es metadata + una condition sobre el perfil. La pertenencia se recalcula en cada evento que
modifica el perfil (decenas de milisegundos) y, al crear el segmento, sobre los perfiles existentes ya indexados.
{
"metadata": {"id": "compradores-recurrentes", "name": "Compradores recurrentes", "scope": "systemscope", "enabled": true},
"condition": {"type": "profilePropertyCondition", "parameterValues": {"propertyName": "properties.totalPurchases", "comparisonOperator": "greaterThanOrEqualTo", "propertyValueInteger": 2}}
}
Carrito abandonado (7 días con addToCart y sin purchase):
{"type": "booleanCondition", "parameterValues": {"operator": "and", "subConditions": [
{"type": "pastEventCondition", "parameterValues": {"numberOfDays": 7, "minimumEventCount": 1, "eventCondition": {"type": "eventTypeCondition", "parameterValues": {"eventTypeId": "addToCart"}}}},
{"type": "notCondition", "parameterValues": {"subCondition":
{"type": "pastEventCondition", "parameterValues": {"numberOfDays": 7, "minimumEventCount": 1, "eventCondition": {"type": "eventTypeCondition", "parameterValues": {"eventTypeId": "purchase"}}}}}}
]}}
En Inoyu → Segments → nuevo pegar solo la condición (el objeto que empieza por "type").
Consultas útiles: GET /cxs/segments/{id}/count (perfiles en el segmento), GET /cxs/segments/{id}/match
(lista), GET /cxs/profiles/{id}/segments. Al borrar un segmento referenciado por otro
(profileSegmentCondition), borrar primero el dependiente y esperar 2 segundos: si no, Unomi lo re-guarda.
Scoring¶
Plan con elementos {condition, value}; el perfil acumula puntos en scores.<planId>. Los elementos deben ser
condiciones sobre el perfil o pastEventCondition (una eventTypeCondition sola provoca un error 500 en 3.0.0).
Ejemplo: 20/30/50 puntos por 1/2/3 compras, +10 por interés declarado, +5 por carrito en 30 días.
Goals¶
Conversión por sesión: startEvent y targetEvent (condiciones). Unomi genera dos reglas ocultas que marcan la
sesión la primera vez que ocurre cada evento; el informe cuenta sesiones iniciadas, convertidas y la tasa, y puede
partirse por una propiedad ({"aggregate":{"type":"terms","property":"profile.properties.ciudad"}}). Solo cuenta
sesiones posteriores a su creación. En Inoyu, el botón "View" funciona gracias a los parches de la imagen.
Tipos de propiedad¶
Declarar una propiedad del perfil (Inoyu → Property Types → Basic, o POST /cxs/profiles/properties):
{"itemId": "totalPurchases", "metadata": {"id": "totalPurchases", "name": "Compras", "systemTags": []}, "type": "integer", "target": "profiles"}
Etiquetar con personalIdentifierProperties las propiedades que la anonimización debe purgar (de fábrica:
firstName, lastName, email, phoneNumber, address, ids de redes sociales).