Guía para desarrolladores de la API de Protected Audience

A medida que leas la documentación de Privacy Sandbox en Android, usa el botón Versión preliminar para desarrolladores o Beta para seleccionar la versión del programa con la que estás trabajando, ya que las instrucciones pueden variar.


Enviar comentarios

La API de Protected Audience en Android (que anteriormente se denominaba FLEDGE) incluye la API de Custom Audience y la de Ad Selection. Las plataformas de tecnología publicitaria y los anunciantes pueden usar estas APIs para publicar anuncios personalizados según la participación anterior en la app limitando el uso compartido de identificadores entre apps y el uso compartido de la información sobre la interacción en la app del usuario con terceros.

La API de Custom Audience se centra en la abstracción de "público personalizado", que representa a un grupo de usuarios con intenciones comunes. Un anunciante puede registrar un usuario con un público personalizado y asociar anuncios relevantes con este. Esta información se almacena de forma local y puede ayudar a definir las ofertas de los anunciantes, el filtrado y la renderización de anuncios.

La API de Ad Selection proporciona un framework que permite que varios desarrolladores ejecuten una subasta a nivel local para un público personalizado. Para lograrlo, el sistema tiene en cuenta los anuncios relevantes asociados con el público personalizado y realiza un procesamiento adicional en anuncios que una plataforma de tecnología publicitaria muestra en el dispositivo.

Las plataformas de tecnología publicitaria pueden integrar estas APIs para implementar el remarketing que preserva la privacidad del usuario. En versiones futuras, se planea admitir casos de uso adicionales, como anuncios de instalación de aplicación. Obtén más información sobre la API de Protected Audience en Android en la propuesta de diseño.

En esta guía, se describe cómo trabajar con la API de Protected Audience en Android para hacer lo siguiente:

  1. Administrar públicos personalizados
  2. Configurar y ejecutar la selección de anuncios en un dispositivo
  3. Informar impresiones de anuncios

Antes de comenzar

Antes de comenzar, completa lo siguiente:

  1. Configura tu entorno de desarrollo para Privacy Sandbox en Android.
  2. Instala una imagen del sistema en un dispositivo compatible o configura un emulador que incluya compatibilidad con Privacy Sandbox en Android.
  3. En una terminal, habilita el acceso a la API de Protected Audience (inhabilitada de forma predeterminada) con el siguiente comando adb.

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. Incluye un permiso ACCESS_ADSERVICES_CUSTOM_AUDIENCE en el manifiesto de tu app:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  5. Haz referencia a una configuración de servicios de anuncios en el elemento <application> de tu manifiesto:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  6. Especifica el recurso XML de servicios de anuncios al que se hace referencia en el manifiesto, como res/xml/ad_services_config.xml. Obtén más información sobre los permisos de los servicios de anuncios y el control de acceso al SDK.

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  7. De forma predeterminada, la API de Ad Selection aplica límites a la cantidad máxima de memoria que una secuencia de comandos de informes de impresiones o subastas puede asignar. La función de limitación de memoria requiere la versión 105.0.5195.58 de WebView o una posterior. La plataforma aplica una verificación de versión, y las llamadas a las APIs de selectAds y reportImpression fallan si no se satisface. Existen dos alternativas para configurar esta opción:

    • La primera es ejecutar el siguiente comando adb para inhabilitar esta verificación:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • La segunda es instalar WebView Beta desde Google Play Store. Debe ser igual a la versión que se mencionó antes o posterior.

Únete a un público personalizado

Un público personalizado representa a un grupo de usuarios con intenciones o intereses comunes, según lo decide la app de un anunciante. Una app o un SDK pueden usar un público personalizado para indicar un público en particular, por ejemplo, una persona que dejó artículos en un carrito de compras. Para crear un público personalizado o unirte a uno de forma asíncrona, haz lo siguiente:

  1. Inicializa el objeto CustomAudienceManager.
  2. Especifica parámetros clave, como el paquete del comprador y un nombre relevante, para crear un objeto CustomAudience. Luego, inicializa el objeto JoinCustomAudienceRequest con el objeto CustomAudience.
  3. Llama a joinCustomAudience() asíncrono con el objeto JoinCustomAudienceRequest y los objetos Executor y OutcomeReceiver relevantes.

Kotlin

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a custom audience.
val audience = CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build()

// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver)

Java

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build();

// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver);

La combinación de los siguientes parámetros identifica de manera única cada objeto CustomAudience en un dispositivo:

  • owner: Nombre del paquete de la app del propietario. Se le asigna de forma implícita el nombre del paquete de la app que realiza la llamada.
  • buyer: Identificador de la red de publicidad del comprador que administra los anuncios para este público personalizado.
  • name: Identificador o nombre arbitrario para el público personalizado.

Llamar a joinCustomAudience() de forma continua con una instancia diferente de CustomAudience actualiza cualquier CustomAudience existente con los parámetros owner, buyer y name que coincidan. Para ayudar a preservar la privacidad, el resultado de la API no distingue entre "creación" y "actualización".

Además, se debe crear CustomAudience con estos parámetros obligatorios:

  • URL de actualización diaria: URL HTTPS que se consulta a diario en segundo plano para actualizar con relación a un público personalizado los indicadores de ofertas del usuario, los datos de ofertas de confianza, y las URLs de renderización y los metadatos para anuncios.
  • URL de lógica de ofertas: URL HTTPS que se consulta durante la selección de anuncios para recuperar la lógica de ofertas de JavaScript de un comprador. Consulta las firmas de las funciones necesarias en JavaScript.
  • IDs de renderización de anuncios: Un ID arbitrario establecido por la tecnología publicitaria del comprador. Esta es una optimización para generar la carga útil de B&A.

Entre los parámetros opcionales para un objeto CustomAudience, se pueden incluir los siguientes:

  • Hora de activación: Un público personalizado solo puede participar en la selección de anuncios y en las actualizaciones diarias después de su hora de activación. Por ejemplo, esto puede ser útil para atraer a los usuarios inactivos de una app.
  • Hora de vencimiento: Momento en el futuro en el que se quita el público personalizado del dispositivo.
  • Indicadores de ofertas del usuario: Cadena JSON que contiene indicadores del usuario, como la configuración regional preferida del usuario, que consume la lógica de ofertas de JavaScript de un comprador para generar ofertas durante el proceso de selección de anuncios. Este formato permite que las plataformas de tecnología publicitaria vuelvan a usar el código en distintas plataformas y facilita el consumo de funciones de JavaScript.
  • Datos de ofertas de confianza: URL HTTPS y lista de cadenas que se usan durante el proceso de selección de anuncios y recuperan los indicadores de ofertas de un servicio de pares clave-valor de confianza.
  • Anuncios: Lista de objetos AdData correspondientes a los anuncios que participan en la selección de anuncios. Cada objeto AdData consta de lo siguiente:
    • URL de renderización: URL HTTPS que se consulta para renderizar el anuncio final.
    • Metadatos: Objeto JSON serializado como una cadena que contiene información que consumirá la lógica de ofertas del comprador durante el proceso de selección de anuncios.
    • Filtros de anuncios: Clase que contiene toda la información necesaria para el filtrado de anuncios de instalación de aplicaciones y la limitación de frecuencia durante la selección de anuncios.

Este es un ejemplo de la creación de una instancia del objeto CustomAudience:

Kotlin

// Minimal initialization of a CustomAudience object
val customAudience: CustomAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build()

Java

// Minimal initialization of a CustomAudience object
CustomAudience customAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build();

Controla los resultados de joinCustomAudience()

El método joinCustomAudience() asíncrono usa el objeto OutcomeReceiver para indicar el resultado de la llamada a la API.

  • La devolución de llamada onResult() indica que el público personalizado se creó o se actualizó de forma correcta.
  • La devolución de llamada onError() indica dos condiciones posibles.

Este es un ejemplo de control del resultado de joinCustomAudience():

Kotlin

var callback: OutcomeReceiver<Void, AdServicesException> =
    object : OutcomeReceiver<Void, AdServicesException> {
    override fun onResult(result: Void) {
        Log.i("CustomAudience", "Completed joinCustomAudience")
    }

    override fun onError(error: AdServicesException) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error)
    }
};

Java

OutcomeReceiver callback = new OutcomeReceiver<Void, AdServicesException>() {
    @Override
    public void onResult(@NonNull Void result) {
        Log.i("CustomAudience", "Completed joinCustomAudience");
    }

    @Override
    public void onError(@NonNull AdServicesException error) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error);
    }
};

Abandona un público personalizado

Si el usuario ya no satisface los criterios comerciales para un público personalizado determinado, una app o un SDK puede llamar a leaveCustomAudience() para quitar el público personalizado del dispositivo. Para quitar CustomAudience según sus parámetros únicos, haz lo siguiente:

  1. Inicializa el objeto CustomAudienceManager.
  2. Inicializa LeaveCustomAudienceRequest con buyer y name del público personalizado. Para obtener más información sobre estos campos de entrada, consulta "Únete a un público personalizado".
  3. Llama al método asíncrono leaveCustomAudience() con el objeto LeaveCustomAudienceRequest y los objetos Executor y OutcomeReceiver relevantes.

Kotlin

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
    LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build()

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver)

Java

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
    new LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build();

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver);

De manera similar a cuando se llama a joinCustomAudience(), el objeto OutcomeReceiver indica el final de una llamada a la API. Para ayudar a proteger la privacidad, un resultado de error no diferencia entre errores internos y argumentos no válidos. Se llama a la devolución de llamada onResult() cuando se completa la llamada a la API, independientemente de si un público personalizado se quita de forma correcta o no.

Ejecuta la selección de anuncios

Si deseas usar la API de Protected Audience para seleccionar anuncios, llama al método selectAds():

  1. Inicializa un objeto AdSelectionManager.
  2. Compila un objeto AdSelectionConfig.
  3. Llama al método asíncrono selectAds() con el objeto AdSelectionConfig y los objetos Executor y OutcomeReceiver relevantes.

Kotlin

val adSelectionManager: AdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionConfig
val adSelectionConfig: AdSelectionConfig =
  AdSelectionConfig.Builder().setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(
        contextualAds.getBuyer(), contextualAds
      )
    ).build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
  adSelectionConfig, executor, outcomeReceiver
)

Java

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionConfig
AdSelectionConfig adSelectionConfig =
  new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(contextualAds.getBuyer(), contextualAds)
    )
    .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(adSelectionConfig, executor, outcomeReceiver);

El método selectAds() requiere una entrada AdSelectionConfig, en la que debes especificar los siguientes parámetros obligatorios:

  • Vendedor: Es el identificador de la red de publicidad del vendedor que inicia la selección de anuncios.
  • URL de lógica de decisión: Es una URL HTTPS que se consulta para obtener la lógica de JavaScript de la red de publicidad del vendedor.
    • URL HTTPS: Se consulta para obtener la lógica de JavaScript de la red de publicidad del vendedor. Consulta las firmas de las funciones necesarias.
    • URI compilado previamente: Sigue el formato de selección de anuncios de FLEDGE. Se arroja IllegalArgumentException si se pasa un URI compilado previamente no compatible o con un formato incorrecto.
  • Compradores de públicos personalizados: Es una lista completa de identificadores de redes de publicidad de compradores que el vendedor permite para participar en el proceso de selección de anuncios. Estos identificadores de compradores corresponden al CustomAudience.getBuyer() de los públicos personalizados participantes.

De manera opcional, los siguientes parámetros se pueden especificar para una selección de anuncios más personalizada:

  • Indicadores de la selección de anuncios: Es un objeto JSON, serializado como una cadena, que contiene indicadores que consumirá la lógica de ofertas de JavaScript del comprador que se recupera de CustomAudience.getBiddingLogicUrl().
  • Indicadores del vendedor: Es un objeto JSON, serializado como una cadena, que contiene indicadores que consumen la lógica de decisión recuperada de JavaScript del vendedor desde AdSelectionConfig.getDecisionLogicUrl().
  • Indicadores por comprador: Es un mapa de objetos JSON, serializado como cadenas, que contiene los indicadores que consumirá la lógica de ofertas de JavaScript de compradores específicos que se recupera de CustomAudience.getBiddingLogicUrl(). Estos indicadores son identificados por los campos del comprador de los públicos personalizados que participan.
  • Anuncios contextuales: Es un conjunto de candidatos de anuncios que se recopilan directamente de los compradores durante una subasta que ocurre fuera de una subasta de Protected Audience.

Una vez que se selecciona un anuncio, los resultados, las ofertas y los indicadores se conservan de forma interna para la generación de informes. La devolución de llamada OutcomeReceiver.onResult() muestra un AdSelectionOutcome que contiene lo siguiente:

  • Una URL de renderización para el anuncio ganador, que se obtiene de AdData.getRenderUrl()
  • Un ID de selección de anuncios único para el usuario del dispositivo, que se utiliza para informar la impresión de anuncios

Si la selección de anuncios no se puede completar correctamente debido a argumentos no válidos, tiempos de espera o un consumo excesivo de recursos, la devolución de llamada OutcomeReceiver.onError() proporciona AdServicesException con los siguientes comportamientos:

  • Si la selección de anuncios se inicia con argumentos no válidos, AdServicesException indicará IllegalArgumentException como la causa.
  • Todos los demás errores recibirán AdServicesException con IllegalStateException como la causa.

Anuncios contextuales

Protected Audience puede incorporar anuncios contextuales en una subasta protegida. Los anuncios contextuales deben seleccionarse en el servidor de tecnología publicitaria y mostrarse al dispositivo fuera de las APIs de Protected Audience. Los anuncios contextuales se pueden incluir en la subasta a través de AdSelectionConfig, en cuyo punto funcionan igual que en los anuncios integrados en el dispositivo, lo que incluye la elegibilidad para el filtrado negativo de anuncios. Una vez que se complete la subasta de Protected Audience, deberás invocar a reportImpression(). De esta manera, se llama a reportWin() en el anuncio contextual ganador, siguiendo el mismo patrón que los informes de impresiones, para recibir el anuncio ganador en un dispositivo. Cada anuncio contextual necesita un comprador, una oferta, un vínculo a la lógica de informes, una URL de renderización y los metadatos del anuncio.

Para implementar anuncios contextuales en la app, la app de destino debe crear un objeto ContextualAds:

Kotlin

val contextualAds: ContextualAds =
  Builder().setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
    //Pass in your valid app install ads
    .setDecisionLogicUri(mContextualLogicUri)
    .setAdsWithBid(appInstallAd)
    .build()

Java

ContextualAds contextualAds = new ContextualAds.Builder()
  .setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
  .setDecisionLogicUri(mContextualLogicUri)
  //Pass in your valid app install ads
  .setAdsWithBid(appInstallAd)
  .build();

El objeto ContextualAds resultante se puede pasar cuando se crea la AdSelectionConfig:

Kotlin

// Create a new ad
val noFilterAd: AdData = Builder()
  .setMetadata(JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build()
val noFilterAdWithBid = AdWithBid(noFilterAd, NO_FILTER_BID)
contextualAds.getAdsWithBid().add(noFilterAdWithBid)

Java

// Create a new ad
AdData noFilterAd = new AdData.Builder()
  .setMetadata(new JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build();
AdWithBid noFilterAdWithBid = new AdWithBid(noFilterAd, NO_FILTER_BID);
contextualAds.getAdsWithBid().add(noFilterAdWithBid);

Filtrado de anuncios de instalación de aplicaciones

El filtrado de anuncios de instalación de aplicaciones te ayuda a filtrar anuncios de instalación para apps que ya están instaladas en un dispositivo.

El primer paso de este proceso es definir qué anunciantes tienen la capacidad de filtrar en el paquete instalado. Esto debe ocurrir en la app a la que quieres segmentar con un anuncio.

Kotlin

//Create a request for setting the app install advertisers
val adtech = AdTechIdentifier.fromString("your.enrolled.uri")
val adtechSet = setOf(adtech)
val request = SetAppInstallAdvertisersRequest(adtechSet)

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  object : OutcomeReceiver<Any?, Exception?>() {
    fun onResult(@NonNull ignoredResult: Any?) {
      Log.v("[your tag]", "Updated app install advertisers")
    }

    fun onError(@NonNull error: Exception?) {
      Log.e("[your tag]", "Failed to update app install advertisers", error)
    }
  })

Java

//Create a request for setting the app install advertisers
AdTechIdentifier adtech = AdTechIdentifier.fromString("your.enrolled.uri");
Set<AdTechIdentifier> adtechSet = Collections.singleton(adtech);
SetAppInstallAdvertisersRequest request = new SetAppInstallAdvertisersRequest(adtechSet);

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  new OutcomeReceiver<Object, Exception>() {
    @Override
    public void onResult(@NonNull Object ignoredResult) {
      Log.v("[your tag]", "Updated app install advertisers");
    }

    @Override
    public void onError(@NonNull Exception error) {
      Log.e("[your tag]", "Failed to update app install advertisers", error);
    }
  });

Cuando se ejecuta el código anterior, los anunciantes que se pasan pueden filtrar las apps instaladas que especificas durante la generación de ofertas. Si necesitas quitar el acceso de un anunciante al estado de instalación de esta app, vuelve a ejecutar este código sin la información del anunciante.

El siguiente paso es configurar el filtrado de anuncios en la aplicación del publicador. La parte que publica el anuncio dentro de la app del publicador (lo más probable es que sea un SDK del proveedor) debe inicializar su objeto AdFilters con información sobre qué anuncios están relacionados con la app que quiere filtrar:

Kotlin

// Instantiate AdFilters object with package names.
val filters: AdFilters = Builder().setAppInstallFilters(
    Builder().setPackageNames(setOf("example.target.app")).build()
  ).build()

Java

// Instantiate AdFilters object with package names.
AdFilters filters = new AdFilters.Builder()
.setAppInstallFilters(
  new AppInstallFilters.Builder()
  .setPackageNames(Collections.singleton("example.target.app"))
  .build())
.build();

Los publicadores orientados a la demanda también pueden establecer un AdFilter para los anuncios que existen dentro de sus públicos personalizados.

También se puede pasar AdFilters cuando se crea una instancia de un objeto AdData nuevo:

Kotlin

// Instantiate an AdData object with the AdFilters created in the
// previous example.
val appInstallAd: AdData =
  Builder().setMetadata("{ ... }") // Valid JSON string
    .setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters).build()

Java

// Instantiate an AdData object with the AdFilters created in the
// previous example.
AdData appInstallAd = new AdData.Builder()
.setMetadata("{ ... }") // Valid JSON string
.setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters)
    .build();

Filtrado de limitación de frecuencia

El filtrado de limitación de frecuencia permite que las tecnologías publicitarias limiten la cantidad de veces que se muestra un anuncio. Este filtrado reduce la sobreexposición del anuncio y optimiza la selección de anuncios alternativos para una campaña publicitaria determinada.

Un filtro de limitación de frecuencia tiene dos componentes principales: el tipo de evento de anuncio y la clave de contador de anuncios. Los tipos de eventos de anuncios disponibles que se pueden utilizar son los siguientes:

  • Win (próximamente): Un evento de ganancia indica que el anuncio ganó una subasta. La API de Protected Audience actualiza automáticamente los eventos de ganancia, y el desarrollador no puede llamarlos de forma directa. Solo los anuncios dentro de un público personalizado determinado pueden ver los datos de ganancias.
  • Impresión: Independiente de reportImpression, un llamador integrado en el dispositivo (SSP o MMP) usa updateAdCounterHistogram() para invocar eventos de impresión en el punto del código que elige. Los eventos de impresión son visibles para todos los anuncios que pertenecen a una DSP determinada y no se limitan a los anuncios en el mismo público personalizado.
  • Vista: El llamador integrado en el dispositivo (SSP o MMP) invoca el evento en un punto del código que elige con una llamada a updateAdCounterHistogram(). Los eventos de vista son visibles para todos los anuncios que pertenecen a una DSP determinada y no se limitan a los anuncios del mismo público personalizado.
  • Clic: El llamador integrado en el dispositivo (SSP o MMP) invoca el evento en un punto del código que elige con una llamada a updateAdCounterHistogram(). Los eventos de clic son visibles para todos los anuncios que pertenecen a una DSP determinada y no se limitan a los anuncios del mismo público personalizado.

En la app del publicador, una SSP o MMP que tienen presencia en el dispositivo invocan eventos de anuncios. Cuando se llama a updateAdCounterHistogram(), se incrementa el contador de un filtro de limitación de frecuencia para que las subastas futuras tengan información actualizada sobre la exposición de un usuario a un anuncio determinado. Los tipos de eventos de anuncios no están vinculados de manera forzosa a la acción del usuario correspondiente y son lineamientos que se proporcionan para ayudar a los llamadores a estructurar su sistema de eventos. Para aumentar los contadores de anuncios en el momento de un evento, el actor integrado en el dispositivo proporciona el ID de selección de anuncio de la subasta de anuncios ganadora.

Las claves de contador de anuncios son números enteros arbitrarios de 32 bits firmados que asigna la tecnología publicitaria de un comprador y corresponden a un conjunto determinado de anuncios, según lo define la DSP. Dado que las claves de contador de anuncios se limitan solo a anuncios que pertenecen a una DSP específica, se pueden seleccionar sin superponerse con histogramas de otra tecnología publicitaria. Las claves de contador de anuncios se usan para incrementar los identificadores específicos de la DSP en los anuncios de una DSP o en un público personalizado determinado para filtrar los anuncios de subastas futuras.

Las claves de contador se pueden aprovechar para priorizar los anuncios que es más probable que sean interesantes para un usuario determinado según sus interacciones con otros anuncios de la tecnología publicitaria de un comprador específico. Por ejemplo, un anuncio que recibió un alto nivel de participación por ganar subastas de anuncios, vistas y clics representa un dato inferido. A modo de ejemplo, un anuncio de palos de golf para zurdos podría indicar que el usuario no estaría interesado en los palos para diestros. Un filtro de limitación de frecuencia configurado para una clave de contador asignada a anuncios para zurdos podría filtrar los anuncios de palos para diestros.

Para utilizar la limitación de frecuencia en tu subasta, primero debes crear objetos KeyedFrequencyCap, como se muestra a continuación:

Kotlin

// Value used when incrementing frequency counter
val adCounterKey = 123

// Frequency cap exceeded after 2 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 2, Duration.ofSeconds(10)
).build()

// Frequency cap exceeded after 1 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 1, Duration.ofSeconds(10)
).build()

Java

// Value used when incrementing frequency counter
int adCounterKey = 123;

// Frequency cap exceeded after 2 counts
KeyedFrequencyCap keyedFrequencyCapForImpression =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 2, Duration.ofSeconds(10)
  ).build();

// Frequency Cap exceeded after 1 counts
KeyedFrequencyCap keyedFrequencyCapForClick =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 1, Duration.ofSeconds(10)
  ).build();

Cuando se hayan creado los objetos KeyedFrequencyCap, podrás pasarlos a un objeto AdFilters.

Kotlin

val filters: AdFilters = Builder()
  .setFrequencyCapFilters(
    Builder()
      .setKeyedFrequencyCapsForImpressionEvents(
        ImmutableObject.of(keyedFrequencyCapForImpression)
      )
      .setKeyedFrequencyCapsForClickEvents(
        ImmutableObject.of(keyedFrequencyCapForClick)
      )
  ).build()

Java

AdFilters filters = new AdFilters.Builder()
    .setFrequencyCapFilters(new FrequencyCapFilters.Builder()
        .setKeyedFrequencyCapsForImpressionEvents(
            ImmutableObject.of(keyedFrequencyCapForImpression)
        )
        .setKeyedFrequencyCapsForClickEvents(
            ImmutableObject.of(keyedFrequencyCapForClick)
        )
    ).build();

Cuando el objeto AdFilters se completa con filtros de limitación de frecuencia, se puede pasar cuando se crea el público personalizado:

Kotlin

// Initialize a custom audience.
val audience: CustomAudience = Builder()
  .setBuyer(buyer)
  .setName(name)
  .setAds(
    listOf(
      Builder()
        .setRenderUri(renderUri)
        .setMetadata(JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()
    )
  ).build()

Java

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setAds(Collections.singletonList(new AdData.Builder()
        .setRenderUri(renderUri)
        .setMetadata(new JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()))
    .build();

Cuando los filtros de limitación de frecuencia se implementan en un público personalizado, la SSP puede invocar los eventos de clic, vista o impresión necesarios.

Kotlin

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

val request: UpdateAdCounterHistogramRequest = Builder(
  adSelectionId,
  FrequencyCapFilters.AD_EVENT_TYPE_CLICK,  //CLICK, VIEW, or IMPRESSION
  callerAdTech
).build()

Java

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

UpdateAdCounterHistogramRequest request =
  new UpdateAdCounterHistogramRequest.Builder(
      adSelectionId,
      FrequencyCapFilters.AD_EVENT_TYPE_CLICK, //CLICK, VIEW, or IMPRESSION
      callerAdTech
).build();

Los anuncios que alcanzaron los límites predeterminados del filtro de limitación de frecuencia se filtran fuera de la subasta. El filtrado se produce antes de que se ejecute la lógica de ofertas para las subastas en el dispositivo y a medida que la carga útil genera para las subastas de servicios de ofertas y subastas. Este kit de herramientas les brinda a las tecnologías publicitarias la flexibilidad para usar las interacciones entre los usuarios y los anuncios de sus públicos personalizados para enfocar en su orientación y minimizar la sobreexposición.

Filtrado de anuncios contextuales sin llamadas de red

Si no hay demanda de remarketing en el dispositivo, puedes ejecutar la selección de anuncios para anuncios contextuales sin llamadas de red. Con los URI precompilados y una lista de anuncios contextuales con ofertas, la plataforma puede omitir la recuperación de la lógica de ofertas, los indicadores de ofertas y los indicadores de puntuación. La plataforma usa un URI precompilado para seleccionar el anuncio contextual con la oferta más alta.

Para mejorar la latencia, las tecnologías publicitarias pueden ejecutar un flujo de selección de anuncios que solo incluya anuncios contextuales con funcionalidad de filtrado de anuncios sin llamadas de red. Esto se logra usando URIs precompilados para los indicadores de puntuación. Consulta la sección de casos de uso y nombres de URI precompilados compatibles para obtener una lista de implementaciones de scoreAds.

Para ejecutar la selección de anuncios sin llamadas de red, haz lo siguiente:

  1. Configura el filtrado de anuncios.
  2. Crea anuncios contextuales.
  3. Crea un objeto AdSelectionConfig con lo siguiente:

    1. Una lista vacía de compradores
    2. Un URI precompilado para seleccionar la oferta más alta
    3. Anuncios contextuales
    4. Un URI vacío para los indicadores de puntuación. Este tiene permitido indicar que no deseas usar la recuperación de indicadores de confianza para la puntuación:
    Uri prebuiltURIScoringUri = Uri.parse("ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=your.registered.uri/reporting");
    // Initialize AdSelectionConfig
    AdSelectionConfig adSelectionConfig =
      new AdSelectionConfig.Builder()
        .setSeller(seller)
        .setDecisionLogicUri(prebuiltURIScoringUri)
        .setCustomAudienceBuyers(Collections.emptyList())
        .setAdSelectionSignals(adSelectionSignals)
        .setSellerSignals(sellerSignals)
        .setPerBuyerSignals(perBuyerSignals)
        .setBuyerContextualAds(buyerContextualAds)
        .setTrustedScoringSignalsUri(Uri.EMPTY)
        .build();
    
  4. Ejecuta la selección de anuncios:

    adSelectionManager.selectAds(
        adSelectionConfig,
        executor,
        outcomeReceiver);
    

Ejecuta tus propios informes de JavaScript mientras usas URIs precompilados

Actualmente, la plataforma de Privacy Sandbox solo tiene una implementación básica de informes de JavaScript disponible para los URIs precompilados. Si deseas ejecutar tu propio código de informes de JavaScript y, al mismo tiempo, usar los URI precompilados para obtener una selección de anuncios de baja latencia, puedes anular el DecisionLogicUri entre la selección de anuncios y las ejecuciones de informes.

  1. Ejecuta los pasos para ejecutar la selección de anuncios contextuales con URIs precompilados.
  2. Crea una copia de AdSelectionConfig antes de ejecutar el informe

    adSelectionConfigWithYourReportingJS = adSelectionConfig.cloneToBuilder()
      // Replace <urlToFetchYourReportingJS> with your own URL:
      .setDecisionLogicUri(Uri.parse(<urlToFetchYourReportingJS>))
      .build();
    
  3. Ejecuta informes de impresiones

    // adSelectionId is from the result of the previous selectAds run
    ReportImpressionRequest request = new ReportImpressionRequest(
      adSelectionId,
      adSelectionConfigWithYourReportingJS);
    adSelectionManager.reportImpression(
      request,
      executor,
      outcomeReceiver);
    

Cómo ejecutar la mediación en cascada

La mediación en cascada requiere que varios SDKs de terceros (redes de terceros) estén organizados por una red de mediación de SDK propia. La mediación en cascada se realiza de la misma manera, independientemente de si la subasta se realizó en el dispositivo o en los servicios de ofertas y subastas (B&A).

Redes de terceros

Las redes de terceros deben proporcionar un adaptador que permita a la red de mediación invocar los métodos necesarios para ejecutar una subasta:

  • Ejecuta la selección de anuncios
  • Informar impresiones

El siguiente es un ejemplo de un adaptador de red de mediación:

Kotlin

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

    init {
        adSelectionManager = context.getSystemService(AdSelectionManager::class.java)
    }

    fun selectAds() {...}

    fun reportImpressions() {...}
}

Java

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

    public NetworkAdaptor() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void selectAds() {...}

    public void reportImpressions() {...}
}

Cada SDK tiene sus propios administradores de servicios de selección de anuncios y clientes, así como su propia implementación de selectAds y reportImpressions. Los proveedores del SDK pueden consultar las secciones para ejecutar la selección de anuncios para subastas integradas en el dispositivo o la explicación de B&A para subastas de B&A. Sigue los pasos para informar impresiones de anuncios (siguiendo los informes de impresiones de SSP única para generar informes).

Red de mediación

Al igual que las redes de terceros, las redes de mediación necesitan implementaciones de selectAds y reportImpression. Consulta las secciones sobre cómo ejecutar la selección de anuncios y cómo informar impresiones de anuncios para obtener más información.

Las redes de mediación son responsables de ejecutar la cadena de mediación y ubicarse en ella. En la siguiente sección, se explica cómo configurar y ejecutar este proceso.

Recupera la cadena de mediación y las ofertas mínimas

La red de mediación es responsable de recuperar los anuncios contextuales propios, la cadena de mediación y las ofertas mínimas de las redes de terceros. Esto puede suceder en una solicitud para recuperar anuncios contextuales que ejecuta la red de mediación. La cadena de mediación determina cómo se realiza la iteración a través de las redes de terceros, y las ofertas mínimas se pueden pasar al proceso de subasta como adSelectionSignals.

Ubicación de la red en la cadena de mediación

Un SDK de mediación puede ubicarse en la cadena de mediación según su eCPM en vivo de ofertas de anuncios propias. En la API de Protected Audience, las ofertas de anuncios son opacas. Un SDK de mediación debe usar AdSelectionFromOutcomesConfig para poder comparar la oferta de un anuncio propia con la oferta mínima de la siguiente red de terceros en la cadena. Si la oferta propia es mayor que la oferta mínima, eso significa que el SDK de mediación se coloca frente a esa red de terceros.

Ejecuta la selección de anuncios

Para recuperar un candidato de anuncio propio, la red de mediación puede ejecutar una subasta integrada en el dispositivo a través de los pasos que se indican en la sección Cómo ejecutar la selección de anuncios. Esto genera un candidato de anuncio propio, una oferta y un AdSelectionId que se usa en el proceso de mediación.

Cómo crear un elemento AdSelectionFromResultssConfig

Un AdSelectionFromOutcomesConfig permite que la red de mediación pase una lista de AdSelectionIds (resultados de subastas anteriores), indicadores de selección de anuncios y un URI para recuperar JavaScript que selecciona un anuncio de varios candidatos. La lista de AdSelectionIds junto con sus ofertas y los indicadores se pasan al código JavaScript, que puede mostrar uno de los AdSelectionIds si supera la oferta mínima o ninguno si la cadena de mediación debe continuar.

Las redes de mediación crean una AdSelectionFromOutcomesConfig con el AdSelectionId propio de la sección anterior, y se tiene en cuenta la oferta mínima de la red de terceros. Se debe crear una AdSelectionFromOutcomesConfig nueva para cada paso en la cadena de mediación.

Kotlin

fun  runSelectOutcome(
    adSelectionClient : AdSelectionClient,
    outcome1p : AdSelectionOutcome,
    network3p : NetworkAdapter) : ListenableFuture<AdSelectionOutcome?> {
    val config = AdSelectionFromOutcomesConfig.Builder()
        .setSeller(seller)
        .setAdSelectionIds(listOf(outcome1p))
        .setSelectionSignals({"bid_floor": bid_floor})
        .setSelectionLogicUri(selectionLogicUri)
        .build()
    return adSelectionClient.selectAds(config)
}

Java

public ListenableFuture<AdSelectionOutcome> runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) {
    AdSelectionFromOutcomesConfig config = new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .build();

    return adSelectionClient.selectAds(config){}
}

La anulación del método selectAds() para la mediación en cascada requiere una entrada AdSelectionFromOutcomesConfig, en la que debes especificar los siguientes parámetros obligatorios:

  • Vendedor: Es el identificador de la red de publicidad del vendedor que inicia la selección de anuncios.
  • AdSelectionIds: Es una lista singleton de una ejecución selectAds() anterior para un anuncio propio.
  • Indicadores de selección de anuncios: Es un objeto JSON, serializado como una cadena, que contiene indicadores que debe usar la lógica de ofertas del comprador. En este caso, incluye la oferta mínima recuperada para la red de terceros específica.
  • URI de lógica de selección: Es una URL HTTPS que se consulta durante la selección de anuncios para recuperar el código JavaScript de la red de mediación para seleccionar un anuncio ganador. Consulta las firmas de las funciones necesarias en JavaScript. JavaScript debe mostrar el anuncio de terceros si la oferta es superior a la oferta mínima, o bien mostrar null. Esto le permite al SDK de mediación truncar la cadena de mediación cuando se encuentra un ganador.

Con AdSelectionOutcomesConfig creada, llama al método selectAds() de la red de terceros que se encuentra primero en la cadena.

Kotlin

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
  AdSelectionFromOutcomesConfig.Builder()
    .setSeller(seller)
    .setAdSelectionIds(listof(outcome1p))
    .setSelectionSignals({"bid_floor": bid_floor})
    .setSelectionLogicUri(selectionLogicUri)
    .setAdSelectionIds(outcomeIds)
    .build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver)

Java

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
        new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .setAdSelectionIds(outcomeIds)
            .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver);

Cómo organizar la mediación en cascada

A continuación, se muestra el orden de las operaciones para ejecutar durante el proceso de mediación.

  1. Ejecuta la selección de anuncios propios.
  2. Realiza la iteración en la cadena de mediación. Para cada red de terceros, haz lo siguiente:
    1. Compila AdSelectionFromOutcomeConfig, incluidos el outcomeId propio y la oferta mínima del SDK de terceros.
    2. Llama a selectAds() con la configuración del paso anterior.
    3. Si el resultado no está vacío, muestra el anuncio.
    4. Llama al método selectAds() del adaptador de red del SDK actual. Si el resultado no está vacío, muestra el anuncio.
  3. Si no se encuentra un ganador en la cadena, muestra el anuncio propio.

Kotlin

fun runWaterfallMediation(mediationChain : List<NetworkAdapter>)
  : Pair<AdSelectionOutcome, NetworkAdapter> {
    val outcome1p = runAdSelection()

    var outcome : AdSelectionOutcome
    for(network3p in mediationChain) {
      outcome = runSelectOutcome(outcome1p, network3p)
      if (outcome1p.hasOutcome() && outcome.hasOutcome()) {
          return Pair(outcome, this)
      }

      outcome = network3p.runAdSelection()
      if(outcome.hasOutcome()) {
          return Pair(outcome, network3p)
      }
    }
  return Pair(outcome1p, this)
}

Java

class MediationNetwork {
    AdSelectionManager adSelectionManager;

    public MediationNetwork() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void runAdSelection() {...}

    public void reportImpressions() {...}

    public Pair<AdSelectionOutcome, NetworkAdapter> runWaterfallMediation(
            List<NetworkAdapter> mediationChain) {
        AdSelectionOutcome outcome1p = runAdSelection();

        AdSelectionOutcome outcome;
        for(NetworkAdapter network3p: mediationChain) {
            if (outcome1p.hasOutcome() &&
              (outcome = runSelectOutcome(outcome1p, network3p)).hasOutcome()) {
                return new Pair<>(outcome, this);
            }

            if((outcome = network3p.runAdSelection()).hasOutcome()) {
                return new Pair<>(outcome, network3p);
            }
        }
        return new Pair<>(outcome1p, this);
    }

    /* Runs comparison by creating an AdSelectionFromOutcomesConfig */
    public AdSelectionOutcome runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) { ... }
}

Cómo informar impresiones de anuncios

Existen dos flujos para informar una impresión de anuncios según cómo se ejecuta la subasta. Si tienes una sola SSP que ejecuta una subasta, sigue esta sección. Si quieres implementar la mediación en cascada, sigue los pasos que se encuentran en la sección de informes de impresiones de mediación en cascada.

Informe de impresiones de SSP única

Después de elegir un anuncio ganador del flujo de trabajo de selección de anuncios, puedes informar la impresión a las plataformas participantes orientadas a la compra y a la venta con el método AdSelectionManager.reportImpression(). Para informar una impresión de anuncios, haz lo siguiente:

  1. Inicializa un objeto AdSelectionManager.
  2. Compila un objeto ReportImpressionRequest con el ID de selección de anuncios.
  3. Llama al método asíncrono reportImpression() con el objeto ReportImpressionRequest y los objetos Executor y OutcomeReceiver relevantes.

Java

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportImpressionRequest
ReportImpressionRequest reportImpressionRequest =
        new ReportImpressionRequest.Builder()
                .setAdSelectionId(adSelectionId)
                .setAdSelectionConfig(adSelectionConfig)
                .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver);

Kotlin

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize a ReportImpressionRequest
val adSelectionConfig: ReportImpressionRequest =
    ReportImpressionRequest.Builder()
        .setAdSelectionId(adSelectionId)
        .setAdSelectionConfig(adSelectionConfig)
        .build()

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver)

Inicializa ReportImpressionRequest con los siguientes parámetros obligatorios:

  • ID de selección de anuncios: Es un ID único solo para el usuario de un dispositivo que identifica a una selección de anuncios correcta.
  • Configuración de selección de anuncios: Es la misma configuración que se usa en la llamada selectAds() identificada con el ID de selección de anuncios proporcionado.

El método reportImpression() asíncrono usa el objeto OutcomeReceiver para indicar el resultado de la llamada a la API.

  • La devolución de llamada onResult() indica si se crearon las URLs de informes de impresiones y si se programó la solicitud.
  • La devolución de llamada onError() indica las siguientes condiciones posibles:
    • Si se inicializa la llamada con un argumento de entrada no válido, AdServicesException indica IllegalArgumentException como la causa.
    • Todos los demás errores recibirán AdServicesException con IllegalStateException como la causa.

Informes de impresiones de la mediación en cascada

Un SDK de mediación debe realizar un seguimiento del SDK ganador para activar sus flujos de informes. Los SDKs que participan en una cadena de mediación deben proporcionar un método que invoque el mediador para activar su propio flujo de informes. Un SDK que participa en una subasta mediada puede seguir los pasos anteriores para implementar sus propios informes.

Las SSPs pueden usar este ejemplo de código del SDK de terceros como prototipo para aprender a unirse a los flujos de mediación:

Pair<AdSelectionOutcome, NetworkAdapter> winnerOutcomeAndNetwork =
         mediationSdk.orchestrateMediation(mediationChain);

if (winner.first.hasOutcome()) {
      winner.second.reportImpressions(winner.first.getAdSelectionId());

Extremos de informes de impresiones

La API de Report Impression emitirá solicitudes GET HTTPS a los extremos que proporciona la plataforma orientada a la venta y la plataforma ganadora orientada a la compra:

Extremo de la plataforma orientada a la compra:

  • La API usa la URL de lógica de ofertas especificada en el público personalizado para recuperar el JavaScript que brinda el comprador y que incluye lógica para mostrar una URL de informe de impresiones.
  • Invoca la función de JavaScript reportWin(), que se espera que muestre la URL del informe de impresiones del comprador.

Extremo de la plataforma orientada a la venta:

  • Usa la URL de lógica de decisión que se especifica en el objeto AdSelectionConfig para recuperar la lógica de decisión de JavaScript del vendedor.
  • Invoca la función de JavaScript reportResult(), que se espera que muestre la URL del informe de impresiones del comprador.

Informes de servicios de ofertas y subastas

Una subasta ejecutada en servicios de ofertas y subastas tendrá toda la información de informes necesaria, incluidas las URLs generadas para los informes de interacción con anuncios, que se incluyen en la respuesta encriptada de la subasta del servidor. Cuando se desencripta la respuesta, se registran las URLs adecuadas en la plataforma, por lo que los informes de impresiones y anuncios siguen los mismos pasos mencionados previamente.

La mejor manera de completar informes de impresiones

El método reportImpression() está diseñado para ofrecer la mejor manera de completar los informes.

Cómo informar interacciones con los anuncios

Protected Audience ofrece compatibilidad con el informe sobre interacciones más detalladas para un anuncio renderizado. Esto puede incluir interacciones como el tiempo de vista, los clics, los desplazamientos del cursor sobre algún elemento o cualquier otra métrica útil que se pueda recopilar. El proceso para recibir estos informes requiere dos pasos. En primer lugar, los compradores y vendedores deben registrarse para recibir estos informes en su JavaScript de informes. Luego, el cliente debe informar estos eventos.

Cómo registrarse para recibir eventos de interacción

El registro para eventos de interacción ocurre en las funciones de JavaScript reportWin() del comprador y reportResult() del vendedor a través de una función de JavaScript proporcionada por la plataforma: registerAdBeacon. Si quieres registrarte para recibir un informe de eventos, solo debes llamar a la función de JavaScript de la plataforma desde tu JavaScript de informes. El siguiente fragmento usa la función reportWin() del comprador, pero el mismo enfoque se aplica a reportResult().

reportWin(
  adSelectionSignals,
  perBuyerSignals,
  signalsForBuyer,
  contextualSignals,
  customAudienceSignals) {
    ...
    // Calculate reportingUri, clickUri, viewUri, and hoverUri
    registerAdBeacon("click", clickUri)
    registerAdBeacon("view", viewUri)
    registerAdBeacon("hover", hoverUri)

    return reportingUrl;
}

Cómo informar eventos de interacción

Después de informar una impresión, los clientes pueden informar las interacciones a las plataformas ganadoras orientadas a la compra y a la venta previamente registradas con el método AdSelectionManager.reportInteraction(). Para informar un evento de anuncio, haz lo siguiente:

  1. Inicializa un objeto AdSelectionManager.
  2. Compila un objeto ReportInteractionRequest con el ID de selección de anuncios, la clave de interacción, los datos de interacción y el destino de los informes.
  3. Llama al método asíncrono reportInteraction() con el objeto request y los objetos Executor y OutcomeReceiver relevantes.
AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportInteractionRequest
ReportInteractionRequest request =
  new ReportInteractionRequest.Builder()
    .setAdSelectionId(adSelectionId)
    .setInteractionKey("view")
    .setInteractionData("{ viewTimeInSeconds : 1 }") // Can be any string
    .setReportingDestinations(
      FLAG_REPORTING_DESTINATION_BUYER | FLAG_REPORTING_DESTINATION_SELLER
    )
    .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportInteraction(
  reportImpressionRequest,
  executor,
  outcomeReceiver);

Inicializa ReportInteractionRequest con los siguientes parámetros obligatorios:

  • ID de selección de anuncios: Es un ID de selección de anuncios recuperado de un AdSelectionOutcome que se mostró antes.
  • Clave de interacción: Es una clave de cadena que define el cliente y que describe la acción que se informa. Debe coincidir con la clave que registró el vendedor o el comprador en las funciones de JavaScript de informes.
  • Datos de interacción: Es una cadena que contiene datos que se incluirán en el informe del evento para enviar en solicitudes POST a los servidores de informes.
  • Destinos de informes: Es una máscara binaria que especifica si se deben informar los eventos al comprador, al vendedor o a ambos. La plataforma proporciona estas marcas, y la máscara de destino final se puede crear con operaciones a nivel de bits. Para informar a un destino, puedes usar la marca que proporciona la plataforma directamente. Para informar a varios destinos, puedes usar el OR a nivel de bits (|) para combinar los valores de las marcas.

El método reportInteraction() asíncrono usa el objeto OutcomeReceiver para indicar el resultado de la llamada a la API.

  • La devolución de llamada onResult() indica que la llamada de interacción de informes es válida.
  • La devolución de llamada onError() indica las siguientes condiciones posibles:
    • Si se realiza la llamada cuando la app se ejecuta en segundo plano, se muestra una IllegalStateException con una descripción de la falla.
    • Si el cliente no puede llamar a reportInteraction(), se muestra una LimitExceededException.
    • Si el paquete no está inscrito para llamar a las APIs de preservación de la privacidad, se muestra una SecurityException().
    • Si las interacciones de los informes de la app son diferentes de las de la app que llamó a selectAds(), se muestra una IllegalStateException.
  • Si el usuario no dio su consentimiento para habilitar las APIs de Privacy Sandbox, la llamada fallará de manera silenciosa.

Extremos de informes de interacciones

La API de interacción de informes emite solicitudes HTTPS POST a los extremos que proporciona la plataforma orientada a la venta y la plataforma ganadora orientada a la compra. Protected Audience hará coincidir las claves de interacción con los URI declarados en el JavaScript de informes y emitirá una solicitud POST a cada extremo para cada interacción que se informe. El tipo de contenido de la solicitud es texto sin formato, y el cuerpo contiene los datos de interacción.

La mejor manera de completar informes de interacción

El objetivo de reportInteraction() es ofrecer la mejor manera de completar los informes a través de HTTP POST.

Actualización diaria en segundo plano

Cuando creas un público personalizado, tu app o SDK pueden inicializar metadatos personalizados. Además, la plataforma puede actualizar los siguientes metadatos personalizados del público con un proceso diario de actualización en segundo plano.

  • Indicadores de ofertas del usuario
  • Datos de ofertas de confianza
  • Lista AdData

Este proceso consulta la URL de actualización diaria definida en el público personalizado y es posible que la URL muestre una respuesta JSON.

  • La respuesta JSON puede contener cualquiera de los campos de metadatos admitidos que deben actualizarse.
  • Cada campo JSON se valida de forma independiente. El cliente ignora los campos con formato incorrecto que no generen actualizaciones para ese campo en particular en la respuesta.
  • Una respuesta HTTP vacía o un objeto JSON vacío "{}" no generan actualizaciones de metadatos.
  • El tamaño del mensaje de respuesta debe limitarse a 10 KB.
  • Todos los URIs son obligatorios para usar HTTPS.
  • trusted_bidding_uri debe compartir el mismo ETLD+1 que el comprador.

Ejemplo: Respuesta JSON para una actualización diaria en segundo plano

{
    "user_bidding_signals" : { ... },  // Valid JSON object
    "trusted_bidding_data" : {
        "trusted_bidding_uri" : 'example-dsp1-key-value-service.com',
        "trusted_bidding_keys" : [ 'campaign123', 'campaign456', ... ]
    },
    'ads' : [
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign123.html',
            'metadata' : { ... }  // Valid JSON object
        },
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign456.html',
            'metadata' : { ... }  // Valid JSON object
        },
        ...
    ]
}

JavaScript para la selección de anuncios

El flujo de trabajo de la selección de anuncios organiza la ejecución de JavaScript que brinda el comprador y el vendedor.

El JavaScript que brinda el comprador se recupera de la URL de lógica de ofertas que se especifica en el público personalizado. El JavaScript que se muestra debe incluir las siguientes funciones:

El JavaScript que brinda el vendedor se recupera de la URL de lógica de decisión que se especifica en el parámetro AdSelectionConfig para la API de Ad Selection. El JavaScript que se muestra debe incluir las siguientes funciones:

generateBid()

function generateBid(
  ad,
  auction_signals,
  per_buyer_signals,
  trusted_bidding_signals,
  contextual_signals,
  user_signals,
  custom_audience_bidding_signals) {
  return {'status': 0, 'ad': ad, 'bid': ad.metadata.result };
}

Parámetros de entrada:

  • ad: Es un objeto JSON con el formato var ad = { 'render_url': url, 'metadata': json_metadata };.
  • auction_signals, per_buyer_signals: Son objetos JSON especificados en el objeto de configuración de la subasta.
  • custom_audience_bidding_signals: Es un objeto JSON que genera la plataforma. El formato de este objeto JSON es el siguiente:

    var custom_audience_signals = {
      "owner":"ca_owner",
      "buyer":"ca_buyer",
      "name":"ca_name",
      "activation_time":"ca_activation_time_epoch_ms",
      "expiration_time":"ca_expiration_time_epoch_ms",
      "user_bidding_signals":"ca_user_bidding_signals"
    }
    

    Donde:

    • owner, buyer y name son cadenas que se toman de las propiedades con el mismo nombre del público personalizado que participa en la selección de anuncios.
    • activation_time y expiration_time son el tiempo de activación y vencimiento del público personalizado, que se expresa como segundos desde el tiempo Unix.
    • ca_user_bidding_signals es una cadena JSON que se especifica en el campo userBiddingSignals de CustomAudience cuando se crea.
    • trusted_bidding_signals, contextual_signals y user_signals son objetos JSON. Se pasan como objetos vacíos y se completarán en versiones futuras. Su formato no se aplica de manera forzosa por la plataforma y es administrado por la tecnología publicitaria.

Resultado:

  • ad: el anuncio al que hace referencia la oferta. La secuencia de comandos puede mostrar una copia del anuncio que recibió con diferentes metadatos. Se espera que no cambie la propiedad render_url del anuncio
  • bid: un valor flotante que representa el valor de la oferta para este anuncio
  • status: un valor entero que puede ser uno de los siguientes:
    • 0: Para una ejecución correcta
    • 1 (o cualquier valor distinto de cero): En caso de que alguno de los indicadores de entrada no sea válido (si generate-bid muestra un valor distinto de cero, el proceso de oferta se invalida para todos los anuncios de PP).

scoreAd()

function scoreAd(
  ad,
  bid,
  ad_selection_config,
  seller_signals,
  trusted_scoring_signals,
  contextual_signal,
  user_signal,
  custom_audience_signal) {
    return {'status': 0, 'score': score };
}

Parámetros de entrada:

  • ad: consulta la documentación de generateBid.
  • bid: el valor de la oferta para el anuncio.
  • ad_selection_config: un objeto JSON que representa el parámetro AdSelectionConfig de la API de selectAds. El formato es el siguiente:

    var ad_selection_config = {
      'seller': 'seller',
      'decision_logic_url': 'url_of_decision_logic',
      'custom_audience_buyers': ['buyer1', 'buyer2'],
      'auction_signals': auction_signals,
      'per_buyer_signals': per_buyer_signals,
      'contextual_ads': [ad1, ad2]
    }
    
  • seller_signals: Son objetos JSON que se leen del parámetro de la API de sellerSignals AdSelectionConfig.

  • trusted_scoring_signal: Lee del campo adSelectionSignals en el parámetro de la API de AdSelectionConfig.

  • contextual_signals, user_signals: objetos JSON. En la actualidad, se pasan como objetos vacíos y se completarán en versiones futuras. Su formato no se aplica de manera forzosa por la plataforma y es administrado por la tecnología publicitaria.

  • per_buyer_signals: Es un objeto JSON que se lee del mapa perBuyerSignal en el parámetro de la API de AdSelectionConfig usando como clave el comprador actual del público personalizado. Estará vacío si el mapa no contiene ninguna entrada para el comprador determinado.

Resultado:

  • score: un valor flotante que representa el valor de puntuación para este anuncio
  • status: un valor entero que puede ser uno de los siguientes:
    • 0: para una ejecución correcta
    • 1: en caso de que customAudienceSignals no sea válido
    • 2: en caso de que AdSelectionConfig no sea válido
    • 3: en caso de que alguno de los otros indicadores no sea válido
    • Cualquier valor distinto de cero causa la falla del proceso; el valor determina el tipo de excepción que se arroja.

selectOutcome()

function selectOutcome(
  outcomes,
  selection_signals) {
    return {'status': 0, 'result': null};
}

Parámetros de entrada:

  • outcomes: Un objeto JSON {"id": id_string, "bid": bid_double}
  • selection_signals: Objetos JSON especificados en el objeto de configuración de la subasta

Resultado:

  • status: 0 para la ejecución correcta y un valor distinto de cero para las fallas
  • result: Uno de los resultados pasados o nulos

reportResult()

function reportResult(ad_selection_config, render_url, bid, contextual_signals) {
   return {
      'status': status,
      'results': {'signals_for_buyer': signals_for_buyer, 'reporting_url': reporting_url }
   };
}

Parámetros de entrada:

  • ad_selection_config: consulta la documentación de scoreAds
  • render_url: la URL de renderización del anuncio ganador
  • bid: la oferta que se ofrece para el anuncio ganador
  • contextual_signals: consulta la documentación de generateBid

Resultado:

  • status: 0 para la ejecución correcta y un valor distinto de cero para las fallas
  • results: un objeto JSON que contiene lo siguiente:
    • signals_for_buyer: Un objeto JSON que se pasa a la función reportWin
    • reporting_url: Una URL que usa la plataforma para notificar la impresión al comprador

reportWin()

function reportWin(
   ad_selection_signals,
   per_buyer_signals,
   signals_for_buyer,
   contextual_signals,
   custom_audience_signals) {
   return {'status': 0, 'results': {'reporting_url': reporting_url } };
}

Parámetros de entrada:

  • ad_selection_signals, per_buyer_signals: Consulta la documentación sobre scoreAd
  • signals_for_buyer: un objeto JSON que muestra reportResult
  • contextual_signals, custom_audience_signals: consulta la documentación de generateBid

Salida:

  • status: 0 para la ejecución correcta y un valor distinto de cero para las fallas
  • results: Un objeto JSON que contiene lo siguiente:
    • reporting_url: Una URL que usa la plataforma para notificar la impresión al vendedor

registerAdBeacon()

function registerAdBeacon(
  interaction_key,
  reporting_uri
)

Parámetros de entrada:

  • interaction_key: Es una cadena que representa el evento. La plataforma la usará más adelante cuando informe las interacciones de eventos para buscar el reporting_uri que debe notificarse. Esta clave debe coincidir con lo que informa el vendedor y lo que registra el comprador o vendedor.
  • reporting_uri: Es un URI para recibir informes de eventos. Debe ser específico para el tipo de evento que se informa. Debe aceptar una solicitud POST para controlar cualquier dato informado junto con el evento.

URIs precompilados de selección de anuncios

Los URI precompilados permiten que las tecnologías publicitarias asignen funciones de JavaScript para la lógica de decisión de selección de anuncios en las clases AdSelectionConfig y AdSelectionFromOutcomesConfig. Los URIs precompilados no requieren llamadas de red para descargar el JavaScript correspondiente. Las tecnologías publicitarias pueden usar URIs precompilados sin tener que configurar un dominio inscrito para alojar JavaScript.

Un URI precompilado se construye con el siguiente formato:

ad-selection-prebuilt:<use-case>/<name>?<required-script-generation-parameters>

La plataforma de Privacy Sandbox proporciona JavaScript con la información de este URI en el entorno de ejecución.

Se arroja IllegalArgumentException en los siguientes casos:

  • Alguno de los parámetros obligatorios no está presente en el URI
  • Hay parámetros no reconocidos en el URI

Casos de uso y nombres de URIs precompilados admitidos

Caso de uso 1: Selección de anuncios

Los URIs precompilados en el caso de uso de ad-selection son compatibles con el flujo selectAds(AdSelectionConfig).

Nombre del URI precompilado: highest-bid-wins

Este URI precompilado proporciona un JavaScript que selecciona el anuncio con la oferta más alta después de la oferta. También proporciona una función de informes básica para informar el render_uri y la bid del ganador.

Parámetros obligatorios

reportingUrl: Es la URL del informe base que se parametriza con el render_uri y la bid del anuncio ganador:

<reportingUrl>?render_uri=<renderUriOfWinnigAd>&bid=<bidOfWinningAd>

Uso

Si la URL de los informes base es https://www.ssp.com/reporting, el URI precompilado sería el siguiente:

`ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=https://www.ssp.com/reporting`

Caso de uso 2: Selección de anuncios a partir de resultados

Los URI precompilados en el caso de uso de ad-selection-from-outcomes admiten el flujo de trabajo selectAds(AdSelectionFromOutcomesConfig).

Nombre del URI precompilado: waterfall-mediation-truncation

El URI precompilado waterfall-mediation-truncation proporciona JavaScript que implementa la lógica de truncamiento de la mediación en cascada en la que JavaScript muestra un anuncio propio si la bid es mayor o igual que el bid floor, y muestra null de no ser así.

Parámetros obligatorios

bidFloor: Es la clave del valor mínimo de la oferta que se pasa en la getSelectionSignals() que se compara con el anuncio del SDK de mediación.

Uso

Si los indicadores de selección de anuncios se ven como {"bid_floor": 10}, el URI precompilado sería el siguiente:

`ad-selection-prebuilt://ad-selection-from-outcomes/waterfall-mediation-truncation/?bidFloor=bid_floor`

Prueba

Para ayudarte a comenzar con la API de Protected Audience, creamos apps de ejemplo en Kotlin y Java, que se encuentran en GitHub.

Requisitos previos

La API de Protected Audience requiere JavaScript durante la selección de anuncios y los informes de impresiones. Hay dos métodos para proporcionar este JavaScript en un entorno de pruebas:

  • Ejecuta un servidor con los extremos HTTPS requeridos que muestra el código JavaScript.
  • Para anular la recuperación remota, proporciona el código necesario de una fuente local.

Cualquiera de los dos métodos requiere la configuración de un extremo HTTPS para administrar los informes de impresiones.

Extremos HTTPS

Para probar la selección de anuncios y los informes de impresiones, deberás configurar 7 extremos HTTPS a los que puede acceder tu dispositivo de prueba o emulador:

  1. Extremo del comprador que publica la lógica de ofertas de JavaScript
  2. Un extremo que publica los indicadores de ofertas
  3. Extremo del vendedor que publica la lógica de decisión de JavaScript
  4. Un extremo que muestra indicadores de puntuación
  5. Extremo de los informes de impresiones del comprador que ganó
  6. Extremo de los informes de impresiones del vendedor
  7. Un extremo que publica las actualizaciones diarias de un público personalizado

Para mayor comodidad, el repositorio de GitHub brinda código básico de JavaScript con fines de prueba. También incluye definiciones del servicio de OpenAPI, que se pueden implementar en una plataforma simulada o de microservicios compatible. Para obtener más detalles, consulta el archivo readme del proyecto.

Cómo anular la recuperación remota de JavaScript

Esta función está diseñada para usarse en pruebas de extremo a extremo. Para anular la recuperación remota, tu app debe ejecutarse en modo de depuración con las opciones para desarrolladores habilitadas.

Para habilitar el modo de depuración en tu aplicación, agrega la siguiente línea al atributo de la aplicación en tu AndroidManifest.xml:

<application
  android:debuggable="true">

Para ver un ejemplo de cómo usar estas anulaciones, consulta la app de ejemplo de la API de Protected Audience en GitHub.

Debes agregar tu propio JavaScript personalizado para controlar las rutinas de selección de anuncios, como las ofertas, las decisiones de puntuación y los informes. Puedes encontrar ejemplos básicos de código JavaScript que manejan todas las solicitudes necesarias en el repositorio de GitHub. La aplicación de ejemplo de la API de Protected Audience demuestra cómo leer el código de ese archivo y prepararlo para usarlo como anulación.

Es posible anular de forma independiente la recuperación de JavaScript orientada a la compra y la venta, aunque necesitarás un extremo HTTPS para publicar cualquier JavaScript para el que no brindes anulaciones. Consulta el archivo README para obtener información sobre cómo configurar un servidor que controle estos casos.

Solo tu paquete puede anular la recuperación de JavaScript para públicos personalizados de tu propiedad.

Cómo anular JavaScript orientado a la venta

Para configurar una anulación de JavaScript orientado a la venta, haz lo siguiente como se muestra en el siguiente ejemplo de código:

  1. Inicializa un objeto AdSelectionManager.
  2. Obtén una referencia a TestAdSelectionManager desde el objeto AdSelectionManager.
  3. Compila un objeto AdSelectionConfig.
  4. Compila una AddAdSelectionOverrideRequest con el objeto AdSelectionConfig y una String que represente el JavaScript que quieres usar como anulación.
  5. Llama al método asíncrono overrideAdSelectionConfigRemoteInfo() con el objeto AddAdSelectionOverrideRequest y los objetos Executor y OutcomeReceiver relevantes.

Kotlin

val testAdSelectionManager: TestAdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java).getTestAdSelectionManager()

// Initialize AdSelectionConfig =
val adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build()

// Initialize AddAddSelectionOverrideRequest
val request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build()

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver)

Java

TestAdSelectionManager testAdSelectionManager =
  context.getSystemService(AdSelectionManager.class).getTestAdSelectionManager();

// Initialize AdSelectionConfig =
AdSelectionConfig adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build();

// Initialize AddAddSelectionOverrideRequest
AddAdSelectionOverrideRequest request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build();

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver);

Consulta la sección Ejecuta la selección de anuncios para obtener más información sobre lo que representa cada uno de los campos en AdSelectionConfig. La diferencia clave es que decisionLogicUrl se puede establecer como un valor de marcador de posición, ya que se ignorará.

Para anular el código JavaScript que se usa durante la selección de anuncios, decisionLogicJs debe contener las firmas de funciones adecuadas del lado del vendedor. Para ver un ejemplo de cómo leer un archivo JavaScript como una cadena, consulta la app de ejemplo de la API de Protected Audience en GitHub.

El método overrideAdSelectionConfigRemoteInfo() asíncrono usa el objeto OutcomeReceiver para indicar el resultado de la llamada a la API.

La devolución de llamada onResult() significa que la anulación se aplicó correctamente. Las llamadas futuras a selectAds() usarán la lógica de decisión y de informe que hayas pasado como anulación.

La devolución de llamada onError() indica dos condiciones posibles:

  • Si se intenta realizar la anulación con argumentos no válidos, AdServiceException indicará IllegalArgumentException como la causa.
  • Si la anulación se intenta con una app que no se ejecuta en el modo de depuración con las opciones para desarrolladores habilitadas, AdServiceException indicará IllegalStateException como la causa.

Cómo restablecer anulaciones orientadas a la venta

En esta sección, se da por sentado que anulaste el código JavaScript orientado a la venta y que tienes una referencia a los elementos TestAdSelectionManager y AdSelectionConfig que se usaron en la sección anterior.

Para restablecer las anulaciones para todos los elementos AdSelectionConfigs, sigue estos pasos:

  1. Llama al método resetAllAdSelectionConfigRemoteOverrides() asíncrono con el objeto OutcomeReceiver relevante.

Kotlin

// Resets overrides for all AdSelectionConfigs
testAadSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
  outComeReceiver)

Java

// Resets overrides for all AdSelectionConfigs
testAdSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
    outComeReceiver);

Después de restablecer las anulaciones orientadas a la venta, las llamadas a selectAds() usan cualquier decisionLogicUrl almacenada en AdSelectionConfig para intentar recuperar el JavaScript necesario.

Si la llamada a resetAllAdSelectionConfigRemoteOverrides() falla, la devolución de llamada OutComeReceiver.onError() proporciona una AdServiceException. Si se intentan quitar las anulaciones con una app que no se ejecuta en el modo de depuración con las opciones para desarrolladores habilitadas, AdServiceException indicará IllegalStateException como la causa.

Cómo anular JavaScript orientado a la compra

  1. Sigue los pasos para unirte a un público personalizado.
  2. Compila una AddCustomAudienceOverrideRequest con el comprador y nombre del público personalizado que deseas anular, además de la lógica de ofertas y los datos que deseas usar como anulación.
  3. Llama al método asíncrono overrideCustomAudienceRemoteInfo() con el objeto AddCustomAudienceOverrideRequest y los objetos Executor y OutcomeReceiver relevantes.

Kotlin

val testCustomAudienceManager: TestCustomAudienceManager =
  context.getSystemService(CustomAudienceManager::class.java).getTestCustomAudienceManager()

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
val request = AddCustomAudienceOverrideRequest.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setBiddingLogicJs(biddingLogicJS)
    .setTrustedBiddingSignals(trustedBiddingSignals)
    .build()

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver)

Java

TestCustomAudienceManager testCustomAudienceManager =
  context.getSystemService(CustomAudienceManager.class).getTestCustomAudienceManager();

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
AddCustomAudienceOverrideRequest request =
    AddCustomAudienceOverrideRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .setBiddingLogicJs(biddingLogicJS)
        .setTrustedBiddingSignals(trustedBiddingSignals)
        .build();

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver);

Los valores para comprador y nombre son los mismos que se usan para crear el público personalizado. Más información sobre estos campos.

También puedes especificar dos parámetros adicionales:

  • biddingLogicJs: JavaScript que contiene la lógica del comprador que se usa durante la selección de anuncios. Consulta las firmas de las funciones necesarias en JavaScript.
  • trustedBiddingSignals: Indicadores de ofertas que se usarán durante la selección de anuncios. Para fines de prueba, puede ser una cadena vacía.

El método overrideCustomAudienceRemoteInfo() asíncrono usa el objeto OutcomeReceiver para indicar el resultado de la llamada a la API.

La devolución de llamada onResult() significa que la anulación se aplicó correctamente. Las llamadas posteriores a selectAds() usan la lógica de informes y ofertas que hayas pasado como anulación.

La devolución de llamada onError() indica dos condiciones posibles.

  • Si se intenta realizar la anulación con argumentos no válidos, AdServiceException indicará IllegalArgumentException como la causa.
  • Si la anulación se intenta con una app que no se ejecuta en el modo de depuración con las opciones para desarrolladores habilitadas, AdServiceException indicará IllegalStateException como la causa.

Cómo restablecer anulaciones orientadas a la compra

En esta sección, se da por sentado que anulaste el código JavaScript orientado a la compra y que tienes una referencia a TestCustomAudienceManager que se usó en la sección anterior.

Para restablecer las anulaciones para todos los públicos personalizados, sigue estos pasos:

  1. Llama al método resetAllCustomAudienceOverrides() asíncrono con objetos Executor y OutcomeReceiver relevantes.

Kotlin

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

Java

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

Después de restablecer las anulaciones orientadas a la compra, las llamadas posteriores a selectAds() usarán la biddingLogicUrl y los trustedBiddingData que estén almacenados en CustomAudience para intentar recuperar el código JavaScript necesario.

Si la llamada a resetCustomAudienceRemoteInfoOverride() falla, la devolución de llamada OutComeReceiver.onError() proporciona una AdServiceException. Si se intentan quitar las anulaciones con una app que no se ejecuta en el modo de depuración con las opciones para desarrolladores habilitadas, AdServiceException indicará IllegalStateException como la causa.

Cómo configurar un servidor de informes

Cuando uses anulaciones de recuperación remota, deberás configurar un servidor al que pueda acceder tu dispositivo o emulador para responder a los eventos de informes. Un extremo simple que muestra 200 es suficiente para realizar pruebas. El repositorio de GitHub incluye definiciones del servicio de OpenAPI, que se pueden implementar en una plataforma simulada o de microservicios compatible. Para obtener más detalles, consulta el archivo readme del proyecto.

Cuando busques las definiciones de OpenAPI, busca el reporting-server.json. Este archivo contiene un extremo simple que muestra 200, que representa un código de respuesta HTTP. Este extremo se usa durante selectAds() y le indica a la API de Protected Audience que los informes de impresiones se completaron correctamente.

Funcionalidad para realizar pruebas

  • Prueba unirte a un público personalizado, abandonarlo y configurarlo, según las acciones del usuario anterior.
  • Prueba iniciar la selección de anuncios en el dispositivo a través de JavaScript alojados de manera remota.
  • Observa cómo la asociación de una app con la configuración de un público personalizado puede afectar los resultados de la selección de anuncios.
  • Prueba los informes de impresiones después de la selección de anuncios.

Limitaciones

En la siguiente tabla, se enumeran las limitaciones para el procesamiento de la API de Protected Audience. Los límites que se detallan pueden estar sujetos a cambios en función de los comentarios. Para conocer las funciones en progreso, lee las notas de la versión.

Componente Descripción del límite Valor del límite
Público personalizado (PP) Cantidad máxima de anuncios por PP 100
Cantidad máxima de PP por aplicación 1000
Cantidad máxima de apps que pueden crear un PP 1000
Retraso máximo en el tiempo de activación de un PP desde el momento de su creación 60 días
Tiempo de caducidad máximo de un PP a partir de su hora de activación 60 días
Cantidad máxima de PP en el dispositivo 4,000
Tamaño máximo del nombre de PP 200 bytes
Tamaño máximo del URI de recuperación diario 400 bytes
Tamaño máximo del URI de lógica de ofertas 400 bytes
Tamaño máximo de los datos de ofertas confiables 10 KB
Tamaño máximo de los indicadores de ofertas del usuario 10 KB
Tasa máxima de llamadas para leaveCustomAudience por comprador 1 por segundo
Tasa máxima de llamadas para joinCustomAudience por comprador 1 por segundo
Recuperación en segundo plano de AC Tiempo de espera de la conexión 5 segundos
Tiempo de espera de lectura de HTTP 30 segundos
Tamaño máximo total de descarga 10 KB
Duración máxima de una iteración de recuperación 5 minutos
Cantidad máxima de PP actualizados por trabajo 1000
Selección de anuncios Cantidad máxima de compradores Por definir
Cantidad máxima de PP por comprador Por definir
Cantidad máxima de anuncios en una subasta Por definir
Tiempo de espera de conexión inicial 5 segundos
Tiempo de espera de lectura de la conexión 5 segundos
Tiempo máximo de ejecución de AdSelection 10 segundos
Tiempo máximo de ejecución de ofertas por PP en AdSelection 5 segundos
Tiempo máximo de ejecución para la puntuación en AdSelection 5 segundos
Tiempo máximo de ejecución por comprador en AdSelection Por definir
Tamaño máximo de la selección de anuncios/vendedor/indicadores por comprador Por definir
Tamaño máximo de las secuencias de comandos del vendedor o comprador Por definir
Tarifa de llamada máxima para selectAds 1 QPS
Informes de impresiones Tiempo mínimo antes de quitar la selección de anuncios de la persistencia 24 h
Cantidad máxima de selecciones de anuncios de almacenamiento Por definir
Tamaño máximo de la URL de salida de los informes Por definir
Tiempo máximo para los informes de impresiones Por definir
Cantidad máxima de reintentos para llamadas de notificación Por definir
Tiempo de espera de la conexión 5 segundos
Tiempo máximo de ejecución general de reportImpression 2 segundos
Tarifa de llamada máxima para reportImpressions 1 QPS
Informes de eventos Cantidad máxima de píxeles contadores por comprador por subasta 10

Cantidad máxima de píxeles contadores por vendedor por subasta

10

Tamaño máximo de la clave del evento

40 bytes

Tamaño máximo de los datos de eventos

64 KB

Anuncios Tamaño máximo de la lista de anuncios 10 KB compartidos por todos los AdData en un solo AC para los anuncios contextuales
URLs Longitud máxima de cualquier cadena de URL tomada como entrada Por definir
JavaScript Tiempo máximo de ejecución 1 segundo para las ofertas y la puntuación para los informes de impresiones
Cantidad máxima de memoria usada 10 MB

Informa errores y problemas

Tus comentarios son una parte fundamental de Privacy Sandbox en Android. Avísanos si tienes problemas o ideas para mejorar Privacy Sandbox en Android.