Calcula los intervalos de ingresos para el esquema de valor de conversión de SKAdNetwork

1. Introducción

Contexto antes de comenzar

Si eres un desarrollador de apps para iOS, debes conocer las actualizaciones de privacidad para iOS 14.5 y versiones posteriores. Para medir las acciones de conversión significativas después de la instalación, Apple proporciona la API de SKAdNetwork, que te permite medir el éxito de tus campañas publicitarias respetando la privacidad del usuario. Según las necesidades de tu empresa, puedes encontrar la forma más óptima de aprovechar SKAdNetwork para obtener estadísticas significativas sobre tus campañas. En este codelab, examinamos una metodología de ejemplo para aprovechar tus datos de GA4F en BigQuery y agrupar los ingresos posteriores a la instalación de la aplicación en buckets, que luego puedes usar para configurar con tu socio de atribución de aplicaciones. Si bien este codelab usa un enfoque basado en los ingresos, también puedes usar enfoques basados en eventos o embudos para la medición de SKAN. Consulta el Centro de ayuda para obtener una orientación más detallada. Este es solo un ejemplo y no es una recomendación oficial de Google. Puedes diseñar tu propio esquema según tus necesidades empresariales específicas.

Qué temas abordaremos

  • Explora los datos de GA4F en BigQuery
  • Encuentra los datos de ingresos de los usuarios que generaron conversiones en un período de 0 a 2 días.
  • Agrupa los datos de ingresos en buckets
  • Comprende la distribución de usuarios en cada bucket
  • Implemente los buckets en el estudio de conversión de SKAN en AppsFlyer

Requisitos previos

2. Cómo acceder a BigQuery Export

Navega al conjunto de datos en GA4F. Para ello, ve a Configuración del proyecto > Integraciones > BigQuery Primero, debes habilitar el botón de activación y, una vez habilitado, el conjunto de datos tarda alrededor de 48 horas en estar disponible. Puedes hacer clic en el vínculo que se muestra a continuación para que te dirija a BigQuery.

1aa4e20bfd3419d1.png

Ejecuta algunas consultas

Ahora que estás en BigQuery, deberías ver las tablas diarias generadas. En la siguiente captura de pantalla de ejemplo, vemos 64 tablas diarias, por lo que la exportación se ejecutó durante 64 días. Si es la primera vez que accedes, es posible que solo veas 1 tabla diaria con los datos del día anterior. A la derecha, verás el esquema de la tabla. Puedes consultar más detalles sobre los campos aquí.

Para comenzar a escribir tu consulta, puedes hacer clic en Consultar > En una pestaña nueva.

42ba59ec655c5d1b.png

Luego, puedes intentar ejecutar la consulta de muestra en la pestaña nueva.

70ef90d32b7cd7f1.png

3. Cómo analizar los datos de ingresos

Recupera datos de instalación

Ahora, para comenzar a crear los segmentos de ingresos, primero debemos analizar los datos de los usuarios que instalaron la aplicación en las últimas 24 a 72 horas. SKAd Network 4.0 te permite ver los datos en un plazo de 0 a 2 días, mientras que SKAd Network 3.5 permite 24 horas de forma predeterminada. Según las capacidades de su socio de atribución en aplicaciones, es posible que pueda modificar este período de actividad en un plazo máximo de 72 horas. Cuando los usuarios instalan la app y la abren por primera vez, el SDK activa el evento first_open y lo registra en BigQuery.

El identificador que puedes usar para BigQuery es user_pseudo_id (también denominado ID de instancia de la aplicación), por lo que puedes usar la siguiente consulta para encontrar a estos usuarios

SELECT
  user_pseudo_id,
  event_name,
  event_date,
  event_timestamp
FROM `project_name.dataset_name.events_2023*`
WHERE
  event_name = 'first_open'
  AND platform = 'IOS'

Aspectos que debes tener en cuenta sobre esta consulta

  • Reemplaza el nombre de la tabla por la tabla exportada de Analytics. Puedes usar comodines para consultar varias tablas diarias. Por ejemplo, 2023* consultará todos los datos en 2023.
  • Si tienes muchos usuarios, también puedes consultar solo los últimos 30 días para acelerar el procesamiento.
  • Filtramos por plataforma = 'IOS'. Si tienes varias apps para iOS en tu proyecto de Firebase, también puedes agregar un filtro para app_info.firebase_app_id a fin de obtener datos de la app específica.

Recupera datos de ingresos

Ahora, veamos una consulta para encontrar los ingresos de tus usuarios. En este caso, suponemos que tus eventos de ingresos son in_app_purchase y ad_impression. Los ingresos de in_app_purchase están disponibles en event_value_usd, mientras que, para ad_impression, los ingresos están disponibles en el parámetro value, dentro de los parámetros del evento. Si no estás familiarizado con los parámetros de eventos de BigQuery, te recomendamos verificar la definición aquí. También puedes probar esta consulta de muestra en nuestra referencia oficial, que también abarca la extracción del valor de event_params.

SELECT
  user_pseudo_id,
  event_name,
  EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
  (
    SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
    FROM UNNEST(event_params)
    WHERE
      KEY = 'value'
      AND event_name = 'ad_impression'
  ) AS ad_funded_revenue,
  (
    SELECT value.string_value
    FROM UNNEST(event_params)
    WHERE
      KEY = 'currency'
      AND event_name = 'ad_impression'
  ) AS ad_revenue_currency,
  (
    CASE
      WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
      ELSE 0
      END) AS iap_revenue_usd,
FROM `project_name.dataset_name.events_2023*`
WHERE
  platform = 'IOS'
  AND event_name IN (
    'in_app_purchase',
    'ad_impression')

Veamos qué hace la consulta. Estas son las cosas que notarías

  • En la cláusula WHERE, filtramos los eventos de ingresos, ya que solo nos interesan esos eventos y, como la última vez, buscamos datos de iOS.
  • Ahora, en la cláusula SELECT, tomamos el valor y la moneda del evento de ingresos publicitarios (ad_impression) y tomamos event_value_in_usd cuando el evento es in_app_purchase.
  • Si envías varias monedas, primero debes alinearlas a una sola para este análisis. A los efectos de este ejemplo, supondremos que la moneda de los ingresos financiados por anuncios también es USD

El resultado sería similar al siguiente (la columna de user_pseudo_id está oculta aquí).

1e1e6943e4b3a6d8.png

Combinación de estos datos

Hasta ahora, ejecutamos dos consultas, una para encontrar los datos de los usuarios que instalaron y abrieron la app, y otra para encontrar los ingresos de esos usuarios. Ahora, recordemos lo que hablamos sobre las limitaciones de la red de SKAd. La ventana de atribución solo puede estar disponible entre 0 y 2 días después de la instalación. Por lo tanto, deberemos verificar las marcas de tiempo de los eventos de instalación y los ingresos, y solo tomar la información si ocurre dentro de ese período. Ahora, intentemos combinarlas en una consulta que proporcione los ingresos totales de cada publicación dos días después de la instalación de la aplicación.

#creating the install table
WITH
  install_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_date,
      event_timestamp
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      event_name = 'first_open'
      AND platform = 'IOS'
  ),
  #creating the revenue table
  revenue_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_timestamp,
      EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
      (
        SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
        FROM UNNEST(event_params)
        WHERE
          KEY = 'value'
          AND event_name = 'ad_impression'
      ) AS ad_funded_revenue,
      (
        SELECT value.string_value
        FROM UNNEST(event_params)
        WHERE
          KEY = 'currency'
          AND event_name = 'ad_impression'
      ) AS ad_revenue_currency,
      (
        CASE
          WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
          ELSE 0
          END) AS iap_revenue_usd,
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      platform = 'IOS'
      AND event_name IN (
        'in_app_purchase',
        'ad_impression')
  )
SELECT
  it.user_pseudo_id AS user_pseudo_id,
  #combine ad revenue and IAP revenue, assuming both are in same currency
  sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
FROM install_table it
INNER JOIN revenue_table rt
  ON it.user_pseudo_id = rt.user_pseudo_id
WHERE
  rt.event_timestamp >= it.event_timestamp
  AND rt.event_timestamp
    <= it.event_timestamp + 86400000000 * 2  #added 86400 000 millisecond as 24 hours, taking for 2 days later
GROUP BY 1

La consulta solo intenta unir los datos de instalación y los de ingresos en el campo user_pseudo_id y, luego, debemos asegurarnos de que la marca de tiempo sea de 2 días. Si usas la versión 3.5 de SKAdNetwork, el valor predeterminado es de 24 horas, por lo que también puedes cambiar la condición para que solo incluya los datos de 1 día.

Agrupa los ingresos en buckets

Después de la consulta anterior, tendrás el user_pseudo_id y los ingresos totales.

2c1986b93e937d19.png

Ahora tenemos que combinar esto en buckets que podamos usar para nuestros rangos de valores de conversión. Para ello, usaremos la función approx_quantiles en BigQuery, que crea automáticamente estos rangos por ti. Supongamos que, para los fines de este ejemplo, queremos crear 5 rangos, por lo que podemos usar SELECT approx_quantiles(total_revenue, 5) AS buckets

Con eso, incorporemos esto a nuestra consulta general.

#creating the install table
WITH
  install_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_date,
      event_timestamp
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      event_name = 'first_open'
      AND platform = 'IOS'
  ),
  #creating the revenue table
  revenue_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_timestamp,
      EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
      (
        SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
        FROM UNNEST(event_params)
        WHERE
          KEY = 'value'
          AND event_name = 'ad_impression'
      ) AS ad_funded_revenue,
      (
        SELECT value.string_value
        FROM UNNEST(event_params)
        WHERE
          KEY = 'currency'
          AND event_name = 'ad_impression'
      ) AS ad_revenue_currency,
      (
        CASE
          WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
          ELSE 0
          END) AS iap_revenue_usd,
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      platform = 'IOS'
      AND event_name IN (
        'in_app_purchase',
        'ad_impression')
  ),
  total_revenue_table AS (
    SELECT
      it.user_pseudo_id AS user_pseudo_id,
      #combine ad revenue and IAP revenue, assuming both are in same currency
      sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
    FROM install_table it
    INNER JOIN revenue_table rt
      ON it.user_pseudo_id = rt.user_pseudo_id
    WHERE
      rt.event_timestamp >= it.event_timestamp
      AND rt.event_timestamp
        <= it.event_timestamp + 86400000000 * 2  #added 86400 000 millisecond as 24 hours
    GROUP BY 1
  )
SELECT approx_quantiles(total_revenue, 5) AS buckets FROM total_revenue_table

Esta consulta debe dividir los ingresos en 5 segmentos, y BigQuery intenta mantener una distribución porcentual coherente.

Ba46f5d993449948.png

Cómo analizar la distribución de usuarios con estos buckets

Este es un paso opcional si deseas comprender la distribución de los usuarios en cada bucket. En nuestro ejemplo, los rangos de bucket que se muestran en la consulta anterior son

  • 0.1
  • 0.5
  • 2
  • 2.5
  • 5 [no se debe usar el último valor en la configuración del rango]

Para los rangos finales, ignoraremos el último bucket 5, ya que ese suele ser el valor máximo, y podemos considerar que 2.5 es el último rango. Esto se debe a que los proveedores de atribución de aplicaciones suelen calcular el ROAS con la media del rango, por lo que se debe excluir el valor atípico para obtener un cálculo más uniforme.

Ahora, intentaremos observar la cantidad de usuarios de cada fecha en todos los intervalos para comprender el volumen diario de usuarios en cada bucket. Podemos hacerlo con esta consulta de muestra, en la que puedes reemplazar los valores del bucket por tus datos reales, y la consulta se vería de la siguiente manera:

#creating the install table
WITH
  install_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_date,
      event_timestamp
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      event_name = 'first_open'
      AND platform = 'IOS'
  ),
  #creating the revenue table
  revenue_table AS (
    SELECT
      user_pseudo_id,
      event_name,
      event_timestamp,
      EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
      (
        SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
        FROM UNNEST(event_params)
        WHERE
          KEY = 'value'
          AND event_name = 'ad_impression'
      ) AS ad_funded_revenue,
      (
        SELECT value.string_value
        FROM UNNEST(event_params)
        WHERE
          KEY = 'currency'
          AND event_name = 'ad_impression'
      ) AS ad_revenue_currency,
      (
        CASE
          WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
          ELSE 0
          END) AS iap_revenue_usd,
    FROM `project_name.dataset_name.events_2023*`
    WHERE
      platform = 'IOS'
      AND event_name IN (
        'in_app_purchase',
        'ad_impression')
  ),
  total_revenue_table AS (
    SELECT
      it.user_pseudo_id AS user_pseudo_id,
      rt.event_date,
      #combine ad revenue and IAP revenue, assuming both are in same currency
      sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
    FROM install_table it
    INNER JOIN revenue_table rt
      ON it.user_pseudo_id = rt.user_pseudo_id
    WHERE
      rt.event_timestamp >= it.event_timestamp
      AND rt.event_timestamp
        <= it.event_timestamp + 86400000000 * 2  #added 86400 000 millisecond as 24 hours
    GROUP BY 1, 2
  )
SELECT
  event_date,
  sum(CASE WHEN total_revenue BETWEEN 0 AND 0.1 THEN 1 ELSE 0 END) AS Bucket1,
  sum(CASE WHEN total_revenue BETWEEN 0.1 AND 0.5 THEN 1 ELSE 0 END) AS Bucket2,
  sum(CASE WHEN total_revenue BETWEEN 0.5 AND 2 THEN 1 ELSE 0 END) AS Bucket3,
  sum(CASE WHEN total_revenue BETWEEN 2 AND 2.5 THEN 1 ELSE 0 END) AS Bucket4,
  sum(CASE WHEN total_revenue > 2.5 THEN 1 ELSE 0 END) AS Bucket5
FROM total_revenue_table
GROUP BY 1 ORDER BY 1 DESC

Debería mostrar los usuarios en cada rango de ingresos para cada día, como se indica a continuación. Si ves valores muy bajos en cualquier bucket o una distribución generalmente desigual, te recomendamos que ajustes la cantidad de buckets y vuelvas a ejecutar la consulta.

bf7d73085fe94cb6.png

Información breve sobre SKAd Network 4.0

SKAd Network 4.0 proporciona varias ventanas de conversión de hasta 2 días, de 3 a 7 días y de 8 a 35 días. En el enfoque anterior, puedes cambiar fácilmente el período para analizar los datos de estas situaciones adicionales. También están disponibles los valores de grano grueso de LOW, MEDIUM y HIGH. Una vez más, si quieres usar este enfoque, puedes considerarlo como 3 buckets. Por lo tanto, si cambias la cantidad de buckets a 3, podrás obtener los umbrales de BAJO, MEDIO y ALTO.

4. Implementación con tu proveedor de atribución

Según la plataforma específica, esta guía puede cambiar. Trabaja con los representantes de la plataforma para obtener la información más reciente sobre este tema. A los efectos de este ejemplo, veremos cómo podemos implementar esto actualmente en AppsFlyer.

En la consulta que ejecutamos anteriormente, los rangos finales que recibimos como resultado fueron los siguientes:

ba46f5d993449948.png

  • Rango 1 : de 0 a 0.1
  • Rango 2: De 0.1 a 0.5
  • Rango 3 : De 0.5 a 2
  • Rango 4 : 2 a 2.5

Recuerda que decidimos ignorar el último rango de ingresos, ya que será un valor atípico y sesgará los cálculos promedio de tu proveedor de atribución de aplicaciones.

AppsFlyer ofrece SKAN Conversion Studio, en el que es muy sencillo ingresar esta información directamente en la IU. Puedes usar la versión 4.0 directamente o una personalizada si usas la versión 3.5, y agrega "Ingresos" de medición. Luego, puedes agregar los rangos de ingresos que calculaste en el análisis anterior.

f8c56abdf9b405f4.png

Prácticas recomendadas y aprendizajes sobre Google Ads

Queremos brindarte algunas recomendaciones si publicas campañas en Google Ads y mides el impacto a través de un esquema de valor de conversión de SKAdNetwork.

  • Asegúrate de que la ventana de conversión que usas en Google Ads coincida con la ventana de actividad que especificaste en tu plataforma de atribución de aplicaciones. En el caso de SKAd network 3.5, es probable que esto ocurra en un plazo de 1 a 3 días, por lo que podrás ajustarlo según corresponda en Google Ads. Para ello, sigue los pasos que se indican aquí.

4fd625aae9d4a43.png

  • Si utilizas AppsFlyer, actualmente el contador de eventos predeterminado es 1, lo que significa que no registra múltiples eventos por usuario. Si utiliza un modelo basado en eventos para la medición de SKAN y lo compara con campañas de CPA objetivo en Google Ads, puede personalizarlo siguiendo esta guía de AppsFlyer.

6c7a4d703567700a.png

5. Felicitaciones

Felicitaciones, configuraste correctamente tu esquema de valor de conversión de SKAdNetwork. Ahora puedes supervisar los datos en tu informe de SKAd Network de Google Ads para verificar los valores de conversión de tus campañas de Google Ads una vez que se hayan publicado.

Aprendiste lo siguiente:

  • Cómo explorar los datos sin procesar enriquecidos de GA4F en BigQuery
  • Enfoque analítico para calcular los buckets de ingresos de tu empresa
  • Implementa el esquema con AppsFlyer