Entwicklerleitfaden für Protected App-Signale

Damit Entwickler mit der Protected App Signals API experimentieren können, In diesem Dokument werden alle APIs der API-Oberfläche beschrieben. Außerdem wird beschrieben, wie Sie eine Testumgebung eingerichtet haben und Beispiele für die Konfiguration Skripts erstellt.

Versionsverlauf

Januar 2024

Erste Version des Entwicklerhandbuchs zur Unterstützung der PAS MVP-Version

März 2024

Änderungen an der API zur Unterstützung von Version M-2024-05 der Android API und der Release von April 2024 der serverseitigen Komponenten. Die wichtigsten Änderungen:

  • Es wurden Details zu den für die On-Device-API erforderlichen Berechtigungen hinzugefügt
  • Es wurden Details zur Kontingentverwaltung für On-Device-Signale hinzugefügt
  • Die generateBid-Signatur wurde mit kontextabhängigen Änderungen aktualisiert Support für Anzeigenabruf und ausgehenden Traffic
  • reportWin-Dokumentation einschließlich Unterstützung von ausgehendem Traffic aktualisiert
  • Dokumentation zur Ad Retrieval API aktualisieren und Unterstützung für das BYOS-Anzeigenabrufen aufheben und die UDF zum Anzeigenabruf dokumentieren,

API-Übersicht

Die Protected Signals API-Oberfläche umfasst verschiedene API-Teilmengen auf verschiedenen Systeme:

  • Android-APIs: <ph type="x-smartling-placeholder">
      </ph>
    • Signal Curation API, bestehend aus:
    • Signals API aktualisieren
    • Signals Encoding API
    • Protected Auktion Support API: Wird von SDKs zum Ausführen der geschützten Auktion verwendet. Auktion auf den Gebots- und Auktionsservern mit Protected App Signale.
  • Serverseitige APIs: <ph type="x-smartling-placeholder">
      </ph>
    • Protected Auktion API: Eine Reihe von JS-Skripts, die in den Gebots- und Auktionsserver. Mit dieser API können Verkäufer und Käufer die geschützte Auktion implementieren.
    • Ad Retrieval API: Verantwortlich für die Bereitstellung einer Liste möglicher Anzeigen Kontext- und Nutzerinformationen, die für das Gebot des Käufers verfügbar sind Server.

Android-Client

Clientseitig besteht die Oberfläche von „Protected App Signals“ aus drei APIs:

  • Update-Signale: Eine Android System API, um die Auswahl von Signalen auf auf dem Gerät.
  • Signalcodierung: Eine JavaScript-API zur Vorbereitung der Signale, die an die während der Auktion.
  • Protected Auktion Support: Eine API zur Unterstützung der Ausführung einer Auktion auf den Gebots- und Auktionsservern. Diese API ist nicht spezifisch für „Protected App Signals“. Es wird auch für Auktionen für Audience API verwenden.

Signals API aktualisieren

Mit der Update Signals API können Anzeigentechnologie-Anbieter Nutzer- und App-bezogene Signale im Namen eines Käufers an. Die API arbeitet mit einem Delegationsmodell. Der Aufrufer stellt einen URI bereit, von dem das Framework die entsprechende und die Logik für die Codierung der Signale, die in der Auktion verwendet werden,

Für die API ist die android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS erforderlich Berechtigung.

Die updateSignals() API ruft ein JSON-Objekt ab aus dem URI, der beschreibt, welche Signale hinzugefügt oder entfernt werden müssen und wie die diese Signale für die Auktion.

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 stellt eine HTTPS-Anfrage an den URI, der in der Abrufanforderung angegeben ist. wenn das Signal aktualisiert wird. Neben den Signalaktualisierungen kann die Antwort auch eine Endpunkt, der die Codierungslogik zum Konvertieren der Rohsignale in codierten Nutzlast. Die Signalaktualisierungen müssen im JSON-Format kann die folgenden Schlüssel haben:

Die Schlüssel der obersten Ebene für das JSON-Objekt müssen einem der fünf Befehle entsprechen:

key

Beschreibung

put

Fügt ein neues Signal hinzu und überschreibt alle vorhandenen Signale mit demselben Schlüssel. Der Wert

Hierbei handelt es sich um ein JSON-Objekt, bei dem die Schlüssel Basis-64-Strings sind, die dem Schlüssel entsprechen, für den sie gespeichert werden sollen, und die Werte aus einem Basis-64-String, der dem festzulegenden Wert entspricht.

append

Fügt einer Zeitreihe von Signalen neue Signale hinzu, wobei die ältesten entfernt werden

Signale, um Platz für neue zu schaffen, wenn die Größe der Reihen das angegebene Maximum überschreitet. Der Wert hierfür ist ein JSON-Objekt, bei dem die Schlüssel Basis-64-Strings sind, die dem Schlüssel entsprechen, an den der Schlüssel angehängt werden soll, und die Werte Objekte mit zwei Feldern: „values“. und „maxSignals“.

"values": Eine Liste von Basis-64-Strings, die Signalwerten entsprechen, die an die Zeitreihe angehängt werden sollen.

„maxSignals“: Die maximale Anzahl von Werten, die in dieser Zeitreihe zulässig sind. Wenn

Wenn die aktuelle Anzahl der mit dem Schlüssel verknüpften Signale „maxSignals“ überschreitet, werden die ältesten Signale entfernt. Beachten Sie, dass Sie an einen Schlüssel anhängen können, der durch "put" hinzugefügt wurde. Beachten Sie, dass es zu einem Fehler führt, wenn Sie mehr als die maximale Anzahl von Werten anhängen.

put_if_not_present

Fügt nur dann ein neues Signal hinzu, wenn keine Signale mit demselben Schlüssel vorhanden sind. Der Wert hierfür ist ein JSON-Objekt, bei dem die Schlüssel Basis-64-Strings sind, die dem Schlüssel entsprechen, für den sie gespeichert werden sollen, und die Werte sind Basis-64-Strings, die dem festzulegenden Wert entsprechen.

remove

Entfernt das Signal für einen Schlüssel. Der Wert hierfür ist eine Liste von Base64-Strings, die den Schlüsseln der zu löschenden Signale entsprechen.

update_encoder

Stellt eine Aktion zum Aktualisieren des Endpunkts und einen URI bereit, der verwendet werden kann

um eine Codierungslogik abzurufen. Der Unterschlüssel zum Angeben einer Aktualisierungsaktion ist „action“. und die

Derzeit wird nur "REGISTER" unterstützt. wird der Encoder-Endpunkt registriert, falls er zum ersten Mal angegeben wurde, oder der vorhandene Endpunkt wird mit dem neu angegebenen Endpunkt überschrieben. Für „REGISTER“ ist die Angabe des Endpunkts erforderlich action.Der Unterschlüssel zum Angeben eines Encoder-Endpunkts ist "endpoint". und der Wert ist der URI,

String für den Endpunkt.

Ein Beispiel für eine 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"
    }
}

Signale haben ein Gerätekontingent von 10 bis 15 KB. Sobald das Kontingent wird überschritten. PPAPI entfernt Signale mithilfe einer FIFO-Strategie. Der Bereinigungsprozess damit das Kontingent kurzzeitig leicht überschritten werden kann, um die Häufigkeit von Bereinigungen zu reduzieren.

Signals Encoding API

Käufer müssen eine JavaScript-Funktion zur Codierung des auf dem Gerät gespeicherte Signale, damit diese während der Auktion. Käufer können dieses Skript bereitstellen, indem sie die URL mit dem Schlüssel "update_encoder" abgerufen einer der Antworten auf eine UpdateSignal API-Anfrage. Das Skript hat die 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 der Größe 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 den Erstellungszeitpunkt der Signale in Epochensekunden.
  • package_name: Ein String, der den Namen des erstellten Pakets darstellt an das Signal senden.

Der Parameter maxSize ist eine Zahl, die die größte zulässige Arraygröße beschreibt für die Ausgabe festlegen.

Die Funktion sollte ein Objekt mit zwei Feldern ausgeben:

  • status: Sollte 0 sein, wenn das Script erfolgreich ausgeführt wurde.
  • results: Sollte ein UInt8Array mit einer Länge von maximal "maxSize" sein. Dieses Array wird bei Auktionen an den Server gesendet und vom prepareDataForAdRetrieval-Script.

Die Codierung bietet AdTechs eine erste Phase des Feature Engineering, in denen sie Transformationen durchführen können, z. B. das Komprimieren von Rohsignalen in basierend auf ihrer eigenen benutzerdefinierten Logik verknüpft sind. Während eines Geschützte Auktion in den vertrauenswürdigen Ausführungsumgebungen (Trusted Execution Environments, TEE), AdTech benutzerdefinierte Logik hat Lesezugriff auf die Signalnutzlasten, Codierung. Die benutzerdefinierte Logik, die Benutzerdefinierte Funktion (User-Defined Function, UDF), die im B&A TEE des Käufers ausgeführt wird hat Lesezugriff auf die codierten Signale und andere Kontextsignale der Publisher-App für die Anzeigenauswahl (Abrufen von Anzeigen und Gebote).

Signalcodierung

Stündlich werden Käufer, die bei ihrem registrierten werden die Signale in einer Auktionsnutzlast codiert. für die Auktionsnutzlast auf dem Gerät gespeichert, verschlüsselt und werden von Verkäufern im Rahmen der Anzeigenauswahldaten erfasst und dann in die Anzeigenauswahl einbezogen. einer geschützten Auktion. Zu Testzwecken können Sie diese Codierung außerhalb von stündliche Kadenz erhalten, indem Sie den folgenden Befehl ausführen:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Versionsverwaltung der Encoder-Logik

Wenn die benutzerdefinierte Encoder-Logik der Anzeigentechnologie heruntergeladen werden soll, kann der Endpunkt eine Versionsnummer in den Antwortheadern angeben. Diese Version wird zusammen mit der Encoderlogik auf dem Gerät beibehalten. Wenn die unverarbeiteten Signale codiert sind, wird die codierte Nutzlast zusammen mit der Version beibehalten, die für Codierung. Diese Version wird auch während einer geschützten Auktion, damit die Anzeigentechnologie-Anbieter ihre Gebots- und Codierungslogik auf Grundlage die Version.

Response header for providing encoder version : X_ENCODER_VERSION

Protected Auktion Support API

Auf Geräteseite ist die Durchführung einer Auktion für Protected App-Signale wie bei einer Auktion für geschützte Zielgruppen.

Gebots- und Auktionsdienste

Zu den serverseitigen APIs gehören:

  • Protected Auktion API: Eine Reihe von JS-Funktionen oder UDFs, die Käufer und Verkäufer in ihren B&A-Komponenten bereitstellen können, um Gebote 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 möglichen Anzeigen für die Auktion des Protected App-Signals verantwortlich ist.

Protected Auktion API

Die Protected Auktion API besteht aus JS API oder UDFs, mit denen Käufer und Verkäufer die zur Implementierung ihrer Auktions- und Gebotslogik verwendet werden.

UDFs für Anzeigentechnologie-Käufer
UDF: „PrepareDataForAdRetrieval“

Bevor Protected App Signals zum Abrufen von Anzeigenkandidaten vom TEE verwendet werden können Anzeigenabrufdienst müssen Käufer die geschützten App-Signale decodieren und vorbereiten. und andere von Verkäufern bereitgestellte Daten. Die UDF-Ausgabe der prepareDataForAdRetrieval des Käufers ist an den Anzeigenabrufdienst an die k potenziellen Anzeigen für Gebote abrufen.

// 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 generieren (generieren)

Nachdem die besten k möglichen Anzeigen zurückgegeben wurden, werden diese an die benutzerdefinierte Gebotslogik des Käufers, generateBid UDF:

// 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 Die Funktion kann auch zwei Arrays zurückgeben, die dann an reportWin übergeben werden. um das Modelltraining zu aktivieren (weitere Informationen zum ausgehenden Traffic und zum Modelltraining) siehe Abschnitt „Berichte“ in der PAS-Erklärung)

UDF für reportWin

Nach Abschluss einer Auktion generiert der Auktionsdienst Berichts-URLs für und registrieren Beacons mithilfe von reportWin UDF (dieselben reportWin-Funktion, die für geschützte Zielgruppen verwendet wird). Dieser wird vom Gerät angepingt, sobald die Anzeige vom Client gerendert wurde. Die Signatur dieser Methode ist fast identisch mit der der Protected Audience API. version mit Ausnahme der zwei zusätzlichen Parameter egressPayload und temporaryUnlimitedEgressPayload, die zum Aktivieren des Modelltrainings verwendet werden und mit den Ergebnissen von generateBid gefüllt.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
UDFs für Anzeigentechnologie-Verkäufer
UDF für ScoreAd

Diese UDF wird von Verkäufern verwendet, um auszuwählen, welche der Anzeigen von Käufern gewinnen.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
UDF für „reportResult“

Diese UDF ermöglicht dem Verkäufer (letztendlich) die Ausführung auf Ereignisebene mit den Informationen zur erfolgreichen Anzeige.

function reportResult(auctionConfig, reporting_metadata) {
  // ...
  registerAdBeacon({"click", clickUrl,"view", viewUrl});
  sendReportTo(reportResultUrl);
  return signalsForWinner;
}

Anzeigenabruf-API

In der MVP-Version wird der Anzeigenabrufdienst ein vom Käufer verwalteter und gehosteter und der Bidding-Dienst ruft Anzeigenkandidaten aus diesem Dienst ab. Ab April 2024 muss der Anzeigenabrufserver in einem vertrauenswürdigen Execution Environment (TEE) und stellt eine gRPC-/Proto-Schnittstelle bereit. Anzeigentechnologie Unternehmen müssen diesen Server einrichten und seine URL als Teil des B&A-Elements angeben. Stack-Bereitstellung. Eine Implementierung dieses Dienstes, die im TEE ausgeführt wird ist im GitHub zur Privacy Sandbox und im Rest der gehen wir davon aus, dass dies der in der Bereitstellung verwendete Code ist.

Ab April 2024 werden Anzeigen mit Kontextpfad in B&A-Versionen unterstützt Datenabruf. In diesem Fall erhält der Gebotsserver eine Liste Anzeigen-IDs, die im Kontext der Auktion vom RTB-Server gesendet werden Die IDs werden an einen TEE-KV-Server gesendet, über den alle Anzeigen in der Gebotsphase zu verwendende Informationen (z. B. Anzeigen-Rendering-URL, Metadaten und Anzeigeneinbettungen zur Verwendung in Top-K-Auswahl). Für diesen zweiten Pfad ist keine spezifische Logik erforderlich, bereitgestellt. Deshalb dokumentieren wir hier nur, wie die TEE-basierte den Anwendungsfall "Anzeigenabruf".

HandleRequest-UDF
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals) {
    return adsMetadataString;
}

Wobei:

  • requestMetadata: JSON. Anfragespezifische Servermetadaten für die UDF. Vorerst leer.
  • preparedDataForAdRetrieval: Der Inhalt dieses Felds hängt von der Anzeige ab Datenabrufstrategie. Beim kontextbezogenen Anzeigenabruf die vom Gerät stammenden und vom Bidding-Service. Beim Abrufen von TEE-Anzeigen über den Anzeigenabrufserver Dieser Parameter enthält das Ergebnis der UDF prepareDataForAdRetrieval. Hinweis: In dieser Phase werden die Protected App-Signale decodiert und entschlüsselt.
  • deviceMetadata: JSON-Objekt mit Gerätemetadaten, die vom Anzeigendienst des Verkäufers weitergeleitet wurden. Weitere Informationen finden Sie in der B&A-Dokumentation.
    • X-Accept-Language: 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: Beliebiger String, der aus kontextbezogenen Geboten stammt Server, der von derselben DSP betrieben wird. Die UDF muss in der Lage sein, die und verwenden Sie ihn. Kontextsignale können beliebige Informationen enthalten, z. B. maschinelles Lernen. Modellversionsinformationen für die geschützte Einbettung, die mithilfe von Geschützte App-Signale.

Die UDF sollte im Erfolgsfall einen String zurückgeben. Der String wird an den der sie dann an die UDF generateBid übergibt. Obwohl die String kann auch einfach ein einfacher String sein. In der Regel sollte der String ein serialisiertes Objekt, dessen Schema von jeder Anzeigentechnologie einzeln definiert wird. Es gibt keine Beschränkung für das Schema, solange die generateBid der Anzeigentechnologie Logik den String erkennen und verwenden kann.

System für die Entwicklung einrichten

Android

So richten Sie Ihre Android-Entwicklungsumgebung ein:

  1. Emulator (bevorzugt) oder physisches Gerät erstellen, auf dem das Image für die Entwicklervorschau 10 ausgeführt wird
  2. 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 Option für die Einwilligung zu von Apps vorgeschlagener Werbung aus.

  1. Führen Sie den folgenden Befehl aus, um die relevanten APIs zu aktivieren. Möglicherweise müssen Sie dies gelegentlich noch einmal ausführen, da die Standardkonfiguration von „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;
  1. Starten Sie das Gerät neu.
  2. Überschreiben Sie die Auktionsschlüssel des Geräts, sodass diese auf Ihren Auktionsschlüsselserver verweisen. Es ist wichtig, dass Sie diesen Schritt vor dem Ausführen einer Auktion ausführen, um zu verhindern, dass falsche Schlüssel im Cache gespeichert werden.

Gebote und Auktionsdienste

Informationen zum Einrichten der B&A-Server finden Sie im Dokumentation zur Self-Service-Einrichtung.

In diesem Dokument geht es um die Konfiguration von käuferspezifischen Servern, Für Verkäufer sind keine Änderungen erforderlich.

Vorbereitung

Bevor ein B&A-Service-Stack bereitgestellt werden kann, muss die Anzeigentechnologie des Käufers:

  • Stellen Sie sicher, dass sie einen eigenen TEE-Anzeigenabrufdienst bereitgestellt haben (siehe entsprechenden Abschnitt).
  • Sicherstellen, dass die Anzeigentechnologie über alle erforderlichen UDFs verfügt (prepareDataForAdRetrieval, generateBid, reportWin, HandleRequest) definiert und gehostet wird.

Informationen zur Funktionsweise der geschützten Auktion mit Protected Audience B&A ist ebenfalls hilfreich, ist aber nicht obligatorisch.

Terraform-Konfiguration

Um geschützte App-Signale verwenden zu können, müssen Anzeigentechnologie-Anbieter die folgenden Anforderungen erfüllen:

  • Unterstützung von geschützten App-Signalen in B&A aktivieren.
  • Geben Sie URL-Endpunkte an, von denen die neuen UDFs für prepareDataForAdRetrieval, generateBid und reportWin abgerufen werden können.

Außerdem wird in diesem Leitfaden davon ausgegangen, dass Anzeigentechnologie-Anbieter B&A für werden weiterhin alle bestehenden Konfigurations-Flags für wie gewohnt in der Remarketing-Auktion an.

Konfiguration der Anzeigentechnologie des Käufers

Am Beispiel dieser Demodatei müssen Käufer die folgenden Flags festlegen:

  • Protected App Signals aktivieren: Aktiviert, um geschützte App-Signale zu erfassen Daten.
  • URLs für geschützte App-Signale: Geben Sie hier die URLs der Signale der geschützten App an. Server.

Anzeigentechnologie-Anbieter müssen die korrekten URLs in den Platzhaltern durch Folgendes ersetzen: Felder:

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

Am Beispiel dieser Demo-Datei müssen Verkäufer die folgenden Flags hinzu. (Hinweis: Nur die Konfiguration für Protected App-Signale ist hervorgehoben. hier). AdTechs müssen sicherstellen, dass sie die richtigen URLs in der Platzhalter:

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"

Schlüsselwert- und Anzeigenabrufdienste

Abhängig von den gewählten Strategien für das Anzeigenabrufen erfordern die Bereitstellung einer oder zwei Instanzen des KV-Dienstes. Wir verweisen an die KV-Instanz, die für den TEE-basierten Anzeigenabruf als Ad Retrieval Server und zur Instanz, um kontextbasierte Pfade zu unterstützen als KV Lookup Server abgerufen werden.

In beiden Fällen folgt die Serverbereitstellung der Dokumentation, die im KV-Server GitHub entfernt, besteht der Unterschied zwischen den beiden Fällen darin, dass die Suche ist sofort einsatzbereit – ohne zusätzliche Konfiguration. Abruf One erfordert die Bereitstellung der UDF HandleRequest, um die Abruflogik aus. Weitere Informationen erhalten Sie auf dem KV-Server Onboarding-Leitfaden. B&A erwartet, dass beide Services im selben Service Mesh wie Bidding bereitgestellt werden.

Beispieleinrichtung

Stellen Sie sich folgendes Szenario vor: Sie verwenden die Anzeigentechnologie Protected App Signals API. werden relevante Signale gespeichert, die auf der App-Nutzung der Nutzer basieren. In unserem Beispiel sind Signale die für In-App-Käufe aus verschiedenen Apps stehen. Während eines werden die verschlüsselten Signale erfasst und an eine geschützte Auktion übergeben. in B&A tätig sind. Die benutzerdefinierten Funktionen des Käufers, die in B&A ausgeführt werden, rufen die Anzeige anhand der Signale ab und berechnen ein Gebot.

[Käufer] Beispiele für Signale

Fügt 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ügt 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"
  }
}

[Käufer] Beispiel für „encodeSignals“

Codiert jedes Signal in zwei Byte, wobei das erste Byte das erste Byte den Signalschlüssel und das zweite Byte das erste Byte des Signalwerts.

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};
}

[Käufer] 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;
}

[Käufer] Beispiel-UDF für den Anzeigenabruf

In unserem Beispiel sendet der Anzeigenabrufserver Metadaten (d.h. die ID für jede Anzeige in in diesem Beispiel, aber kann jeweils andere Daten enthalten, die für die Erstellen von Geboten) für jeden der Top-K-Anzeigenkandidaten.

function HandleRequest(requestMetadata, protectedSignals, deviceMetadata,
                      contextualSignals) {
 return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"

[Käufer] 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};
}

[Käufer] reportWin-Beispiel

Die UDF „reportWin“ meldet dem Käufer, 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;
}

[Verkäufer] Schlüsselwert-Server einrichten

Verkäufer müssen einen KV-Server für Bewertungssignale einrichten, damit eine Zuordnung vorhanden ist aus den Anzeigen-Rendering-URLs in die entsprechenden Bewertungssignale ein, z. B.: wenn https:/buyer-domain.com/get-fitness-app und https:/buyer-domain.com/get-fastfood-app sollten vom Käufer zurückgegeben werden, Der Verkäufer kann folgende Beispielantwort für Bewertungssignale erhalten, wenn er von den SFE mit GET auf 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"
      ]
   }
}

[Verkäufer] ScoreAd-Beispiel

/**
 * 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
  };
}

[Verkäufer] Beispiel für reportResult

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 zum Erstellen einer App verwendet werden kann, die eine einfache wie oben beschrieben, haben wir eine Beispiel-App für „Protected App Signals“ erstellt, Sie finden sie in diesem Beispiel-Repository.