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. - Devuelve el resultado de la subasta de B&A a 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 la subasta 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 del explicador para obtener más información. |
perBuyerConfig |
Opcional. Establece la 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 |
Es 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 del explicador para obtener más información. |
coordinatorOrigin |
Opcional, pero será obligatorio en el futuro. 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 del explicador para obtener más información. |
Cuando se realiza la llamada, el navegador lee los grupos de intereses de los compradores que se indican en perBuyerConfig y encripta los datos del comprador. Estos datos del comprador contienen información de varios sitios que se usará para las ofertas y no se pueden descifrar fuera de un TEE. Para la optimización de la carga útil, solo se incluyen en ella el nombre del grupo de interés, las claves de indicadores de ofertas de confianza y los indicadores del navegador.
En el objeto de datos de la subasta de anuncios que devuelve 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 al SAS
Una solicitud de subasta unificada es una solicitud que contiene la carga útil de la subasta contextual en texto sin formato 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 de request encriptados que el navegador generó en la llamada a getInterestGroupAdAuctionData(). Esta solicitud se envía a SAS, donde se coordina 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 a fetch() desde la página:
- La llamada debe incluir la opción
adAuctionHeaders: true, que indica al navegador que verifique la respuesta de esta llamada en un momento posterior 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
sellerproporcionado a las llamadas degetInterestGroupAdAuctionData()yrunAdAuction().
El cuerpo de la llamada contiene lo siguiente:
- Es la carga útil de la subasta contextual de texto sin formato que SAS usará para ejecutar la subasta contextual.
- Es la carga útil encriptada de la subasta de Protected Audience que el SAS debe enviar al 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 devuelve de 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 de JavaScript para navegadores proporciona las funciones atob() y btoa() en window que realizan la conversión entre datos binarios y cadenas ASCII codificadas en base64. (atob significa de ASCII a binario y btoa significa de 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 devuelve de esta llamada a fetch también está en una codificación base64, por lo que debes decodificarlo para volver a obtener 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 del SFE desde el 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.
Construye la carga útil de SelectAdRequest
La carga útil de la solicitud de la llamada a 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 encriptados de la subasta de anuncios del navegador se codificaron en base64, se deben decodificar y volver a convertirlos en datos binarios si la solicitud a SFE se envía con gRPC. Si la solicitud se envía a través de HTTP, los datos encriptados de la subasta de anuncios pueden permanecer en su formato codificado en Base64.
Para ver otros campos definidos en la solicitud de SelectAd, consulta la definición del .proto de SelectAdRequest.
Establece el campo del vendedor de nivel superior para las subastas de modo mixto y de componentes
Si el vendedor ejecuta una subasta en 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 un 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 un 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',
}
}
Llama al SelectAd de SFE
La llamada a SFE desde SAS se puede realizar con gRPC o HTTP.
Llamada de 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 para el cliente de SFE se puede encontrar en el repositorio de la app de prueba local.
Llamada HTTP al proxy de Envoy
La solicitud HTTP POST a SFE se envía a la ruta de acceso /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ío de metadatos
Los siguientes metadatos de la llamada de la página al SAS se deben agregar a la llamada SelectAd del SAS al SFE:
Accept-LanguageUser-Agent- Dirección IP
Cuando se envían los metadatos a SFE, deben usar los siguientes encabezados no estándar, ya que gRPC puede alterar el encabezado User-Agent:
X-Accept-LanguageX-User-AgentX-BnA-Client-IP
A continuación, se muestra un ejemplo de cómo se pueden retransmitir 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);
})
A continuación, se muestra un ejemplo de cómo se pueden retransmitir 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 organizada por el servidor
Si eres un vendedor de nivel superior que ejecuta una subasta de varios vendedores orquestada por el servidor, la llamada a GetComponentAuctionCiphertexts se realiza a SFE antes de que se realice la llamada a SelectAd. La respuesta contiene las cargas útiles de la subasta de componentes reencriptadas que se envían a los servicios de anuncios de componentes del vendedor. Los resultados de la subasta de anuncios de B&A del componente devuelto se proporcionan a la llamada SelectAd del SFE del vendedor de nivel superior.
Consulta la explicación sobre varios vendedores en GitHub para obtener más información.
Devuelve el resultado de la subasta de B&A a la página
Una vez que finaliza la subasta de B&A, el resultado encriptado de la subasta se devuelve a SAS, y SAS 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 encriptado 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.
En Node, la creación de un hash SHA-256 con codificación base64 se ve de la siguiente manera:
import { createHash } from 'crypto';
createHash('sha256')
.update(binaryData, 'base64')
.digest('base64url');
Adjuntar el hash en el encabezado de respuesta y devolver el resultado de la subasta a la página se ve 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()
});
});
})
Dado que esta es una respuesta a la solicitud de subasta unificada realizada 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 hashes en Ad-Auction-Result repitiendo el encabezado o separando los hashes. 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 la subasta unificada que se devuelve desde el 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 de 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 devuelve la llamada a 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 en modo mixto
Para ejecutar una subasta de B&A en modo mixto en la que pueden participar tanto los compradores en el dispositivo como los de B&A, la configuración de la subasta de la llamada 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 en modo mixto, el resultado de la subasta de B&A y la configuración de la subasta 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 coordinada por el dispositivo, cada vendedor componente envía el resultado de la subasta de B&A y los parámetros de configuración de la 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 comprender mejor el tema, consulta las siguientes explicaciones en GitHub:
- Obtén más información sobre la arquitectura de B&A para la Web
- Experimenta con Protected Audience con B&A siguiendo 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.