Guide du développeur des signaux d'application protégés

Pour aider les développeurs à tester l'API Protected App Signals, ce document décrit toutes les API de la surface de l'API, explique comment configurer un environnement de test et fournit des exemples de configuration et de scripts.

Historique des versions

Janvier 2024

Première version du guide du développeur compatible avec la version MVP PAS

Mars 2024

Modifications apportées à l'API pour assurer la compatibilité avec la version M-2024-05 de l'API Android et le Version d'avril 2024 des composants côté serveur. Principaux changements:

  • Ajout de détails sur les autorisations requises pour l'API sur l'appareil
  • Ajout d'informations sur la gestion du quota de signaux sur l'appareil
  • Mise à jour de la signature generateBid avec les modifications liées au contexte Prise en charge de la récupération et de la sortie des annonces
  • Mise à jour de la documentation sur reportWin, y compris la prise en charge du trafic de sortie
  • Mise à jour de la documentation de l'API Ad Retrieval qui supprime la prise en charge de la récupération d'annonces BYOS et documenter la fonction définie par l'utilisateur sur la récupération d'annonces

Présentation de l'API

La surface de l'API Protected Signals inclut différents sous-ensembles d'API sur différents systèmes :

  • API Android :
    • API Signal Curation, composée des éléments suivants :
    • Mettre à jour l'API Signals
    • API Signals Encoding
    • API Protected Auction Support : à utiliser par les SDK pour lancer la mise aux enchères protégée sur les serveurs d'enchères et de mise aux enchères à l'aide de signaux d'application protégés.
  • API côté serveur :
    • API Protected Auction : série de scripts JavaScript exécutés dans les serveurs d'enchères et de mise aux enchères. Cette API permet aux vendeurs et aux acheteurs d'écrire la logique pour implémenter l'enchère protégée.
    • API Ad Retrieval : chargée de fournir une liste d'annonces candidates en fonction des informations contextuelles et utilisateur mises à la disposition du serveur d'enchères de l'acheteur.

Client Android

Côté client, la surface des signaux d'application protégés se compose de trois API différentes :

  • Signaux de mise à jour : API du système Android permettant de gérer les signaux sur l'appareil.
  • Encodage des signaux : API JavaScript pour préparer les signaux à envoyer au serveur lors de l'enchère.
  • Protected Auction Support : API permettant l'exécution d'une enchère protégée sur les serveurs d'enchères et de mise aux enchères. Cette API n'est pas spécifique aux signaux d'application protégés et sert également à prendre en charge les enchères pour l'API Protected Audience.

Mettre à jour l'API Signals

L'API Update Signals permet aux technologies publicitaires d'enregistrer des signaux liés à l'utilisateur inscrit et à l'application pour le compte d'un acheteur. L'API fonctionne sur un modèle de délégation. L'appelant fournit un URI à partir duquel le framework extrait les signaux correspondants, ainsi que la logique permettant d'encoder ces signaux à utiliser lors de l'enchère.

L'API nécessite le android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS l'autorisation.

L'API updateSignals() récupère un objet JSON. de l'URI, qui décrit les signaux à ajouter ou à supprimer, et explique comment s'y préparer ces signaux pour la mise aux enchères.

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 plate-forme envoie une requête HTTPS à l'URI fourni dans la requête pour récupérer les mises à jour des signaux. Avec les mises à jour des signaux, la réponse peut inclure un point de terminaison qui héberge la logique d'encodage permettant de convertir les signaux bruts en charge utile encodée. Les mises à jour des signaux doivent être au format JSON et peuvent avoir les clés suivantes :

Les clés de niveau supérieur de l'objet JSON doivent correspondre à l'une des cinq commandes suivantes :

clé

Description

put

Ajoute un nouveau signal en écrasant tous les signaux existants ayant la même clé. La valeur

correspondante est un objet JSON dans lequel les clés sont des chaînes en base64 correspondant à la clé à mettre et les valeurs sont des chaînes en base64 correspondant à la valeur à mettre.

append

Ajoute un ou plusieurs nouveaux signaux à une série temporelle de signaux, en supprimant les plus anciens

afin de faire de la place pour les nouveaux si la taille de la série dépasse la taille maximale donnée. La valeur correspondante est un objet JSON dans lequel les clés sont des chaînes en base64 correspondant à la clé à ajouter. Les valeurs sont des objets comportant deux champs : "values" et "maxSignals".

"values" : liste de chaînes en base64 correspondant aux valeurs de signaux à ajouter à la série temporelle.

"maxSignals" : nombre maximal de valeurs autorisées dans cette série temporelle. Si

le nombre actuel de signaux associés à la clé dépasse la valeur maxSignals, les signaux les plus anciens seront supprimés. Notez que vous pouvez ajouter des signaux à une clé ajoutée par le biais de la méthode "put". Notez que si vous ajoutez plus de valeurs que le nombre maximal autorisé, un échec se produira.

put_if_not_present

Ajoute un nouveau signal uniquement s'il n'existe aucun signal associé à la même clé. La valeur correspondante est un objet JSON dans lequel les clés sont des chaînes en base64 correspondant à la clé à insérer et les valeurs sont une chaîne en base64 correspondant à la valeur à mettre.

remove

Supprime le signal d'une clé. La valeur correspondante est une liste de chaînes en base64 correspondant aux clés de signaux à supprimer.

update_encoder

Fournit une action pour mettre à jour le point de terminaison et un URI qui peuvent être utilisés

pour récupérer une logique d'encodage. La sous-clé permettant de fournir une action de mise à jour est "action" et

les valeurs actuellement prises en charge sont uniquement "REGISTER". Si le point de terminaison de l'encodeur est fourni pour la première fois, il enregistre le point de terminaison de l'encodeur ou écrase le point de terminaison existant par le nouveau point de terminaison fourni. Vous devez indiquer le point de terminaison pour l'action "REGISTER". La sous-clé permettant de fournir un point de terminaison d'encodeur est "endpoint" et sa valeur est la chaîne URI

du point de terminaison.

Voici comment se présente un exemple de requête JSON :

{
    "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"
    }
}

Les signaux ont un quota sur l'appareil de l'ordre de 10 à 15 Ko. Une fois que le quota est dépassé, PPAPI expulsera les signaux à l'aide d'une stratégie FIFO. Le processus d'éviction le quota peut être légèrement dépassé pendant de courts intervalles de temps dans afin de réduire la fréquence des évictions.

API Signals Encoding

Les acheteurs doivent fournir une fonction Java Script à utiliser pour encoder les signaux stockés sur l'appareil à envoyer au serveur lors de l'enchère protégée. Les acheteurs peuvent fournir ce script en ajoutant l'URL à partir de laquelle il peut être extrait à l'aide de la clé "update_encoder" dans l'une des réponses à une requête API UpdateSignal. Le script aura la signature suivante :

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)};
}

Le paramètre signals est un mappage de clés au format UInt8Arrays de taille 4 à des listes d'objets des signaux d'application protégés. Chaque objet des signaux d'application protégés comporte trois champs :

  • signal_value : un UInt8Array représentant la valeur du signal.
  • creation_time : un nombre représentant l'heure de création des signaux en secondes Epoch.
  • package_name : une chaîne représentant le nom du package qui a créé le signal.

Le paramètre maxSize est un nombre décrivant la plus grande taille de tableau autorisée pour la sortie.

La fonction doit générer un objet avec deux champs :

  • status : doit être défini sur 0 si le script a bien été exécuté.
  • results : doit être un UInt8Array de longueur inférieure ou égale à maxSize. Ce tableau sera envoyé au serveur lors des enchères et préparé par le script prepareDataForAdRetrieval.

L'encodage fournit aux technologies publicitaires une étape initiale d'ingénierie des caractéristiques, au cours de laquelle elles peuvent effectuer des transformations telles que la compression de signaux bruts en versions concaténées en fonction de leur propre logique personnalisée. Notez que lors d'enchères protégées exécutées dans les environnements d'exécution sécurisés (TEE, Trusted Execution Environments), la logique personnalisée des technologies publicitaires dispose d'un accès en lecture aux charges utiles de signaux générées par l'encodage. La logique personnalisée, appelée fonction définie par l'utilisateur (UDF), exécutée dans les environnements d'exécution sécurisés d'enchères et de mises aux enchères de l'acheteur disposera d'un accès en lecture aux signaux encodés et aux autres signaux de contexte fournis par l'application de l'éditeur pour effectuer la sélection des annonces (récupération des annonces et enchères).

Encodage des signaux

Toutes les heures, les acheteurs qui ont fourni une logique d'encodage avec leurs signaux enregistrés sont encodés dans une charge utile d'enchère. Le tableau d'octets de la charge utile de l'enchère est conservé sur l'appareil. Il est chiffré et les données seront collectées par les vendeurs dans le cadre des données sur la sélection des annonces, puis incluses dans le cadre d'une enchère protégée. Pour les tests, vous pouvez déclencher cet encodage en dehors de sa fréquence horaire en exécutant la commande suivante :

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Gestion des versions de la logique d'encodeur

Lorsqu'une requête est effectuée pour télécharger la logique d'encodeur personnalisé de la technologie publicitaire, le point de terminaison de la technologie publicitaire peut répondre avec un numéro de version dans les en-têtes de réponse. Cette version est conservée avec la logique d'encodeur sur l'appareil. Lorsque les signaux bruts sont encodés, la charge utile encodée est conservée avec la version utilisée pour l'encodage. Cette version est également envoyée au serveur d'enchères et de mise aux enchères lors d'une mise aux enchères protégée, afin que les technologies publicitaires puissent aligner leur logique d'enchères et d'encodage en fonction de la version.

Response header for providing encoder version : X_ENCODER_VERSION

API Protected Auction Support

Côté appareil, le lancement d'une mise aux enchères pour les signaux d'application protégés revient à la même mise aux enchères que pour les audiences protégées.

Services d'enchères et de mise aux enchères

Les API côté serveur incluent :

  • API Protected Auction : série de fonctions JS, ou UDF, que les acheteurs et les vendeurs peuvent déployer sur les composants des enchères et de mise aux enchères dont ils sont propriétaires, afin de déterminer les enchères et la logique d'enchères.
  • API Ad Retrieval : les acheteurs peuvent implémenter cette API en implémentant un point de terminaison REST qui sera chargé de fournir un ensemble d'annonces candidates pour la mise aux enchères des signaux d'application protégés.

API Protected Auction

L'API Protected Auction se compose d'une API JS ou de plusieurs UDF que les acheteurs et les vendeurs peuvent utiliser pour implémenter leur logique d'enchères et de mise aux enchères.

Fonction définie par l'utilisateur (UDF) de technologies publicitaires pour les acheteurs
UDF prepareDataForAdRetrieval

Avant que les signaux d'application protégés puissent être utilisés pour récupérer les annonces candidates à partir du TEE service de récupération d'annonces, les acheteurs doivent décoder et préparer les signaux d'application protégés et d'autres données fournies par le vendeur. La sortie de l'UDF prepareDataForAdRetrieval de l'acheteur est transmise au service de récupération d'annonces afin de récupérer les k premières annonces candidates pour les enchères.

// 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 adtech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
   return {};
}
UDF generateBid

Une fois les k premières annonces candidates renvoyées, elles sont transmises à la logique d'enchères personnalisées de l'acheteur, UDF generateBid :

// 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>
    };
}

Le résultat de cette fonction est une enchère unique pour une annonce candidate, représentée sous forme de fichier JSON équivalent à ProtectedAppSignalsAdWithBidMetadata La fonction peut également renvoyer deux tableaux qui seront ensuite transmis à reportWin. pour permettre l'entraînement du modèle (pour en savoir plus sur la sortie et l'entraînement de modèle, reportez-vous à la section sur la création de rapports dans la vidéo d'explication de PAS.)

UDF reportWin

À la fin d'une enchère, le service d'enchères génère des URL de rapport pour les acheteurs et les balises d'enregistrement à l'aide de reportWin UDF (identique reportWin utilisée pour les audiences protégées). L'appareil enverra un ping une fois l'annonce diffusée par le client. La signature de cette méthode est presque identique à celle de l'API Protected Audience version, à l'exception des deux paramètres supplémentaires egressPayload et temporaryUnlimitedEgressPayload permettant d'entraîner le modèle et qui sont contenant les résultats de generateBid.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
Fonctions définies par l'utilisateur (UDF) de technologies publicitaires pour les vendeurs
UDF scoreAd

Les vendeurs utilisent cette UDF pour sélectionner les annonces envoyées par les acheteurs qui remporteront l'enchère.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
UDF reportResult

Cette UDF permet au vendeur (à terme) de créer des rapports au niveau des événements avec les informations concernant l'annonce gagnante.

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

API Ad Retrieval

Dans la version MVP , le service de récupération d'annonces sera géré et hébergé par l'acheteur et le service d'enchères récupère les annonces candidates à partir de ce service. À partir d'avril 2024, le serveur de récupération d'annonces devra s'exécuter dans un environnement d'exécution (TEE) et exposera une interface gRPC/proto. Les entreprises de technologie publicitaire doivent configurer ce serveur et fournir leur URL lors du déploiement de la pile d'enchères et dans le cadre de la mise aux enchères. Une implémentation de ce service s'exécutant dans le TEE est disponible sur le GitHub de la Privacy Sandbox et dans les autres dans la documentation, nous supposons qu'il s'agit du code utilisé dans le déploiement.

À partir d'avril 2024, les versions d'enchères et de mise aux enchères accepteront les annonces avec chemin contextuel la récupération. Dans ce cas, le serveur d'enchères reçoit une liste identifiants d'annonce envoyés par le serveur d'enchères en temps réel lors de la partie contextuelle de l'enchère Les identifiants seront envoyés à un serveur TEE KV pour récupérer toutes les annonces des informations connexes à utiliser lors de la phase d'enchères (par exemple, ad-render-url, métadonnées et représentations vectorielles continues d'annonces à utiliser dans sélection top-k). Ce deuxième chemin n'a pas besoin de logique spécifique pour être déployé. Nous verrons donc uniquement comment configurer le TEE en fonction de la récupération d'annonces.

HandleRequest définie par l'utilisateur
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals) {
    return adsMetadataString;
}

Où :

  • requestMetadata : JSON Métadonnées du serveur de requêtes à la fonction définie par l'utilisateur. Vide pour l'instant.
  • preparedDataForAdRetrieval: le contenu de ce champ dépend de l'annonce. de récupération des données. Ce paramètre permet de récupérer des annonces contextuelles. contient les signaux bruts provenant de l'appareil et transmis par le d'enchères. Dans le cas d'une récupération d'annonce TEE à l'aide du serveur de récupération d'annonces, ce paramètre contiendra le résultat de la fonction prepareDataForAdRetrieval définie par l'utilisateur. Remarque: À ce stade, les signaux d'application protégés sont décodés et non chiffrés.
  • deviceMetadata: objet JSON contenant les métadonnées de l'appareil transférées par les services publicitaires du vendeur. Pour en savoir plus, consultez la documentation sur les enchères et les mises aux enchères.
    • X-Accept-Language: langue utilisée sur l'appareil.
    • X-User-Agent: user-agent utilisé sur l'appareil.
    • X-BnA-Client-IP: adresse IP de l'appareil.
  • contextualSignals: chaîne arbitraire issue des enchères contextuelles géré par la même DSP. La fonction définie par l'utilisateur doit être capable de décoder et l'utiliser. Les signaux contextuels peuvent contenir des informations du type ML les informations de version de modèle pour la représentation vectorielle continue protégée transmises à l'aide de des signaux d'application protégés.

En cas de réussite, la fonction définie par l'utilisateur doit renvoyer une chaîne. La chaîne est renvoyée au d'enchères, qui la transmet ensuite à la fonction generateBid définie par l'utilisateur. Bien que le Il peut s'agir d'une simple chaîne. Il s'agit probablement d'une Objet sérialisé dont le schéma est défini par chaque technologie publicitaire de manière autonome. Il n'y a aucune contrainte sur le schéma tant que l'generateBid de la technologie publicitaire peut reconnaître et utiliser la chaîne.

Configurer le système pour le développement

Android

Pour configurer votre environnement de développement Android, vous devez procéder comme suit :

  1. Créez un émulateur (de préférence) ou un appareil physique qui exécute l'image Preview développeur 10.
  2. Pour ce faire, exécutez la commande suivante :
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

Sélectionnez ensuite l'option affichée permettant d'autoriser les annonces suggérées par les applis.

  1. Exécutez la commande suivante pour activer les API appropriées. Vous devrez peut-être réexécuter cette commande de temps en temps, car la configuration par défaut de la colonne "Désactivé" sera régulièrement synchronisée.
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. Redémarrez l'appareil.
  2. Ignorez les clés d'enchères de l'appareil pour qu'elles pointent vers votre serveur de clés d'enchères. Il est important d'effectuer cette étape avant de tenter de lancer une mise aux enchères afin d'éviter la mise en cache de clés incorrectes.

Services d'enchères et de mise aux enchères

Pour configurer les serveurs d'enchères et de mise aux enchères, consultez la documentation de configuration en libre-service.

Ce document explique comment configurer les serveurs propres à l'acheteur, car aucune modification n'est requise pour les vendeurs.

Conditions préalables

Avant de déployer une pile de services d'enchères et de mise aux enchères, la technologie publicitaire de l'acheteur doit :

  • Assurez-vous qu'ils ont déployé leur propre service de récupération d'annonces TEE (consultez la la section concernée).
  • S'assurer que la technologie publicitaire dispose de toutes les UDF nécessaires (prepareDataForAdRetrieval, generateBid, reportWin, HandleRequest) définies et hébergées.

Il est également utile de comprendre le fonctionnement des enchères protégées avec l'API Protected Audience avec les enchères et mises aux enchères, mais ce n'est pas obligatoire.

Configuration Terraform

Pour utiliser les signaux d'application protégés, les technologies publicitaires doivent :

  • Prendre en charge des signaux d'application protégés dans les enchères et mises aux enchères.
  • Fournir les points de terminaison d'URL à partir desquels les nouvelles UDF pour prepareDataForAdRetrieval, generateBid et reportWin peuvent être extraites.

En outre, ce guide part du principe que les technologies publicitaires qui souhaitent utiliser les enchères et mises aux enchères pour le remarketing doivent définir comme d'habitude tous les indicateurs de configuration existants pour les enchères de remarketing.

Configuration des technologies publicitaires des acheteurs

En prenant ce fichier de démonstration comme exemple, les acheteurs doivent définir les indicateurs suivants :

  • Activer les signaux d'application protégés : permet de collecter les données des signaux d'application protégés.
  • URL des signaux d'application protégés : définit les URL des serveurs de signaux d'application protégés.

Les technologies publicitaires doivent remplacer les URL appropriées dans les espaces réservés pour les champs suivants :

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"

Configuration des technologies publicitaires des vendeurs

En prenant ce fichier démo comme exemple, les vendeurs doivent définir les indicateurs suivants. (Remarque : Seule la configuration liée aux signaux d'application protégés est mise en surbrillance ici.) Les technologies publicitaires doivent s'assurer de remplacer les URL appropriées dans les espaces réservés :

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"

KV et services de récupération d'annonces

En fonction des stratégies choisies pour permettre la récupération d'annonces, le système le déploiement d'une ou deux instances du service KV. Nous ferons référence à l'instance d'instance de KV utilisée pour la récupération des annonces basée sur le TEE Ad Retrieval Server et à l'instance pour prendre en charge la compatibilité basée sur un chemin contextuel en tant que KV Lookup Server.

Dans les deux cas, le déploiement des serveurs est conforme à la documentation disponible dans le GitHub du serveur KV, la différence entre les deux cas est que la recherche est prêt à l'emploi et ne nécessite aucune configuration supplémentaire. la récupération 1 nécessite le déploiement de la fonction HandleRequest définie par l'utilisateur pour implémenter la logique de récupération. Pour plus de détails, consultez la section sur le serveur KV guide de démarrage. Notez que les enchères et mises aux enchères s'attendent à ce que les deux services déployé dans le même maillage de services que le service d'enchères.

Exemple de configuration

Prenons le scénario suivant : à l'aide de l'API Protected App Signals, une technologie publicitaire stocke des signaux pertinents en fonction de l'utilisation de l'application par l'utilisateur. Dans notre exemple, les signaux qui représentent les achats via plusieurs applications sont stockés. Lors d'une enchère, les signaux chiffrés sont collectés et transmis à des enchères protégées qui se déroulent dans les enchères et mises aux enchères. Les UDF de l'acheteur exécutées dans les enchères et les mises aux enchères utilisent ces signaux pour extraire les annonces candidates et calculer une enchère.

[Acheteur] Exemples de signaux

Ajoute un signal avec une clé de 0 et une valeur de 1.

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

Ajoute un signal avec une clé de 1 et une valeur de 2.

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

[Acheteur] Exemple d'utilisation d'encodeSignals

Encode chaque signal en deux octets, le premier octet étant le premier octet de la clé du signal et le deuxième octet étant le premier octet de la valeur du signal.

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};
}

[Acheteur] Exemple d'utilisation de 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, 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 adtech 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;
}

[Acheteurs] Exemple de fonction définie par l'utilisateur sur la récupération d'annonces

Dans notre exemple, le serveur de récupération d'annonces envoie des métadonnées (c'est-à-dire l'identifiant de chaque annonce de cet exemple, mais il peut contenir d'autres données pour chacune des annonces susceptibles de vous aider à générer des enchères ultérieurement) pour chacune des k premières annonces candidates.

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

[Acheteurs] Exemple d'utilisation de generateBid

/**
 * 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};
}

[Acheteurs] Exemple d'utilisation de reportWin

L'UDF reportWin indique à l'acheteur qu'il a remporté l'enchère.

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

[Vendeur] Configuration du serveur de KV

Les vendeurs doivent configurer un serveur de KV pour les signaux d'évaluation afin qu'un mappage entre les URL de rendu des annonces et les signaux d'évaluation correspondants soit disponible. Par exemple : si https:/buyer-domain.com/get-fitness-app et https:/buyer-domain.com/get-fastfood-app doivent être renvoyé par l'acheteur, le vendeur peut avoir l'exemple suivant de réponse des signaux d'évaluation lorsqu'il est interrogé par le SFE à l'aide d'un GET sur 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"
      ]
   }
}

[Vendeur] Exemple d'utilisation de scoreAd

/**
 * 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
  };
}

[Vendeur] Exemple d'utilisation de reportResult

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

Application exemple

Pour illustrer comment l'API peut être utilisée pour créer une application qui utilise un flux simple (comme décrit ci-dessus), nous avons créé un exemple d'application Protected App Signals, disponible dans cet exemple de dépôt.