Przewodnik dla programistów dotyczący Protected App Signals

ad techproject_path: /_project.yaml book_path: /_book.yaml keywords: api:ProtectedAppSignals, docType:Guide, skill:Beginner, audienceAdBuyer, audienceAdSeller, topicAdAuction, contentTypeFundamental, category:Mobile, apiGroupAds

Aby pomóc deweloperom w eksperymentowaniu z interfejsem Protected App Signals API, w tym dokumencie opisujemy wszystkie interfejsy API w ramach interfejsu API, szczegółowo wyjaśniamy, jak skonfigurować środowisko testowe, oraz podajemy przykłady konfiguracji i skryptów.

Historia zmian

stycznia 2024 r.

Pierwsza wersja przewodnika dla deweloperów obsługująca wersję MVP usługi PAS

Marzec 2024 r.

Zmiany w interfejsie API, które obsługują wersję M-2024-05 interfejsu Android API i wersję komponentów po stronie serwera z kwietnia 2024 roku. Najważniejsze zmiany:

  • Dodano szczegóły dotyczące uprawnień wymaganych w przypadku interfejsu API na urządzeniu.
  • Dodano szczegóły dotyczące zarządzania limitami sygnałów na urządzeniu
  • Zaktualizowany podpis generateBid ze zmianami związanymi z kontekstowym pobieraniem reklam i obsługą wychodzącą
  • Zaktualizowana dokumentacja reportWin, w tym obsługa wychodzenia
  • Aktualizacja dokumentacji interfejsu Ad Retrieval API przez usunięcie obsługi pobierania reklam BYOS i udokumentowanie funkcji zdefiniowanej przez użytkownika do pobierania reklam

Przegląd interfejsów API

Interfejs Protected Signals API obejmuje różne podzbiory interfejsu API w różnych systemach:

  • Interfejsy API Androida:
    • Signal Curation API, który obejmuje:
    • Update Signals API
    • Signals Encoding API
    • Protected Auction Support API: interfejs API, który ma być używany przez pakiety SDK do przeprowadzania chronionej aukcji na serwerach licytacji i aukcji (B&A) z użyciem chronionych sygnałów aplikacji.
  • Interfejsy API po stronie serwera:
    • Protected Auction API: seria skryptów JS działających na serwerach określania stawek i aukcji. Ten interfejs API umożliwia sprzedawcom i kupującym pisanie logiki do wdrażania aukcji chronionej.
    • Ad Retrieval API: odpowiada za dostarczanie listy reklam, które mogą się wyświetlić, na podstawie informacji kontekstowych i o użytkownikach udostępnianych serwerowi licytującemu kupującego.

Klient Androida

Po stronie klienta interfejs Protected App Signals składa się z 3 różnych interfejsów API:

  • Sygnały aktualizacji: interfejs API systemu Android, który umożliwia selekcjonowanie sygnałów na urządzeniu.
  • Kodowanie sygnałów: interfejs API JavaScript do przygotowywania sygnałów, które mają być wysyłane na serwer podczas aukcji.
  • Obsługa aukcji chronionych: interfejs API obsługujący przeprowadzanie aukcji chronionych na serwerach określania stawek i aukcji. Ten interfejs API nie jest przeznaczony wyłącznie do sygnałów z chronionych aplikacji. Jest też używany do obsługi aukcji interfejsu Protected Audience API.

Update Signals API

Interfejs Update Signals API umożliwia dostawcom technologii reklamowych rejestrowanie sygnałów związanych z użytkownikami i aplikacjami w imieniu kupującego. Interfejs API działa w oparciu o model delegowania. Wywołujący podaje identyfikator URI, z którego platforma pobiera odpowiednie sygnały i logikę kodowania tych sygnałów do wykorzystania w aukcji.

Interfejs API wymaga uprawnienia android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS.

Interfejs updateSignals() API pobierze z identyfikatora URI obiekt JSON, który opisuje, które sygnały należy dodać lub usunąć, oraz jak 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, aby pobrać aktualizacje sygnałów. Oprócz aktualizacji sygnałów odpowiedź może zawierać punkt końcowy, który hostuje logikę kodowania służącą do przekształcania surowych sygnałów w zakodowany ładunek. Aktualizacje sygnałów powinny być w formacie JSON i mogą zawierać te klucze:

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

key

Opis

put

Dodaje nowy sygnał, zastępując wszystkie istniejące sygnały o tym samym kluczu. Wartość

to obiekt JSON, w którym klucze są ciągami tekstowymi w formacie Base64 odpowiadającymi kluczowi do umieszczenia, a wartości są ciągami tekstowymi w formacie Base64 odpowiadającymi wartości do umieszczenia.

append

Dołącza nowy sygnał lub sygnały do szeregu czasowego sygnałów, usuwając najstarszy.

sygnałów, aby zrobić miejsce na nowe, jeśli rozmiar serii przekracza podaną wartość maksymalną. Wartością tego parametru jest obiekt JSON, w którym klucze są ciągami znaków w standardzie Base64 odpowiadającymi kluczowi do dołączenia, a wartości są obiektami z 2 polami: „values” i „maxSignals”.

„values”: lista ciągów zakodowanych w formacie Base64 odpowiadających wartościom sygnałów, które mają zostać dołączone do szeregu 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 za pomocą metody 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 jeszcze sygnałów o tym samym kluczu. Wartość tego parametru to obiekt JSON, w którym klucze są ciągami znaków zakodowanymi w formacie Base64 odpowiadającymi kluczowi do umieszczenia, a wartości są ciągami znaków zakodowanymi w formacie Base64 odpowiadającymi wartości do umieszczenia.

remove

Usuwa sygnał klucza. Wartością jest lista ciągów zakodowanych w formacie Base64, które odpowiadają kluczom sygnałów, które mają zostać usunięte.

update_encoder

Zawiera działanie umożliwiające zaktualizowanie punktu końcowego oraz identyfikator URI, którego można użyć.

pobierać logikę kodowania. Podkluczem do podania działania aktualizacji jest „action”, a

Obsługiwana jest tylko wartość „REGISTER”, która rejestruje punkt końcowy kodera, jeśli jest podany po raz pierwszy, lub zastępuje istniejący punkt końcowy nowo podanym punktem końcowym. Podanie punktu końcowego jest wymagane w przypadku działania „REGISTER”. Podklucz do podania punktu końcowego kodera to „endpoint”, a wartość to URI.

ciąg znaków punktu końcowego.

Przykładowe żądanie w formacie JSON wyglądałoby 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"
    }
}

Sygnały będą miały na urządzeniu limit w wysokości 10–15 KB. Po przekroczeniu limitu interfejs PPAPI usunie sygnały, stosując strategię FIFO. Proces usuwania pozwoli na krótkotrwałe przekroczenie limitu, aby zmniejszyć częstotliwość usuwania.

Signals Encoding API

Kupujący muszą dostarczyć funkcję JavaScript, która będzie używana do kodowania sygnałów przechowywanych na urządzeniu, aby wysyłać je na serwer podczas aukcji chronionej. Kupujący mogą udostępnić ten skrypt, dodając adres URL, z którego można go pobrać, za pomocą klucza „update_encoder” w dowolnej odpowiedzi na żądanie interfejsu UpdateSignal API. Skrypt będzie miał ten 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 kluczy w formie tablic UInt8Array o rozmiarze 4 do list obiektów Protected App Signals. Każdy obiekt Protected App Signals ma 3 pola:

  • signal_value: tablica UInt8Array reprezentująca wartość sygnału.
  • creation_time: liczba reprezentująca czas utworzenia sygnałów w sekundach od początku epoki.
  • package_name: ciąg znaków reprezentujący nazwę pakietu, który utworzył sygnał.

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

Funkcja powinna zwracać obiekt z 2 polami:

  • status: jeśli skrypt został uruchomiony prawidłowo, powinna to być wartość 0.
  • results: powinien być tablicą UInt8Array o długości mniejszej lub równej maxSize. Ta tablica będzie wysyłana na serwer podczas aukcji i przygotowywana przez skrypt prepareDataForAdRetrieval.

Kodowanie zapewnia technologiom reklamowym wstępny etap inżynierii funkcji, na którym mogą one przeprowadzać transformacje, takie jak kompresowanie surowych sygnałów do wersji połączonych na podstawie własnej logiki niestandardowej. Pamiętaj, że podczas aukcji chronionej uruchomionej w zaufanych środowiskach wykonawczych (TEE) niestandardowa logika technologii reklamowych będzie miała dostęp do odczytu ładunków sygnałów wygenerowanych przez kodowanie. Logika niestandardowa, zwana funkcją zdefiniowaną przez użytkownika (UDF), działająca w środowisku TEE platformy B&A kupującego będzie mieć dostęp do odczytu zakodowanych sygnałów i innych sygnałów kontekstowych dostarczanych przez aplikację wydawcy w celu wyboru reklamy (pobierania reklamy i licytowania).

Kodowanie sygnałów

Co godzinę sygnały kupujących, którzy podali logikę kodowania wraz z zarejestrowanymi sygnałami, będą kodowane w ładunku aukcji.Tablica bajtów ładunku aukcji jest przechowywana na urządzeniu, szyfrowana i zbierana przez sprzedawców w ramach danych wyboru reklamy, które są uwzględniane w aukcji chronionej. Aby przetestować kodowanie, możesz je wywołać poza godzinowym harmonogramem, uruchamiając to polecenie:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Wersje logiki kodera

Gdy zostanie wysłane żądanie pobrania niestandardowej logiki kodera technologii reklamowej, punkt końcowy technologii reklamowej może w nagłówkach odpowiedzi podać numer wersji. Ta wersja jest przechowywana wraz z logiką kodera na urządzeniu. Gdy surowe sygnały są kodowane, zakodowany ładunek jest zapisywany wraz z wersją używaną do kodowania. Ta wersja jest też wysyłana na serwer B&A podczas aukcji chronionej, dzięki czemu dostawcy technologii reklamowych mogą dostosowywać logikę określania stawek i kodowania na podstawie tej wersji.

Response header for providing encoder version : X_ENCODER_VERSION

Interfejs Protected Auction Support API

Po stronie urządzenia przeprowadzenie aukcji sygnałów z chronionych aplikacji jest takie samo jak przeprowadzenie aukcji dla chronionych odbiorców.

Usługi określania stawek i aukcji

Interfejsy API po stronie serwera obejmują:

  • Protected Auction API: seria funkcji JS lub funkcji zdefiniowanych przez użytkownika, które kupujący i sprzedający mogą wdrażać w należących do nich komponentach B&A, aby określać logikę ustalania stawek i aukcji.
  • Ad Retrieval API: kupujący mogą wdrożyć ten interfejs API, implementując punkt końcowy REST, który będzie odpowiadać za dostarczanie zestawu potencjalnych reklam na potrzeby aukcji z sygnałami z aplikacji chronionych.

Protected Auction API

Interfejs Protected Auction API składa się z interfejsu JS API lub funkcji zdefiniowanych przez użytkownika, których kupujący i sprzedawcy mogą używać do implementowania logiki aukcji i licytowania.

Funkcje zdefiniowane przez użytkownika w technologii reklamowej kupującego
Funkcja UDF prepareDataForAdRetrieval

Zanim sygnały z chronionych aplikacji będą mogły być używane do pobierania kandydatów na reklamy z usługi pobierania reklam w TEE, kupujący muszą zdekodować i przygotować sygnały z chronionych aplikacji oraz inne dane dostarczone przez sprzedawcę. Dane wyjściowe prepareDataForAdRetrieval funkcji zdefiniowanej przez użytkownika są przekazywane do usługi pobierania reklam, aby pobrać k najlepszych reklam kandydatów do ustalania 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 ad tech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
   return {};
}
Funkcja UDF generateBid

Po zwróceniu k najlepszych kandydatów na reklamy są oni przekazywani do niestandardowej logiki określania stawek kupującego, generateBid funkcji zdefiniowanej przez użytkownika:

// 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 za kandydata na reklamę, przedstawiona jako odpowiednik JSON ProtectedAppSignalsAdWithBidMetadata. Funkcja może też zwracać 2 tablice, które zostaną następnie przekazane do funkcji reportWin, aby umożliwić trenowanie modelu (więcej informacji o wychodzących danych i trenowaniu modelu znajdziesz w sekcji raportowania w wyjaśnieniu dotyczącym PAS).

funkcja UDF reportWin

Po zakończeniu aukcji usługa aukcyjna wygeneruje adresy URL raportowania dla kupujących i zarejestruje sygnały za pomocą reportWin funkcji zdefiniowanej przez użytkownika (UDF) (jest to ta sama funkcja, która jest używana w przypadku Protected Audience).reportWin Urządzenie wyśle ping po wyświetleniu reklamy przez klienta. Sygnatura tej metody jest prawie taka sama jak w wersji Protected Audience, z wyjątkiem 2 dodatkowych parametrów egressPayloadtemporaryUnlimitedEgressPayload, które służą do włączania trenowania modelu i są wypełniane wynikami z generateBid.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
Funkcje zdefiniowane przez użytkownika w technologii reklamowej sprzedawcy
funkcja UDF scoreAd

Ta funkcja zdefiniowana przez użytkownika jest używana przez sprzedawców do wybierania, które z otrzymanych od kupujących reklam wygrają aukcję.

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

Ta funkcja zdefiniowana przez użytkownika umożliwia sprzedawcy (w przyszłości) generowanie raportów na poziomie zdarzenia z informacjami o wygrywającej reklamie.

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

Ad Retrieval API

W wersji MVP usługa pobierania reklam będzie usługą zarządzaną i hostowaną przez kupującego , a usługa określania stawek będzie pobierać z niej kandydatów do wyświetlenia reklamy. Od kwietnia 2024 r. serwer pobierania reklam musi działać w zaufanym środowisku wykonawczym (TEE) i udostępniać interfejs GRPC/proto. Firmy z branży technologii reklamowych muszą skonfigurować ten serwer i podać jego adres URL w ramach wdrażania stosu B&A. Implementacja tej usługi działająca w TEE jest dostępna w repozytorium GitHub Piaskownicy prywatności. W pozostałej części dokumentacji zakładamy, że jest to kod używany we wdrożeniu.

Od kwietnia 2024 r. wersje B&A obsługują pobieranie reklam na ścieżce kontekstowej. W takim przypadku serwer licytujący otrzyma listę identyfikatorów reklam przesłanych przez serwer RTB podczas kontekstowej części aukcji. Identyfikatory zostaną wysłane na serwer TEE KV, aby pobrać wszystkie informacje związane z reklamą, które będą używane w fazie określania stawek (np. adres URL renderowania reklamy, metadane i osadzenia reklam, które będą używane w selekcji top-k). Druga ścieżka nie wymaga wdrożenia żadnej konkretnej logiki, dlatego opisujemy tutaj tylko sposób konfigurowania przypadku użycia związanego z pobieraniem reklam na podstawie TEE.

funkcja UDF getCandidateAds
function getCandidateAds(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals, contextualAdIds,) {
    return adsMetadataString;
}

Gdzie:

  • requestMetadata: JSON. Metadane serwera dotyczące poszczególnych żądań do funkcji UDF. Na razie pusto.
  • preparedDataForAdRetrieval: zawartość tego pola zależy od strategii pobierania reklam. W przypadku pobierania reklam kontekstowych ten parametr będzie zawierać surowe sygnały pochodzące z urządzenia i przekazywane z usługi ustalania stawek. W przypadku pobierania reklam w środowisku TEE za pomocą serwera pobierania reklam ten parametr będzie zawierać wynik działania prepareDataForAdRetrievalfunkcji zdefiniowanej przez użytkownika. Uwaga: na tym etapie sygnały z chronionych aplikacji zostaną zdekodowane i odszyfrowane.
  • deviceMetadata: obiekt JSON zawierający metadane urządzenia przekazane przez usługę reklamową sprzedawcy. Więcej informacji znajdziesz w dokumentacji 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 serwera określania stawek kontekstowych obsługiwanego przez tę samą platformę DSP. Funkcja UDF powinna być w stanie zdekodować ciąg znaków i go użyć. Sygnały kontekstowe mogą zawierać dowolne informacje, np. informacje o wersji modelu ML w przypadku chronionego osadzania przekazywanego za pomocą chronionych sygnałów aplikacji.
  • contextualAdIds: obiekt JSON zawierający opcjonalną listę identyfikatorów reklam.

W przypadku powodzenia funkcja zdefiniowana przez użytkownika powinna zwrócić ciąg. Ciąg znaków jest zwracany do serwera licytującego, który następnie przekazuje go do funkcji UDF generateBid. Chociaż ciąg znaków może być zwykłym ciągiem znaków, najprawdopodobniej powinien być obiektem serializowanym, którego schemat jest definiowany przez każdą firmę technologiczną zajmującą się reklamami. Nie ma ograniczeń dotyczących schematu, o ile logika technologii reklamowej generateBid może rozpoznać i użyć ciągu znaków.

Konfigurowanie systemu pod kątem programowania

Android

Aby skonfigurować środowisko programistyczne na Androida, musisz wykonać te czynności:

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

Następnie wybierz opcję, która wyświetla się po wyrażeniu zgody na reklamy sugerowane przez aplikację.

  1. Aby włączyć odpowiednie interfejsy API, uruchom to polecenie. Od czasu do czasu może być konieczne ponowne uruchomienie tego procesu, ponieważ domyślna konfiguracja wyłączonego ustawienia 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. Aby zapobiec buforowaniu nieprawidłowych kluczy, przed uruchomieniem aukcji należy wykonać ten krok.

Usługi określania stawek i aukcji

Aby skonfigurować serwery B&A, zapoznaj się z dokumentacją dotyczącą samodzielnej konfiguracji.

W tym dokumencie skupimy się na tym, jak skonfigurować serwery kupującego, ponieważ sprzedawcy nie muszą wprowadzać żadnych zmian.

Wymagania wstępne

Przed wdrożeniem stosu usług B&A technologia reklamowa kupującego musi:

  • Sprawdź, czy wdrożyli własną usługę pobierania reklam w środowisku TEE (patrz odpowiednia sekcja).
  • Sprawdź, czy platforma reklamowa ma wszystkie niezbędne funkcje zdefiniowane przez użytkownika (prepareDataForAdRetrieval, generateBid, reportWin, getCandidateAds) i czy są one hostowane.

Znajomość działania aukcji chronionej z interfejsem Protected Audience API w połączeniu z funkcją B&A będzie pomocna, ale nie jest wymagana.

Konfiguracja Terraform

Aby korzystać z sygnałów z chronionych aplikacji, dostawcy technologii reklamowych muszą:

  • Włącz w usługach B&A obsługę sygnałów z chronionych aplikacji.
  • Podaj punkty końcowe URL, z których można pobrać nowe funkcje zdefiniowane przez użytkownika dla prepareDataForAdRetrieval, generateBidreportWin.

W tym przewodniku zakładamy też, że platformy reklamowe, które chcą używać interfejsu B&A do remarketingu, będą nadal ustawiać wszystkie dotychczasowe flagi konfiguracji aukcji remarketingowej.

Konfiguracja technologii reklamowych kupującego

Na przykładzie tego pliku demonstracyjnego kupujący muszą ustawić te flagi:

  • Włącz sygnały z aplikacji chronionych: włączone, aby zbierać dane sygnałów z aplikacji chronionych.
  • Adresy URL Protected App Signals: ustaw adresy URL serwerów Protected App Signals.

Technologie reklamowe muszą zastąpić prawidłowe adresy URL w polach zastępczych w przypadku tych pól:

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 reklamowych sprzedawcy

Na przykładzie tego pliku demonstracyjnego sprzedawcy muszą ustawić te flagi: (Uwaga: wyróżniona jest tylko konfiguracja związana z sygnałami z aplikacji chronionych). Technologie reklamowe muszą sprawdzić, czy w miejscach zastępczych umieszczają prawidłowe adresy URL:

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"

Usługi pobierania kluczy weryfikacyjnych i reklam

W zależności od strategii wybranych do obsługi pobierania reklam system będzie wymagać wdrożenia 1 lub 2 instancji usługi KV. Instancję KV używaną do pobierania reklam na podstawie TEE będziemy nazywać Ad Retrieval Server, a instancję obsługującą pobieranie na podstawie ścieżki kontekstowej – KV Lookup Server.

W obu przypadkach wdrożenie serwerów jest zgodne z dokumentacją dostępną w repozytorium GitHub serwera KV. Różnica między tymi przypadkami polega na tym, że wyszukiwanie działa od razu bez dodatkowej konfiguracji, a pobieranie wymaga wdrożenia getCandidateAds funkcji zdefiniowanej przez użytkownika w celu zaimplementowania logiki pobierania. Więcej informacji znajdziesz w przewodniku po wdrażaniu serwera KV. Pamiętaj, że zespół B&A oczekuje, że obie usługi zostaną wdrożone w tej samej siatce usług co usługa ustalania stawek.

Przykładowa konfiguracja

Rozważmy ten scenariusz: platforma reklamowa korzysta z interfejsu Protected App Signals API, aby przechowywać odpowiednie sygnały na podstawie korzystania przez użytkownika z aplikacji. W naszym przykładzie przechowywane są sygnały reprezentujące zakupy w aplikacji z kilku aplikacji. Podczas aukcji zbierane są zaszyfrowane sygnały, które są przekazywane do aukcji chronionej działającej w usługach reklamowych i analitycznych. Funkcje zdefiniowane przez użytkownika kupującego działające w ramach określania stawek i automatyzacji wykorzystują sygnały do pobierania kandydatów do wyświetlenia reklam i obliczania stawki.

Przykłady sygnałów [kupującego]

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

[Buyer] encodeSignals example

Koduje każdy sygnał w 2 bajtach, przy czym pierwszy bajt to pierwszy bajt klucza 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};
}

Przykład funkcji [Buyer] 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, an 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 ad tech 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] Funkcja UDF do pobierania przykładowych reklam

W naszym przykładzie serwer pobierania reklam wysyła metadane (czyli w tym przypadku identyfikator każdej reklamy, ale może też zawierać inne dane, które mogą być przydatne przy generowaniu stawek w późniejszym czasie) dla każdego z k najlepszych kandydatów na reklamę.

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

[Buyers] generateBid example

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

Przykładowy raport [Kupujący]

reportWin Funkcja zdefiniowana przez użytkownika informuje kupującego, ż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 klucz-wartość sygnałów oceny, aby dostępne było mapowanie adresów URL renderowania reklam na odpowiednie sygnały oceny. Przykład: jeśli kupujący zwróci https:/buyer-domain.com/get-fitness-apphttps:/buyer-domain.com/get-fastfood-app, sprzedawca może uzyskać następującą odpowiedź sygnałów oceny, gdy SFE wyśle zapytanie za pomocą GEThttps://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"
      ]
   }
}

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

Przykład wyniku raportu [Sprzedawca]

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

Aby pokazać, jak za pomocą interfejsu API można utworzyć aplikację korzystającą z tego procesu, stworzyliśmy przykładową aplikację Protected App Signals, którą znajdziesz w tym repozytorium.