API TURTLEDOVE RTB Simulation

Dans le cadre de Privacy Sandbox, Chrome a proposé TURTLEDOVE, une API intégrée au navigateur qui permet aux annonceurs et aux entreprises de technologie publicitaire de diffuser des annonces ciblées par groupes de centres d'intérêt sans passer par des cookies tiers, ce qui protège les utilisateurs du suivi intersites. Avant que Chrome implémente TURTLEDOVE, l'équipe RTB de Google propose une simulation d'API TURTLEDOVE côté serveur qui permet à ses partenaires RTB (partenaires Authorized Buyers et Open Bidding) de tester l'API. La simulation permet aux partenaires et à Google d'en savoir plus sur l'efficacité du flux de type TURTLEDOVE, de générer des commentaires pertinents sur les améliorations potentielles de l'API sur les forums publics et de faciliter la transition vers la publicité personnalisée sans utiliser de cookies tiers.

Dans la première phase de la simulation, les enchérisseurs hébergent leur appartenance à un groupe de centres d'intérêt. Les enchérisseurs fournissent également à l'avance des fonctions d'enchères à Google via une API. Au moment de la diffusion, Google divise chaque demande d'enchère couverte par la simulation en deux requêtes: une requête contextuelle et une requête ciblée par centres d'intérêt. La requête contextuelle est semblable à la demande d'enchère actuelle, mais sans identifiants utilisateur (tels que les champs google_user_id et hosted_match_data) disponibles. Les requêtes de groupes de centres d'intérêt ne contiennent aucune information contextuelle et ne contiennent que des champs d'identification des utilisateurs (sous réserve des paramètres de confidentialité existants). Les enchères des groupes de centres d'intérêt ne contiennent pas de valeur de CPM, mais font référence à une fonction d'enchères que Google exécute côté serveur dans un environnement de type "bac à sable". Les enchères sont exécutées normalement avec les enchères contextuelles et les enchères calculées par les fonctions d'enchères.

Au cours de la première phase de la simulation, Google envoie des ID utilisateur pseudonymes aux requêtes par centres d'intérêt. L'objectif est de réduire le travail de mise en œuvre des deux côtés afin de pouvoir démarrer les tests plus tôt. La présence d'identifiants utilisateur dans les requêtes par centres d'intérêt sera soumise aux contrôles et protections de confidentialité existants (par exemple, lorsqu'un utilisateur désactive la publicité personnalisée).

Procédure

organigramme

  1. Le système d'enchères en temps réel collabore avec les annonceurs pour créer, gérer et héberger des groupes de centres d'intérêt pour chaque annonceur et chaque utilisateur appartenant à ces groupes.
  2. Lorsqu'il visite la page Web d'un éditeur, son navigateur télécharge le tag d'emplacement publicitaire de Google. Le navigateur de l'utilisateur demande une annonce depuis la plate-forme Google pour les éditeurs.
  3. Le système d'enchères en temps réel fournit une ou plusieurs fonctions d'enchères (en tant que fonctions JavaScript) à l'avance à Google. (Consultez la section Fonctions d'enchères.)
  4. Pour la petite partie des demandes couvertes par le test, Google envoie des demandes d'enchères contextuelles et des demandes d'enchères basées sur les centres d'intérêt distinctes à chaque enchérisseur participant au test (consultez la section Demandes d'enchères).
  5. Le système d'enchères utilise le pseudonyme d'utilisateur disponible dans la demande d'enchère du groupe de centres d'intérêt et le mappe aux groupes de centres d'intérêt correspondants. Le système d'enchères en temps réel renvoie des réponses contextuelles aux enchères et des réponses aux enchères basées sur les centres d'intérêt (consultez la section Réponses aux enchères).
    1. Les réponses aux enchères contextuelles seront semblables aux réponses d'aujourd'hui, avec zéro ou plusieurs enchères contextuelles. De plus, la réponse d'enchère contextuelle peut transmettre des signaux de contexte personnalisés de l'enchérisseur qui seront fournis à la fonction d'enchères en tant qu'entrée.
    2. Les réponses aux enchères basées sur les centres d'intérêt ne spécifient pas d'enchère, mais le nom de la fonction d'enchères. Google exécute la fonction d'enchères pour obtenir une enchère.
  6. Google lance une mise aux enchères côté serveur avec les candidats suivants:

    1. Enchères issues de la réponse contextuelle.
    2. Enchères de la réponse du groupe de centres d'intérêt avec les prix des enchères calculés en exécutant les fonctions d'enchères.
    3. Enchères standards d'autres enchérisseurs

    Notez qu'il s'agit de la même mise aux enchères qu'aujourd'hui.

  7. Google renvoie une annonce gagnante dans le navigateur de l'utilisateur, qui s'affiche normalement.

Fonctions d'enchères

Les fonctions d'enchères sont des fonctions fournies par les enchérisseurs qui renvoient une valeur d'enchère pour une annonce par centre d'intérêt et un espace publicitaire donnés . Dans la proposition TURTLEDOVE d'origine, cette fonction est stockée dans le navigateur de l'utilisateur. Dans cette simulation, les enchérisseurs importeront les fonctions d'enchères dans Google via une API avant de diffuser les annonces. Lors de la diffusion d'annonces, un nom de fonction d'enchères est spécifié dans la réponse du groupe de centres d'intérêt. Google exécute cette fonction d'enchères dans un environnement de type "bac à sable" pour obtenir une valeur d'enchère. Cette valeur d'enchère par centres d'intérêt participera à la même mise aux enchères que l'enchère contextuelle.

Interface de la fonction d'enchères

La fonction d'enchères doit être une fonction pure sans effet secondaire implémentée dans JavaScript et qui sera exécutée dans un bac à sable fourni par la place de marché. Une fonction d'enchères n'a pas accès au réseau, au stockage ni à aucune autre forme d'E/S et ne peut conserver aucun état entre les appels pour différentes demandes d'enchères. La fonction d'enchères calcule et renvoie un CPM basé sur un prix d'enchère pour un candidat d'annonce donné, sur la base d'une combinaison de données contextuelles et de données de groupes de centres d'intérêt.

Une fonction d'enchères doit accepter et s'exécuter avec un objet vide comme paramètre d'entrée. Une entrée vide est fournie aux fonctions d'enchères lors de leur initialisation unique. Au moment de l'initialisation, un instantané de la fonction d'enchères est créé et appelé plusieurs fois pour permettre au compilateur JIT (juste à temps) d'optimiser les points chauds dans le code.

/**
 * Returns a bid price CPM for a given ad candidate.
 *
 * @param {Object} inputs an object with the
 *                 following named fields:
 *                   - openrtbContextualBidRequest or googleContextualBidRequest
 *                   - customContextualSignal
 *                   - interestBasedBidData
 */
function biddingFunction(inputs) {
  ...
  return inputs.interestBasedBidData.cpm
      * inputs.customContextualSignals.placementMultiplier;
}

Les champs nommés dans l'argument d'objet inputs incluent (sous réserve de modification à mesure de la progression du test):

openrtbContextualBidRequest (Objet JS) Demande d'enchère contextuelle dans le protocole OpenRTB. Les enchérisseurs qui utilisent le protocole RTB d'Authorized Buyers doivent ignorer cette entrée et ne doivent pas l'utiliser dans leurs fonctions d'enchères.
googleContextualBidRequest (Objet JS) Demande d'enchère contextuelle dans le protocole Google Authorized Buyers. Les enchérisseurs utilisant le protocole OpenRTB doivent ignorer cette entrée et ne doivent pas l'utiliser dans leurs fonctions d'enchères.
customContextualSignal (Objet JS) Données personnalisées fournies par l'enchérisseur dans la réponse de l'enchère contextuelle. L'enchérisseur détermine le format.
interestBasedBidData (Objet JS) Données personnalisées fournies par l'enchérisseur dans la réponse à l'enchère d'un groupe de centres d'intérêt. L'enchérisseur détermine le format.

Gérer les fonctions d'enchères via une API

Cette ressource d'API expérimentale permet aux enchérisseurs d'importer des fonctions d'enchères dans Google et de les gérer.

Point de terminaison de service de base:https://realtimebidding.googleapis.com

Ressource: Fonction d'enchères

{
  "name": string,
  "biddingFunction": string
}

Le champ name représente le nom de la fonction d'enchères. Il doit respecter le format bidders/{bidderAccountId}/biddingFunctions/{biddingFunctionName}, où biddingFunctionName est choisi par un enchérisseur.

Le champ biddingFunction est le code source JavaScript de la fonction d'enchères, avec les exigences suivantes:

  • Taille < 5 Mio.
  • Il doit respecter les exigences de l'interface de la fonction d'enchères.
  • Doit permettre l'exécution sans aucune entrée lors de la création initiale dans le bac à sable.

Exemple :

{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;})"
}

Créer une fonction d'enchères

Une fonction d'enchères sera disponible dans les réponses des groupes de centres d'intérêt environ une heure après un appel réussi de l'API CreateBiddingFunction.

POST https://realtimebidding.googleapis.com/v1alpha/{parent=bidders/*}/biddingFunctions
Paramètres de chemin d'accès
parent Chaîne au format bidders/{bidderAccountId}
Body: Fonction d'enchères à créer
{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;})"
}
Réponse (fonction d'enchère)
{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;};)"
}

Répertorier les fonctions d'enchères existantes

GET https://realtimebidding.googleapis.com/v1alpha/bidders/{bidderAccountId}/biddingFunctions
Paramètres de chemin d'accès
parent Chaîne au format bidders/{bidderAccountId}.
Paramètres de requête
pageToken Jeton de chaîne identifiant une page de résultats que le serveur doit renvoyer. Cette valeur est reçue d'une réponse à un appel ListBiddingFunctions précédent si les résultats ne tiennent pas sur une page.
Réponse
{
  "biddingFunctions": [
    {
      object (BiddingFunction)
    }
  ],
  "nextPageToken": string
}
Exemple d'appel
GET https://realtimebidding.googleapis.com/v1alpha/bidders/123456789/biddingFunctions

Modifications apportées au protocole du système d'enchères en temps réel à partir de la simulation TURTLEDOVE

Protocole RTB Authorized Buyers

Demandes d'enchères

Dans le test, une demande d'enchère contextuelle ressemble aux demandes d'enchères classiques, mais les identifiants utilisateur pseudonymes sont masqués.

// All fields will be filled unless otherwise specified.
message BidRequest {
  // Fields below would not be populated in the experiment
  optional string google_user_id = ...;
  optional uint32 cookie_version = ...;
  optional int32 cookie_age_seconds = ...;
  optional bytes hosted_match_data = ...;
  optional string session_id = ...;

  // Contextual fields below will be populated
  optional string publisher_id = ...;
  optional string url = ...;
  ...
  message Mobile {
    // Device advertising identifiers below would not be populated
    // in the contextual requests in the experiment
    optional bytes encrypted_advertising_id = ...;
    optional bytes advertising_id = ...;
    ...
    optional bytes encrypted_hashed_idfa = ...;
    optional bytes hashed_idfa = ...;
    ...
  }
  ...
  message AdSlot {
    message MatchingAdData {
      repeated int64 billing_id = ...;
      ...
    }
    ...
  }
  repeated AdSlot adslot = ...;
  ...
}

Exemple :

{
  id: "_\321\326\000\n\301\207\n\323\n\227",
  ip: "S\030\347",
  user_agent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
  publisher_country: "RU",
  geo_criteria_id: 9061060,
   adslot: [{
    id: 1,
    ad_block_key: 3613182520,
    width:   [240,200,120],
    height:   [400,200,240],
    matching_ad_data:   [{
      billing_id:     [923487589],
      minimum_cpm_micros: 850000
    }]
  }]
}

Une requête ciblée par centres d'intérêt dans le test contiendra des identifiants utilisateur conventionnels, soumis à tous les contrôles et protections de confidentialité existants, mais ne contiendra pas les informations contextuelles (URL de la page, ID d'éditeur, etc.).

// Most fields would not be populated in the experiment unless otherwise specified.
message BidRequest {
   // Will be provided, subject to the existing privacy controls.
  optional string google_user_id = ...;
  optional uint32 cookie_version = ...;
  optional int32 cookie_age_seconds = ...;
  optional bytes hosted_match_data = ...;

  message AdSlot {
    // Will be filled.
    repeated int32 width = ...;
    repeated int32 height = ...;
    optional ConsentedProvidersSettings consented_providers_settings = ...;
    optional bool regs_gdpr = ...;
    optional bool regs_lgpd = ...;

    message MatchingAdData {
      // Will be filled.
      repeated int64 billing_id = ...;
      ...
    }
    ...
  }
  repeated AdSlot adslot = ...;
  ...
}

Exemple :

id: "_\322\207\000\003\320\n\031\177C\307\215\035"
adslot {
  id: 1
  width: 1200
  height: 60
  consented_providers_settings {
    consented_providers: 292
    tcf_consent_string: "CO-eDrRO-eDrREkAAAAAAAAeYwf95y3p-wzhheMCY70-vv__7v3ff_3g"
  }
  regs_gdpr: true
  matching_ad_data {
    billing_id: 9833784997
  }
}
google_user_id: "ABCDEF1"
hosted_match_data: "ABCABCABC2"

Réponses aux enchères

Une réponse d'enchère contextuelle peut contenir des données contextuelles personnalisées spécifiques à un enchérisseur, dans un format arbitraire, qui seront transmises ultérieurement à la fonction d'enchères.

message BidResponse {
  message Ad {
    message AdSlot {
      required int64 max_cpm_micros = ...;
      ...
    }
    repeated AdSlot adslot = ...;
    ...
  }
  repeated Ad ad = ...;
  // Contains contextual signals that will be passed to the bidding function.
  // This can be any JSON value. For example:
  // {"foo": "bar", "base": [1, 2, 3]}
  optional google.protobuf.Value custom_contextual_signal = ...;

  ...
}

Par exemple :

ad {
  html_snippet: "<iframe src=\"http://example.com/something" width=\"300\" height=\"250\" scrolling=\"no\" frameBorder=\"0\" ></iframe>"
  adslot {
    id: 1
    max_cpm_micros: 100000
    billing_id: 1234567890
  }
  click_through_url: "https://www.example.com.pl"
  attribute: 47
  buyer_creative_id: "FFI399F3HI9HFH"
  width: 300
  height: 250
  impression_tracking_url: "http://example.com/impression"
}
custom_contextual_signal {
 struct_value {
   fields {
     name: "string_data_name"
     value {
       string_value: "string_value_1"
     }
   }
   fields {
     name: "bool_data_name"
     value {
       bool_value: true
     }
   }
 }
}
processing_time_ms: 1

Une enchère basée sur les groupes de centres d'intérêt

Dans la réponse à l'enchère du groupe de centres d'intérêt, chaque enchère contiendra une référence à la fonction d'enchères par son nom. Les fonctions d'enchères sont fournies à l'avance par un enchérisseur.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
message BidResponse {
  // Ad HTML code that will be rendered normally upon winning.
  optional string html_snippet = ...;

  message Ad {
    message AdSlot {
      // Should not be populated for interest group-based bids.
      required int64 max_cpm_micros = ...;
      ...
    }
    repeated AdSlot adslot = ...;

    // Will be filled.
    // This is the bidding function name that references a bidding function
    // that is provided ahead of time through Bidding functions API resource.
    optional string bidding_function_name = ...;

    // Contains interest group-related data that will be passed
    // to the bidding function. This can be any JSON value.
    optional google.protobuf.Value interest_group_data = ...;
    ...
  }
  repeated Ad ad = ...;
  ...
}

Exemple :

ad {
  html_snippet: "<iframe src=\"http://example.com/something" width=\"300\" height=\"250\" scrolling=\"no\" frameBorder=\"0\" ></iframe>"
  adslot {
    id: 1
    max_cpm_micros: 0
    billing_id: 1234567890
    bidding_function_name: "bidders/123/biddingFunctions/my_bidding_function_1"
    interest_group_data {
      struct_value {
        fields {
          name: "string_data_name"
          value {
            string_value: "string_value_1"
          }
        }
        fields {
          name: "bool_data_name"
          value {
            bool_value: true
          }
        }
      }
    }
  }
  click_through_url: "https://www.example.com.pl"
  attribute: 47
  buyer_creative_id: "FFI399F3HI9HFH"
  width: 300
  height: 250
  impression_tracking_url: "http://example.com/impression"
}
processing_time_ms: 1

OpenRTB

Demandes d'enchères

Requête contextuelle (au format JSON)
// All fields will be filled unless otherwise specified.
{
  // Fields below would not be populated in the experiment
  "user": {...}

  "device": {
    // Fields below would not be populated in the experiment
    "ifa": ...
    "dpidsha1": ...
    "dpidmd5": ...


    // Other fields will not be affected by the experiment
    ...
  }

  // Other fields will not be affected by the experiment
  ...
}
Requête ciblée par centres d'intérêt (au format JSON)
// Most fields would not be populated in the experiment unless otherwise specified.
{
  // Will be provided, subject to the existing privacy controls.
  "user": {
    "id": "BFEUKH3"
    "buyeruid": "FEI3F3I29"
    "ext": {
      "consented_providers": [ 292 ]
      "tcf_consent_string": "CO-eDrRO-eDrREkAAilsbO2dYGD9Pn8HT3ZCY70-vv__7v3ff_3g"
    }
  }

  "imp": {
    // Will be provided, subject to the existing privacy controls.
    "banner": {
      "w": ...
      "h": ...
    }

    "ext": {
      // Will be provided, subject to the existing privacy controls.
      "billing_id": [...]

      // Other fields will not be provided by the experiment
      ...
    }
  }
}

Réponses aux enchères

Une réponse d'enchère contextuelle peut contenir des données contextuelles personnalisées, spécifiques à un enchérisseur, qui seront transmises ultérieurement à la fonction d'enchères.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
{
  ...
  "seatbid": [{
     "bid": [...],
     ...
  }],
  ...
  "ext": {
    // Contains contextual signals that will be passed to the bidding function.
    // This signal can be any JSON blob. For example:
    // {"foo", "bar", "base": [1, 2, 3]}
    "custom_contextual_signal": ...
  }
}

Réponse à une enchère basée sur des groupes de centres d'intérêt

Dans la réponse à l'enchère du groupe de centres d'intérêt, chaque enchère contiendra une référence à la fonction d'enchères par son nom. Les fonctions d'enchères sont fournies à l'avance par un enchérisseur.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
{
  "bid": [{
       "id": ...
       ...
       "ext": {
         // This is the bidding function name that references a bidding function
         // that is provided ahead of time through Bidding functions API resource.
         "bidding_function_name": ...

         // Contains interest group related data that will be passed to the
         // bidding function.
         // This signal can be any JSON blob. For example:
         // {"foo", "bar", "base": [1, 2, 3]}
         "interest_group_data": ...
       }
    }
    ...
  ]
}