Damit Entwickler die Protected App Signals API ausprobieren können, werden in diesem Dokument alle APIs der API-Oberfläche beschrieben. Außerdem erfahren Sie, wie Sie eine Testumgebung einrichten, und es werden Beispiele für die Konfiguration und Scripts bereitgestellt.
Versionsverlauf
Januar 2024
Erste Version des Entwicklerhandbuchs für die PAS-MVP-Version
März 2024
Änderungen an der API zur Unterstützung der M-2024-05-Version der Android API und der Veröffentlichung der serverseitigen Komponenten im April 2024. Die wichtigsten Änderungen:
- Details zu den für die On-Device API erforderlichen Berechtigungen hinzugefügt
- Details zur Kontingentverwaltung für On-Device-Signale wurden hinzugefügt
- Die
generateBid
-Signatur wurde mit Änderungen im Zusammenhang mit der Abruf- und Ausstiegsunterstützung für kontextbezogene Anzeigen aktualisiert. - Aktualisierte
reportWin
-Dokumentation mit Unterstützung für den Traffic-Ausgang - Dokumentation der Ad Retrieval API aktualisieren, um die Unterstützung für den Abruf von BYOS-Anzeigen zu entfernen und die UDF für den Anzeigenabruf zu dokumentieren
API-Übersicht
Die Protected Signals API umfasst verschiedene API-Subsets in verschiedenen Systemen:
- Android APIs:
- Signal Curation API, bestehend aus:
- Update Signals API
- Signals Encoding API
- Protected Auction Support API: Wird von SDKs verwendet, um die geschützte Auktion mithilfe von Protected App-Signalen auf den Bidding and Auction-Servern (B&A) auszuführen.
- Serverseitige APIs:
- Protected Auction API: Eine Reihe von JS-Scripts, die auf den Gebots- und Auktionsservern ausgeführt werden. Mit dieser API können Verkäufer und Käufer die Logik für die Implementierung der geschützten Auktion schreiben.
- Ad Retrieval API: Stellt eine Liste potenzieller Anzeigen bereit, basierend auf den Kontext- und Nutzerinformationen, die dem Gebotsserver des Käufers zur Verfügung gestellt werden.
Android-Client
Auf der Clientseite besteht die Protected App Signals-Oberfläche aus drei verschiedenen APIs:
- Update-Signale: Eine Android-System-API, mit der Signale auf dem Gerät ausgewählt werden können.
- Signalcodierung: Eine JavaScript API, mit der die Signale für die Übertragung an den Server während der Auktion vorbereitet werden.
- Unterstützung für geschützte Auktionen: Eine API zur Unterstützung der Ausführung einer geschützten Auktion auf den Gebots- und Auktionsservern. Diese API ist nicht speziell für geschützte App-Signale gedacht und wird auch für Auktionen für die Protected Audience API verwendet.
Update Signals API
Mit der Update Signals API können Anbieter von Anzeigentechnologien nutzer- und appbezogene Signale im Namen eines Käufers registrieren. Die API basiert auf einem Delegationsmodell. Der Aufrufer stellt einen URI bereit, von dem das Framework die entsprechenden Signale abholt, und die Logik zum Codieren dieser Signale für die Auktion.
Für die API ist die Berechtigung android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS
erforderlich.
Die updateSignals()
API ruft ein JSON-Objekt vom URI ab, das beschreibt, welche Signale hinzugefügt oder entfernt werden sollen und wie diese Signale für die Auktion vorbereitet werden.
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);
Die Plattform sendet eine HTTPS-Anfrage an den in der Anfrage angegebenen URI, um die Signalaktualisierungen abzurufen. Neben den Signalaktualisierungen kann die Antwort einen Endpunkt enthalten, der die Codierungslogik für die Umwandlung der Rohsignale in eine codierte Nutzlast hostet. Die Signalaktualisierungen sollten im JSON-Format vorliegen und die folgenden Schlüssel enthalten:
Die Schlüssel der obersten Ebene für das JSON-Objekt müssen einem der fünf Befehle entsprechen:
key |
Beschreibung |
|
Es wird ein neues Signal hinzugefügt und alle vorhandenen Signale mit demselben Schlüssel werden überschrieben. Der Wert „for“ ist ein JSON-Objekt, bei dem die Schlüssel Base64-Strings sind, die dem Schlüssel entsprechen, für den ein Wert festgelegt werden soll, und die Werte Base64-Strings sind, die dem Wert entsprechen, der festgelegt werden soll. |
|
Hängt einer Zeitreihe von Signalen neue Signale an und entfernt die ältesten Signale, um Platz für neue zu schaffen, wenn die Größe der Reihe das angegebene Maximum überschreitet. Der Wert dafür ist ein JSON-Objekt, bei dem die Schlüssel Base64-Strings sind, die dem Schlüssel entsprechen, an den angehängt werden soll, und die Werte Objekte mit zwei Feldern sind: „values“ und „maxSignals“. „values“: Eine Liste von Base64-Strings, die den Signalwerten entsprechen, die an die Zeitreihe angehängt werden sollen. „maxSignals“: Die maximale Anzahl von Werten, die in dieser Zeitreihe zulässig sind. Wenn die aktuelle Anzahl der mit dem Schlüssel verknüpften Signale maxSignals überschreitet, werden die ältesten Signale entfernt. Sie können einem Schlüssel, der mit „put“ hinzugefügt wurde, Elemente anhängen. Wenn Sie mehr als die maximale Anzahl von Werten anhängen, führt dies zu einem Fehler. |
|
Es wird nur dann ein neues Signal hinzugefügt, wenn keine Signale mit demselben Schlüssel vorhanden sind. Der Wert dafür ist ein JSON-Objekt, bei dem die Schlüssel Base64-Strings sind, die dem Schlüssel entsprechen, für den der Wert festgelegt werden soll, und die Werte Base64-Strings sind, die dem Wert entsprechen, der festgelegt werden soll. |
|
Entfernt das Signal für einen Schlüssel. Der Wert ist eine Liste von Base64-Strings, die den Schlüsseln der zu löschenden Signale entsprechen. |
|
Bietet eine Aktion zum Aktualisieren des Endpunkts und einen URI, der verwendet werden kann um eine Codierungslogik abzurufen. Der Unterschlüssel für die Angabe einer Aktualisierungsaktion ist „action“ und der Derzeit wird nur „REGISTER“ unterstützt. Damit wird der Encoder-Endpunkt registriert, wenn er zum ersten Mal angegeben wird, oder der vorhandene Endpunkt wird mit dem neu angegebenen Endpunkt überschrieben. Für die Aktion „REGISTER“ ist die Angabe des Endpunkts erforderlich. Der Unterschlüssel für die Angabe eines Encoder-Endpunkts ist „endpoint“ und der Wert ist der URI. für den Endpunkt. |
Eine Beispiel-JSON-Anfrage würde so aussehen:
{
"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"
}
}
Für Signale gilt ein On-Device-Kontingent von etwa 10–15 KB. Sobald das Kontingent überschritten wird, werden Signale von PPAPI mithilfe einer FIFO-Strategie entfernt. Beim Auslagerungsprozess kann das Kontingent für kurze Zeit leicht überschritten werden, um die Häufigkeit von Auslagerungen zu reduzieren.
Signals Encoding API
Käufer müssen eine JavaScript-Funktion angeben, mit der die auf dem Gerät gespeicherten Signale codiert werden, die während der geschützten Auktion an den Server gesendet werden sollen. Käufer können dieses Script bereitstellen, indem sie in einer der Antworten auf eine UpdateSignal API-Anfrage die URL angeben, unter der es abgerufen werden kann. Verwenden Sie dazu den Schlüssel „update_encoder“. Das Script hat folgende Signatur:
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)};
}
Der Parameter signals
ist eine Zuordnung von Schlüsseln in Form von UInt8Arrays mit einer Größe von 4 zu Listen von Protected App Signals-Objekten. Jedes Protected App Signals-Objekt hat drei Felder:
signal_value
: Ein UInt8Array, das den Wert des Signals darstellt.creation_time
: Eine Zahl, die die Erstellungszeit der Signale in Epochen-Sekunden angibt.package_name
: Ein String, der den Namen des Pakets darstellt, aus dem das Signal erstellt wurde.
Der Parameter maxSize
ist eine Zahl, die die maximal zulässige Arraygröße für die Ausgabe beschreibt.
Die Funktion sollte ein Objekt mit zwei Feldern ausgeben:
status
: Sollte 0 sein, wenn das Script erfolgreich ausgeführt wurde.results
: Muss ein UInt8Array mit einer Länge haben, die kleiner oder gleich maxSize ist. Dieses Array wird während Auktionen an den Server gesendet und vomprepareDataForAdRetrieval
-Script vorbereitet.
Die Codierung bietet Werbetechnologien eine erste Phase der Feature-Entwicklung, in der sie Transformationen wie die Komprimierung von Rohsignalen in zusammenhängende Versionen basierend auf ihrer eigenen benutzerdefinierten Logik ausführen können. Hinweis: Bei einer geschützten Auktion, die in einer Trusted Execution Environment (TEE) ausgeführt wird, hat die benutzerdefinierte Logik der Anzeigentechnologie Lesezugriff auf die Signalnutzlasten, die durch die Codierung generiert werden. Die benutzerdefinierte Logik, die als User Defined Function (UDF) bezeichnet wird und im B&A TEE des Käufers ausgeführt wird, hat Lesezugriff auf die codierten Signale und anderen kontextbezogenen Signale, die von der Publisher-App zur Anzeigenauswahl (Anzeigenabruf und Gebotsabgabe) bereitgestellt werden.
Signalcodierung
Bei Käufern, die für ihre registrierten Signale eine Codierungslogik angegeben haben, werden die Signale stündlich in eine Auktionsnutzlast codiert.Das Byte-Array für die Auktionsnutzlast wird auf dem Gerät gespeichert, verschlüsselt und von Verkäufern als Teil der Daten zur Anzeigenauswahl erfasst, die in einer geschützten Auktion enthalten sein sollen. Zum Testen können Sie diese Codierung außerhalb der stündlichen Taktung auslösen, indem Sie den folgenden Befehl ausführen:
adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Versionierung der Encoderlogik
Wenn eine Anfrage zum Herunterladen der benutzerdefinierten Codierungslogik der Anzeigentechnologie gestellt wird, kann der AdTech-Endpunkt mit einer Versionsnummer in den Antwortheadern antworten. Diese Version wird zusammen mit der Encoderlogik auf dem Gerät gespeichert. Wenn die Rohsignale codiert werden, wird die codierte Nutzlast zusammen mit der für die Codierung verwendeten Version gespeichert. Diese Version wird auch während einer geschützten Auktion an den B&A-Server gesendet, damit Anbieter von Anzeigentechnologien ihre Gebots- und Codierungslogik anhand der Version ausrichten können.
Response header for providing encoder version : X_ENCODER_VERSION
Protected Auction Support API
Auf Geräteseite ist das Ausführen einer Auktion für geschützte App-Signale mit dem Ausführen einer Auktion für geschützte Zielgruppen identisch.
Gebots- und Auktionsdienste
Zu den serverseitigen APIs gehören:
- Protected Auction API: Eine Reihe von JS-Funktionen oder UDFs, die Käufer und Verkäufer auf ihren B&A-Komponenten bereitstellen können, um die Gebots- und Auktionslogik zu bestimmen.
- Ad Retrieval API: Käufer können diese API implementieren, indem sie einen REST-Endpunkt implementieren, der für die Bereitstellung einer Reihe von Anzeigenkandidaten für die Auktion mit geschütztem App-Signal verantwortlich ist.
Protected Auction API
Die Protected Auction API besteht aus der JS API oder UDFs, mit denen Käufer und Verkäufer ihre Auktions- und Gebotslogik implementieren können.
UDFs für Käufer-Werbetechnologie
UDF „prepareDataForAdRetrieval“
Bevor Anzeigenkandidaten mithilfe von geschützten App-Signalen aus dem TEE-Anzeigenabrufdienst abgerufen werden können, müssen Käufer die geschützten App-Signale und andere vom Verkäufer bereitgestellte Daten decodieren und vorbereiten. Die prepareDataForAdRetrieval
-UDF-Ausgabe für Käufer wird an den Anzeigenabrufdienst übergeben, um die Top-K-Anzeigen für Gebote abzurufen.
// 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 {};
}
generateBid UDF
Nachdem die Top-k-Anzeigenkandidaten zurückgegeben wurden, werden sie an die Logik für benutzerdefinierte Gebote des Käufers, generateBid
UDF, übergeben:
// 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>
};
}
Die Ausgabe dieser Funktion ist ein einzelnes Gebot für einen Anzeigenkandidaten, das als JSON-Äquivalent zu ProtectedAppSignalsAdWithBidMetadata
dargestellt wird.
Die Funktion kann auch zwei Arrays zurückgeben, die dann an reportWin
übergeben werden, um das Modelltraining zu ermöglichen. Weitere Informationen zu Ausgängen und Modelltraining finden Sie im Abschnitt zu Berichten in der PAS-Erläuterung.
UDF „reportWin“
Nach Abschluss einer Auktion generiert der Auktionsdienst Berichts-URLs für die Käufer und registriert Beacons mithilfe der reportWin
-UDF (dies ist dieselbe reportWin
-Funktion, die für geschützte Zielgruppen verwendet wird).
Dieser wird vom Gerät gepingt, sobald die Anzeige vom Client gerendert wurde.
Die Signatur dieser Methode ist fast identisch mit der Version für geschützte Zielgruppen, mit Ausnahme von zwei zusätzlichen Parametern, egressPayload
und temporaryUnlimitedEgressPayload
, die zum Aktivieren des Modelltrainings verwendet werden und mit den Ergebnissen von generateBid
ausgefüllt werden.
// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals,
egressPayload, temporaryUnlimitedEgressPayload) {
// ...
}
UDFs für die Anzeigentechnologie des Verkäufers
UDF „scoreAd“
Diese UDF wird von Verkäufern verwendet, um auszuwählen, welche der Anzeigen, die von Käufern erhalten wurden, die Auktion gewinnen soll.
function scoreAd(adMetadata, bid, auctionConfig,
trustedScoringSignals, bid_metadata) {
// ...
return {desirability: desirabilityScoreForThisAd,
allowComponentAuction: true_or_false};
}
UDF „reportResult“
Mit dieser UDF kann der Verkäufer (eventuell) Berichte auf Ereignisebene mit den Informationen zur erfolgreichen Anzeige erstellen.
function reportResult(auctionConfig, reporting_metadata) {
// ...
registerAdBeacon({"click", clickUrl,"view", viewUrl});
sendReportTo(reportResultUrl);
return signalsForWinner;
}
Ad Retrieval API
In der MVP-Version ist der Anzeigenabrufdienst ein vom Käufer verwalteter und gehosteter Dienst. Der Gebotsservice ruft Anzeigenkandidaten aus diesem Dienst ab. Ab April 2024 muss der Anzeigenabrufserver in einer Trusted Execution Environment (TEE) ausgeführt werden und eine GRPC/Proto-Schnittstelle bereitstellen. Anbieter von Anzeigentechnologien müssen diesen Server einrichten und seine URL im Rahmen der Bereitstellung des B&A-Stacks angeben. Eine Implementierung dieses Dienstes, die im TEE ausgeführt wird, ist im GitHub-Repository der Privacy Sandbox verfügbar. Im Rest der Dokumentation wird davon ausgegangen, dass dies der Code ist, der bei der Bereitstellung verwendet wird.
Ab April 2024 unterstützen B&A-Versionen das Abrufen von Anzeigen über Kontextpfade. In diesem Fall erhält der Bidding-Server eine Liste mit Anzeigen-IDs, die vom RTB-Server während des kontextbezogenen Teils der Auktion gesendet wurden. Die IDs werden an einen TEE-KV-Server gesendet, um alle Anzeigeninformationen abzurufen, die während der Gebotsphase verwendet werden sollen (z. B. Anzeigen-Render-URL, Metadaten und Anzeigen-Embeddings, die für die Top-K-Auswahl verwendet werden sollen). Für diesen zweiten Pfad muss keine bestimmte Logik bereitgestellt werden. Daher wird hier nur beschrieben, wie der Anwendungsfall für die TEE-basierte Anzeigenabfrage konfiguriert wird.
UDF „getCandidateAds“
function getCandidateAds(requestMetadata, preparedDataForAdRetrieval,
deviceMetadata, contextualSignals, contextualAdIds,) {
return adsMetadataString;
}
Wobei:
requestMetadata
: JSON. Servermetadaten pro Anfrage an die UDF. Noch leer.preparedDataForAdRetrieval
: Der Inhalt dieses Felds hängt von der Strategie zum Abrufen von Anzeigen ab. Beim Abrufen kontextbezogener Anzeigen enthält dieser Parameter die Rohsignale, die vom Gerät stammen und vom Gebotsservice übergeben werden. Bei der Abrufmethode „TEE“ mit dem Anzeigenabrufserver enthält dieser Parameter das Ergebnis derprepareDataForAdRetrieval
-UDF. Hinweis: In dieser Phase werden die Protected App Signals decodiert und entschlüsselt.deviceMetadata
: JSON-Objekt mit Gerätemetadaten, die vom Werbedienst des Verkäufers weitergeleitet werden. Weitere Informationen finden Sie in der B&A-Dokumentation.X-Accept-Language
: Die auf dem Gerät verwendete Sprache.X-User-Agent
: Der auf dem Gerät verwendete User-Agent.X-BnA-Client-IP
: IP-Adresse des Geräts.
contextualSignals
: Zufallsstring, der vom Server für kontextbezogene Gebote stammt, der von derselben DSP betrieben wird. Die UDF kann den String decodieren und verwenden. Kontextsignale können beliebige Informationen enthalten, z. B. Informationen zur ML-Modellversion für die geschützte Einbettung, die mithilfe von geschützten App-Signalen übergeben wurden.contextualAdIds
: JSON-Objekt mit einer optionalen Liste von Anzeigen-IDs.
Die UDF sollte bei Erfolg einen String zurückgeben. Der String wird an den Bidding-Server zurückgegeben, der ihn dann an die generateBid
-UDF weitergibt. Der String kann auch ein einfacher String sein, sollte aber höchstwahrscheinlich ein serialisiertes Objekt sein, dessen Schema von jeder Anzeigentechnologie individuell definiert wird.
Es gibt keine Einschränkungen für das Schema, solange die generateBid
-Logik der Anzeigentechnologie den String erkennen und verwenden kann.
System für die Entwicklung einrichten
Android
So richten Sie Ihre Android-Entwicklungsumgebung ein:
- Einen Emulator (bevorzugt) oder ein physisches Gerät erstellen, auf dem das Image der Entwicklervorschau 10 ausgeführt wird
- Führen Sie den folgenden Befehl aus:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity
Wählen Sie dann die angezeigte Option aus, um der Auslieferung von in Apps vorgeschlagenen Anzeigen zuzustimmen.
- Führen Sie den folgenden Befehl aus, um die entsprechenden APIs zu aktivieren. Möglicherweise müssen Sie diesen Vorgang gelegentlich wiederholen, da die Standardkonfiguration „Deaktiviert“ regelmäßig synchronisiert wird.
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;
- Starten Sie das Gerät neu.
- Überschreiben Sie die Auktionsschlüssel des Geräts, damit sie auf Ihren Auktionsschlüsselserver verweisen. Es ist wichtig, diesen Schritt auszuführen, bevor Sie eine Auktion starten, um zu verhindern, dass falsche Schlüssel im Cache gespeichert werden.
Gebots- und Auktionsdienste
Eine Anleitung zum Einrichten der B&A-Server findest du in der Dokumentation zur Einrichtung.
In diesem Dokument geht es hauptsächlich um die Konfiguration der käuferspezifischen Server, da für Verkäufer keine Änderungen erforderlich sind.
Vorbereitung
Bevor ein B&A-Dienststack bereitgestellt wird, muss die Anzeigentechnologie des Käufers Folgendes erfüllen:
- Sie müssen einen eigenen TEE-Anzeigenabrufdienst bereitgestellt haben (siehe entsprechender Abschnitt).
- Achten Sie darauf, dass alle erforderlichen UDFs (
prepareDataForAdRetrieval
,generateBid
,reportWin
,getCandidateAds
) in der Anzeigentechnologie definiert und gehostet werden.
Es ist hilfreich, wenn Sie wissen, wie die geschützte Auktion mit geschützten Zielgruppen mit B&A funktioniert. Dies ist jedoch keine Voraussetzung.
Terraform-Konfiguration
Für die Verwendung von geschützten App-Signalen müssen Anbieter von Anzeigentechnologien Folgendes tun:
- Aktivieren Sie die Unterstützung für geschützte App-Signale in B&A.
- Geben Sie URL-Endpunkte an, von denen die neuen UDFs für
prepareDataForAdRetrieval, generateBid
undreportWin
abgerufen werden können.
Außerdem wird in diesem Leitfaden davon ausgegangen, dass Anbieter von Anzeigentechnologien, die Bidding& Analytics für Remarketing verwenden möchten, wie gewohnt alle vorhandenen Konfigurations-Flags für Remarketing-Auktionen festlegen.
Konfiguration der Anzeigentechnologie des Käufers
Anhand dieser Demodatei müssen Käufer die folgenden Flags festlegen:
- Protected App Signals aktivieren: Damit werden Daten zu Protected App Signals erfasst.
- Protected App Signals-URLs: Geben Sie die URLs der Protected App Signals-Server an.
Anbieter von Anzeigentechnologien müssen die richtigen URLs in den Platzhaltern für die folgenden Felder einfügen:
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"
Konfiguration der Anzeigentechnologie des Verkäufers
Anhand dieser Demodatei müssen Verkäufer die folgenden Flags festlegen. Hinweis: Hier ist nur die Konfiguration für Protected App Signals hervorgehoben. Anbieter von Anzeigentechnologien müssen dafür sorgen, dass sie die richtigen URLs in den Platzhaltern einfügen:
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"
KV- und Anzeigenabrufdienste
Je nach den Strategien, die für die Anzeigenabrufunterstützung ausgewählt wurden, muss eine oder zwei Instanzen des KV-Dienstes bereitgestellt werden. Wir bezeichnen die KV-Instanz, die für die TEE-basierte Anzeigenabfrage verwendet wird, als Ad Retrieval Server
und die Instanz, die die kontextbasierte Pfadabfrage unterstützt, als KV Lookup Server
.
In beiden Fällen erfolgt die Serverbereitstellung gemäß der Dokumentation im GitHub-Repository des KV-Servers. Der Unterschied zwischen den beiden Fällen besteht darin, dass die Suche ohne zusätzliche Konfiguration funktioniert, während für die Abfrage die Bereitstellung der getCandidateAds
-UDF erforderlich ist, um die Abruflogik zu implementieren. Weitere Informationen finden Sie im Onboarding-Leitfaden für KV-Server. B&A erwartet, dass beide Dienste im selben Service Mesh wie der Gebotsservice bereitgestellt werden.
Beispielkonfiguration
Angenommen, eine Anzeigentechnologie speichert mithilfe der Protected App Signals API relevante Signale basierend auf der App-Nutzung der Nutzer. In unserem Beispiel werden Signale gespeichert, die In-App-Käufe aus mehreren Apps darstellen. Während einer Auktion werden die verschlüsselten Signale erfasst und an eine geschützte Auktion übergeben, die in B&A ausgeführt wird. Die UDFs des Käufers, die in B&A ausgeführt werden, verwenden die Signale, um Anzeigenkandidaten abzurufen und ein Gebot zu berechnen.
[Buyer] Beispiele für Signale
Fügen Sie ein Signal mit dem Schlüssel „0“ und dem Wert „1“ hinzu.
{
"put": {
"AA==": "AQ=="
},
"update_encoder": {
"action": "REGISTER",
"endpoint": "https://example.com/example_script"
}
}
Fügen Sie ein Signal mit dem Schlüssel „1“ und dem Wert „2“ hinzu.
{
"put": {
"AQ==": "Ag=="
},
"update_encoder": {
"action": "REGISTER",
"endpoint": "https://example.com/example_script"
}
}
[Buyer] Beispiel für encodeSignals
Codiert jedes Signal in zwei Byte, wobei das erste Byte das erste Byte des Signalschlüssels und das zweite Byte das erste Byte des Signalwerts ist.
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};
}
[Buyer] Beispiel für prepareDataForAdRetrieval
/**
* `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;
}
[Buyers] Beispiel-UDF für die Anzeigenabfrage
In unserem Beispiel sendet der Anzeigenabrufserver Metadaten (d.h. die ID für jede Anzeige in diesem Beispiel, kann aber auch andere Daten für jede Anzeige enthalten, die später beim Generieren von Geboten hilfreich sein können) für jede der Top-K-Anzeigenkandidaten.
function getCandidateAds(requestMetadata, protectedSignals, deviceMetadata,
contextualSignals, contextualAdIds,) {
return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"
[Buyers] Beispiel für „generateBid“
/**
* 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};
}
[Buyers] Beispiel für reportWin
Die reportWin
-UDF informiert den Käufer darüber, dass er die Auktion gewonnen hat.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals, directFromSellerSignals,
egressPayload,
temporaryUnlimitedEgressPayload) {
sendReportTo("https://buyer-controlled-domain.com/");
registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
return;
}
[Seller] KV-Server einrichten
Verkäufer müssen einen KV-Server für Bewertungssignale einrichten, damit eine Zuordnung der Anzeigen-Render-URLs zu den entsprechenden Bewertungssignalen verfügbar ist. Beispiel: Wenn https:/buyer-domain.com/get-fitness-app
und https:/buyer-domain.com/get-fastfood-app
vom Käufer zurückgegeben werden, kann der Verkäufer die folgende Beispielantwort für Bewertungssignale erhalten, wenn der SFE mit einer GET
auf https://key-value-server-endpoint.com?client_type=1&renderUrls=<render-url-returned-by-the-buyer>
fragt:
{
"renderUrls" : {
"https:/buyer-domain.com/get-fitness-app" : [
"1",
"2"
],
"https:/buyer-domain.com/get-fastfood-app" : [
"3",
"4"
]
}
}
[Seller] scoreAd example
/**
* 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
};
}
Beispiel für „reportResult“ von [Seller]
function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
let signalsForWinner = {};
sendReportTo("https://seller-controlled-domain.com");
registerAdBeacon({"clickEvent":
"https://seller-controlled-domain.com/clickEvent"});
return signalsForWinner;
}
Beispiel-App
Als Beispiel dafür, wie die API verwendet werden kann, um eine App mit einem einfachen Ablauf wie oben beschrieben zu erstellen, haben wir eine Beispiel-App für geschützte App-Signale erstellt, die in diesem Beispiel-Repository zu finden ist.