Definir dados de público-alvo

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 objeto AdData 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:

  1. Inicialize o objeto CustomAudienceManager.
  2. Crie um objeto CustomAudience especificando parâmetros importantes, por exemplo, o pacote do comprador e um nome relevante. Em seguida, inicialize o objeto JoinCustomAudienceRequest com o objeto CustomAudience.
  3. Chame o método joinCustomAudience() assíncrono com o objeto JoinCustomAudienceRequest e os objetos Executor e OutcomeReceiver 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.

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:

  1. Inicialize o objeto CustomAudienceManager.
  2. Inicialize a LeaveCustomAudienceRequest com os elementos buyer e name do público-alvo personalizado. Para saber mais sobre esses campos de entrada, consulte Aderir diretamente a um público-alvo personalizado.
  3. Chame o método assíncrono leaveCustomAudience() com o objeto LeaveCustomAudienceRequest e os objetos Executor e 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);

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.