Guida per gli sviluppatori degli indicatori di app protetti

ad techproject_path: /_project.yaml book_path: /_book.yaml keywords: api:ProtectedAppSignals, docType:Guide, skill:Beginner, audienceAdBuyer, audienceAdSeller, topicAdAuction, contentTypeFundamental, category:Mobile, apiGroupAds

Per aiutare gli sviluppatori a iniziare a sperimentare l'API Protected App Signals, questo documento descrive tutte le API all'interno della superficie API, spiega come configurare un ambiente di test e fornisce esempi di configurazione e script.

Cronologia delle versioni

Gennaio 2024

Prima release della guida per sviluppatori che supporta la release MVP di PAS

Marzo 2024

Modifiche all'API per supportare la release M-2024-05 dell'API Android e la release di aprile 2024 dei componenti lato server. Modifiche più importanti:

  • Sono stati aggiunti dettagli sulle autorizzazioni richieste per l'API on-device
  • Sono stati aggiunti dettagli sulla gestione della quota degli indicatori sul dispositivo
  • Firma generateBid aggiornata con modifiche relative al recupero di annunci contestuali e al supporto dell'uscita
  • Documentazione reportWin aggiornata, incluso il supporto dell'uscita
  • Aggiorna la documentazione dell'API Ad Retrieval rimuovendo il supporto del recupero di annunci BYOS e documentando la UDF di recupero di annunci

Panoramica dell'API

La superficie dell'API Protected Signals include diversi sottoinsiemi di API su sistemi diversi:

  • API Android:
    • API Signal Curation, composta da:
    • API Update Signals
    • API Signals Encoding
    • API Protected Auction Support: da utilizzare dagli SDK per eseguire l'asta protetta sui server Bidding and Auction (B&A) utilizzando Protected App Signals.
  • API lato server:
    • API Protected Auction: una serie di script JS in esecuzione nei server di offerte e aste. Questa API consente a venditori e acquirenti di scrivere la logica per implementare l'asta protetta.
    • API Ad Retrieval: responsabile della fornitura di un elenco di annunci candidati in base alle informazioni contestuali e sugli utenti rese disponibili al server di offerta dell'acquirente.

Client Android

Sul lato client, la superficie Protected App Signals è costituita da tre API diverse:

  • Update Signals: un'API di sistema Android per consentire la cura dei segnali sul dispositivo.
  • Codifica degli indicatori: un'API JavaScript per preparare gli indicatori da inviare al server durante l'asta.
  • Supporto dell'asta protetta: un'API per supportare l'esecuzione di un'asta protetta sui server di offerta e asta. Questa API non è specifica per Protected App Signals e viene utilizzata anche per supportare le aste per l'API Protected Audience.

API Update Signals

L'API Update Signals consente alle tecnologie pubblicitarie di registrare indicatori relativi a utenti e app per conto di un acquirente. L'API funziona con un modello di delega. Il chiamante fornisce un URI da cui il framework recupera gli indicatori corrispondenti e la logica per codificare questi indicatori da utilizzare nell'asta.

L'API richiede l'autorizzazione android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS.

L'API updateSignals() recupererà un oggetto JSON dall'URI che descrive quali indicatori aggiungere o rimuovere e come prepararli per l'asta.

Executor executor = Executors.newCachedThreadPool();
ProtectedSignalsManager protectedSignalsManager
     =  ProtectedSignalsManager.get(context);

// Initialize a UpdateSignalsRequest
UpdateSignalsRequest updateSignalsRequest = new
  UpdateSignalsRequest.Builder(Uri.parse("https://example-adtech1.com/signals"))
      .build();

OutcomeReceiver<Object, Exception> outcomeReceiver = new OutcomeReceiver<Object, Exception>() {
  @Override
  public void onResult(Object o) {
    //Post-success actions
  }

  @Override
  public void onError(Exception error) {
    //Post-failure actions
  };

// Call updateSignals
protectedSignalsManager.updateSignals(updateSignalsRequest,
    executor,
    outcomeReceiver);

La piattaforma effettua una richiesta https all'URI fornito nella richiesta per recuperare gli aggiornamenti dei segnali. Oltre agli aggiornamenti dei segnali, la risposta può includere un endpoint che ospita la logica di codifica per convertire i segnali non elaborati in payload codificato. Gli aggiornamenti dei segnali devono essere in formato JSON e possono avere le seguenti chiavi:

Le chiavi di primo livello per l'oggetto JSON devono corrispondere a uno dei cinque comandi:

chiave

Descrizione

put

Aggiunge un nuovo indicatore, sovrascrivendo gli indicatori esistenti con la stessa chiave. Il valore

perché si tratta di un oggetto JSON in cui le chiavi sono stringhe Base64 corrispondenti alla chiave da inserire e i valori sono stringhe Base64 corrispondenti al valore da inserire.

append

Aggiunge uno o più nuovi indicatori a una serie temporale di indicatori, rimuovendo quelli meno recenti

segnali per fare spazio a quelli nuovi se le dimensioni della serie superano il massimo indicato. Il valore è un oggetto JSON in cui le chiavi sono stringhe base64 corrispondenti alla chiave a cui aggiungere i valori, mentre i valori sono oggetti con due campi: "values" e "maxSignals".

"values": un elenco di stringhe Base64 corrispondenti ai valori dei segnali da aggiungere alla serie temporale.

"maxSignals": il numero massimo di valori consentiti in questa serie temporale. Se non visualizzi l'icona

il numero attuale di indicatori associati alla chiave supera maxSignals, gli indicatori meno recenti verranno rimossi. Tieni presente che puoi aggiungere una chiave aggiunta da put. Tieni presente che l'aggiunta di un numero di valori superiore al massimo consentito causerà un errore.

put_if_not_present

Aggiunge un nuovo indicatore solo se non esistono indicatori con la stessa chiave. Il valore è un oggetto JSON in cui le chiavi sono stringhe Base64 corrispondenti alla chiave da inserire e i valori sono stringhe Base64 corrispondenti al valore da inserire.

remove

Rimuove il segnale per una chiave. Il valore è un elenco di stringhe Base64 corrispondenti alle chiavi degli indicatori da eliminare.

update_encoder

Fornisce un'azione per aggiornare l'endpoint e un URI che può essere utilizzato

per recuperare una logica di codifica. La sottochiave per fornire un'azione di aggiornamento è "action" e

L'unico valore supportato è "REGISTER", che registra l'endpoint del codificatore se fornito per la prima volta o sovrascrive quello esistente con l'endpoint appena fornito. La fornitura dell'endpoint è obbligatoria per l'azione "REGISTER". La sottochiave per fornire un endpoint codificatore è "endpoint" e il valore è l'URI

stringa per l'endpoint.

Una richiesta JSON di esempio avrebbe il seguente aspetto:

{
    "put": {
        "AAAAAQ==": "AAAAZQ==",
        "AAAAAg==": "AAAAZg=="
    },
    "append": {
        "AAAAAw==": {
            "values": [
                "AAAAZw=="
            ],
            "max_signals": 3
        }
    },
    "put_if_not_present": {
        "AAAABA==": "AAAAaQ==",
        "AAAABQ==": "AAAAag=="
    },
    "update_encoder": {
        "action": "REGISTER",
        "endpoint": "https://adtech1.com/Protected App Signals_encode_script.js"
    }
}

I segnali avranno una quota sul dispositivo nell'ordine di 10-15 KB. Una volta superata la quota, l'API PP eliminerà gli indicatori utilizzando una strategia FIFO. La procedura di sfratto consentirà di superare leggermente la quota per brevi intervalli di tempo per ridurre la frequenza degli sfratti.

API Signals Encoding

Gli acquirenti sono tenuti a fornire una funzione JavaScript da utilizzare per codificare i segnali memorizzati sul dispositivo da inviare al server durante l'asta protetta. Gli acquirenti possono fornire questo script aggiungendo l'URL da cui può essere recuperato utilizzando la chiave "update_encoder" in una delle risposte a una richiesta dell'API UpdateSignal. Lo script avrà la seguente firma:

function encodeSignals(signals, maxSize) {
  let result = new Uint8Array(maxSize);
  // first entry will contain the total size
  let size = 1;
  let keys = 0;
  
  for (const [key, values] of signals.entries()) {
    keys++;
    // In this encoding we only care about the first byte
    console.log("key " + keys + " is " + key)
    result[size++] = key[0];
    result[size++] = values.length;
    for(const value of values) {
      result[size++] = value.signal_value[0];
    }
  }
  result[0] = keys;
  
  return { 'status': 0, 'results': result.subarray(0, size)};
}

Il parametro signals è una mappa dalle chiavi sotto forma di UInt8Arrays di dimensione 4 a elenchi di oggetti Protected App Signals. Ogni oggetto Protected App Signals ha tre campi:

  • signal_value: un UInt8Array che rappresenta il valore del segnale.
  • creation_time: un numero che rappresenta l'ora di creazione dei segnali in secondi epoch.
  • package_name: una stringa che rappresenta il nome del pacchetto che ha creato il segnale.

Il parametro maxSize è un numero che descrive la dimensione massima consentita dell'array per l'output.

La funzione deve restituire un oggetto con due campi:

  • status: deve essere 0 se lo script è stato eseguito correttamente.
  • results: deve essere un UInt8Array di lunghezza inferiore o uguale a maxSize. Questo array verrà inviato al server durante le aste e preparato dallo script prepareDataForAdRetrieval.

La codifica fornisce alle tecnologie pubblicitarie una fase iniziale di ingegneria delle funzionalità, in cui possono eseguire trasformazioni come la compressione dei segnali non elaborati in versioni concatenate in base alla propria logica personalizzata. Tieni presente che durante un'asta protetta eseguita negli ambienti di esecuzione attendibili (TEE), la logica personalizzata della tecnologia pubblicitaria avrà accesso in lettura ai payload dei segnali generati dalla codifica. La logica personalizzata, nota come funzione definita dall'utente (UDF), in esecuzione nel TEE di B&A dell'acquirente avrà accesso in lettura agli indicatori codificati e ad altri indicatori contestuali forniti dall'app del publisher per eseguire la selezione degli annunci (recupero e offerta degli annunci).

Codifica dei segnali

Ogni ora, gli acquirenti che hanno fornito la logica di codifica con i propri indicatori registrati vedranno i propri indicatori codificati in un payload dell'asta.L'array di byte per il payload dell'asta viene salvato sul dispositivo, è criptato e verrà raccolto dai venditori nell'ambito dei dati di selezione degli annunci da includere in un'asta protetta. Per i test, puoi attivare questa codifica al di fuori della sua cadenza oraria eseguendo questo comando:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Controllo delle versioni della logica del codificatore

Quando viene effettuata una richiesta per scaricare la logica del codificatore personalizzato della tecnologia pubblicitaria, l'endpoint della tecnologia pubblicitaria può rispondere con un numero di versione nelle intestazioni della risposta. Questa versione viene salvata insieme alla logica del codificatore sul dispositivo. Quando i segnali non elaborati vengono codificati, il payload codificato viene reso persistente insieme alla versione utilizzata per la codifica. Questa versione viene inviata anche al server B&A durante un'asta protetta, in modo che le tecnologie pubblicitarie possano allineare la logica di offerta e codifica in base alla versione.

Response header for providing encoder version : X_ENCODER_VERSION

API Protected Auction Support

Sul lato dispositivo, l'esecuzione di un'asta per gli indicatori protetti delle app è uguale all'esecuzione di un'asta per i Protected Audience.

Servizi di offerte e aste

Le API lato server includono:

  • API Protected Auction: una serie di funzioni JS o UDF che acquirenti e venditori possono implementare nei componenti B&A di loro proprietà per determinare la logica di offerta e asta.
  • API Ad Retrieval: gli acquirenti possono implementare questa API implementando un endpoint REST che sarà responsabile della fornitura di un insieme di annunci candidati per l'asta Protected App Signal.

API Protected Auction

L'API Protected Auction è costituita da API JS o UDF che acquirenti e venditori possono utilizzare per implementare la logica di asta e offerta.

Funzioni definite dall'utente di tecnologia pubblicitaria dell'acquirente
funzione definita dall'utente prepareDataForAdRetrieval

Prima che i Protected App Signals possano essere utilizzati per recuperare i candidati annuncio dal servizio di recupero degli annunci TEE, gli acquirenti devono decodificare e preparare i Protected App Signals e altri dati forniti dal venditore. L'output della funzione definita dall'utente prepareDataForAdRetrieval degli acquirenti viene trasmesso al servizio di recupero degli annunci per recuperare i primi k annunci candidati per le offerte.

// Inputs
// ------
// encodedOnDeviceSignals: A Uint8Array of bytes from the device.
// encodedOnDeviceSignalsVersion: An integer representing the encoded
//   version of the signals.
// sellerAuctionSignals: Information about auction (ad format, size) derived
//                       contextually.
// contextualSignals: Additional contextual signals that could help in
//                    generating bids.
//
// Outputs
// -------
// Returns a JSON structure to be used for retrieval.
// The structure of this object is left to the ad tech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
   return {};
}
generateBid UDF

Una volta restituiti i primi k annunci candidati, questi vengono passati alla logica di offerta personalizzata dell'acquirente, generateBid UDF:

// Inputs
// ------
// ads: Data string returned by the ads retrieval service. This can include Protected App Signals
//   ads and related ads metadata.
// sellerAuctionSignals: Information about the auction (ad format, size),
//                       derived contextually
// buyerSignals: Any additional contextual information provided by the buyer
// preprocessedDataForRetrieval: This is the output of this UDF.
function generateBid(ads, sellerAuctionSignals, buyerSignals,
                    preprocessedDataForRetrieval,
                    rawSignals, rawSignalsVersion) {
    return { "ad": <ad Value Object>,
             "bid": <float>,
             "render": <render URL string>,
             'adCost': <optional float ad cost>,
             "egressPayload": <limitedEgressPayload>,
             "temporaryUnlimitedEgressPayload": <temporaryUnlimitedEgressPayload>
    };
}

L'output di questa funzione è una singola offerta per un candidato annuncio, rappresentata come un equivalente JSON di ProtectedAppSignalsAdWithBidMetadata. La funzione può anche restituire due array che verranno poi passati a reportWin per consentire l'addestramento del modello (per maggiori dettagli sull'uscita e sull'addestramento del modello, consulta la sezione sui report nella spiegazione di PAS).

Funzione definita dall'utente reportWin

Al termine di un'asta, il servizio aste genera URL di reporting per gli acquirenti e registra i beacon utilizzando la reportWin UDF (questa è la stessa funzione reportWin utilizzata per Protected Audience). Il dispositivo invierà un ping una volta che l'annuncio è stato visualizzato dal client. La firma di questo metodo è quasi identica alla versione di Protected Audience, ad eccezione di due parametri aggiuntivi egressPayload e temporaryUnlimitedEgressPayload, che vengono utilizzati per attivare l'addestramento del modello e vengono compilati con i risultati di generateBid.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
Funzioni definite dall'utente per la tecnologia pubblicitaria del venditore
scoreAd UDF

Questa UDF viene utilizzata dai venditori per selezionare quale degli annunci ricevuti dagli acquirenti vincerà l'asta.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
Funzione definita dall'utente reportResult

Questa UDF consente al venditore di (eventualmente) generare report a livello di evento con le informazioni relative all'annuncio vincente.

function reportResult(auctionConfig, reporting_metadata) {
  // ...
  registerAdBeacon({"click", clickUrl,"view", viewUrl});
  sendReportTo(reportResultUrl);
  return signalsForWinner;
}

API Ad Retrieval

Nella release MVP , il servizio di recupero degli annunci sarà un servizio gestito e ospitato dall'acquirente e il servizio di offerta recupera i candidati annuncio da questo servizio. A partire da aprile 2024, il server di recupero degli annunci deve essere eseguito in un ambiente di esecuzione attendibile (TEE) ed esporrà un'interfaccia GRPC/proto. Le società di tecnologia pubblicitaria devono configurare questo server e fornire il relativo URL nell'ambito dell'implementazione dello stack di B&A. Un'implementazione di questo servizio in esecuzione nel TEE è disponibile in GitHub di Privacy Sandbox e nel resto della documentazione. Supponiamo che questo sia il codice utilizzato nell'implementazione.

A partire da aprile 2024, le versioni di B&A supportano il recupero degli annunci con percorso contestuale. In questo caso, il server di offerta riceverà un elenco di identificatori pubblicitari inviati dal server RTB durante la parte contestuale dell'asta. Gli identificatori verranno inviati a un server TEE KV per recuperare tutte le informazioni relative agli annunci da utilizzare durante la fase di offerta (ad esempio URL di rendering dell'annuncio, metadati e incorporamenti dell'annuncio da utilizzare nella selezione top-k). Questo secondo percorso non richiede alcuna logica specifica per essere implementato, pertanto documenteremo qui solo come configurare lo scenario d'uso del recupero degli annunci basato su TEE.

Funzione definita dall'utente getCandidateAds
function getCandidateAds(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals, contextualAdIds,) {
    return adsMetadataString;
}

Dove:

  • requestMetadata: JSON. Metadati del server per richiesta alla UDF. Per il momento è vuoto.
  • preparedDataForAdRetrieval: il contenuto di questo campo dipende dalla strategia di recupero degli annunci. In caso di recupero di annunci contestuali, questo parametro conterrà i segnali non elaborati provenienti dal dispositivo e trasmessi dal servizio di offerta. In caso di recupero di annunci TEE tramite il server di recupero degli annunci, questo parametro conterrà il risultato della UDF prepareDataForAdRetrieval. Nota: in questa fase, Protected App Signals verrà decodificato e decriptato.
  • deviceMetadata: oggetto JSON contenente i metadati del dispositivo inoltrati dal servizio di pubblicazione di annunci del venditore. Per ulteriori dettagli, consulta la documentazione di B&A.
    • X-Accept-Language: la lingua utilizzata sul dispositivo.
    • X-User-Agent: User agent utilizzato sul dispositivo.
    • X-BnA-Client-IP: indirizzo IP del dispositivo.
  • contextualSignals: stringa arbitraria generata dal server di offerta contestuale gestito dalla stessa DSP. Si prevede che la funzione definita dall'utente sia in grado di decodificare la stringa e utilizzarla. I segnali contestuali possono contenere informazioni quali la versione del modello ML per l'incorporamento protetto passato utilizzando i segnali protetti delle app.
  • contextualAdIds: oggetto JSON contenente un elenco facoltativo di ID annuncio.

La UDF deve restituire una stringa in caso di esito positivo. La stringa viene restituita al server delle offerte, che a sua volta la passa alla UDF generateBid. Sebbene la stringa possa essere una semplice stringa, molto probabilmente dovrebbe essere un oggetto serializzato il cui schema è definito da ogni ad tech. Non esistono vincoli per lo schema, a condizione che la logica generateBid della tecnologia pubblicitaria possa riconoscere e utilizzare la stringa.

Configurare il sistema per lo sviluppo

Android

Per configurare l'ambiente di sviluppo Android, devi:

  1. Crea un emulatore (opzione preferita) o un dispositivo fisico che esegue l'immagine di anteprima per sviluppatori 10
  2. Esegui questo comando:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

Quindi, seleziona l'opzione mostrata per acconsentire agli annunci suggeriti dalle app.

  1. Esegui questo comando per abilitare le API pertinenti. Potresti dover eseguire di nuovo questa operazione di tanto in tanto, poiché la configurazione predefinita di disattivazione verrà sincronizzata periodicamente.
adb shell device_config put adservices fledge_custom_audience_service_kill_switch false;  adb shell device_config put adservices fledge_select_ads_kill_switch false; adb shell device_config put adservices fledge_on_device_auction_kill_switch false; adb shell device_config put adservices fledge_auction_server_kill_switch false; adb shell "device_config put adservices disable_fledge_enrollment_check true";  adb shell device_config put adservices ppapi_app_allow_list '\*'; adb shell device_config put adservices fledge_auction_server_overall_timeout_ms 60000;
  1. Riavvia il dispositivo.
  2. Esegui l'override delle chiavi dell'asta del dispositivo in modo che puntino al tuo server delle chiavi dell'asta. È importante eseguire questo passaggio prima di tentare di eseguire un'asta per evitare che le chiavi errate vengano memorizzate nella cache.

Servizi di offerte e aste

Per configurare i server B&A, consulta la documentazione di configurazione self-service.

Questo documento si concentrerà su come configurare i server specifici dell'acquirente, poiché non sono necessarie modifiche per i venditori.

Prerequisiti

Prima di eseguire il deployment di uno stack di servizi B&A, la tecnologia pubblicitaria dell'acquirente deve:

  • Verifica che abbia eseguito il deployment del proprio servizio di recupero degli annunci TEE (consulta la sezione pertinente).
  • Verifica che le tecnologie pubblicitarie dispongano di tutte le UDF necessarie (prepareDataForAdRetrieval, generateBid, reportWin, getCandidateAds) definite e ospitate.

Anche la comprensione di come funziona l'asta protetta con Protected Audience con B&A sarà utile, ma non è obbligatoria.

Configurazione di Terraform

Per utilizzare Protected App Signals, le tecnologie pubblicitarie devono:

  • Attiva il supporto degli indicatori protetti delle app in B&A.
  • Fornisci gli endpoint URL da cui è possibile recuperare le nuove UDF per prepareDataForAdRetrieval, generateBid e reportWin.

Inoltre, questa guida presuppone che le tecnologie pubblicitarie che vogliono utilizzare B&A per il remarketing continuino a impostare tutti i flag di configurazione esistenti per l'asta di remarketing come di consueto.

Configurazione della tecnologia pubblicitaria dell'acquirente

Utilizzando questo file demo come esempio, gli acquirenti devono impostare i seguenti flag:

  • Attiva Protected App Signals: attivato per raccogliere i dati di Protected App Signals.
  • URL Protected App Signals: impostato sugli URL dei server Protected App Signals.

Le tecnologie pubblicitarie devono sostituire gli URL corretti nei segnaposto per i seguenti campi:

module "buyer" {
  # ... More config here.

  runtime_flags = {
    # ... More config here.

    ENABLE_PROTECTED_APP_SIGNALS                  = "true"
    PROTECTED_APP_SIGNALS_GENERATE_BID_TIMEOUT_MS = "60000"
    TEE_AD_RETRIEVAL_KV_SERVER_ADDR               = "<service mesh address of the instance>"
    AD_RETRIEVAL_TIMEOUT_MS                       = "60000"
    BUYER_CODE_FETCH_CONFIG                       = <<EOF
    {
        "protectedAppSignalsBiddingJsUrl": "<URL to Protected App Signals generateBid UDF>",
        "urlFetchTimeoutMs": 60001, # This has to be > 1 minute.
        "urlFetchPeriodMs": 13000000,
        "prepareDataForAdsRetrievalJsUrl": "<URL to the UDF>"
    }
    EOF

  }  # runtime_flags

}  # Module "buyer"

Configurazione della tecnologia pubblicitaria del venditore

Utilizzando questo file demo come esempio, i venditori devono impostare i seguenti flag. (Nota: qui è evidenziata solo la configurazione relativa a Protected App Signals). Le tecnologie pubblicitarie devono verificare di sostituire gli URL corretti nei segnaposto:

module "seller" {
  # ... More config here.

  runtime_flags = {
    # ... More config here.

    ENABLE_PROTECTED_APP_SIGNALS                  = "true"

    SELLER_CODE_FETCH_CONFIG                           = <<EOF
  {
    "urlFetchTimeoutMs": 60001, # This has to be > 1 minute.
    "urlFetchPeriodMs": 13000000,
    "protectedAppSignalsBuyerReportWinJsUrls": {"<Buyer Domain>": "URL to reportWin UDF"}
  }
  EOF

  }  # runtime_flags

}  # Module "seller"

Servizi di recupero di valori chiave e annunci

A seconda delle strategie scelte per supportare il recupero degli annunci, il sistema richiederà il deployment di una o due istanze del servizio KV. Faremo riferimento all'istanza KV utilizzata per il recupero degli annunci basato su TEE come Ad Retrieval Server e all'istanza per supportare il recupero basato su percorso contestuale come KV Lookup Server.

In entrambi i casi, il deployment dei server segue la documentazione disponibile su GitHub del server KV. La differenza tra i due casi è che la ricerca funziona immediatamente senza alcuna configurazione aggiuntiva, mentre il recupero richiede il deployment della UDF getCandidateAds per implementare la logica di recupero. Per maggiori dettagli, consulta la guida all'onboarding del server KV. Tieni presente che B&A prevede che entrambi i servizi vengano implementati nella stessa service mesh del servizio di offerta.

Configurazione di esempio

Considera lo scenario seguente: utilizzando l'API Protected App Signals, una tecnologia pubblicitaria memorizza indicatori pertinenti in base all'utilizzo dell'app da parte dell'utente. Nel nostro esempio, vengono memorizzati indicatori che rappresentano gli acquisti in-app di diverse app. Durante un'asta, gli indicatori criptati vengono raccolti e trasferiti a un'asta Protected Auction in esecuzione in B&A. Le funzioni definite dall'utente dell'acquirente eseguite in B&A utilizzano i segnali per recuperare i candidati annuncio e calcolare un'offerta.

Esempi di indicatori [acquirente]

Aggiunge un indicatore con una chiave pari a 0 e un valore pari a 1.

{
  "put": {
    "AA==": "AQ=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

Aggiunge un indicatore con una chiave di 1 e un valore di 2.

{
  "put": {
    "AQ==": "Ag=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

Esempio di [Buyer] encodeSignals

Codifica ogni segnale in due byte, il primo byte è il primo byte della chiave del segnale e il secondo byte è il primo byte del valore del segnale.

function encodeSignals(signals, maxSize) {
  // if there are no signals don't write a payload
  if (signals.size === 0) {
      return {};
  }

  let result = new Uint8Array(signals.size * 2);
  let index = 0;
  
  for (const [key, values] of signals.entries()) {
    result[index++] = key[0];
    result[index++] = values[0].signal_value[0];
  }
  
  return { 'status': 0, 'results': result};
}

Esempio di [Buyer] prepareDataForAdRetrieval

/**
 * `encodedOnDeviceSignals` is a Uint8Array and would contain
 * the app signals emanating from device. For purpose of the
 * demo, in our sample example, we assume that device is sending
 * the signals with pair of bytes formatted as following:
 * "<ID><In app spending>". Where ID corresponds to an ad category
 * that user uses on device, and the in app spending is a measure
 * of how much money the user has spent in this app category
 * previously. In our example, an ID of 0 will correspond to a
 * fitness ad category and a non-zero ID will correspond to
 * food app category -- though this info will be useful
 * later in the B&A pipeline.
 *
 * Returns a JSON object indicating what type of ad(s) may be
 * most relevant to the user. In a real setup ad techs might
 * want to decode the signals as part of this script.
 *
 * Note: This example script makes use of only encoded device signals
 * but ad tech can take other signals into account as well to prepare
 * the data that will be useful down stream for ad retrieval and
 * bid generation. The max length of the app signals used in this
 * sample example is arbitrarily limited to 4 bytes.
 */
function prepareDataForAdRetrieval(encodedOnDeviceSignals,
                                   encodedOnDeviceSignalsVersion,
                                   sellerAuctionSignals,
                                   contextualSignals) {
  if (encodedOnDeviceSignals.length === 0 || encodedOnDeviceSignals.length > 4 ||
      encodedOnDeviceSignals.length % 2 !== 0) {
     throw "Expected encoded signals length to be an even number in (0, 4]";
  }

  var preparedDataForAdRetrieval = {};
  for (var i = 0; i < encodedOnDeviceSignals.length; i += 2) {
    preparedDataForAdRetrieval[encodedOnDeviceSignals[i]] = encodedOnDeviceSignals[i + 1];
  }
  return preparedDataForAdRetrieval;
}

[Acquirenti] Funzione definita dall'utente di recupero degli annunci di esempio

Nel nostro esempio, il server di recupero degli annunci invia i metadati (ad es. l'ID per ogni annuncio in questo esempio, ma può contenere altri dati per ciascun annuncio che possono essere utili per generare offerte in un secondo momento) per ciascuno dei primi k candidati all'annuncio.

function getCandidateAds(requestMetadata, protectedSignals, deviceMetadata,
                      contextualSignals,   contextualAdIds,) {
 return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"

[Acquirenti] generateBid example

/**
 * This script receives the data returned by the ad retrieval service
 * in the `ads` argument. This argument is supposed to contain all
 * the Protected App Signals related ads and the metadata obtained from the retrieval
 * service.
 *
 * `preparedDataForAdRetrieval` argument contains the data returned
 * from the `prepareDataForAdRetrieval` UDF.
 *
 * This script is responsible for generating bids for the ads
 * collected from the retrieval service and ad techs can decide to
 * run a small inference model as part of this script in order to
 * decide the best bid given all the signals available to them.
 *
 * For the purpose of the demo, this sample script assumes
 * that ad retrieval service has sent us most relevant ads for the
 * user and this scripts decides on the ad render URL as well as
 * what value to bid for each ad based on the previously decoded
 * device signals. For simplicity sake, this script only considers
 * 2 types of app categories i.e. fitness and food.
 *
 * Note: Only one bid is returned among all the
 * input ad candidates.
 */
function generateBid(ads, sellerAuctionSignals, buyerSignals, preparedDataForAdRetrieval) {
  if (ads === null) {
    console.log("No ads obtained from the ad retrieval service")
    return {};
  }     
        
  const kFitnessAd = "0";
  const kFoodAd = "1";
  const kBuyerDomain = "https://buyer-domain.com";
        
  let resultingBid = 0;
  let resultingRender = kBuyerDomain + "/no-ad";
  for (let i = 0 ; i < ads.length; ++i) {
    let render = "";
    let bid = 0;
    switch (ads[i].adId) {
      case kFitnessAd:
        render = kBuyerDomain + "/get-fitness-app";
        bid = preparedDataForAdRetrieval[kFitnessAd];
        break;
      case kFoodAd:
        render = kBuyerDomain + "/get-fastfood-app";
        bid = preparedDataForAdRetrieval[kFoodAd];
        break;
      default:
        console.log("Unknown ad category");
        render = kBuyerDomain + "/no-ad";
        break;
    }
    console.log("Existing bid: " + resultingBid + ", incoming candidate bid: " + bid);
    if (bid > resultingBid) {
      resultingBid = bid;
      resultingRender = render;
    }
  }
  return {"render": resultingRender, "bid": resultingBid};
}

Esempio di report [Acquirenti]

La reportWin UDF comunica all'acquirente che ha vinto l'asta.

function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                                       buyerReportingSignals, directFromSellerSignals,
                                       egressPayload,
                                       temporaryUnlimitedEgressPayload) {
  sendReportTo("https://buyer-controlled-domain.com/");
  registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
  return;
}

[Seller] KV server setup

I venditori devono configurare un server KV di indicatori di punteggio in modo che sia disponibile un mapping dagli URL di rendering degli annunci agli indicatori di punteggio corrispondenti, ad esempio: se https:/buyer-domain.com/get-fitness-app e https:/buyer-domain.com/get-fastfood-app devono essere restituiti dall'acquirente, il venditore può avere la seguente risposta degli indicatori di punteggio di esempio quando viene interrogato da SFE utilizzando un GET su https://key-value-server-endpoint.com?client_type=1&renderUrls=<render-url-returned-by-the-buyer>:

{
   "renderUrls" : {
      "https:/buyer-domain.com/get-fitness-app" : [
         "1",
         "2"
      ],
      "https:/buyer-domain.com/get-fastfood-app" : [
         "3",
         "4"
      ]
   }
}

[Seller] scoreAd example

/**
 * This module generates a random desirability score for the Protected App
 * Signals ad in this example. In a production deployment,
 * however, the sellers would want to use all the available signals to generate
 * a score for the ad.
 */
function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function scoreAd(adMetadata, bid, auctionConfig,
                                   trustedScoringSignals, deviceSignals,
                                   directFromSellerSignals) {
  return {
    "desirability": getRandomInt(10000),
    "allowComponentAuction": false
  };
}

[Seller] reportResult example

function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
  let signalsForWinner = {};
    sendReportTo("https://seller-controlled-domain.com");
    registerAdBeacon({"clickEvent":
                    "https://seller-controlled-domain.com/clickEvent"});
    return signalsForWinner;
}

App di esempio

Come esempio di come l'API può essere utilizzata per creare un'app che utilizza questo flusso, abbiamo creato un'app di esempio Protected App Signals che può essere trovata in questo repository di esempio.