Para ayudar a los desarrolladores a comenzar a experimentar con la API de Protected App Signals, en este documento, se describen todas las APIs dentro de la plataforma de la API, se detalla cómo configurar un entorno de pruebas y se brindan ejemplos de la configuración y las secuencias de comandos.
Historial de versiones
enero de 2024
Primera versión de la guía para desarrolladores que respalda la versión del MVP de PAS
Marzo de 2024
Cambios en la API para admitir la versión M-2024-05 de la API de Android y la Lanzamiento de los componentes del servidor de abril de 2024. Cambios más importantes:
- Se agregaron detalles sobre los permisos necesarios para la API en el dispositivo.
- Se agregaron detalles sobre la administración de la cuota de indicadores integrados en el dispositivo.
- Se actualizó la firma
generateBid
con cambios relacionados con la orientación contextual recuperación de anuncios y compatibilidad con salida - Se actualizó la documentación de
reportWin
, incluida la compatibilidad con la salida - Actualización de la documentación de la API de Ad Retrieval para quitar la compatibilidad con la recuperación de anuncios BYOS y documentar la UDF de recuperación de anuncios
Descripción general de la API
La plataforma de la API de Protected Signals incluye diferentes subconjuntos de la API en diferentes sistemas:
- APIs de Android:
- API de Signal Curation, que incluye lo siguiente:
- API de Update Signals
- API de Signals Encoding
- API de Protected Auction Support (se usará en los SDKs para ejecutar la subasta protegida en los servidores de ofertas y subastas (B&A) con indicadores de app protegidos)
- APIs del servidor:
- API de Protected Auction: Una serie de secuencias de comandos de JS que se ejecutan en los servidores de ofertas y subastas. Esta API permite a los vendedores y compradores escribir la lógica para implementar la subasta protegida.
- API de Ad Retrieval: Se ocupa de proporcionar una lista de anuncios candidatos, según la información contextual y la del usuario que se pone a disposición del servidor de ofertas del comprador.
Cliente de Android
En el cliente, la plataforma de Protected App Signals consta de tres APIs diferentes:
- Update Signals: Una API del sistema Android que permite la selección de los indicadores en el dispositivo.
- Signals Encoding: Una API de JavaScript para preparar los indicadores que se enviarán al servidor durante la subasta.
- Protected Auction Support: Una API para admitir la ejecución de una subasta protegida en los servidores de ofertas y subastas. Esta API no es específica para Protected App Signals y también se usa para admitir subastas de la API de Protected Audience.
API de Update Signals
La API de Update Signals les proporciona a las tecnologías publicitarias la capacidad de registrar indicadores relacionados con el usuario y la app en nombre de un comprador. La API funciona en un modelo de delegación. El llamador proporciona un URI a partir del cual el framework recupera los indicadores correspondientes y la lógica para codificar esos indicadores que se usarán en la subasta.
La API requiere android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS
permiso.
La API de updateSignals()
recuperará un objeto JSON
del URI que describe qué indicadores agregar o quitar y cómo prepararte
esos indicadores para la subasta.
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 plataforma realiza una solicitud HTTPS para el URI proporcionado en la solicitud para recuperar las actualizaciones de los indicadores. Junto con las actualizaciones de los indicadores, la respuesta puede incluir un extremo que aloje la lógica de codificación para convertir los indicadores sin procesar en una carga útil codificada. Se espera que las actualizaciones de los indicadores tengan el formato JSON y puedan tener las siguientes claves:
Las claves de nivel superior del objeto JSON deben corresponder a uno de estos cinco comandos:
Clave |
Descripción |
|
Agrega un indicador nuevo y reemplaza los existentes con la misma clave. El valor de esta clave es un objeto JSON en el que las claves son cadenas de base 64 correspondientes a la clave que se va a colocar y los valores son cadenas de base 64 correspondientes al valor que se va a colocar. |
|
Agrega uno o varios indicadores nuevos a una serie temporal de indicadores, y quita los más antiguos para incluir los nuevos si el tamaño de la serie supera el máximo determinado. El valor de esta clave es un objeto JSON en el que las claves son cadenas de base 64 correspondientes a la clave que se agrega y los valores son objetos con dos campos: "values" y "maxSignals". "values": Una lista de cadenas de base 64 correspondientes a los valores del indicador que se agregarán a las series temporales. "maxSignals": La cantidad máxima de valores permitidos en esta serie temporal. Si la cantidad actual de indicadores asociados con la clave supera el objeto maxSignals, se quitarán los indicadores más antiguos. Ten en cuenta que puedes agregarlo a una clave introducida por put. Ten en cuenta que, si agregas más valores que la cantidad máxima, se producirá un error. |
|
Agrega un indicador nuevo solo si no hay indicadores existentes con la misma clave. El valor de esta clave es un objeto JSON en el que las claves son cadenas de base 64 correspondientes a la clave que se va a colocar y los valores son cadenas de base 64 correspondientes al valor que se va a colocar. |
|
Quita el indicador de una llave. El valor es una lista de cadenas base 64 correspondientes a las claves de los indicadores que se deben borrar. |
|
Proporciona una acción para actualizar el extremo y un URI que se puede usar para recuperar una lógica de codificación. La subclave para proporcionar una acción de actualización es "action", y el valor admitido actualmente solo es "REGISTER", que registrará el extremo del codificador si se proporciona por primera vez o reemplazará el existente con el extremo proporcionado recientemente. Es obligatorio proporcionar el extremo para la acción "REGISTER". La clave secundaria para proporcionar un extremo del codificador es "endpoint" y el valor es la cadena del URI para el extremo. |
Por ejemplo, Una solicitud JSON se vería de la siguiente manera:
{
"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"
}
}
Las señales tendrán una cuota en el dispositivo de 10 a 15 KB. Una vez que la cuota se supere la PPAPI expulsará los indicadores mediante una estrategia FIFO. El proceso de expulsión permitirá que la cuota se supere ligeramente durante intervalos cortos de a fin de reducir la frecuencia de las expulsiones.
API de Signals Encoding
Los compradores deben proporcionar una función de Java Script que se utilice para codificar los indicadores almacenados en el dispositivo que se enviarán al servidor durante la subasta protegida. Los compradores pueden proporcionar esta secuencia de comandos agregando la URL que se puede recuperar con la clave "update_encoder" en cualquiera de las respuestas a una solicitud a la API de UpdateSignal. La secuencia de comandos tendrá la siguiente firma:
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)};
}
El parámetro signals
es un mapa de claves en forma de UInt8Arrays de tamaño 4 para las listas de objetos de Protected App Signals. Cada objeto de Protected App Signals tiene los siguientes tres campos:
signal_value
: Un UInt8Array que representa el valor del indicador.creation_time
: Un número que representa la hora de creación de los indicadores en segundos de época.package_name
: Una cadena que representa el nombre del paquete que creó el indicador.
El parámetro maxSize
es un número que describe el tamaño del array más grande permitido para el resultado.
La función debería generar un objeto con dos campos:
status
: Debe ser 0 si la secuencia de comandos se ejecutó de forma correcta.results
: Debe ser un UInt8Array con una longitud menor o igual que maxSize. Este array se enviará al servidor durante las subastas y será preparado por la secuencia de comandosprepareDataForAdRetrieval
.
La codificación les proporciona a las tecnologías publicitarias una etapa inicial de ingeniería de atributos, en la que pueden realizar transformaciones, por ejemplo, comprimir indicadores sin procesar en versiones concatenadas, según su propia lógica personalizada. Ten en cuenta que, durante una subasta protegida que se ejecuta en los entornos de ejecución confiables (TEE), la lógica personalizada de la tecnología publicitaria tendrá acceso de lectura a las cargas útiles de los indicadores que generó la codificación. La lógica personalizada, conocida como función definida por el usuario (UDF), que se ejecuta en el TEE de B&A del comprador, tendrá acceso de lectura a los indicadores codificados y a otros indicadores contextuales que proporciona la app del publicador para realizar la selección de anuncios (recuperación de anuncios y ofertas).
Codificación de indicadores
Cada hora, los compradores que proporcionaron la lógica de codificación con sus indicadores registrados tendrán los indicadores codificadas en una carga útil de subasta. El array de bytes para la carga útil de la subasta se conservará en el dispositivo, estará encriptado y será recopilado por los vendedores como parte de los datos de la selección de anuncios para que se incluyan en una subasta protegida. Para realizar pruebas, puedes activar esta codificación fuera de su frecuencia por hora ejecutando el siguiente comando:
adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Control de las versiones de la lógica del codificador
Cuando se realiza una solicitud para descargar la lógica personalizada del codificador de la tecnología publicitaria, el extremo de esta puede responder con un número de versión en los encabezados de respuesta. Esta versión se conserva junto con la lógica del codificador en el dispositivo. Cuando se codifican los indicadores sin procesar, la carga útil codificada se conserva junto con la versión que se usó para la codificación. Esta versión también se envía al servidor de B&A durante una subasta protegida, de modo que las tecnologías publicitarias puedan alinear su lógica de oferta y codificación en función de la versión.
Response header for providing encoder version : X_ENCODER_VERSION
API de Protected Auction Support
En el dispositivo, ejecutar una subasta para los indicadores de apps protegidos es lo mismo que ejecutar una subasta para públicos protegidos.
Servicios de ofertas y subastas
Las APIs del servidor incluyen lo siguiente:
- API de Protected Auction: Una serie de funciones de JS o UDF que los compradores y vendedores pueden implementar en los componentes de B&A que poseen para determinar las ofertas y la lógica de la subasta.
- API de Ad Retrieval: Los compradores pueden implementar esta API si implementan un extremo de REST que se ocupará de proporcionar un conjunto de anuncios candidatos para la subasta de los indicadores de apps protegidos.
API de Protected Auction
La API de Protected Auction consta de la API de JS o UDF que los compradores y vendedores pueden usar para implementar su lógica de subasta y oferta.
UDF de la tecnología publicitaria del comprador
UDF prepareDataForAdRetrieval
Antes de que se puedan usar los indicadores de apps protegidos para recuperar anuncios candidatos del TEE
servicio de recuperación de anuncios, los compradores deben decodificar y preparar los indicadores de apps protegidos
y otros datos proporcionados por el vendedor. El resultado de la UDF prepareDataForAdRetrieval
de los compradores se pasa al servicio de recuperación de anuncios para obtener los anuncios candidatos Top-K para ofertar.
// 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
Una vez que se muestran los anuncios candidatos Top-K, los candidatos se pasan a la lógica de oferta personalizada del comprador, la 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>
};
}
El resultado de esta función es una oferta única para un candidato de anuncio, representada
como un JSON equivalente a
ProtectedAppSignalsAdWithBidMetadata
La función también puede mostrar dos arrays que luego se pasarán a reportWin
para habilitar el entrenamiento de modelos (para obtener más detalles sobre la salida y el entrenamiento de modelos
consulta la sección de informes de la explicación del PAS).
UDF informeWin
Cuando concluya una subasta, el servicio de subastas generará URL de informes para
a los compradores y registrar balizas con la UDF reportWin
(es la misma
función reportWin
que se usa para Protected Audience).
El dispositivo hará ping una vez que el cliente renderice el anuncio.
La firma de este método es casi la misma que la de Protected Audience
version, excepto por dos parámetros adicionales, egressPayload
y
temporaryUnlimitedEgressPayload
que se usan para habilitar el entrenamiento de modelos y son
se propagan con los resultados de generateBid
.
// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals,
egressPayload, temporaryUnlimitedEgressPayload) {
// ...
}
UDF de la tecnología publicitaria del vendedor
UDF scoreAd
Los vendedores usan esta UDF para seleccionar cuál de los anuncios recibidos de los compradores ganará la subasta.
function scoreAd(adMetadata, bid, auctionConfig,
trustedScoringSignals, bid_metadata) {
// ...
return {desirability: desirabilityScoreForThisAd,
allowComponentAuction: true_or_false};
}
UDF reportResult
Esta UDF le permite al vendedor generar (en algún momento) informes al nivel del evento con la información sobre el anuncio ganador.
function reportResult(auctionConfig, reporting_metadata) {
// ...
registerAdBeacon({"click", clickUrl,"view", viewUrl});
sendReportTo(reportResultUrl);
return signalsForWinner;
}
API de Ad Retrieval
En la versión de MVP , el servicio de recuperación de anuncios será un servicio administrado y alojado por el comprador El servicio de ofertas recupera los anuncios candidatos de este servicio. A partir de abril de 2024, el servidor de recuperación de anuncios debe ejecutarse en un Execution Environment (TEE) y expondrá una interfaz GRPC/proto. Las empresas de tecnología publicitaria deben configurar este servidor y proporcionar su URL como parte de la implementación de la pila de B&A. Una implementación de este servicio que se ejecuta en el TEE está disponible en GitHub de Privacy Sandbox y en el resto del documentación, asumimos que este es el código que se usa en la implementación.
A partir de abril de 2024, las versiones de B&A admiten anuncios de ruta contextual y la recuperación de datos. En este caso, el servidor de Licitación recibirá una lista de identificadores de anuncios que envía el servidor de RTB durante la parte contextual de la subasta. Los identificadores se enviarán a un servidor TEE KV para recuperar todo el anuncio. Información relacionada que se utilizará durante la fase de oferta (por ejemplo, la URL de renderización del anuncio, los metadatos y las incorporaciones de anuncios que se usarán en selección de Top-K). Esta segunda ruta no necesita ninguna lógica específica para por lo que solo documentaremos cómo configurar el TEE basado de recuperación de anuncios.
UDF de HandleRequest
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
deviceMetadata, contextualSignals) {
return adsMetadataString;
}
Aquí:
requestMetadata
: JSON. Metadatos del servidor por solicitud a la UDF. Por el momento, está vacío.preparedDataForAdRetrieval
: El contenido de este campo depende del anuncio. estrategia de recuperación. En el caso de la recuperación de anuncios contextuales , este parámetro contendrá las señales sin procesar que se originan en el dispositivo y que se transmiten desde el de Google Cloud. En el caso de la recuperación de anuncios de TEE a través del servidor de recuperación de anuncios este parámetro contendrá el resultado de la UDFprepareDataForAdRetrieval
. Nota: En esta etapa, los indicadores de apps protegidos se decodificarían y no se encriptarían.deviceMetadata
: Es un objeto JSON que contiene metadatos del dispositivo que el servicio de anuncios del vendedor reenvía. Consulta la documentación de B&A para obtener más detalles.X-Accept-Language
: Es el idioma que se usa en el dispositivo.X-User-Agent
: El usuario-agente que se usa en el dispositivo.X-BnA-Client-IP
: Es la dirección IP del dispositivo.
contextualSignals
: Cadena arbitraria originada a partir de las ofertas contextuales opere en la misma DSP. Se espera que la UDF pueda decodificar el y usarla. Los indicadores contextuales pueden contener cualquier información, como el AA información de la versión del modelo para la incorporación protegida que se pasó con Indicadores de apps protegidos
La UDF debe mostrar una cadena en caso de éxito. La cadena se devuelve al
servidor de ofertas que, luego, lo pasa a la UDF generateBid
. Si bien el
puede ser una simple cadena; lo más probable es que esta sea una
objeto serializado cuyo esquema se define por cada tecnología publicitaria por su cuenta.
No hay restricción en el esquema, siempre y cuando el generateBid
de la tecnología publicitaria
lógica pueda reconocer y usar la cadena.
Configura tu sistema para el desarrollo
Android
Para configurar tu entorno de desarrollo de Android, debes hacer lo siguiente:
- Crea un emulador (preferido) o un dispositivo físico que ejecute la imagen de la versión preliminar para desarrolladores 10.
- Ejecuta lo siguiente:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity
Luego, selecciona la opción que se muestra para dar consentimiento a los anuncios sugeridos por apps.
- Ejecuta el siguiente comando para habilitar las APIs relevantes. En ocasiones, es posible que debas volver a ejecutarlo, ya que la configuración predeterminada para la opción de inhabilitar se sincronizará de forma periódica.
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;
- Reinicia el dispositivo.
- Anula las claves de subasta del dispositivo para que apunten a tu servidor de claves de subasta. Es importante realizar este paso antes de intentar ejecutar una subasta para evitar que se almacenen en caché claves incorrectas.
Servicios de ofertas y subastas
Para configurar los servidores de B&A, consulta la documentación sobre la configuración del servicio automático.
Este documento se enfocará en cómo configurar los servidores específicos del comprador, ya que no se requieren cambios para los vendedores.
Requisitos previos
Antes de implementar una pila de servicios de B&A, la tecnología publicitaria del comprador debe hacer lo siguiente:
- Asegurarse de que se haya implementado su propio servicio de recuperación de anuncios de TEE (consulta el sección relevante).
- Asegúrate de que la tecnología publicitaria tenga todas las UDF necesarias
(
prepareDataForAdRetrieval
,generateBid
,reportWin
yHandleRequest
) definidos y alojados.
También será útil comprender cómo funciona la subasta protegida con el público protegido con B&A, pero no es obligatorio.
Configuración de Terraform
Para usar indicadores de apps protegidos, las tecnologías publicitarias deben hacer lo siguiente:
- Habilitar la compatibilidad con los indicadores de apps protegidos en B&A.
- Proporcionar extremos de URLs desde los que se puedan recuperar las UDF nuevas para
prepareDataForAdRetrieval, generateBid
yreportWin
.
Además, en esta guía, se supone que las tecnologías publicitarias que desean usar B&A para el remarketing seguirán estableciendo todas las marcas de configuración existentes para la subasta de remarketing como de costumbre.
Configuración de la tecnología publicitaria del comprador
Con este archivo de demostración como ejemplo, los compradores deben establecer las siguientes marcas:
- Habilitar los indicadores de apps protegidos: Se habilita para recopilar los datos de indicadores de apps protegidos.
- URLs de los indicadores de apps protegidos: Configúralas en las URLs de los servidores de los indicadores de apps protegidos.
Las tecnologías publicitarias deben sustituir las URLs correctas en los marcadores de posición por los siguientes campos:
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"
Configuración de la tecnología publicitaria del vendedor
Con este archivo de demostración como ejemplo, los vendedores deben configurar las siguientes marcas. (Nota: Aquí solo se menciona la configuración relacionada con los indicadores de apps protegidos). Las tecnologías publicitarias deben asegurarse de reemplazar las URLs correctas en los marcadores de posición:
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"
Servicios de recuperación de anuncios y KV
Según las estrategias elegidas para admitir la recuperación de anuncios,
requieren la implementación de una o dos instancias del servicio KV. Haremos referencia a
a la instancia de KV utilizada para la recuperación de anuncios basada en TEE como
Ad Retrieval Server
y a la instancia para admitir rutas contextuales basadas
recuperable como KV Lookup Server
.
En ambos casos, la implementación de servidores sigue la documentación disponible en la
GitHub del servidor KV, la diferencia entre ambos casos es que la búsqueda
funciona de inmediato, sin ninguna configuración adicional, mientras
la recuperación uno requiere la implementación de la UDF HandleRequest
para implementar
la lógica de recuperación. Para obtener más información, consulta el servidor KV
guía de integración. Ten en cuenta que B&A espera que ambos servicios
implementar en la misma malla de servicios que el servicio de ofertas.
Configuración de ejemplo
Ten en cuenta la siguiente situación: con la API de Protected App Signals, una tecnología publicitaria almacena indicadores relevantes en función del uso de la app por parte del usuario. En nuestro ejemplo, se almacenan indicadores que representan compras directas desde la aplicación de varias apps. Durante una subasta, los indicadores encriptados se recopilan y pasan a una subasta protegida que se ejecuta en B&A. Las UDF del comprador que se ejecutan en B&A usan los indicadores para recuperar anuncios candidatos y calcular una oferta.
Ejemplos de indicadores [comprador]
Agrega un indicador con una clave de 0 y un valor de 1.
{
"put": {
"AA==": "AQ=="
},
"update_encoder": {
"action": "REGISTER",
"endpoint": "https://example.com/example_script"
}
}
Agrega un indicador con una clave de 1 y un valor de 2.
{
"put": {
"AQ==": "Ag=="
},
"update_encoder": {
"action": "REGISTER",
"endpoint": "https://example.com/example_script"
}
}
Ejemplo de encodeSignals [comprador]
Codifica cada indicador en dos bytes. El primero es el primero de la clave del indicador, y el segundo es el primer byte del valor del indicador.
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};
}
Ejemplo de prepareDataForAdRetrieval [comprador]
/**
* `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;
}
Muestra de UDF de recuperación de anuncios [comprador]
En nuestro ejemplo, el servidor de recuperación de anuncios envía metadatos (es decir, el ID de cada anuncio en este ejemplo, pero puede contener otros datos de cada uno que pueden ser útiles para generar ofertas más adelante) para cada uno de los anuncios candidatos Top-K.
function HandleRequest(requestMetadata, protectedSignals, deviceMetadata,
contextualSignals) {
return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"
Ejemplo de generateBid [comprador]
/**
* 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};
}
Ejemplo de reportWin [comprador]
La UDF reportWin
le informa al comprador que ganó la subasta.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals, directFromSellerSignals,
egressPayload,
temporaryUnlimitedEgressPayload) {
sendReportTo("https://buyer-controlled-domain.com/");
registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
return;
}
Configuración del servidor KV [vendedor]
Los vendedores deben configurar un servidor KV de indicadores de puntuación, de modo que haya una asignación disponible desde las URLs de renderización de anuncios para los indicadores de puntuación correspondientes, por ejemplo: si https:/buyer-domain.com/get-fitness-app
y https:/buyer-domain.com/get-fastfood-app
se devolvieran al comprador, el vendedor podría mostrar el siguiente ejemplo de respuesta de indicadores de puntuación cuando es consultado por SFE con un elemento GET
en 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"
]
}
}
Ejemplo de scoreAd [vendedor]
/**
* 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
};
}
Ejemplo de reportResult [vendedor]
function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
let signalsForWinner = {};
sendReportTo("https://seller-controlled-domain.com");
registerAdBeacon({"clickEvent":
"https://seller-controlled-domain.com/clickEvent"});
return signalsForWinner;
}
App de ejemplo
Como ejemplo de cómo se puede usar la API para crear una app que utilice un flujo simple como el descrito anteriormente, creamos una app de ejemplo de los indicadores de apps protegidos que se puede encontrar en este repositorio de ejemplo.