Руководство разработчика сигналов защищенных приложений

Чтобы помочь разработчикам начать экспериментировать с API защищенных сигналов приложений, в этом документе описываются все API в рамках API-интерфейса, подробно объясняется, как настроить тестовую среду, и приводятся примеры конфигурации и скриптов.

История версий

Январь 2024 г.

Первая версия руководства для разработчиков, поддерживающая выпуск PAS MVP.

Март 2024 г.

Изменения в API для поддержки выпуска Android API M-2024-05 и выпуска серверных компонентов в апреле 2024 года. Наиболее заметные изменения:

  • Добавлена ​​информация о разрешениях, необходимых для работы с API на устройстве.
  • Добавлены подробности об управлении квотами сигналов на устройстве.
  • Обновлена ​​сигнатура generateBid с изменениями, связанными с контекстным получением рекламы и поддержкой исходящего трафика.
  • Обновлена ​​документация reportWin , включая поддержку исходящего трафика.
  • Обновить документацию по API получения рекламы, удалив поддержку получения рекламы с использованием BYOS и задокументировав пользовательскую функцию (UDF) для получения рекламы.

Обзор API

Интерфейс API защищенных сигналов включает в себя различные подмножества API в разных системах:

  • API Android:
    • API для обработки сигналов, состоящий из:
    • API сигналов обновления
    • API кодирования сигналов
    • API поддержки защищенного аукциона: предназначен для использования SDK для запуска защищенного аукциона на серверах торгов и аукционов (B&A) с помощью сигналов защищенного приложения.
  • API на стороне сервера:
    • API для защищенного аукциона: набор JavaScript-скриптов, работающих на серверах торгов и аукционов. Этот API позволяет продавцам и покупателям писать логику для реализации защищенного аукциона.
    • API для получения объявлений: отвечает за предоставление списка подходящих объявлений с учетом контекстной информации и данных о пользователе, доступных серверу торгов покупателя.

Клиент для Android

На стороне клиента интерфейс Protected App Signals состоит из трех различных API:

  • Update Signals: API системы Android, позволяющий управлять сигналами на устройстве.
  • Кодирование сигналов: JavaScript API для подготовки сигналов, отправляемых на сервер во время аукциона.
  • Поддержка защищенных аукционов: API для поддержки выполнения защищенного аукциона на серверах торгов и аукционов. Этот API не является специфичным для сигналов защищенных приложений и также используется для поддержки аукционов для API защищенной аудитории.

API сигналов обновления

API Update Signals предоставляет рекламным компаниям возможность регистрировать сигналы, связанные с пользователями и приложениями, от имени покупателя. API работает по модели делегирования. Вызывающая сторона предоставляет URI, с которого фреймворк получает соответствующие сигналы и логику кодирования этих сигналов для использования в аукционе.

Для работы API требуется разрешение android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS .

API-функция updateSignals() получает JSON-объект из URI, описывающий, какие сигналы следует добавить или удалить, а также как подготовить эти сигналы для аукциона.

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

Платформа отправляет HTTPS-запрос на URI, указанный в запросе, для получения обновлений сигналов. Вместе с обновлениями сигналов ответ может включать конечную точку, содержащую логику кодирования для преобразования необработанных сигналов в закодированную полезную нагрузку. Ожидается, что обновления сигналов будут в формате JSON и могут содержать следующие ключи:

Ключи верхнего уровня объекта JSON должны соответствовать одной из пяти команд:

ключ

Описание

put

Добавляет новый сигнал, перезаписывая все существующие сигналы с тем же ключом. Значение

Это JSON-объект, где ключами являются строки в формате Base64, соответствующие нужному ключу, а значениями — строки в формате Base64, соответствующие нужному значению.

append

Добавляет новый сигнал/сигналы к временному ряду сигналов, удаляя самый старый.

Сигналы освобождают место для новых элементов, если размер серии превышает заданный максимум. Значением этого сигнала является JSON-объект, где ключами являются строки в формате Base64, соответствующие ключу, к которому нужно добавить элемент, а значениями — объекты с двумя полями: "values" и "maxSignals".

"values": Список строк в формате Base64, соответствующих значениям сигнала, которые необходимо добавить к временному ряду.

"maxSignals": Максимальное количество значений, допустимых в этом временном ряду. Если

Если текущее количество сигналов, связанных с ключом, превышает maxSignals, самые старые сигналы будут удалены. Обратите внимание, что к ключу, добавленному с помощью put, можно добавлять значения. Обратите внимание, что добавление большего количества значений, чем максимально допустимое, приведет к ошибке.

put_if_not_present

Добавляет новый сигнал только в том случае, если нет существующих сигналов с тем же ключом. Значением является JSON-объект, где ключи — это строки в формате Base64, соответствующие ключу, который нужно добавить, а значения — это строки в формате Base64, соответствующие значению, которое нужно добавить.

remove

Удаляет сигнал для определенной клавиши. Значением этой строки является список строк в формате Base64, соответствующих клавишам сигналов, которые следует удалить.

update_encoder

Предоставляет действие для обновления конечной точки и URI, который можно использовать.

Для получения логики кодирования. Подключ для указания действия обновления — это «action», а

Поддерживается только значение "REGISTER", которое зарегистрирует конечную точку кодировщика, если она указана впервые, или перезапишет существующую новой конечной точкой. Указание конечной точки является обязательным для действия "REGISTER". Подключ для указания конечной точки кодировщика — "endpoint", а значением является URI.

строка для конечной точки.

Пример JSON-запроса будет выглядеть следующим образом:

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

Для сигналов будет установлена ​​квота на устройстве в размере 10-15 Кбит/с. После превышения квоты PPAPI будет вытеснять сигналы, используя стратегию FIFO. Процесс вытеснения будет допускать небольшое превышение квоты в течение коротких промежутков времени, чтобы уменьшить частоту вытеснений.

API кодирования сигналов

Покупатели обязаны предоставить функцию JavaScript, которая будет использоваться для кодирования сигналов, хранящихся на устройстве, и отправляться на сервер во время защищенного аукциона. Покупатели могут предоставить этот скрипт, добавив URL-адрес, откуда его можно получить, используя ключ "update_encoder" в любом из ответов на запрос API UpdateSignal. Скрипт будет иметь следующую сигнатуру:

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

Параметр signals представляет собой карту, в которой ключи в виде массивов UInt8 размером 4 соответствуют спискам объектов Protected App Signals. Каждый объект Protected App Signals имеет три поля:

  • signal_value : массив UInt8Array, представляющий значение сигнала.
  • creation_time : Число, представляющее время создания сигналов в секундах эпохи.
  • package_name : Строка, представляющая имя пакета, создавшего сигнал.

Параметр maxSize — это число, описывающее максимально допустимый размер массива для выходных данных.

Функция должна выводить объект с двумя полями:

  • status : Должен быть равен 0, если скрипт выполнился успешно.
  • results : должен представлять собой массив UInt8Array длиной меньше или равной maxSize. Этот массив будет отправлен на сервер во время аукционов и подготовлен скриптом prepareDataForAdRetrieval .

Кодирование предоставляет специалистам по рекламным технологиям начальный этап проектирования признаков, где они могут выполнять преобразования, такие как сжатие необработанных сигналов в объединенные версии на основе собственной пользовательской логики. Следует отметить, что во время защищенного аукциона, работающего в доверенных средах выполнения (TEE), пользовательская логика рекламных технологий будет иметь доступ для чтения к полезным нагрузкам сигналов, сгенерированным кодированием. Пользовательская логика, известная как определяемая пользователем функция (UDF) , работающая в среде выполнения B&A покупателя (TEE), будет иметь доступ для чтения к закодированным сигналам и другим контекстным сигналам, предоставляемым приложением издателя для выбора рекламы (получения рекламы и назначения ставок).

кодирование сигналов

Каждый час покупатели, предоставившие логику кодирования вместе со своими зарегистрированными сигналами, будут получать кодированные данные для аукциона. Массив байтов для данных аукциона сохраняется на устройстве, шифруется и будет собираться продавцами в рамках данных выбора рекламы для включения в защищенный аукцион. Для тестирования вы можете запустить это кодирование вне его почасового цикла, выполнив следующую команду:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
Версионирование логики кодировщика

Когда поступает запрос на загрузку пользовательской логики кодирования рекламной технологии, конечная точка рекламной технологии может ответить номером версии в заголовках ответа. Эта версия сохраняется вместе с логикой кодирования на устройстве. При кодировании необработанных сигналов закодированная полезная нагрузка сохраняется вместе с версией, использованной для кодирования. Эта версия также отправляется на сервер B&A во время защищенного аукциона, чтобы рекламные технологии могли согласовывать свою логику назначения ставок и кодирования в соответствии с этой версией.

Response header for providing encoder version : X_ENCODER_VERSION

API поддержки защищенных аукционов

На уровне устройств проведение аукциона для защищенных сигналов приложений аналогично проведению аукциона для защищенных аудиторий .

Услуги по проведению торгов и аукционов

К серверным API относятся:

  • API защищенного аукциона: набор функций JavaScript или пользовательских функций (UDF), которые покупатели и продавцы могут развертывать на принадлежащих им компонентах B&A для определения ставок и логики аукциона.
  • API для получения рекламы: Покупатели могут реализовать этот API, создав REST-конечную точку, которая будет отвечать за предоставление набора потенциальных рекламных объявлений для аукциона защищенных сигналов приложений.

API защищенного аукциона

API защищенного аукциона состоит из JavaScript-интерфейсов или пользовательских функций, которые покупатели и продавцы могут использовать для реализации своей логики аукциона и торгов.

Универсальные поля для рекламных технологий покупателей
пользовательская функция prepareDataForAdRetrieval

Прежде чем сигналы защищенных приложений (Protected App Signals) можно будет использовать для получения потенциальных рекламных объявлений из сервиса TEE Ad Retrieval, покупатели должны расшифровать и подготовить сигналы защищенных приложений и другие предоставленные продавцом данные. Выходные данные пользовательской функции prepareDataForAdRetrieval передаются в сервис получения рекламных объявлений для получения k лучших потенциальных рекламных объявлений для участия в торгах .

// 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 {};
}
generateBid UDF

После получения k лучших потенциальных объявлений, эти объявления передаются в пользовательскую логику назначения ставок покупателя, функцию generateBid :

// Inputs
// ------
// ads: Data string returned by the ads retrieval service. This can include Protected App Signals
//   ads and related ads metadata.
// sellerAuctionSignals: Information about the auction (ad format, size),
//                       derived contextually
// buyerSignals: Any additional contextual information provided by the buyer
// preprocessedDataForRetrieval: This is the output of this UDF.
function generateBid(ads, sellerAuctionSignals, buyerSignals,
                    preprocessedDataForRetrieval,
                    rawSignals, rawSignalsVersion) {
    return { "ad": <ad Value Object>,
             "bid": <float>,
             "render": <render URL string>,
             'adCost': <optional float ad cost>,
             "egressPayload": <limitedEgressPayload>,
             "temporaryUnlimitedEgressPayload": <temporaryUnlimitedEgressPayload>
    };
}

Результатом работы этой функции является отдельная ставка для рекламного кандидата, представленная в формате JSON, эквивалентном ProtectedAppSignalsAdWithBidMetadata . Функция также может возвращать два массива, которые затем будут переданы в reportWin для обучения модели (более подробную информацию об исходящем трафике и обучении модели см. в разделе отчетности в пояснении PAS ).

reportWin UDF

После завершения аукциона сервис аукциона сгенерирует URL-адреса для отчетов покупателям и зарегистрирует маяки с помощью функции reportWin (это та же функция reportWin , которая используется для защищенных аудиторий) . Устройство отправит запрос на этот маяк после того, как клиент отобразит объявление. Сигнатура этого метода практически идентична версии для защищенных аудиторий, за исключением двух дополнительных параметров egressPayload и temporaryUnlimitedEgressPayload , которые используются для включения обучения модели и заполняются результатами функции generateBid .

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
Технологические пользовательские поля для рекламы продавцов
scoreAd UDF

Этот пользовательский профиль используется продавцами для выбора того, какие из объявлений, полученных от покупателей, выиграют аукцион.

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

Эта пользовательская функция позволяет продавцу (в конечном итоге) создавать отчеты на уровне событий с информацией о выигрышном объявлении.

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

API для получения рекламы

В MVP-версии сервис получения рекламы будет управляться и размещаться покупателем, а сервис торгов будет получать рекламные кандидаты из этого сервиса. Начиная с апреля 2024 года, сервер получения рекламы должен работать в доверенной среде выполнения (TEE) и будет предоставлять интерфейс GRPC/proto. Компании, работающие в сфере рекламных технологий, должны настроить этот сервер и предоставить его URL-адрес в рамках развертывания стека B&A. Реализация этого сервиса, работающего в TEE, доступна на GitHub Privacy Sandbox , и в остальной документации мы предполагаем, что именно этот код использовался при развертывании.

Начиная с апреля 2024 года, версии B&A поддерживают контекстный путь получения рекламы. В этом случае сервер торгов получит список идентификаторов объявлений, отправленных сервером RTB во время контекстной части аукциона. Идентификаторы будут отправлены на сервер TEE KV для получения всей информации, связанной с рекламой, которая будет использоваться на этапе торгов (например, URL-адрес рендеринга объявления, метаданные и встраивания объявлений для использования в выборе топ-k). Этот второй путь не требует развертывания какой-либо специальной логики, поэтому здесь мы опишем только то, как настроить сценарий использования получения рекламы на основе TEE.

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

Где:

  • requestMetadata : JSON. Метаданные сервера для каждого запроса, передаваемые в пользовательскую функцию. Пока пусто.
  • preparedDataForAdRetrieval : содержимое этого поля зависит от стратегии получения рекламы. В случае контекстного получения рекламы этот параметр будет содержать необработанные сигналы, поступающие с устройства и передаваемые из службы торгов. В случае получения рекламы с использованием TEE (Tax-Executive Entity) с помощью сервера получения рекламы этот параметр будет содержать результат пользовательской функции prepareDataForAdRetrieval . Примечание: на этом этапе сигналы защищенного приложения будут декодированы и не зашифрованы.
  • deviceMetadata : JSON-объект, содержащий метаданные устройства, передаваемые рекламным сервисом продавца. Дополнительные сведения см. в документации B&A.
    • X-Accept-Language : язык, используемый на устройстве.
    • X-User-Agent : Агент пользователя, используемый на устройстве.
    • X-BnA-Client-IP : IP-адрес устройства.
  • contextualSignals : произвольная строка, полученная с сервера контекстных торгов, управляемого тем же DSP. Предполагается, что пользовательская функция сможет декодировать эту строку и использовать её. Contextual Signals может содержать любую информацию, например, информацию о версии модели машинного обучения для защищённого встраивания, передаваемого с помощью Protected App Signals.
  • contextualAdIds : JSON-объект, содержащий необязательный список идентификаторов объявлений.

Функция UDF должна возвращать строку в случае успеха. Эта строка возвращается на сервер торгов, который затем передает ее функции UDF generateBid . Хотя строка может быть просто обычной строкой, скорее всего, это должен быть сериализованный объект, схема которого определяется каждой рекламной технологией самостоятельно. Ограничений по схеме нет, если логика generateBid рекламной технологии может распознать и использовать эту строку.

Настройте свою систему для разработки.

Android

Для настройки среды разработки Android необходимо выполнить следующие действия:

  1. Создайте эмулятор (предпочтительно) или физическое устройство, на котором запущен образ Developer Preview 10.
  2. Выполните следующие действия:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

Затем выберите показанный вариант, чтобы дать согласие на показ рекламы, предлагаемой приложением.

  1. Выполните следующую команду, чтобы включить соответствующие API. Возможно, вам потребуется периодически перезапускать эту команду, поскольку конфигурация по умолчанию (отключено) будет периодически синхронизироваться.
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. Перезагрузите устройство.
  2. Переопределите аукционные ключи устройства, указав в них адрес вашего аукционного сервера. Важно выполнить этот шаг перед попыткой проведения аукциона, чтобы предотвратить кэширование некорректных ключей.

Услуги по проведению торгов и аукционов

Для настройки серверов B&A обратитесь к документации по самостоятельной настройке .

В этом документе основное внимание будет уделено настройке серверов, предназначенных для покупателей, поскольку продавцам никаких изменений не требуется.

Предварительные требования

Перед развертыванием комплекса сервисов B&A, технологическому обеспечению для размещения рекламы покупателям необходимо:

  • Убедитесь, что они развернули собственную службу получения рекламы TEE (см. соответствующий раздел ).
  • Убедитесь, что в рекламной технологической системе определены и размещены все необходимые пользовательские функции ( prepareDataForAdRetrieval , generateBid , reportWin , getCandidateAds ).

Понимание того, как работает защищенный аукцион с защищенной аудиторией в B&A, также будет полезным, но не обязательным.

Конфигурация Terraform

Для использования сигналов защищенных приложений рекламным компаниям необходимо:

  • Включите поддержку сигналов защищенных приложений в B&A.
  • Укажите URL-адреса конечных точек, с которых можно получить новые пользовательские функции для prepareDataForAdRetrieval, generateBid и reportWin .

Кроме того, в данном руководстве предполагается, что специалисты по рекламным технологиям, желающие использовать B&A для ремаркетинга, будут продолжать устанавливать все существующие флаги конфигурации для аукциона ремаркетинга в обычном режиме.

Настройка рекламных технологий для покупателей

Используя этот демонстрационный файл в качестве примера, покупателям необходимо установить следующие флаги:

  • Включить сигналы защищенных приложений : Эта опция позволяет собирать данные сигналов защищенных приложений.
  • URL-адреса серверов Protected App Signals : Установите значения URL-адресов серверов Protected App Signals.

Специалистам по рекламным технологиям необходимо заменить следующие поля в заполнителях на правильные URL-адреса:

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"

Настройка рекламных технологий продавца

Используя этот демонстрационный файл в качестве примера, продавцы должны установить следующие флаги. (Примечание: здесь выделена только конфигурация, связанная с сигналами защищенных приложений). Специалистам по рекламе необходимо убедиться, что они подставляют правильные 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"

Услуги поиска KV и рекламы

В зависимости от выбранных стратегий для поддержки поиска рекламы, системе потребуется развернуть один или два экземпляра сервиса ключ-значение (KV). Экземпляр KV, используемый для поиска рекламы на основе TEE, мы будем называть Ad Retrieval Server , а экземпляр, поддерживающий поиск на основе контекстного пути, — KV Lookup Server .

В обоих случаях развертывание серверов осуществляется в соответствии с документацией, доступной на GitHub сервера KV . Разница между ними заключается в том, что случай поиска работает «из коробки» без дополнительной настройки, в то время как для получения данных требуется развертывание пользовательской функции getCandidateAds для реализации логики получения данных. Для получения более подробной информации ознакомьтесь с руководством по подключению сервера KV . Обратите внимание, что B&A ожидает, что оба сервиса будут развернуты в той же сервисной сети, что и сервис торгов.

Пример настройки

Рассмотрим следующий сценарий: используя API защищенных сигналов приложений, рекламная технологическая компания хранит релевантные сигналы на основе использования приложения пользователем. В нашем примере хранятся сигналы, представляющие собой внутриигровые покупки в нескольких приложениях. Во время аукциона зашифрованные сигналы собираются и передаются в защищенный аукцион, работающий в B&A. Пользовательские функции покупателя, работающие в B&A, используют сигналы для получения кандидатов на показ рекламы и вычисления ставки.

Примеры сигналов [покупателя]

Добавляет сигнал с ключом 0 и значением 1.

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

Добавляет сигнал с ключом 1 и значением 2.

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

[Покупатель] Пример encodeSignals

Каждый сигнал кодируется в два байта, при этом первый байт является первым байтом ключа сигнала, а второй байт — первым байтом значения сигнала.

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

[Покупатель] Пример подготовки данных для получения рекламы

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

[Покупатели] Пример пользовательского поля для получения рекламы

В нашем примере сервер получения объявлений отправляет метаданные (т.е. идентификатор для каждого объявления в этом примере, но может содержать и другие данные, которые могут быть полезны для генерации ставок в дальнейшем) для каждого из k лучших кандидатов на размещение объявлений.

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

[Покупатели] Пример генерации ставки

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

[Покупатели] reportWin пример

reportWin UDF сообщает покупателю о том, что он выиграл аукцион.

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

[Продавец] Настройка KV-сервера

Продавцы должны настроить сервер сигналов оценки (ключ-значение), чтобы обеспечить сопоставление URL-адресов рендеринга объявлений с соответствующими сигналами оценки. Например: если покупатель вернет https:/buyer-domain.com/get-fitness-app и https:/buyer-domain.com/get-fastfood-app , продавец может получить следующий пример ответа сигналов оценки при запросе к SFE с помощью GET по адресу 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"
      ]
   }
}

[Продавец] пример оценки рекламы

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

[Продавец] reportResult пример

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

Пример приложения

В качестве примера того, как можно использовать API для создания приложения, работающего по этому алгоритму, мы создали демонстрационное приложение Protected App Signals, которое можно найти в этом репозитории примеров .