Les services d'enchères et de mise aux enchères sont un ensemble de services destinés aux acheteurs et aux vendeurs d'annonces qui s'exécutent dans un environnement d'exécution sécurisé (TEE) pour faciliter les enchères Protected Audience (PA). Ce guide du développeur explique comment un vendeur peut intégrer une mise aux enchères avec enchères publicitaires Chrome pour les enchères et les mises aux enchères.
Tutoriel
La procédure peut se résumer comme suit:
- Appeler
getInterestGroupAdAuctionData()
pour obtenir la charge utile chiffrée à partir du navigateur - Appelez
fetch('https://your-ad-server.example')
et envoyez la requête d'enchères unifiées avec la charge utile chiffrée à votre SAS. - Appelez l'opération
SelectAd()
de votre SFE à partir de votre SAS pour exécuter l'enchère d'enchères et de mise aux enchères. - Renvoyez le résultat de l'enchère aux enchères et aux mises aux enchères sur la page, ainsi que le hachage de la réponse.
- Appelez
runAdAuction()
dans le navigateur pour exécuter une mise aux enchères par enchères publiques avec un seul vendeur, en mode mixte ou avec plusieurs vendeurs, et transmettez le résultat de la mise aux enchères côté serveur à l'appel.
Obtenir des données chiffrées sur les enchères d'annonces
Pour obtenir les données nécessaires à l'exécution des enchères et des mises aux enchères côté serveur, le code JavaScript du vendeur sur la page de l'éditeur appelle navigator.getInterestGroupAdAuctionData()
.
const adAuctionData = await navigator.getInterestGroupAdAuctionData({
seller: 'https://ssp.example', // Required
requestSize: 51200,
coordinatorOrigin: 'https://publickeyservice.pa.gcp.privacysandboxservices.com/',
perBuyerConfig: {
'https://dsp-x.example': { targetSize: 8192 },
'https://dsp-y.example': { targetSize: 8192 }
}
});
const { requestId, request } = adAuctionData;
Champ | Description |
---|---|
seller |
Obligatoire. Origine du vendeur qui organise l'enchère. Cette valeur doit correspondre à la valeur seller de l'appel runAdAuction() ultérieurement.
|
requestSize |
Facultatif. Définit la taille maximale de la charge utile de toutes les données de l'acheteur. Pour en savoir plus, consultez la section Taille de la requête de la vidéo explicative. |
perBuyerConfig |
Facultatif. Définit des configurations pour chaque acheteur et contrôle également les acheteurs qui participent aux enchères d'enchères et de mise aux enchères.
Si les origines des acheteurs sont listées dans |
targetSize |
Facultatif si requestSize est défini. Obligatoire si une origine d'acheteur est définie dans perBuyerConfig , mais que requestSize ne l'est pas. Définit la taille maximale de la charge utile des données de cet acheteur. Pour en savoir plus, consultez la section Taille de la requête de la vidéo explicative. |
coordinatorOrigin |
Facultatif, mais deviendra obligatoire à terme. Si cette valeur n'est pas définie, la valeur par défaut est https://publickeyservice.pa.gcp.privacysandboxservices.com .Définit le coordinateur à utiliser pour extraire la clé de chiffrement de la charge utile. Pour en savoir plus, consultez la section Coordinateur de la vidéo explicative. |
Lorsque l'appel est effectué, le navigateur lit les groupes de centres d'intérêt des acheteurs listés dans perBuyerConfig
et chiffre les données des acheteurs. Ces données d'acheteur contiennent des informations intersites à utiliser pour les enchères et ne peuvent pas être déchiffrées en dehors d'un TEE. Pour l'optimisation de la charge utile, seuls le nom du groupe d'intérêts, les clés de signal d'enchères approuvées et les signaux du navigateur sont inclus dans la charge utile.
Dans l'objet de données d'enchères publicitaires renvoyé par l'appel getInterestGroupAdAuctionData()
, la chaîne requestId
et le tableau d'octets request
chiffré sont disponibles.
La chaîne requestId
est utilisée plus tard lorsque runAdAuction()
est appelé pour terminer l'enchère dans le navigateur. La charge utile request
chiffrée est envoyée au service publicitaire du vendeur dans le cadre de la demande d'enchères unifiées.
Pour voir un exemple de cet appel, consultez le code JavaScript du vendeur de l'application de test locale.
Envoyer la requête d'enchères unifiées à SAS
Une requête d'enchères unifiées est une requête qui contient la charge utile d'enchères contextuelles en texte brut et la charge utile d'enchères PA. La charge utile d'enchères d'enchères publiques est constituée des données request
chiffrées générées par le navigateur dans l'appel getInterestGroupAdAuctionData()
. Cette requête est envoyée à SAS, où les enchères contextuelles et les enchères d'enchères et d'enchères publiques sont orchestrées.
fetch('https://ssp.example/ad-auction', {
method: 'POST',
adAuctionHeaders: true,
body: JSON.stringify({
contextualAuctionPayload: { somePayload },
protectedAudienceAuctionPayload: encodeBinaryData(request)
}),
});
Pour envoyer la requête à SAS, un appel fetch()
est effectué à partir de la page:
- L'appel doit inclure l'option
adAuctionHeaders: true
, qui indique au navigateur de vérifier la réponse de cet appel ultérieurement, lorsquerunAdAuction()
est appelé pour terminer l'enchère dans le navigateur. - L'origine de la requête de récupération doit correspondre à l'origine
seller
fournie aux appelsgetInterestGroupAdAuctionData()
etrunAdAuction()
.
Le corps de l'appel contient les éléments suivants:
- Charge utile d'enchères contextuelles en texte brut à utiliser par SAS pour exécuter les enchères contextuelles.
- Charge utile d'enchères Protected Audience chiffrée à envoyer au SFE par SAS pour exécuter les enchères et mises aux enchères côté serveur.
Pour voir un exemple de cet appel, consultez le code JavaScript du vendeur de l'application de test locale.
Encodage et décodage en base64
La charge utile request
chiffrée renvoyée par l'appel getInterestGroupAdAuctionData()
est une instance de Uint8Array
, un type de données que JSON ne peut pas gérer. Pour envoyer le tableau d'octets au format JSON, vous pouvez appliquer un encodage base64 aux données binaires pour les convertir en chaîne.
L'API du navigateur JavaScript fournit les fonctions atob()
et btoa()
sur window
qui convertissent les données binaires en chaîne ASCII encodée en base64. (atob
signifie "ASCII vers binaire" et btoa
"binaire vers ASCII").
L'appel de btoa()
pour encoder des données binaires dans une chaîne encodée en base64 se présente comme suit:
function encodeBinaryData(data) {
return btoa(String.fromCharCode.apply(null, data));
}
Le résultat de l'enchère d'enchères et de mise aux enchères chiffré renvoyé par cet appel fetch
est également encodé en base64. Vous devez donc le décoder en données binaires. Appelez atob()
pour décoder la chaîne ASCII encodée en base64 en données binaires:
function decodeBase64String(base64string) {
return new Uint8Array(
atob(base64string)
.split('')
.map((char) => char.charCodeAt(0))
);
}
Toutefois, une chaîne encodée en base64 est généralement environ 33% plus volumineuse que les données d'origine. Pour améliorer encore la latence, utilisez un format autre que JSON pour envoyer les données binaires.
Appeler SelectAd
de SFE pour exécuter les enchères et les mises aux enchères
Une fois que le service publicitaire du vendeur a reçu la demande d'enchères unifiées de la page, la mise aux enchères contextuelle s'exécute en premier pour déterminer le gagnant de la mise aux enchères contextuelle et collecter les signaux de l'acheteur à transmettre à la mise aux enchères et aux enchères PA. Ensuite, l'enchère d'enchères et de mise aux enchères est lancée en appelant l'opération SelectAd
de la SFE à partir de SAS avec la charge utile de la requête. Notez que certaines métadonnées de la requête de la page envoyée à SAS à l'étape 2 sont transmises à SFE.
Créer la charge utile SelectAdRequest
La charge utile de la requête de l'appel SelectAd
peut être construite comme suit:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp.example',
auction_signals: '{"testKey":"someValue"}',
seller_signals: '{"testKey":"someValue"}',
buyer_list: [
'https://dsp-x.example',
'https://dsp-y.example',
],
per_buyer_config: {
'https://dsp-x.example': { buyer_signals: '{"testKey": "someValue"}' },
'https://dsp-y.example': { buyer_signals: '{"testKey": "someValue"}' },
},
},
client_type: 'CLIENT_TYPE_BROWSER',
protected_auction_ciphertext: decodeBase64string(request)
};
Notez que si les données d'enchères publicitaires chiffrées du navigateur ont été encodées en base64, elles doivent être décodées en données binaires si la requête envoyée à la SFE utilise gRPC. Si la requête est envoyée via HTTP, les données d'enchères publicitaires chiffrées peuvent rester sous leur forme encodée en base64.
Pour afficher les autres champs définis dans la requête SelectAd
, consultez la définition du protocole SelectAdRequest
.
Définir le champ du vendeur de premier niveau pour les enchères en mode mixte et les enchères par composants
Si le vendeur exécute une mise aux enchères en mode mixte ou participe en tant que vendeur de composants à une mise aux enchères multivendeur, le champ top_level_seller
doit être défini dans la requête.
Si vous êtes un vendeur en mode mixte, la valeur top_level_seller
correspond à votre origine:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp-mix.example',
top_level_seller: 'https://ssp-mix.example',
}
}
Si vous êtes un vendeur de composants, la valeur top_level_seller
correspond au vendeur de premier niveau de l'enchère multivendeur:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp-mix.example',
top_level_seller: 'https://ssp-top.example',
}
}
Appeler le SelectAd
de SFE
L'appel à SFE à partir de SAS peut être effectué avec gRPC ou HTTP.
Appel gRPC
La requête gRPC envoyée à SFE ressemble à celle-ci avec Express dans Node avec un client gRPC:
import grpc from '@grpc/grpc-js';
// Load proto definition
const packageDefinition = protoLoader.loadSync(protoPath, { keepCase: true, enums: String });
const {
privacy_sandbox: {
bidding_auction_servers: { SellerFrontEnd }
}
} = grpc.loadPackageDefinition(packageDefinition);
// Instantiate the gRPC client
const sfeGrpcClient = new SellerFrontEnd('192.168.84.104:50067', grpc.credentials.createInsecure());
// Send SelectAd request
sfeGrpcClient.selectAd(selectAdRequest,(error, response) => {
// Handle SFE response
});
La définition du protocole pour le client SFE se trouve dans le dépôt d'applications de test local.
Appel HTTP au proxy Envoy
La requête HTTP POST envoyée à SFE est envoyée au chemin d'accès /v1/selectAd
et se présente comme suit:
fetch('https://ssp-ba.example/sfe/v1/selectAd', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(selectAdRequest),
});
Transmettre les métadonnées
Les métadonnées suivantes de l'appel de la page à SAS doivent être ajoutées à l'appel SelectAd
de SAS à SFE:
Accept-Language
User-Agent
- Adresse IP
Lorsque les métadonnées sont envoyées à SFE, elles doivent utiliser les en-têtes non standards suivants, car gRPC peut modifier l'en-tête User-Agent
:
X-Accept-Language
X-User-Agent
X-BnA-Client-IP
Vous trouverez ci-dessous un exemple de transfert de métadonnées à l'aide d'Express dans Node avec un client gRPC:
sellerAdService.post('/ad-auction', (req, res) => {
// …
const metadata = new grpc.Metadata();
metadata.add('X-Accept-Language', req.header('Accept-Language'));
metadata.add('X-User-Agent', req.header('User-Agent'));
metadata.add('X-BnA-Client-IP', req.ip);
const sfeGrpcClient = createSfeGrpcClient();
sfeGrpcClient.selectAd(selectAdRequest, metadata, callbackFn);
})
Voici un exemple de transfert de métadonnées à l'aide d'un appel HTTP:
sellerAdService.post('/ad-auction', (req, res) => {
// …
fetch('https://ssp-ba.example/sfe/v1/selectAd', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Accept-Language': req.header('Accept-Language'),
'X-User-Agent': req.header('User-Agent'),
'X-BnA-Client-IP': req.ip
},
body: JSON.stringify(selectAdRequest)
});
})
Enchères multivendeurs orchestrées par le serveur
Si vous êtes un vendeur de niveau supérieur qui exécute une enchère multivendeur orchestrée par le serveur, l'appel GetComponentAuctionCiphertexts
est effectué auprès de SFE avant l'appel SelectAd
. La réponse contient les charges utiles d'enchères de composants re-chiffrées qui sont envoyées aux services publicitaires des vendeurs de composants. Les résultats des enchères d'annonces d'enchères et de mise aux enchères du composant renvoyés sont fournis à l'appel SelectAd
du SFE du vendeur de niveau supérieur.
Pour en savoir plus, consultez la présentation du multivendeur sur GitHub.
Renvoie le résultat de la mise aux enchères sur la page
Une fois l'enchère de mise aux enchères et de mise aux enchères terminée, le résultat de l'enchère chiffré est renvoyé à SAS, qui répond à la requête d'enchères unifiées à partir de la page de l'étape 2 avec le résultat de l'enchère chiffré. Dans la réponse SAS à la page, le hachage SHA-256 encodé en base64url du résultat de l'enchère chiffrée est défini dans l'en-tête de réponse Ad-Auction-Result
. Ce hachage est utilisé par le navigateur pour valider la charge utile à la fin de l'enchère dans le client.
La création d'un hachage SHA-256 avec encodage base64 se présente comme suit dans Node:
import { createHash } from 'crypto';
createHash('sha256')
.update(binaryData, 'base64')
.digest('base64url');
L'ajout du hachage dans l'en-tête de réponse et le renvoi du résultat de l'enchère sur la page se présentent comme suit:
sellerAdService.post('/ad-auction', (req, res) => {
// …
sfeGrpcClient.selectAd(selectAdRequest, metadata, (error, response) => {
const { auction_result_ciphertext } = response;
const ciphertextShaHash = createHash('sha256')
.update(auction_result_ciphertext, 'base64')
.digest('base64url');
res.set('Ad-Auction-Result', ciphertextShaHash);
res.json({
protectedAudienceAuctionResult: encodeBinaryData(auction_result_ciphertext),
contextualAuctionResult: getContextualAuctionResult()
});
});
})
Comme il s'agit d'une réponse à la requête d'enchères unifiées effectuée à partir de la page à l'étape 2, le résultat de la mise aux enchères contextuelle est également inclus dans la réponse.
Vous pouvez inclure plusieurs hachages dans le Ad-Auction-Result
en répétant l'en-tête ou en séparant les hachages. Les deux en-têtes de réponse suivants sont équivalents:
Ad-Auction-Result: ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0=,9UTB-u-WshX66Xqz5DNCpEK9z-x5oCS5SXvgyeoRB1k=
Ad-Auction-Result: ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0=
Ad-Auction-Result: 9UTB-u-WshX66Xqz5DNCpEK9z-x5oCS5SXvgyeoRB1k=
Pour voir un exemple de cet appel, consultez le code du serveur du vendeur de l'application de test locale.
Appeler runAdAuction()
pour finaliser l'enchère
La réponse aux enchères unifiées renvoyée par SAS inclut le résultat de l'enchère d'enchères et de mise aux enchères chiffré. Cette charge utile est transmise à l'appel runAdAuction()
pour finaliser l'enchère dans le navigateur. La valeur requestId
de l'appel getInterestGroupAdAuctionData()
à l'étape 1 est également transmise à l'enchère.
// Get the encrypted ad auction data (Step #1)
const { requestId, request } = navigator.getInterestGroupAdAuctionData(adAuctionDataConfig)
// Send unified auction request (Step #2)
const response = await fetch('https://ssp-ba.example/ad-auction', {
method: 'POST',
body: JSON.stringify({
adAuctionRequest: encodeBinaryData(request),
}),
});
const { protectedAudienceAuctionResult } = await response.json();
// Finish the auction in the browser
await navigator.runAdAuction({
// pass in "requestId" and "protectedAudienceAuctionResult"
// the config structure will differ based on the auction configuration
});
La structure de la configuration des enchères transmise à l'appel runAdAuction()
varie en fonction de la configuration des enchères choisie par le vendeur.
Enchères avec un seul vendeur
Pour exécuter une mise aux enchères d'enchères et de mise aux enchères avec un seul vendeur, la configuration de l'enchère de l'appel runAdAuction()
est construite comme suit:
await navigator.runAdAuction({
seller: 'https://ssp-ba.example',
requestId,
serverResponse: protectedAudienceAuctionResult,
});
Le champ requestId
accepte le requestId
renvoyé par l'appel getInterestGroupAdAuctionData()
. Le champ serverResponse
accepte un tableau d'octets de l'enchère d'enchères et de mise aux enchères exécutée à l'étape 3.
Pour voir un exemple de cet appel, consultez le code JavaScript du vendeur de l'application de test locale.
Enchères en mode mixte
Pour exécuter une mise aux enchères en mode mixte, où les acheteurs sur l'appareil et les acheteurs de mise aux enchères peuvent participer, la configuration des enchères de l'appel runAdAuction()
est construite comme suit:
await navigator.runAdAuction({
seller: 'https://ssp-mix.example',
decisionLogicURL: 'https://ssp-mix.example/score-ad.js',
componentAuctions: [
// B&A auction result
{
seller: 'https://ssp-mix.example',
requestId,
serverResponse: protectedAudienceAuctionResult,
},
// On-device auction config
{
seller: 'https://ssp-mix.example',
decisionLogicURL: 'https://ssp-mix.example/on-device-score-ad.js',
interestGroupBuyers: [
'https://dsp-a.example', // On-device buyer
'https://dsp-a.example', // On-device buyer
],
},
]
});
Pour faciliter les enchères en mode mixte, le résultat des enchères et la configuration des enchères sur l'appareil sont transmis dans le champ componentAuctions
. Dans une mise aux enchères en mode mixte, la valeur seller
est identique pour la configuration de premier niveau et les configurations des composants.
Pour voir un exemple de cet appel, consultez le code JavaScript du vendeur de l'application de test locale.
Enchères multivendeurs
Si vous êtes un vendeur de premier niveau qui exécute une mise aux enchères multivendeur orchestrée par l'appareil, chaque vendeur de composants envoie le résultat de la mise aux enchères d'enchères et les configurations d'enchères sur l'appareil.
await navigator.runAdAuction({
seller: 'https://ssp-top.example',
decisionLogicURL: 'https://ssp-top.example/score-ad.js',
componentAuctions: [
// SSP-BA's B&A-only auction result
{
seller: 'https://ssp-ba.example',
requestId: 'g8312cb2-da2d-4e9b-80e6-e13dec2a581c',
serverResponse: Uint8Array(560) [193, 120, 4, …] // Encrypted B&A auction result
},
// SSP-MIX's B&A auction result
{
seller: 'https://ssp-mix.example',
requestId: 'f5135cb2-da2d-4e9b-80e6-e13dec2a581c',
serverResponse: Uint8Array(560) [133, 20, 4, …] // Encrypted B&A auction result
}.
// SSP-MIX's on-device auction config
{
seller: 'https://ssp-mix.example',
interestGroupBuyers: ['https://dsp-a.example', 'https://dsp-b.example'],
decisionLogicURL: 'https://ssp-mix.example/score-ad.js',
}
// SSP-OD's on-device auction config
{
seller: 'https://ssp-od.example',
interestGroupBuyers: ['https://dsp-a.example', 'https://dsp-b.example'],
decisionLogicURL: 'https://ssp-od.example/score-ad.js',
}
]
})
Pour voir un exemple de cet appel, consultez le code JavaScript du vendeur de l'application de test locale.
Étapes suivantes
Après avoir lu ce guide, vous pouvez procéder comme suit:
En savoir plus
- Pour en savoir plus, consultez les explications suivantes sur GitHub :
- En savoir plus sur l'architecture des enchères et des mises aux enchères pour le Web
- Testez Protected Audience avec des tests A/B en suivant l'atelier de programmation sur les tests locaux de bout en bout.
Vous avez des questions ?
- Si vous avez des questions sur les services d'enchères et de mise aux enchères, ouvrez un problème dans le dépôt des services d'enchères et de mise aux enchères.
- Si vous avez une question sur la Privacy Sandbox en général, ouvrez un problème dans le dépôt privacy-sandbox-dev-support.