Campañas in-app
Muestra mensajes segmentados a los usuarios mientras usan activamente tu aplicación. Los mensajes in-app no requieren permiso, pueden incluir contenido enriquecido e interactivo, y conviven con Push y Email en el asistente unificado de campañas.
Resumen
Las campañas in-app te permiten:
- Incorporar usuarios nuevos con consejos y tutoriales útiles.
- Anunciar funciones y actualizaciones de producto.
- Impulsar la interacción con indicaciones y CTA.
- Promocionar ofertas con mensajes contextuales.
- Ejecutar experimentos con variantes A/B y grupos de control.
Ventajas principales:
- No requiere permiso, a diferencia de Push.
- Contenido enriquecido e interactivo.
- Se contextualiza con la actividad actual del usuario.
- Tasas de interacción más altas que Push o Email.
- Se muestra con las fuentes, los colores y el modo oscuro de la propia app (mensajes nativos).
Requisitos previos
Asegúrate de haber integrado primero el SDK:
El SDK sincroniza las campañas aptas y las muestra cuando los usuarios cumplen tus criterios de disparador y segmentación.
Tipos de mensaje
Elige uno de los diseños según tu caso de uso:
| Tipo | Diseño | Ideal para |
|---|---|---|
| Modal | Centro de la pantalla con fondo superpuesto | Anuncios importantes y lanzamientos de funciones |
| Banner | Franja superior o inferior | Consejos rápidos y ofertas urgentes |
| Deslizante | Aparece desde la parte inferior | Indicaciones sutiles y logros desbloqueados |
| Pantalla completa | Ocupa toda la pantalla | Onboarding y actualizaciones importantes |
| Personalizado | Renderizado definido por desarrollo, configurado por API | Requisitos de interfaz únicos |
Crear una campaña in-app
Las campañas in-app usan el mismo asistente de seis pasos que cualquier otro canal. Consulta Creación de campañas para la estructura compartida. Los dos pasos que difieren son Redactar y Entrega.
Paso Redactar
El paso Redactar usa VariantTabs con un selector de tres métodos, igual que Email:
- Crear con arrastrar y soltar: editor visual para quienes no desarrollan.
- Crear con HTML: vista dividida con editor de código a la izquierda y vista previa en directo en un iframe aislado a la derecha.
- Crear desde plantilla: elige una de tus plantillas in-app guardadas.
Sea cual sea el método, el HTML creado se guarda en el customContent de la variante. Una vez redactada una variante, se contrae en una tarjeta AuthoredSummary con una miniatura iframe de 200 × 220 del mensaje renderizado. Haz clic para volver a abrir el editor.
Los mensajes HTML requieren que la app lo habilite
Los tres métodos anteriores producen HTML, que la app muestra dentro de un web view. Como un mensaje HTML ejecuta JavaScript escrito por el autor dentro de la app, el SDK no lo mostrará salvo que los desarrolladores lo hayan habilitado explícitamente (allowHtmlJsInAppMessages).
Una app que no lo ha habilitado omite las campañas HTML en silencio: el usuario no ve nada. Si no estás seguro, consúltalo con los desarrolladores antes de programar una campaña HTML, o usa un mensaje nativo.
Mensajes nativos
Un mensaje nativo es contenido estructurado - titular, texto, imagen y hasta tres botones - que la app dibuja con sus propios componentes. No interviene ningún web view ni se omite nada, así que se muestra en cualquier app independientemente del ajuste anterior, coincide con las fuentes, los colores y el modo oscuro de la app, y funciona con lectores de pantalla.
La contrapartida es el control: tú eliges las palabras, la imagen y los botones; la app decide cómo se ven.
| Nativo | HTML | |
|---|---|---|
| Se muestra sin que la app lo habilite | Sí | No |
| Coincide con el estilo de la app | Sí | Solo si lo reconstruyes en CSS |
| Control total de la maquetación | No | Sí |
| Funciona donde no hay web view (por ejemplo, tvOS) | Sí | No |
El contenido nativo se crea en el mosaico App style del paso Compose, junto a Drag & Drop y HTML. Si creas campañas mediante la API, consulta Campaigns API para la referencia de campos.
Colores, tipografía y CSS personalizado
En Style (optional) puedes sobrescribir el fondo de la tarjeta, el color del texto, el relleno del botón principal y su etiqueta, y el radio de las esquinas. Deja un campo vacío y el mensaje hereda ese valor de la aplicación - que es justo lo que hace que un mensaje nativo parezca parte de ella, así que cambia algo solo cuando la campaña necesite un momento de marca.
Si defines un color de botón y ningún color de etiqueta, la etiqueta se elige automáticamente - negro o blanco, el que siga siendo legible sobre tu relleno.
Dos controles son solo para web:
- Tipografía - una aplicación solo puede mostrar las fuentes que incluye, así que nombrar una que no tiene acabaría en algo que se ve mal. Los móviles conservan su propia tipografía.
- CSS personalizado, en Advanced - para lo que los campos no pueden expresar. Cada selector que escribas se reescribe para quedar dentro de este mensaje antes de aplicarse, así que ninguna regla llega al resto de la página, y las reglas de aquí tienen prioridad sobre los campos de color anteriores. Los móviles no tienen motor CSS y lo ignoran.
Qué puedes seleccionar: la propia tarjeta, h2 (titular), p (mensaje), button.primary y button.secondary. Los campos de color también se exponen como variables CSS - --joryio-inapp-bg, --joryio-inapp-fg, --joryio-inapp-primary, --joryio-inapp-primary-fg, --joryio-inapp-radius, --joryio-inapp-font - para que puedas redefinirlas dentro de una media query.
Las mismas pestañas de variantes A/B funcionan para in-app, incluidos los grupos de control.
Hacer que los botones funcionen (web)
Un mensaje con HTML personalizado se ejecuta dentro de un marco aislado (sandbox), por lo que no puede acceder directamente ni a tu página ni a la nuestra. En su lugar, Joryio le proporciona un pequeño puente.
El onclick en línea no funciona, ni funcionará. Todos los atributos de
manejadores de eventos se eliminan del HTML al guardar el mensaje: eso es
precisamente lo que impide que un mensaje ejecute código arbitrario en tu sitio.
Escribir onclick="..." produce un botón que parece correcto y no hace nada. Usa uno
de los dos mecanismos siguientes.
data-joryio-action - la forma habitual
<button data-joryio-action="requestPushPermission">Activar notificaciones</button>
<button data-joryio-action="closeMessage">No, gracias</button>
| Acción | Qué hace |
|---|---|
requestPushPermission | Muestra la solicitud de notificaciones del navegador |
closeMessage | Cierra el mensaje |
logConversion | Registra una conversión de esta campaña |
logConversion acepta un nombre mediante data-joryio-event; si lo omites, la
conversión se registra como in_app_conversion.
Todo esto está también en el panel de propiedades del editor - On click, Conversion event (optional) y Click name (reports) - así que la mayoría de los mensajes no necesitan tocar el HTML.
Los clics se registran solos
Cualquier clic en <a> o <button> se informa automáticamente. Para nombrar un clic
en los informes, añade data-action:
<a href="/pricing" data-action="pricing_cta">Ver planes</a>
Los enlaces http(s) y los relativos a la raíz se abren desde la página anfitriona;
las anclas, mailto: y tel: se comportan con normalidad.
window.joryioBridge - para mensajes con su propio script
Un mensaje que incluye su propio <script> puede llamar al puente directamente, que
es la única forma de pasar argumentos:
<button id="save">Guardar mi talla</button>
<script>
document.getElementById('save').addEventListener('click', function () {
joryioBridge.setCustomUserAttribute('preferred_size', 'M');
joryioBridge.logCustomEvent('size_selected', { size: 'M' });
joryioBridge.closeMessage();
});
</script>
| Método | Propósito |
|---|---|
logCustomEvent(name, properties) | Registrar un evento del usuario |
setCustomUserAttribute(key, value) | Escribir un atributo en el perfil |
logConversion(event) | Registrar una conversión de esta campaña |
logClick(action) | Registrar un clic con nombre |
changeUser(userId) | Identificar al visitante |
requestPushPermission() | Mostrar la solicitud de notificaciones |
navigate(url, target) | Abrir una URL desde la página anfitriona |
closeMessage() | Cerrar el mensaje |
Fíjate en la diferencia: addEventListener dentro de tu propio <script> está bien;
lo que se elimina es el atributo onclick.
Esto es solo para web. En iOS y Android un mensaje HTML se ejecuta en el web view de la app y los mensajes nativos usan sus propios botones, así que allí conecta los CTA mediante la configuración de botones de la campaña, no con markup.
Paso Entrega
El paso Entrega de las campañas in-app está diseñado específicamente para ellas. En vez del selector de tipo de envío de los demás canales, obtienes lo siguiente:
Selector principal de disparador
Una fila de cinco tarjetas, con Al ocurrir un evento marcado como RECOMENDADO:
| Disparador | Cuándo se muestra el mensaje |
|---|---|
| Inmediato | En la siguiente sesión apta del usuario. |
| Al ocurrir un evento (recomendado) | Cuando se registra un evento para el usuario. |
| Toque en notificación Push | Después de que tocar una notificación Push lleve al usuario a tu aplicación. |
| Cambio de atributo | Cuando cambia el valor de un atributo observado. |
| Umbral de atributo | Cuando un atributo numérico cruza un umbral. |
Cada tarjeta tiene un subtítulo de una línea y una descripción más larga. Al elegir una tarjeta aparece la configuración de ese modo en un panel gris suave debajo:
- Inmediato: sin configuración adicional, solo el retraso de visualización compartido que se explica abajo.
- Al ocurrir un evento: selector de evento con búsqueda y alternativa
+ Crear evento, además de condiciones de propiedad opcionales. - Toque en notificación Push: un fragmento para copiar y pegar que muestra cómo conectar el SDK a este ID de campaña.
- Cambio de atributo: selector de atributo y campos de valor anterior y valor nuevo.
- Umbral de atributo: selector de atributo, operador (
>,<,≥,≤,=) y valor de umbral.
Retraso de visualización
Un único campo Retraso de visualización se comparte en todos los modos de disparador. Introduce la duración en segundos, minutos u horas mediante el selector de unidad. El mensaje espera ese tiempo después de que se active el disparador antes de aparecer.
Programación
Elige las fechas empieza el y caduca el con zonas horarias separadas. El selector de zona horaria fija arriba el valor predeterminado del espacio de trabajo, después la hora local del destinatario y luego toda la lista IANA, de modo que los casos habituales están sobre el cuadro de búsqueda.
Límite de frecuencia
Una tarjeta reúne los controles de frecuencia:
- Máximo de impresiones por usuario: por ejemplo, 3 veces.
- Ventana de tiempo: 1 h / 24 h / 7 días / 30 días / 90 días / durante toda la vida, o una ventana personalizada.
- Retraso mínimo entre impresiones: intervalo mínimo entre apariciones consecutivas.
Debajo, una tarjeta independiente de Reglas de contacto del espacio de trabajo ofrece el interruptor Ignorar reglas de contacto. Omitir estas reglas puede ser adecuado para mensajes transaccionales o críticos, pero nunca debería ser la opción predeterminada.
- No abrumes a los usuarios con varios mensajes in-app por sesión.
- Separa las impresiones: un intervalo de 24 h o más es un buen valor predeterminado.
- Reserva «Ignorar reglas de contacto» para mensajes realmente críticos.
Modo de evaluación
Un selector de dos tarjetas, no un menú desplegable, porque las compensaciones son demasiado importantes como para ocultarlas:
| Modo | Latencia | Qué obtienes | A qué renuncias |
|---|---|---|---|
| Sincronización diferencial (recomendado) | ~80 ms | Campañas ilimitadas. Segmentación completa por segmento, entidad y comportamiento. Datos de entidades en plantillas. | Una ida y vuelta al servidor cuando cambian atributos observados. |
| Solo al inicio de sesión | <10 ms | Se evalúa una vez al iniciar la sesión. | Los cambios no se reflejan hasta que el usuario inicie una sesión nueva. |
Ambos modos mantienen las campañas sincronizadas en el dispositivo y disparan sus activadores localmente, así que un mensaje aparece sin una llamada de red en el momento de mostrarlo.
Un panel descriptivo debajo de las tarjetas amplía el modo seleccionado. Sincronización diferencial es la opción correcta para la mayoría de usos de producción.
Renderizado en servidor
En los modos Sincronización diferencial y Solo al inicio de sesión, el contenido del mensaje se renderiza en el servidor antes de llegar al dispositivo. Los tokens de personalización, los bloques de contenido y los datos de catálogo se resuelven del lado del servidor. Esto da a los mensajes in-app la misma potencia de renderizado que Email: funcionan los datos de entidades, fragmentos blocks.* y búsquedas en el catálogo de productos.
Usa el botón Probar renderizado en servidor del creador de campañas in-app para renderizar el mensaje en servidor con un usuario elegido y ver exactamente lo que recibirá el SDK. Comprueba la personalización, los bloques y el resultado de catálogo antes de activar la campaña.
Configuración avanzada
Es un panel contraído bajo la tarjeta de evaluación. Al abrirlo:
Modo de observación: controla cuándo el SDK vuelve a evaluar si una campaña es apta después de cambios de atributos:
- Auto (recomendado): el SDK detecta automáticamente de qué atributos dependen la segmentación y las plantillas de campaña, y vuelve a evaluar cuando cambian.
- Siempre: vuelve a evaluar en cada cambio de atributo.
- Nunca: solo al inicio de sesión.
Desempate de prioridad: se usa cuando dos campañas aptas comparten la misma prioridad:
- Más reciente (predeterminado): muestra primero la campaña creada más recientemente.
- Más antigua: muestra primero la campaña más antigua (FIFO).
- Aleatorio: selección aleatoria entre las campañas aptas.
Diferencias en el paso Audiencia
El paso Audiencia funciona como en cualquier otro canal - el mismo selector de modo y creador de filtros v2 - con una parte oculta:
- La tarjeta Opciones de envío está oculta. Los mensajes in-app no tienen concepto de suscripción: el SDK los muestra con independencia del estado de aceptación de Email, SMS o Push.
El aviso ámbar «Enviar a todos» también usa un texto diferente: los riesgos de in-app son la fatiga por modales y agotar el límite de frecuencia, no la entregabilidad. Por eso los ejemplos de filtros usan last_seen within 7 days y plan = free.
Personalización con Liquid
Las plantillas in-app admiten la sintaxis completa de plantillas Liquid. En los modos Sincronización diferencial y Solo al inicio de sesión, la plantilla se renderiza en el servidor, por lo que también puede usar datos de entidades, bloques de contenido y datos de catálogo:
¡Hola, {{ user.firstName | default: "qué tal" }}!
¡Has conseguido {{ user.points }} puntos!
{% if user.plan == 'free' %}
<p>Mejora tu plan para desbloquear más recompensas.</p>
{% else %}
<p>¡Gracias por ser miembro {{ user.plan }}!</p>
{% endif %}
Último pedido: n.º {{ entities.order.id }} ({{ entities.order.total | currency }})
Los filtros disponibles incluyen date_format, pluralize, currency, truncate y default. Consulta Plantillas Liquid para ver la referencia completa.
Seguimiento de clics en enlaces
Los clics en enlaces dentro de mensajes in-app se miden automáticamente y se atribuyen a la campaña. No necesitas configuración adicional ni reescritura de etiquetas. Los recuentos de clics aparecen en la analítica de campaña junto a las impresiones, así que puedes medir el CTR y usar clics como señales de conversión en pruebas A/B.
Pruebas A/B
In-app admite las mismas pestañas de variantes A/B que todos los demás canales, incluidos los grupos de control. La asignación de variante es determinista: la primera vez que se evalúa a un usuario, su ID se aplica a una función hash que lo coloca en un grupo de peso y se conserva esa asignación. Por tanto, el mismo usuario siempre ve la misma variante.
Los grupos de control no ven ningún mensaje: quedan retenidos por completo. Esto te permite medir la mejora incremental de la campaña frente a no hacer nada, comparando las tasas de conversión.
Variante A: 45 % - mostrar campaña
Variante B: 45 % - mostrar alternativa
Control: 10 % - no mostrar nada
Conversión de variante A: 5 %
Conversión de control: 2 %
Mejora: +150 %
Prácticas recomendadas
Empieza con Sincronización diferencial
La mayoría de las campañas deberían usar el modo Sincronización diferencial: ofrece el mejor equilibrio entre funciones y rendimiento.### Usa el modo de observación Auto
Deja que el SDK detecte las dependencias de atributos. Cambia a Siempre solo si necesitas observar atributos que no se usan directamente en la segmentación; cambia a Nunca solo para mensajes de bienvenida estáticos.
Implementa límites de frecuencia
Evita la fatiga por mensajes:
- Interacción alta: 3 impresiones cada 7 días.
- Moderada: 2 impresiones cada 14 días.
- Frecuencia baja: 1 impresión cada 30 días.
Prueba con variantes A/B
Incluye siempre grupos de control al medir el impacto en conversiones. Distribución recomendada: 45 % / 45 % / 10 % de control.
Solución de problemas
La campaña no se muestra
Comprueba, en este orden:
- Que el estado de campaña sea
active, nodraft. - Que la programación incluya la hora actual, entre
startsAtyexpiresAt. - Que el usuario cumpla los filtros de segmentación.
- Que no se haya superado el límite de frecuencia para este usuario.
- Que no la esté bloqueando una campaña de prioridad más alta.
- Que el usuario no esté en un grupo de control.
Errores de plantilla Liquid
- Atributos ausentes: envuélvelos con
| default: "valor alternativo". - Sintaxis incorrecta: comprueba que coincidan
{% endif %}y{% endfor %}.
Problemas de rendimiento
- Simplifica la lógica de segmentación.
- Optimiza las plantillas Liquid y evita bucles costosos.
- Usa Solo al inicio de sesión para mensajes estáticos.
In-app frente a Push
| Función | In-app | Push |
|---|---|---|
| Permiso | No requerido | Requerido |
| Cuándo se muestra | Mientras la aplicación está abierta | En cualquier momento |
| Contenido enriquecido | Sí | Limitado |
| Interactividad | Alta | Limitada |
| Alcance | Solo usuarios activos | Todos los usuarios con el SDK instalado |
| Ideal para | Interacción contextual | Reactivación |
Usa los dos juntos: Push para impulsar aperturas de aplicación e in-app para interactuar con usuarios activos.
Próximos pasos
- Creación de campañas: referencia del asistente compartido.
- Notificaciones Push.
- Pruebas A/B.
- Plantillas Liquid.