Los servicios de ofertas y subastas (B&A) son un conjunto de servicios para compradores y vendedores de anuncios que se ejecutan en un entorno de ejecución confiable (TEE) para facilitar una subasta de Protected Audience (PA). En esta guía para desarrolladores, se explica cómo un vendedor puede realizar la integración con una subasta de PA de Chrome para B&A.
Explicación
Los pasos se pueden resumir de la siguiente manera:
- Llama a
getInterestGroupAdAuctionData()
para obtener la carga útil encriptada del navegador. - Llama a
fetch('https://your-ad-server.example')
y envía la solicitud de subasta unificada con la carga útil encriptada a tu SAS. - Llama a la operación
SelectAd()
de tu SFE desde tu SAS para ejecutar la subasta de B&A. - Muestra el resultado de la subasta de B&A en la página junto con el hash de la respuesta.
- Llama a
runAdAuction()
en el navegador para ejecutar una subasta de PA de un solo vendedor, de modo mixto o de varios vendedores, y pasa el resultado de la subasta de B&A del servidor a la llamada.
Obtén datos encriptados de subastas de anuncios
Para obtener los datos necesarios para ejecutar la subasta de B&A del servidor, el código JavaScript del vendedor en la página del publicador llama a 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;
Campo | Descripción |
---|---|
seller |
Obligatorio. Es el origen del vendedor que ejecuta la subasta. Este valor debe coincidir con el valor de seller en la llamada a runAdAuction() más adelante.
|
requestSize |
Opcional. Establece el tamaño máximo de la carga útil de todos los datos del comprador. Consulta la sección tamaño de la solicitud de la explicación para obtener más información. |
perBuyerConfig |
Opcional. Establece parámetros de configuración para cada comprador y también controla qué compradores participan en la subasta de B&A.
Si los orígenes del comprador se enumeran en |
targetSize |
Opcional si se configura requestSize . Obligatorio si se establece un origen del comprador en perBuyerConfig , pero no se establece requestSize . Establece el tamaño máximo de la carga útil de los datos de ese comprador. Consulta la sección tamaño de la solicitud de la explicación para obtener más información. |
coordinatorOrigin |
Opcional, pero será obligatorio en algún momento. Si no se establece, el valor predeterminado es https://publickeyservice.pa.gcp.privacysandboxservices.com .Establece el coordinador que se usará para recuperar la clave para encriptar la carga útil. Consulta la sección coordinador de la explicación para obtener más información. |
Cuando se realiza la llamada, el navegador lee los grupos de intereses de los compradores que se enumeran en perBuyerConfig
y encripta sus datos. Estos datos del comprador contienen información entre sitios que se usará para las ofertas y no se pueden desencriptar fuera de un TEE. Para la optimización de la carga útil, solo se incluyen en la carga útil el nombre del grupo de intereses, las claves de los indicadores de ofertas de confianza y los indicadores del navegador.
En el objeto de datos de subasta de anuncios que muestra la llamada a getInterestGroupAdAuctionData()
, están disponibles la cadena requestId
y el array de bytes request
encriptado.
La cadena requestId
se usa más adelante cuando se llama a runAdAuction()
para finalizar la subasta en el navegador. La carga útil request
encriptada se envía al servicio de anuncios del vendedor como parte de la solicitud de subasta unificada.
Para ver un ejemplo de esta llamada, consulta el código JavaScript del vendedor de la app de prueba local.
Envía la solicitud de subasta unificada a SAS
Una solicitud de subasta unificada es una solicitud que contiene la carga útil de la subasta contextual de texto simple y la carga útil de la subasta de B&A de PA. La carga útil de la subasta de B&A de PA son los datos request
encriptados que el navegador generó en la llamada a getInterestGroupAdAuctionData()
. Esta solicitud se envía a SAS, donde se orquestan la subasta contextual y la subasta de B&A de PA.
fetch('https://ssp.example/ad-auction', {
method: 'POST',
adAuctionHeaders: true,
body: JSON.stringify({
contextualAuctionPayload: { somePayload },
protectedAudienceAuctionPayload: encodeBinaryData(request)
}),
});
Para enviar la solicitud a SAS, se realiza una llamada fetch()
desde la página:
- La llamada debe incluir la opción
adAuctionHeaders: true
, que le indica al navegador que verifique la respuesta de esta llamada más adelante cuando se llame arunAdAuction()
para finalizar la subasta en el navegador. - El origen de la solicitud de recuperación debe coincidir con el origen de
seller
proporcionado a las llamadasgetInterestGroupAdAuctionData()
yrunAdAuction()
.
El cuerpo de la llamada contiene lo siguiente:
- Es la carga útil de la subasta contextual en texto simple que usará SAS para ejecutar la subasta contextual.
- Es la carga útil de subasta de Protected Audience encriptada que SAS envía a SFE para ejecutar la subasta de B&A del servidor.
Para ver un ejemplo de esta llamada, consulta el código JavaScript del vendedor de la app de prueba local.
Codificación y decodificación en base64
La carga útil request
encriptada que se muestra desde la llamada getInterestGroupAdAuctionData()
es una instancia de Uint8Array
, que es un tipo de datos que JSON no puede controlar. Para enviar el array de bytes en formato JSON, puedes aplicar una codificación base64 a los datos binarios para convertirlos en una cadena.
La API del navegador de JavaScript proporciona las funciones atob()
y btoa()
en window
que convierten entre datos binarios y cadenas ASCII codificadas en base64. (atob
significa ASCII a binario y btoa
significa binario a ASCII).
La llamada a btoa()
para codificar datos binarios en una cadena codificada en base64 se ve de la siguiente manera:
function encodeBinaryData(data) {
return btoa(String.fromCharCode.apply(null, data));
}
El resultado de la subasta de B&A encriptado que se muestra desde esta llamada a fetch
también está en una codificación base64, por lo que debes volver a decodificarlo a datos binarios. Llama a atob()
para decodificar la cadena ASCII con codificación base64 en datos binarios:
function decodeBase64String(base64string) {
return new Uint8Array(
atob(base64string)
.split('')
.map((char) => char.charCodeAt(0))
);
}
Sin embargo, una cadena codificada en base64 suele ser un 33% más grande que los datos originales. Si deseas mejorar aún más la latencia, usa un formato que no sea JSON para enviar los datos binarios.
Llama a SelectAd
de SFE para ejecutar la subasta de B&A
Una vez que el servicio de anuncios del vendedor recibe la solicitud de subasta unificada de la página, primero se ejecuta la subasta contextual para determinar el ganador de la subasta contextual y recopilar los indicadores del comprador que se pasarán a la subasta de B&A de PA. Luego, se inicia la subasta de B&A llamando a la operación SelectAd
de SFE desde SAS con la carga útil de la solicitud. Ten en cuenta que algunos metadatos de la solicitud de la página a SAS en el paso 2 se reenvían a SFE.
Crea la carga útil de SelectAdRequest
La carga útil de la solicitud de la llamada SelectAd
se puede construir de la siguiente manera:
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)
};
Ten en cuenta que, si los datos de subasta de anuncios encriptados del navegador se codificaron en base64, se deben decodificar a datos binarios si la solicitud a SFE se envía con gRPC. Si la solicitud se envía mediante HTTP, los datos encriptados de la subasta de anuncios pueden permanecer en su forma codificada en Base64.
Para ver otros campos definidos en la solicitud SelectAd
, consulta la definición de proto de SelectAdRequest
.
Establece el campo de vendedor de nivel superior para las subastas de modo mixto y de componentes
Si el vendedor ejecuta una subasta de modo mixto o participa como vendedor de componentes en una subasta de varios vendedores, se debe definir el campo top_level_seller
en la solicitud.
Si eres vendedor de modo mixto, el valor de top_level_seller
es tu origen:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp-mix.example',
top_level_seller: 'https://ssp-mix.example',
}
}
Si eres vendedor de componentes, el valor de top_level_seller
es el vendedor de nivel superior de la subasta de varios vendedores:
const selectAdRequest = {
auction_config: {
seller: 'https://ssp-mix.example',
top_level_seller: 'https://ssp-top.example',
}
}
Llamar al SelectAd
de SFE
La llamada a SFE desde SAS se puede realizar con gRPC o HTTP.
Llamada a gRPC
La solicitud de gRPC a SFE se ve de la siguiente manera con Express en Node con un cliente de 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 definición de proto del cliente de SFE se encuentra en el repositorio de apps de prueba local.
Llamada HTTP al proxy de Envoy
La solicitud HTTP POST a SFE se envía a la ruta /v1/selectAd
y se ve de la siguiente manera:
fetch('https://ssp-ba.example/sfe/v1/selectAd', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(selectAdRequest),
});
Reenvía metadatos
Los siguientes metadatos de la llamada de la página a SAS se deben agregar a la llamada SelectAd
de SAS a SFE:
Accept-Language
User-Agent
- Dirección IP
Cuando los metadatos se envían a SFE, deben usar los siguientes encabezados no estándar porque gRPC puede alterar el encabezado User-Agent
:
X-Accept-Language
X-User-Agent
X-BnA-Client-IP
El siguiente es un ejemplo de cómo se pueden reenviar los metadatos con Express en Node con un cliente de 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);
})
El siguiente es un ejemplo de cómo se pueden reenviar los metadatos con una llamada 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)
});
})
Subasta de varios vendedores orquestada por el servidor
Si eres un vendedor de nivel superior que ejecuta una subasta de varios vendedores orquestada por el servidor, la llamada GetComponentAuctionCiphertexts
se realiza a SFE antes de que se realice la llamada SelectAd
. La respuesta contiene las cargas útiles de subasta de componentes reencriptadas que se envían a los servicios de anuncios del vendedor de componentes. Los resultados de la subasta de anuncios de B&A del componente que se muestra se proporcionan a la llamada SelectAd
de la SFE del vendedor de nivel superior.
Consulta la explicación de varios vendedores en GitHub para obtener más información.
Muestra el resultado de la subasta de B&A en la página
Después de que finaliza la subasta de B&A, el resultado encriptado de la subasta se muestra a SAS, que responde a la solicitud de subasta unificada de la página en el paso 2 con el resultado encriptado de la subasta. En la respuesta de SAS a la página, el hash SHA-256 codificado en base64url del resultado de la subasta encriptada se establece en el encabezado de respuesta Ad-Auction-Result
. El navegador usa este hash para verificar la carga útil cuando finaliza la subasta en el cliente.
Crear un hash SHA-256 con codificación base64 se ve de la siguiente manera en Node:
import { createHash } from 'crypto';
createHash('sha256')
.update(binaryData, 'base64')
.digest('base64url');
Si adjuntas el hash en el encabezado de respuesta y devuelves el resultado de la subasta a la página, se verá de la siguiente manera:
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()
});
});
})
Como esta es una respuesta a la solicitud de subasta unificada que se realizó desde la página en el paso 2, el resultado de la subasta contextual también se incluye en la respuesta.
Se pueden incluir varios valores hash en el Ad-Auction-Result
repitiendo el encabezado o separándolos. Los siguientes dos encabezados de respuesta son equivalentes:
Ad-Auction-Result: ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0=,9UTB-u-WshX66Xqz5DNCpEK9z-x5oCS5SXvgyeoRB1k=
Ad-Auction-Result: ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0=
Ad-Auction-Result: 9UTB-u-WshX66Xqz5DNCpEK9z-x5oCS5SXvgyeoRB1k=
Para ver un ejemplo de esta llamada, consulta el código del servidor del vendedor de la app de prueba local.
Llama a runAdAuction()
para completar la subasta.
La respuesta de subasta unificada que se muestra desde SAS incluye el resultado encriptado de la subasta de B&A. Esta carga útil se pasa a la llamada runAdAuction()
para finalizar la subasta en el navegador. El valor requestId
de la llamada a getInterestGroupAdAuctionData()
en el paso 1 también se pasa a la subasta.
// 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 estructura de la configuración de la subasta que se pasa a la llamada runAdAuction()
difiere según la configuración de la subasta que elija el vendedor.
Subasta de un solo vendedor
Para ejecutar una subasta de B&A de un solo vendedor, la configuración de la subasta de la llamada runAdAuction()
se construye de la siguiente manera:
await navigator.runAdAuction({
seller: 'https://ssp-ba.example',
requestId,
serverResponse: protectedAudienceAuctionResult,
});
El campo requestId
acepta el requestId
que muestra la llamada getInterestGroupAdAuctionData()
. El campo serverResponse
acepta un array de bytes de la subasta de B&A que se ejecutó en el paso 3.
Para ver un ejemplo de esta llamada, consulta el código JavaScript del vendedor de la app de prueba local.
Subasta de modo mixto
Para ejecutar una subasta de B&A en modo mixto en la que pueden participar compradores integrados en el dispositivo y de B&A, la configuración de la subasta de la llamada a runAdAuction()
se construye de la siguiente manera:
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
],
},
]
});
Para facilitar una subasta de modo mixto, el resultado de la subasta de B&A y la configuración de la subasta integrada en el dispositivo se pasan al campo componentAuctions
. En una subasta de modo mixto, el valor de seller
es el mismo para la configuración de nivel superior y las configuraciones de componentes.
Para ver un ejemplo de esta llamada, consulta el código JavaScript del vendedor de la app de prueba local.
Subasta de varios vendedores
Si eres un vendedor de nivel superior que ejecuta una subasta de varios vendedores orquestada por el dispositivo, cada vendedor de componentes envía su resultado de subasta de B&A y las configuraciones de subasta en el dispositivo.
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',
}
]
})
Para ver un ejemplo de esta llamada, consulta el código JavaScript del vendedor de la app de prueba local.
Próximos pasos
Después de leer esta guía, puedes seguir estos pasos:
Más información
- Para obtener una comprensión más profunda, consulta los siguientes instructivos en GitHub:
- Obtén más información sobre la arquitectura de B&A para la Web.
- Para experimentar con Protected Audience con pruebas A/B, sigue el codelab de pruebas locales de extremo a extremo.
¿Tienes alguna pregunta?
- Si tienes alguna pregunta sobre los servicios de ofertas y subastas, abre un problema en el repositorio de los servicios de ofertas y subastas.
- Si tienes alguna pregunta sobre Privacy Sandbox en general, abre un problema en el repositorio de privacy-sandbox-dev-support.