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.
La API de Protected Audience de Android se puede usar para unirse a públicos personalizados y salir de ellos en el dispositivo de un usuario. Cuando creas y te unes a un público personalizado, puedes delegar a un servidor desde el que recuperarás algunas o todas las propiedades del público personalizado, o bien puedes especificar esta información cuando llames a la API directamente.
Públicos personalizados
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.
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 objetoAdData
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.
Recupera y únete a un público personalizado
La API de fetchAndJoinCustomAudience
permite que los compradores deleguen unirse a un público personalizado aprovechando la presencia en el dispositivo de sus MMP o SSP de socios.
Para que esto funcione, el llamador integrado en el dispositivo (ya sea un MMP o un SDK de la SSP) crea un objeto fetchAndJoinCustomAudienceRequest
que se ve de la siguiente manera:
/**
* @param fetchUri The URL to retrieve the CA from.
* (optional)@param name The name of the CA to join.
* (optional)@param activationTime The time when the CA will activate.
* (optional)@param expirationTime The time when the CA will expire,
must be a time in the future otherwise this will fail
* (optional)@param userBiddingSignals The user bidding signals used at auction.
*/
val request = FetchAndJoinCustomAudienceRequest.Builder(fetchUri)
.setName(name)
.setActivationTime(activationTime)
.setExpirationTime(expirationTime)
.setUserBiddingSignals(userBiddingSignals)
.build()
/**
* @param fetchUri The URL to retrieve the CA from.
* (optional)@param name The name of the CA to join.
* (optional)@param activationTime The time when the CA will activate.
* (optional)@param expirationTime The time when the CA will expire,
must be a time in the future otherwise this will fail
* (optional)@param userBiddingSignals The user bidding signals used at auction.
*/
FetchAndJoinCustomAudienceRequest request =
new FetchAndJoinCustomAudienceRequest.Builder(fetchUri)
.setName(name) //Optional
.setActivationTime(activationTime) //Optional
.setExpirationTime(expirationTime) //Optional
.setUserBiddingSignals(userBiddingSignals) //Optional
.build();
Nota importante sobre todos los parámetros opcionales: Si se establecen dentro de la solicitud de recuperación, sus datos no se pueden anular con lo que muestra el comprador, lo que le brinda al llamador integrado en el dispositivo controles adicionales sobre lo que qué público personalizado se conserva.
El elemento fetchUri
debe apuntar a un extremo del servidor que opere el comprador, que mostrará un objeto JSON del público personalizado que coincida con el siguiente formato:
//Return a 200 response with data matching the format of the following in the body
{
"daily_update_uri": "https://js.example.com/bidding/daily",
"bidding_logic_uri": "https://js.example.com/bidding",
"user_bidding_signals": {
"valid": true,
"arbitrary": "yes"
},
"trusted_bidding_data": {
"trusted_bidding_uri": "https://js.example.com/bidding/trusted",
"trusted_bidding_keys": [
"key1",
"key2"
]
},
"ads": [
{
"render_uri": "https://js.example.com/render/fetch_and_join_ad1",
"metadata": {
"valid": 1
}
},
{
"render_uri": "https://js.example.com/render/fetch_and_join_ad2",
"metadata": {
"valid": 2
}
}
]
}
Puedes encontrar más información sobre cómo es resuelto por la API, en la propuesta de diseño para delegar la unión a un público personalizado.
Pruebas
Una vez que hayas implementado la llamada de recuperación dentro del código del cliente y hayas configurado un extremo en el DSP para mostrar los datos del público personalizado, puedes probar la delegación de la unión a un público personalizado. Antes de ejecutar la app, deberás ejecutar los comandos de la página Configuración de pruebas. Una vez que ejecutes estos comandos, deberías poder comenzar a realizar, de forma correcta, llamadas con la API de Fetch.
Para ver un ejemplo de este flujo, se agregaron las llamadas de recuperación al repositorio de muestras de Privacy Sandbox en GitHub.
Cómo unirse a un público personalizado directamente
Si ya tienes toda la información que necesitas para crear un público personalizado y unirte a él, puedes hacerlo directamente con una llamada asíncrona a la API de Protected Audience. Para crear un público personalizado o unirte a uno directamente, haz lo siguiente:
- Inicializa el objeto
CustomAudienceManager
. - Especifica parámetros clave, como el paquete del comprador y un nombre relevante, para crear un objeto
CustomAudience
. Luego, inicializa el objetoJoinCustomAudienceRequest
con el objetoCustomAudience
. - Llama a
joinCustomAudience()
asíncrono con el objetoJoinCustomAudienceRequest
y los objetosExecutor
yOutcomeReceiver
relevantes.
val customAudienceManager: CustomAudienceManager =
context.getSystemService(CustomAudienceManager::class.java)
// Minimal initialization of a CustomAudience object
val audience: 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()
// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()
// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
executor,
outcomeReceiver)
CustomAudienceManager customAudienceManager =
context.getSystemService(CustomAudienceManager.class);
// Minimal initialization of a CustomAudience object
CustomAudience audience = 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();
// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();
// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
executor,
outcomeReceiver);
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.- Si
JoinCustomAudienceRequest
se inicializa con argumentos no válidos,AdServicesException
indicaIllegalArgumentException
como la causa. - Todos los demás errores recibirán
AdServicesException
conIllegalStateException
como la causa.
- Si
Este es un ejemplo de control del resultado de joinCustomAudience()
:
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)
}
};
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:
- Inicializa el objeto
CustomAudienceManager
. - Inicializa
LeaveCustomAudienceRequest
conbuyer
yname
del público personalizado. Para obtener más información sobre estos campos de entrada, consulta "Únete directamente a un público personalizado". - Llama al método asíncrono
leaveCustomAudience()
con el objetoLeaveCustomAudienceRequest
y los objetosExecutor
yOutcomeReceiver
relevantes.
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)
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.