Przewodnik dla programistów dotyczący Protected App Signals

Aby ułatwić deweloperom eksperymentowanie z interfejsem Protected App Signals API, W tym dokumencie opisujemy wszystkie interfejsy API dostępne w ramach platformy, a także szczegółowo opisujemy, jak skonfigurować środowisko testowe i podać przykłady konfiguracji oraz skryptów.

Historia zmian

Styczeń 2024 r.

Pierwsza wersja przewodnika dla deweloperów obsługującego wersję PAS MVP

Marzec 2024 r.

Zmiany w interfejsie API na potrzeby obsługi wersji M-2024-05 interfejsu API Androida oraz Udostępnienie komponentów po stronie serwera w kwietniu 2024 r. Najważniejsze zmiany:

  • Dodaliśmy szczegóły o uprawnieniach wymaganych dla interfejsu API działającego na urządzeniu
  • Dodano szczegóły dotyczące zarządzania limitem sygnałów na urządzeniu
  • Zaktualizowano podpis generateBid o zmiany związane z kontekstem obsługa pobierania i ruchu wychodzącego z reklam
  • Zaktualizowano dokumentację reportWin, w tym obsługę ruchu wychodzącego
  • Zaktualizuj dokumentację interfejsu Ad Retrieval API: nie obsługuje pobierania reklam BYOS i dokumentowanie funkcji UDF pobierania reklam.

Przegląd interfejsów API

Interfejs Protected Signals API zawiera różne podzbiory interfejsów API systemy:

  • Interfejsy API dla Androida:
    • Interfejs Signal Curation API składa się z tych elementów:
    • Aktualizowanie interfejsu Signals API
    • Interfejs Signals Encoding API
    • Interfejs Protected Session Support API: który jest używany przez pakiety SDK do uruchamiania chronionych aukcja na serwerach ustalania stawek i aukcji korzystających z Protected App Sygnały.
  • Interfejsy API po stronie serwera:
    • Protected Session API: seria skryptów JS działających w sekcji „Określanie stawek” Serwery aukcji. Ten interfejs API umożliwia sprzedawcom i kupującym zapisywanie reguł przeprowadzić aukcję chronioną.
    • Ad Retrieval API: odpowiada za udostępnienie listy kandydatów do danej reklamy informacje kontekstowe i informacje o użytkowniku udostępniane licytującemu przez kupującego; serwera.

Klient na Androida

Po stronie klienta platforma Chronione sygnały aplikacji składa się z 3 elementów. różne interfejsy API:

  • Aktualizowanie sygnałów: interfejs Android System API, który umożliwia selekcję sygnałów urządzenia.
  • Kodowanie sygnałów: interfejs API JavaScript do przygotowywania sygnałów do wysłania serwera podczas aukcji.
  • Obsługa aukcji Protected: interfejs API do obsługi aukcja na serwerach określania stawek i aukcji. Ten interfejs API nie dotyczy są chronione sygnały aplikacji i służą również do obsługi aukcji Audience API.
.

Aktualizowanie interfejsu Signals API

Interfejs Update Signals API umożliwia technikom reklamowym rejestrowanie użytkowników sygnały z aplikacji w imieniu kupującego. Interfejs API działa w modelu przekazywania dostępu. Element wywołujący podaje identyfikator URI, z którego platforma pobiera odpowiednie oraz kodowanie tych sygnałów do użycia w aukcji.

Interfejs API wymaga android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS uprawnienia.

Interfejs API updateSignals() pobierze obiekt JSON z identyfikatora URI zawierającego informacje o tym, które sygnały należy dodać lub usunąć oraz jak się przygotować te sygnały do aukcji.

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

Platforma wysyła żądanie https do identyfikatora URI podanego w żądaniu pobrania. sygnał się zaktualizuje. Oprócz aktualizacji sygnału odpowiedź może zawierać który hostuje logikę kodowania konwertując nieprzetworzone sygnały na zakodowany ładunek. Aktualizacje sygnałów powinny mieć postać JSON oraz może mieć następujące klucze:

Klucze najwyższego poziomu w przypadku obiektu JSON muszą odpowiadać jednemu z 5 poleceń:

klucz

Opis

put

Dodaje nowy sygnał, zastępując wszystkie dotychczasowe sygnały tym samym kluczem. Wartość

dla tego obiektu JSON jest to obiekt JSON, w którym klucze są ciągami 64 podstaw odpowiadającymi kluczowi, dla którego ma zostać umieszczony klucz, a wartościami są ciągi w formacie 64 odpowiadające wartości do umieszczenia.

append

Dodaje nowy sygnał/sygnały do ciągu czasowego i usuwa najstarsze

aby zrobić miejsce na nowe, jeśli rozmiar serii przekracza podany limit. Wartością tego obiektu jest obiekt JSON, w którym klucze to ciągi w formacie 64 odpowiadające kluczowi, do którego mają zostać dołączone ciągi, a wartościami są obiektami z 2 polami: „values”. i maxSignals.

„values”: lista ciągów w formacie 64 odpowiadających wartościom sygnałów, które mają zostać dołączone do ciągu czasowego.

„maxSignals”: maksymalna liczba wartości dozwolonych w tym ciągu czasowym. Jeśli

bieżąca liczba sygnałów powiązanych z kluczem przekracza wartość maxSignals. Najstarsze sygnały zostaną usunięte. Pamiętaj, że możesz dołączyć do klucza dodanego przez polecenie put. Pamiętaj, że dodanie większej liczby wartości niż maksymalna spowoduje błąd.

put_if_not_present

Dodaje nowy sygnał tylko wtedy, gdy nie ma żadnych sygnałów z tym samym kluczem. Wartością tego obiektu jest obiekt JSON, w którym klucze są ciągami 64 podstaw odpowiadającymi kluczowi, dla którego ma zostać umieszczony klucz, a wartościami są ciągami w formacie 64 odpowiadającym wartości do umieszczenia.

remove

Usuwa sygnał klucza. Wartością jest lista ciągów w formacie 64 odpowiadających kluczom sygnałów, które należy usunąć.

update_encoder

Udostępnia działanie aktualizacji punktu końcowego i identyfikator URI, którego można użyć

aby pobrać logikę kodowania. Klucz podrzędny dotyczący działania aktualizacji to „action” oraz

obecnie obsługiwane wartości to „REGISTER” , który rejestruje punkt końcowy kodera, jeśli został podany po raz pierwszy, lub zastąpi istniejący punkt końcowy nowo podanym punktem końcowym. Podanie punktu końcowego jest wymagane w przypadku instancji „REGISTER” action. Kluczem podrzędnym punktu końcowego kodera jest „punkt końcowy”. a wartością jest identyfikator URI

ciągu znaków dla punktu końcowego.

Przykładowe żądanie JSON będzie wyglądać tak:

{
    "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"
    }
}

Na urządzeniu będzie obowiązywał limit 10–15 KB. Po osiągnięciu limitu zostanie przekroczony. PPAPI usunie sygnały za pomocą strategii FIFO. Proces usuwania pozwoli na niewielkie przekroczenie limitu na krótkie przedziały czasu aby ograniczyć częstotliwość usuwania treści.

Interfejs Signals Encoding API

Kupujący muszą dostarczyć funkcję JavaScript, która będzie używana do kodowania sygnałów przechowywanych na urządzeniu i wysyłanych na serwer podczas Aukcja. Kupujący mogą dostarczyć ten skrypt, dodając adres URL pobrane z klucza „update_encoder” w dowolnej odpowiedzi na Żądanie do interfejsu UpdateSignal API. Skrypt będzie miał następujący podpis:

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

Parametr signals to mapa z kluczy w formacie UInt8tablicas o rozmiarze 4. do list obiektów Protected App Signals. Każdy obiekt w Protected App Signals ma 3 pola:

  • signal_value: UInt8tablica reprezentująca wartość sygnału.
  • creation_time: liczba reprezentująca czas utworzenia sygnałów w sekunda-epoki.
  • package_name: ciąg znaków reprezentujący nazwę utworzonego pakietu. i wysyłanie sygnałów.

Parametr maxSize to liczba opisująca największy dozwolony rozmiar tablicy danych wyjściowych.

Funkcja powinna zwrócić obiekt z 2 polami:

  • status: jeśli skrypt został uruchomiony, wartość powinna wynosić 0.
  • results: powinna być tablicą UInt8 o długości mniejszej od maxSize lub jej równej. Ta tablica zostanie wysłana do serwera podczas aukcji i przygotowana przez Skrypt prepareDataForAdRetrieval.

Kodowanie zapewnia technikom reklamowym początkowy etap opracowywania funkcji, gdzie mogą przeprowadzać transformacje, np. kompresować nieprzetworzone sygnały połączone wersje według własnej logiki. Pamiętaj, że w okresie technologia reklamowa w ramach aukcji chronionej działających w Trusted Execution Environments (TEE) niestandardową logikę będzie mieć dostęp z możliwością odczytu do ładunków sygnałów generowanych przez kodowanie. Własna logika, Funkcja zdefiniowana przez użytkownika (UDF) działająca w środowisku B&A kupującego będzie mieć dostęp z możliwością odczytu zakodowanych sygnałów i innych sygnałów kontekstowych które aplikacja wydawcy udostępnia do wyboru reklamy (pobieranie reklam określanie stawek).

Kodowanie sygnałów

Co godzinę kupujący, którzy dostarczyli kodowanie swoich rejestrów będą zakodowane w ładunku aukcji. dla ładunku aukcji jest zachowywana na urządzeniu i jest szyfrowana będą zbierane przez sprzedawców w ramach danych o wyborze reklamy i uwzględniane jako część aukcji chronionej. Jeśli chcesz przetestować to kodowanie, możesz to zrobić poza jego częstotliwość godzinową, uruchamiając następujące polecenie:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Obsługa wersji logiki kodera

W przypadku żądania pobrania niestandardowej logiki kodera technologii reklamowych punkt końcowy może odpowiedzieć, podając numer wersji w nagłówkach odpowiedzi. Ta wersja jest zachowywana razem z ustawieniami logicznymi kodera urządzenia. Gdy nieprzetworzone sygnały zakodowany ładunek jest zachowywany wraz z wersją używaną przez kodowanie. Ta wersja jest również wysyłana do serwera B&A podczas przesyłania aukcji, aby technologie reklamowe mogły dostosować logikę określania stawek i kodowania na podstawie wersję.

Response header for providing encoder version : X_ENCODER_VERSION

Interfejs Protected Publishing Support API

Po stronie urządzenia przeprowadzenie aukcji dotyczącej Protected App Signals to tak samo jak w przypadku aukcji dla chronionych odbiorców.

Określanie stawek i usługi aukcyjne

Interfejsy API po stronie serwera obejmują:

  • Protected Session API: seria funkcji JS lub UDF, które kupujący i sprzedawcy mogą wdrożyć w swoich komponentach B&A, aby określić stawki i logikę aukcji.
  • Interfejs Ad Retrieval API: kupujący mogą wdrożyć ten interfejs API, implementując punkt końcowy REST, który będzie odpowiedzialny za przesyłanie zestawu reklam kandydujących do aukcji chronionego sygnału aplikacji.

Interfejs Protected Session API

Interfejs Protected Session API składa się z interfejsu JS API lub funkcji UDF, które kupujący i sprzedawcy mogą do implementacji logiki aukcji i określania stawek.

UDF technologii reklamowych kupującego
UDF narzędzia do przygotowania danych do pobierania reklam

Zanim chronione sygnały aplikacji były używane do pobierania kandydatów na reklamy z TEE w usłudze pobierania reklam, kupujący muszą dekodować i przygotować chronione sygnały aplikacji i inne dane przekazywane przez sprzedawców. Dane wyjściowe UDF kupujących prepareDataForAdRetrieval to przekazywane do usługi pobierania reklam do pobranie 100 reklam z najlepszej pozycji na potrzeby określania stawek.

// 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 funkcji generateBid

Po zwróceniu tysięcy najlepszych reklam kandydujących są one przekazywane do logikę ustalania stawek niestandardowych kupującego, 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>
    };
}

Wynikiem tej funkcji jest pojedyncza stawka dla kandydującej reklamy, reprezentowana jako odpowiednik JSON ProtectedAppSignalsAdWithBidMetadata Funkcja może również zwrócić 2 tablice, które zostaną przekazane do funkcji reportWin aby włączyć trenowanie modelu (więcej informacji o ruchu wychodzącym i trenowaniu modelu zapoznaj się z sekcją raportowania w objaśnieniu PAS)

RaportWin UDF

Po zakończeniu aukcji usługa aukcyjna wygeneruje raporty adresów URL dla zapytania i zarejestrują beacony za pomocą funkcji reportWin UDF (to jest to samo reportWin wykorzystywanej na potrzeby Protected Audience API). Będzie ona pingowana przez urządzenie, gdy reklama zostanie wyrenderowana przez klienta. Podpis tej metody jest prawie taki sam jak w przypadku Protected Audience API version, z wyjątkiem dwóch dodatkowych parametrów egressPayload oraz temporaryUnlimitedEgressPayload, które są używane do trenowania modelu i są z wynikami z generateBid.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
UDF technologii reklamowych sprzedawców
UDF reklamy

Ta funkcja UDF jest używana przez sprzedawców do wybierania reklam, które otrzymały kupujących wygra aukcję.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
UDF wyniku raportu

Ta UDF umożliwia sprzedawcy wykonanie (ostatecznie) poziomu zdarzenia zawierać w raportach informacje o zwycięskiej reklamie.

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

Interfejs Ad Retrieval API

W wersji MVP usługa pobierania reklam będzie zarządzana i hostowana przez kupującego , a usługa ustalania stawek będzie pobierać z niej kandydatów reklam. Od kwietnia 2024 r. serwer pobierania reklam musi używać Środowisko wykonawcze (TEE) i udostępni interfejs GRPC/proto. Technologie reklamowe muszą skonfigurować ten serwer i podać jego adres URL w ramach stosunkowo dużo. Implementacja tej usługi działająca w TEE jest dostępna w Piaskownicy prywatności na GitHubie i w pozostałych przy założeniu, że jest to kod używany we wdrożeniu.

Od kwietnia 2024 r. wersje B&A obsługują kontekstową reklamę ze ścieżką pobieranie danych. W takim przypadku serwer ustalania stawek otrzyma listę identyfikatory reklam wysyłane przez serwer RTB podczas kontekstowej części aukcji. Identyfikatory zostaną przesłane do serwera TEE KV, aby pobrać wszystkie reklamy powiązane informacje do wykorzystania na etapie ustalania stawek, (na przykład ad-render-url, metadane i wektory dystrybucyjne reklam, które będą używane wybór górnego K). Ta druga ścieżka nie wymaga żadnej logiki więc omówimy wyłącznie sposób konfigurowania w oparciu o TEE. pobierania reklam.

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

Gdzie:

  • requestMetadata: plik JSON. Metadane serwera żądania wysyłane do funkcji UDF. Na razie puste.
  • preparedDataForAdRetrieval: zawartość tego pola zależy od reklamy. strategii pobierania. W przypadku kontekstowego pobierania reklam , ten parametr będzie zawierać nieprzetworzone sygnały pochodzące z urządzenia i przekazywane usługę określania stawek. W przypadku pobierania reklam przez TEE za pomocą serwera Ad Retrieval Server ten parametr będzie zawierać wynik funkcji UDF prepareDataForAdRetrieval. Uwaga: na tym etapie chronione sygnały aplikacji będą dekodowane i niezaszyfrowane.
  • deviceMetadata: obiekt JSON zawierający metadane urządzenia przekazane przez usługę reklamową sprzedawcy. Więcej informacji znajdziesz w dokumentacji usługi B&A.
    • X-Accept-Language: język używany na urządzeniu.
    • X-User-Agent: klient użytkownika używany na urządzeniu.
    • X-BnA-Client-IP: adres IP urządzenia.
  • contextualSignals: dowolny ciąg znaków pochodzący z określania stawek kontekstowych. obsługiwany przez tę samą platformę DSP. Należy się spodziewać, że UDF będzie w stanie zdekodować i używać ich. Sygnały kontekstowe mogą zawierać dowolne informacje, np. systemy uczące się informacje o wersji modelu dla chronionego wektora dystrybucyjnego przekazywanego za pomocą Chronione sygnały aplikacji.

Po udanym działaniu funkcja UDF powinna zwrócić ciąg znaków. Ciąg jest zwracany do funkcji serwera ustalania stawek, który przekazuje go do funkcji UDF generateBid. Mimo że może być prostym ciągiem, najprawdopodobniej będzie to zserializowany obiekt, którego schemat jest zdefiniowany przez poszczególne technologie reklamowe. Schemat nie ma ograniczeń, dopóki atrybut generateBid technologii reklamowej funkcje logiczne rozpoznają i z niego korzystają.

Konfigurowanie systemu na potrzeby programowania

Android

Aby skonfigurować środowisko programistyczne Androida, wykonaj te czynności:

  1. Utwórz emulator (preferowane) lub urządzenie fizyczne z obrazem w wersji dla programistów w wersji 10.
  2. Wykonaj zapytanie:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

Następnie wybierz pokazaną opcję wyrażenia zgody na reklamy sugerowane przez aplikacje.

  1. Uruchom poniższe polecenie, aby włączyć odpowiednie interfejsy API. Może być konieczne ponowne uruchamianie, ponieważ domyślna konfiguracja wyłączonej konfiguracji będzie okresowo synchronizowana.
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. Uruchom urządzenie ponownie.
  2. Zastąp klucze aukcji urządzenia, aby wskazywały Twój serwer kluczy aukcji. Ten krok należy wykonać przed próbą przeprowadzenia aukcji, aby zapobiec zapisywaniu nieprawidłowych kluczy w pamięci podręcznej.

Określanie stawek Usługi aukcyjne

Aby skonfigurować serwery B&A, zapoznaj się z samodzielną konfiguracją.

W tym dokumencie skupimy się na konfigurowaniu konkretnych serwerów kupującego. sprzedawcy nie muszą wprowadzać żadnych zmian.

Wymagania wstępne

Przed wdrożeniem stosu usług B&A kupujący technologie reklamowe muszą:

  • Zadbać o wdrożenie własnej usługi pobierania reklam TEE (zobacz odpowiedniej sekcji).
  • Zadbaj o to, aby technologie reklamowe miały wszystkie niezbędne funkcje UDF (prepareDataForAdRetrieval, generateBid, reportWin, HandleRequest) zdefiniowanych i hostowanych.

Znajomość sposobu działania aukcji chronionej z użyciem Protected Audience API Warunki korzystania z usługi również będą pomocne, ale nie są obowiązkowe.

Konfiguracja Terraform

Aby korzystać z Chronionych sygnałów aplikacji, technologie reklamowe muszą:

  • Włącz w B&A obsługę Protected App Signals.
  • Podaj punkty końcowe adresu URL, z których można pobierać nowe funkcje UDF dla prepareDataForAdRetrieval, generateBid i reportWin.

W tym przewodniku zakładamy też, że specjaliści z branży technologii reklamowych, którzy chcą korzystać z oferty B&A remarketing będzie nadal ustawiać wszystkie obecne flagi konfiguracji dla remarketingu tak jak zwykle.

Konfiguracja technologii reklam kupującego

Korzystając z tego przykładowego pliku demonstracyjnego, kupujący muszą ustawić te flagi:

  • Włącz chronione sygnały aplikacji: umożliwia zbieranie chronionych sygnałów aplikacji. i skalowalnych danych.
  • Adresy URL w Protected App Signals: ustaw na adresy URL chronionych sygnałów aplikacji. serwerów.

Techniki reklamowe muszą zastąpić prawidłowe adresy URL w obiektach zastępczych: pola:

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"

Konfiguracja technologii reklam sprzedawcy

Używając tego pliku prezentacji jako przykładu, sprzedawcy muszą ustawić tych flag. Uwaga: wyróżniona jest tylko konfiguracja związana z Protected App Signals tutaj). Specjaliści ds. technologii reklamowych muszą dopilnować, by zastępowały prawidłowe adresy URL w parametrze obiekty zastępcze:

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"

słowa kluczowe i usługi pobierania reklam

W zależności od wybranych strategii pobierania reklam system będzie wymaga wdrożenia 1 lub 2 instancji usługi KV. Polecamy do instancji KV używanej do pobierania reklam opartego na TEE jako Ad Retrieval Server i instancję w celu obsługi ścieżki kontekstowej i pobierasz jako KV Lookup Server.

W obu przypadkach wdrożenie serwerów odbywa się zgodnie z dokumentacją dostępną w KV GitHub, różnica między tymi 2 przypadkami polega na tym, że wyszukiwanie obudowa działa od razu i nie wymaga dodatkowej konfiguracji. pobieranie 1 wymaga wdrożenia funkcji UDF HandleRequest zasady pobierania. Więcej informacji można znaleźć na stronie Serwer KV . Firma B&A oczekuje, że obie usługi będą wdrożone w tej samej siatce usług co usługa określania stawek.

Przykładowa konfiguracja

Rozważmy ten scenariusz: za pomocą interfejsu Protected App Signals API przechowuje odpowiednie sygnały na podstawie danych o korzystaniu z aplikacji przez użytkownika. W naszym przykładzie sygnały które reprezentują zakupy w kilku aplikacjach. Podczas zaszyfrowane sygnały są zbierane i przekazywane do aukcji chronionej. w B&A. UDF kupującego używane w B&A używają sygnałów do pobierania reklamy i obliczą stawkę.

[Kupujący] Przykłady sygnałów

Dodaje sygnał z kluczem 0 i wartością 1.

{
  "put": {
    "AA==": "AQ=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

Dodaje sygnał z kluczem 1 i wartością 2.

{
  "put": {
    "AQ==": "Ag=="
  },
  "update_encoder": {
    "action": "REGISTER",
    "endpoint": "https://example.com/example_script"
  }
}

[Kupujący] przykład kodowania sygnałów

Koduje każdy sygnał na 2 bajty, przy czym pierwszy bajt to pierwszy bajt klucz sygnału, a drugi bajt to pierwszy bajt wartości sygnału.

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

[Kupujący] Przykład readyDataForAdRetrieval

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

[Kupujący] Przykładowy UDF pobierania reklam

W naszym przykładzie serwer pobierania reklam wysyła metadane (tj. identyfikator każdej reklamy w w tym przykładzie, ale mogą zawierać inne dane, które pomogą generowanie stawek) dla każdego z tys. najlepszych kandydatów.

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

[Kupujący] Przykład strony 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};
}

[Kupujący] Przykład raportu Win

UDF reportWin zgłasza kupującemu, że wygrał aukcję.

function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                                       buyerReportingSignals, directFromSellerSignals,
                                       egressPayload,
                                       temporaryUnlimitedEgressPayload) {
  sendReportTo("https://buyer-controlled-domain.com/");
  registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
  return;
}

[Sprzedawca] Konfiguracja serwera KV

Sprzedawcy muszą skonfigurować serwer KV sygnałów oceniania, aby zapewnić mapowanie. z adresów URL renderowania reklam do odpowiednich sygnałów punktowych, na przykład: jeśli https:/buyer-domain.com/get-fitness-app i Kupujący otrzymał od Ciebie zwrot https:/buyer-domain.com/get-fastfood-app, sprzedawca może otrzymać poniższy przykładowy sygnał punktowy odpowiedzi na zapytanie SFE przy użyciu interfejsu GET w systemie 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"
      ]
   }
}

[Sprzedawca] Przykład ScoreAd

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

[Sprzedawca] – przykład wyniku raportu

function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
  let signalsForWinner = {};
    sendReportTo("https://seller-controlled-domain.com");
    registerAdBeacon({"clickEvent":
                    "https://seller-controlled-domain.com/clickEvent"});
    return signalsForWinner;
}

Przykładowa aplikacja

Jako przykład wykorzystania interfejsu API do stworzenia aplikacji używającej prostego w podany powyżej sposób, utworzyliśmy przykładową aplikację w ramach Protected App Signals, która znajdziesz w tym przykładowym repozytorium.