Um público-alvo personalizado representa um grupo de usuários com intenções ou interesses em comum conforme decidido por um app de anunciante. Um app ou SDK pode usar um público-alvo personalizado para indicar um público específico, como alguém que deixou itens no carrinho de compras.
A API Protected Audience do Android pode ser usada para entrar e sair de públicos-alvo personalizados no dispositivo de um usuário. Ao criar e associar um público-alvo personalizado, você pode delegar a um servidor de onde vai buscar algumas ou todas as propriedades do público-alvo personalizado ou especificar essas informações ao chamar a API diretamente.
Públicos-alvo personalizados
A combinação dos parâmetros abaixo identifica cada objeto
CustomAudience
de forma exclusiva em um dispositivo:
owner
: nome do pacote do app do proprietário, definido implicitamente como o nome do pacote do app autor da chamada.buyer
: identificador da rede de publicidade do comprador, que gerencia anúncios para o público-alvo personalizado.name
: um nome ou identificador arbitrário para o público-alvo personalizado.
Além disso, o CustomAudience
precisa ser criado com estes parâmetros
necessários:
- URL de atualização diária: um URL HTTPS consultado diariamente em segundo plano para atualizar os indicadores de lances do usuário de um público-alvo personalizado e os dados de lances confiáveis, além de renderizar URLs e metadados de anúncios.
- URL de lógica de lances: um URL HTTPS consultado durante a seleção de anúncios para buscar a lógica de lances JavaScript de um comprador. Confira as assinaturas de função necessárias no JavaScript.
- IDs de renderização do anúncio: um ID arbitrário definido pela adtech do comprador. Essa é uma otimização para gerar o payload de lances e leilões (link em inglês).
Os parâmetros opcionais de um objeto CustomAudience
podem incluir:
- Momento de ativação: um público-alvo personalizado só pode participar da seleção de anúncios e das atualizações diárias após o momento da ativação. Isso pode ser útil para engajar usuários que não interagem mais com um app, por exemplo.
- Prazo de validade: uma data futura para remoção do público personalizado do dispositivo.
- Indicadores de lances do usuário: uma string JSON com indicadores do usuário, como localidade preferida, que o JavaScript da lógica de lances do comprador vai consumir para gerar lances durante o processo de seleção de anúncios. Esse formato permite que plataformas de adtech reutilizem o código em várias plataformas e facilita o consumo em funções JavaScript.
- Dados de lances confiáveis: um URL HTTPS e uma lista de strings usadas durante o processo de seleção de anúncios para buscar indicadores de lances de um serviço de chave-valor confiável.
- Anúncios: uma lista de objetos
AdData
correspondentes aos anúncios que participam da seleção. Cada objetoAdData
consiste em:- URL de renderização: um URL HTTPS que é consultado para renderizar o anúncio final.
- Metadados: um objeto JSON serializado como uma string que contém informações que vão ser consumidas pela lógica de lances do comprador durante o processo de seleção de anúncios.
- Filtros de anúncios: uma classe que contém todas as informações necessárias para a filtragem de anúncios de instalação de apps e o limite de frequência durante a seleção de anúncios.
Buscar e aderir a um público-alvo personalizado
A API fetchAndJoinCustomAudience
permite que os compradores deleguem a participação em um público-alvo
personalizado aproveitando a presença no dispositivo de MMPs ou SSPs parceiros.
Para que isso funcione, o autor da chamada no dispositivo (seja um SDK de MMP ou SSP)
cria um fetchAndJoinCustomAudienceRequest
semelhante a este:
Kotlin
/**
* @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()
Java
/**
* @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();
Uma observação importante sobre todos os parâmetros opcionais é que, se eles forem definidos dentro da solicitação de busca, os dados não poderão ser substituídos pelo que for retornado do comprador, proporcionando ao autor da chamada no dispositivo mais controles sobre qual público-alvo personalizado é mantido.
O fetchUri
precisa apontar para um endpoint do servidor operado pelo comprador,
que vai retornar um objeto JSON de público-alvo personalizado que corresponda ao formato mostrado
aqui:
//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
}
}
]
}
Mais informações sobre como isso é resolvido no lado da API podem ser encontradas na Proposta de design para a delegação de ACs.
Testes
Depois de implementar a chamada de busca no código do cliente e configurar um endpoint no lado da DSP para retornar os dados de público-alvo personalizado, é possível testar a delegação de participação em um público-alvo personalizado. Antes de executar o app, você precisa executar os comandos na página Configuração de teste. Depois de executar esses comandos, você poderá começar a fazer chamadas usando a API Fetch.
Para conferir um exemplo desse fluxo, as chamadas de busca foram adicionadas ao repositório de exemplos do Sandbox de privacidade no GitHub (link em inglês).
Participar de um público-alvo personalizado diretamente
Se você já tiver todas as informações necessárias para criar e participar de um público-alvo personalizado, faça isso diretamente usando uma chamada assíncrona da API Protected Audience. Para criar ou participar de um público-alvo personalizado diretamente, faça o seguinte:
- Inicialize o objeto
CustomAudienceManager
. - Crie um objeto
CustomAudience
especificando parâmetros importantes, por exemplo, o pacote do comprador e um nome relevante. Em seguida, inicialize o objetoJoinCustomAudienceRequest
com o objetoCustomAudience
. - Chame o método
joinCustomAudience()
assíncrono com o objetoJoinCustomAudienceRequest
e os objetosExecutor
eOutcomeReceiver
relevantes.
Kotlin
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)
Java
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);
Processar resultados de joinCustomAudience()
O método joinCustomAudience()
assíncrono usa o objeto
OutcomeReceiver
para informar o resultado da chamada de API.
- O callback
onResult()
indica que o público-alvo personalizado foi criado ou atualizado. - O callback
onError()
indica duas condições possíveis.- Se a
JoinCustomAudienceRequest
for inicializada com argumentos inválidos, aAdServicesException
vai indicar umaIllegalArgumentException
como causa. - Todos os outros erros vão receber uma
AdServicesException
com umaIllegalStateException
como causa.
- Se a
Confira um exemplo de como processar o 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);
}
};
Sair de um público-alvo personalizado
Se o usuário não atender mais aos critérios comerciais de um determinado público-alvo
personalizado, um app ou SDK vai poder chamar leaveCustomAudience()
para remover o público-alvo
do dispositivo. Para remover um CustomAudience
com base nos parâmetros
exclusivos, siga estas etapas:
- Inicialize o objeto
CustomAudienceManager
. - Inicialize a
LeaveCustomAudienceRequest
com os elementosbuyer
ename
do público-alvo personalizado. Para saber mais sobre esses campos de entrada, consulte Aderir diretamente a um público-alvo personalizado. - Chame o método assíncrono
leaveCustomAudience()
com o objetoLeaveCustomAudienceRequest
e os objetosExecutor
eOutcomeReceiver
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);
O OutcomeReceiver
informa o final de uma chamada de API de maneira semelhante
à chamada do método joinCustomAudience()
. Para proteger a privacidade, um resultado de erro não faz
distinção entre erros internos e argumentos inválidos. O callback onResult()
é chamado quando a chamada de API é concluída, independente de um público-alvo personalizado
correspondente ser removido ou não.