デベロッパーが Protected App Signals API のテストを開始できるように、このドキュメントでは、この API サーフェス内のすべての API について説明し、テスト環境の設定方法の詳細、構成とスクリプトの例を紹介します。
バージョン履歴
2024 年 1 月
PAS MVP リリースをサポートするデベロッパー ガイドの最初のリリース
2024 年 3 月
Android API の M-2024-05 リリースをサポートする API の変更と サーバーサイド コンポーネントのリリース(2024 年 4 月)。最も注目すべき変更点:
- オンデバイス API に必要な権限の詳細を追加しました
- オンデバイス シグナルの割り当て管理に関する詳細を追加しました
generateBid
署名を更新し、コンテキストに関連する変更を追加しました 広告取得と下り(外向き)のサポート- 下り(外向き)のサポートを含む
reportWin
のドキュメントを更新しました - Ad Retrieval API のドキュメントを更新し、BYOS による広告取得のサポートを削除 広告取得 UDF の文書化と
API の概要
Protected Signals API サーフェスには、システムごとに異なる API のサブセットが含まれています。
- Android API:
- 次の要素で構成される Signal Curation API
- Update Signals API
- Signals Encoding API
- Protected Auction Support API: Protected App Signals を使用して、入札とオークション(B&A)サーバーで Protected Auction を実行するために SDK で使用されます。
- サーバーサイド API:
- Protected Auction API: 入札とオークション サーバーで実行される一連の JS スクリプト。この API を使用すると、販売者と購入者は Protected Auction を実装するロジックを記述できます。
- Ad Retrieval API: 購入者の入札サーバーで入手可能なコンテキスト情報とユーザー情報に基づき、広告候補のリストを提供します。
Android クライアント
クライアント サイドでは、Protected App Signals サーフェスは 3 つの異なる API で構成されています。
- Update Signals: デバイス上でシグナルのキュレーションを可能にする Android System API。
- Signals Encoding: オークション中にサーバーに送信するシグナルを準備する JavaScript API。
- Protected Auction Support: 入札とオークション サーバーでの Protected Auction の実行をサポートする API。この API は、Protected App Signals に固有のものではなく、Protected Audience API のオークションをサポートするためにも使用されます。
Update Signals API
Update Signals API は、購入者に代わってユーザーとアプリに関連するシグナルを登録する機能を広告テクノロジーに提供します。API は委任モデルで動作します。呼び出し元は、フレームワークによるシグナルの取得元となる URI と、オークションで使用するシグナルをエンコードするロジックを提供します。
API には android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS
が必要です。
付与します。
updateSignals()
API は 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);
プラットフォームは、リクエストで指定された URI に HTTP リクエストを行い、シグナルの更新を取得します。レスポンスには、シグナルの更新とともに、未加工のシグナルをエンコードされたペイロードに変換するためのエンコード ロジックをホストするエンドポイントを含めることができます。シグナルの更新は JSON 形式であることが期待され、次のキーを含めることができます。
JSON オブジェクトの最上位キーは、次の 5 つのコマンドのいずれかに対応する必要があります。
キー |
説明 |
|
新しいシグナルを追加し、同じキーで既存のシグナルを上書きします。この値 は JSON オブジェクトで、キーは追加するキーに対応する Base 64 文字列であり、値は追加する値に対応する Base 64 文字列です。 |
|
時系列のシグナルに新しいシグナルを付加します。時系列のサイズが所定の最大値を超えた場合には、最も古い シグナルを削除して、新しいシグナルのスペースを確保します。この値は JSON オブジェクトで、キーは追加先のキーに対応する Base 64 文字列で、値は「values」と「maxSignals」の 2 つのフィールドを持つオブジェクトです。 「values」: 時系列に追加するシグナル値に対応する Base 64 文字列のリスト。 「maxSignals」: この時系列で許可される値の最大数。なお、 キーに関連付けられている現在のシグナルの数が maxSignals を超えると、最も古いシグナルが削除されます。put によって追加されたキーに追記できます。最大数を超える値を追加するとエラーになります。 |
|
同じキーを持つ既存のシグナルがない場合にのみ、新しいシグナルを追加します。この値は、追加するキーに対応する Base 64 文字列である JSON オブジェクトであり、値は追加する値に対応する Base 64 文字列です。 |
|
キーのシグナルを削除します。この値は、削除する必要があるシグナルのキーに対応する Base 64 文字列のリストです。 |
|
エンドポイントを更新するアクションと、エンコード ロジックを取得できる URL を 提供します。更新アクションを提供するためのサブキーは「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 KB のデバイス上の割り当てがあります。割り当てが 超過すると、PPAPI が FIFO 戦略を使用してシグナルを強制排除します。強制排除プロセス 一定の間隔で割り当てをわずかに超えることが エビクションの頻度を減らすために必要です。
Signals Encoding API
購入者は、デバイスに保存されたシグナルをエンコードして、Protected Auction 中にサーバーに送信する JavaScript 関数を提供する必要があります。購入者は、UpdateSignal API リクエストに対するレスポンスに「update_encoder」キーを使用してフェッチできる URL を追加することで、このスクリプトを提供できます。スクリプトのシグネチャは次のとおりです。
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
パラメータは、サイズ 4 の UInt8Arrays 形式のキーから Protected App Signals オブジェクトのリストへのマップです。各 Protected App Signals オブジェクトには、次の 3 つのフィールドがあります。
signal_value
: シグナルの値を表す UInt8Array。creation_time
: シグナルの作成時刻を表す数値(エポック秒単位)。package_name
: シグナルを作成したパッケージの名前を表す文字列。
maxSize
パラメータは、出力の最大許容配列サイズを示す数値です。
この関数は、次の 2 つのフィールドを持つオブジェクトを出力します。
status
: スクリプトが正常に実行された場合は 0 にする必要があります。results
: maxSize 以下の長さの UInt8Array にする必要があります。この配列はオークション中にサーバーに送信され、prepareDataForAdRetrieval
スクリプトによって準備されます。
エンコードにより、広告テクノロジーは特徴量エンジニアリングの最初のステージが得られます。ここでは、独自のカスタム ロジックに基づいて、未加工のシグナルを連結バージョンに圧縮するなどの変換を実行できます。高信頼実行環境(TEE)で Protected Auction が実行される場合、広告テクノロジーのカスタム ロジックに、エンコードによって生成されたシグナル ペイロードへの読み取りアクセス権が付与されます。購入者の B&A TEE で実行されるカスタム ロジックはユーザー定義関数(UDF)と呼ばれ、エンコードされたシグナルやパブリッシャー アプリが提供するその他のコンテキスト シグナルにアクセスし、広告選択(広告の取得と入札)を行います。
シグナル エンコード
登録されたシグナルを使用してエンコード ロジックを提供した購入者は、1 時間ごとにシグナルがオークション ペイロードにエンコードされます。オークション ペイロードのバイト配列はデバイス上で保持され、暗号化され、広告選択データの一部として販売者によって収集され、Protected Auction の一部として組み込まれます。テストのために、次のコマンドを実行して、1 時間ごとの周期外でこのエンコードをトリガーできます。
adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
エンコーダ ロジックのバージョニング
広告テクノロジーのカスタム エンコーダ ロジックをダウンロードするリクエストが行われると、広告テクノロジー エンドポイントはレスポンス ヘッダーのバージョン番号で応答できます。このバージョンは、デバイス上のエンコーダ ロジックとともに保持されます。未加工のシグナルがエンコードされると、エンコードされたペイロードはエンコードに使用されたバージョンとともに保持されます。このバージョンは、Protected Auction の際に B&A サーバーにも送信されるため、広告テクノロジーはバージョンに基づいて入札とエンコードのロジックを調整できます。
Response header for providing encoder version : X_ENCODER_VERSION
Protected Auction Support API
デバイス側では、Protected App Signals のオークションの実行は、Protected Audience のオークションの実行と同じです。
入札およびオークション サービス
サーバーサイド API には次のものがあります。
- Protected Auction API: 購入者と販売者が所有する B&A コンポーネントにデプロイできる一連の JS 関数または UDF で、入札とオークション ロジックを決定できます。
- Ad Retrieval API: 購入者は、Protected App Signal オークションの広告候補群を提供する REST エンドポイントを実装することで、この API を実装できます。
Protected Auction API
Protected Auction API は、購入者と販売者がオークションと入札のロジックを実装するために使用できる JS API または UDF で構成されています。
購入者の広告テクノロジー UDF
prepareDataForAdRetrieval UDF
Protected App Signals を使用して TEE から広告候補を取得する前に
広告取得サービス。購入者は Protected App Signals をデコードして準備する必要がある
販売者提供データなどを収集します購入者の prepareDataForAdRetrieval
UDF 出力は広告取得サービスに渡され、入札対象の上位 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 adtech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
return {};
}
generateBid UDF
上位 k 個の広告候補が返された後、広告候補は購入者のカスタム入札ロジック 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>
};
}
この関数の出力は、広告候補に対する 1 回の入札であり、
同等の JSON として、
ProtectedAppSignalsAdWithBidMetadata
。
この関数は 2 つの配列を返し、reportWin
に渡すこともできます。
モデルのトレーニングを有効にします(下り(外向き)と
PAS 説明書のレポート セクションを参照)
reportWin UDF
オークションが終了すると、オークション サービスで生成されたレポート URL が
購入者とビーコンを登録し、reportWin
UDF(これは同じ
reportWin
関数(Protected Audience に使用される)をご覧ください。
これは、クライアントによって広告がレンダリングされると、デバイスから ping されます。
このメソッドのシグネチャは Protected Audience とほぼ同じ
version です。ただし、次の 2 つのパラメータ egressPayload
と
temporaryUnlimitedEgressPayload
これらはモデルのトレーニングに使用され、
generateBid
の結果が入力されます。
// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
buyerReportingSignals,
egressPayload, temporaryUnlimitedEgressPayload) {
// ...
}
販売者の広告テクノロジー UDF
scoreAd UDF
販売者は、この UDF を使用して、購入者から受け取った広告のうち、オークションに勝つ広告を選択します。
function scoreAd(adMetadata, bid, auctionConfig,
trustedScoringSignals, bid_metadata) {
// ...
return {desirability: desirabilityScoreForThisAd,
allowComponentAuction: true_or_false};
}
reportResult UDF
この UDF を使用すると、販売者は(最終的に)落札広告に関する情報を含むイベントレベルのレポートを実行できます。
function reportResult(auctionConfig, reporting_metadata) {
// ...
registerAdBeacon({"click", clickUrl,"view", viewUrl});
sendReportTo(reportResultUrl);
return signalsForWinner;
}
Ad Retrieval API
MVP リリースでは、広告取得サービスは購入者が管理およびホストするサービスとなります。 入札サービスは、このサービスから広告候補を取得します。 2024 年 4 月より、広告取得サーバーは信頼できる 実行環境(TEE)であり、gRPC/proto インターフェースを公開します。広告テクノロジー 企業はこのサーバーをセットアップし、B&A の一部としてその URL を提供する必要があります。 スタックのデプロイですTEE で実行されるこのサービスの実装 プライバシー サンドボックスの GitHub と、 デプロイで使用されるコードがこれであると仮定しています。
2024 年 4 月より B&A 版でコンテキスト パス広告がサポートされるようになりました 使用します。この場合、入札サーバーは オークションのコンテキスト部分で RTB サーバーから送信される広告 ID。 識別子は、すべての広告を取得するために TEE KV サーバーに送信されます。 入札フェーズで使用する関連情報 (例: ad-render-url、メタデータ、広告エンベディングを トップ K の選択など)。この 2 つ目のパスでは、特定のロジックを そのため、ここでは TEE ベースの構成方法のみを ユースケースにも適しています
HandleRequest UDF
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
deviceMetadata, contextualSignals) {
return adsMetadataString;
}
ここで
requestMetadata
: JSON。UDF に対するリクエストごとのサーバー メタデータ。今は空です。preparedDataForAdRetrieval
: このフィールドの内容は広告によって異なります。 説明します。コンテキスト広告を取得する場合、このパラメータは にはデバイスから発信された未加工のシグナルが含まれます。 入札サービスになります広告取得サーバーを使用して TEE 広告を取得する場合は、 このパラメータには、prepareDataForAdRetrieval
UDF の結果が含まれます。 注: この段階では、Protected App Signals はデコードされ、暗号化されません。deviceMetadata
: 販売者の広告サービスから転送されたデバイスのメタデータを含む JSON オブジェクト。詳細については、B&A のドキュメントをご覧ください。X-Accept-Language
: デバイスで使用される言語。X-User-Agent
: デバイスで使用されるユーザー エージェント。X-BnA-Client-IP
: デバイスの IP アドレス。
contextualSignals
: コンテンツ ターゲット入札からの任意の文字列 同じ DSP によって運用されるものとUDF は、データをデコードできることが期待されます。 その文字列を使用します。コンテキスト シグナルには、ML や 保護されたエンベディングのモデル バージョン情報( Protected App Signals。
UDF は成功すると文字列を返します。文字列は
入札サーバーが generateBid
UDF に渡されます。ただし、
string には単純な文字列を指定できます。ほとんどの場合、
スキーマが各広告テクノロジーによって独自に定義されるシリアル化されたオブジェクト。
広告テクノロジーの generateBid
がある限り、スキーマに対する制約はありません。
ロジックは文字列を認識して使用できます。
開発用のシステムをセットアップする
Android
Android 開発環境をセットアップするには、以下を行う必要があります。
- デベロッパー プレビュー 10 イメージを実行するエミュレータ(推奨)または物理デバイスを作成する
- 以下のコマンドを実行します。
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity
次に、アプリによる広告の提案に同意するオプションを選択します。
- 次のコマンドを実行して、関連する 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;
- デバイスを再起動します。
- デバイスのオークション キーをオーバーライドして、オークション キー サーバーを指定します。誤ったキーがキャッシュに保存されないようにするには、オークションを実行する前にこの手順を行うことが重要です。
入札およびオークション サービス
B&A サーバーを設定するには、セルフサービスによるセットアップのドキュメントをご覧ください。
このドキュメントでは、販売者は変更する必要がないため、購入者固有のサーバーの構成方法について説明します。
前提条件
B&A サービス スタックをデプロイする前に、購入者の広告テクノロジーは次のことを行う必要があります。
- お客様が独自の TEE 広告取得サービスを導入していることを確認します( 関連セクションをご覧ください)。
- 広告テクノロジーに必要な UDF がすべてあることを確認する
(
prepareDataForAdRetrieval
、generateBid
、reportWin
、HandleRequest
) 定義してホストできます。
Protected Audience を使用する Protected Auction と B&A がどのように連携するかを理解しておくと役立ちますが、必須ではありません。
Terraform の構成
Protected App Signals を使用するには、広告テクノロジーが次のことを行う必要があります。
- B&A で Protected App Signals のサポートを有効にする。
prepareDataForAdRetrieval, generateBid
とreportWin
の新しい UDF を取得できる URL エンドポイントを指定する。
また、このガイドでは、リマーケティングに B&A を使用する広告テクノロジーが、引き続き通常どおりリマーケティング オークションの既存のすべての構成フラグを設定することを前提としています。
購入者の広告テクノロジーの設定
このデモファイルを例として使用し、購入者は次のフラグを設定する必要があります。
- Protected App Signals を有効にする: Protected App Signals のデータの収集を有効にします。
- Protected App Signals の URL: Protected App Signals サーバーの URL に設定します。
広告テクノロジーは、次のフィールドのプレースホルダを正しい 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"
販売者の広告テクノロジーの設定
このデモファイルを例として使用し、販売者は次のフラグを設定する必要があります。(注: ここでは、Protected App Signals に関連する構成のみを特に表示しています)。広告テクノロジーは、プレースホルダを正しい 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 サービスのインスタンスを 1 つまたは 2 つデプロイする必要があります。この専門講座では
TEE ベースの広告取得に使用される KV インスタンスに
Ad Retrieval Server
とインスタンスへの接続(コンテキスト パスベース)
KV Lookup Server
として取得できます。
いずれの場合も、サーバーのデプロイは、
KV サーバーの GitHub では、この 2 つのケースの違いは、
特別な設定なしですぐに機能しますが
2 つ目の UDF を実装するために HandleRequest
UDF のデプロイが必要
渡します。詳細については、KV サーバー
オンボーディング ガイドをご覧ください。B&A では、両方のサービスが
入札サービスと同じサービス メッシュにデプロイされます。
セットアップ例
次のシナリオを考えてみましょう。Protected App Signals API を使用して、広告テクノロジーがユーザーのアプリの使用状況に基づいて関連するシグナルを保存します。この例では、複数のアプリからのアプリ内購入を表すシグナルが保存されています。オークション中に暗号化されたシグナルが収集され、B&A で実行されている Protected Auction に渡されます。B&A で実行されている購入者の UDF は、シグナルを使用して広告の候補をフェッチし、入札単価を計算します。
[購入者] Signals の例
キーが 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 の例
各シグナルを 2 バイトにエンコードします。1 番目のバイトはシグナルキーの最初のバイト、2 番目のバイトはシグナル値の最初のバイトです。
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};
}
[購入者] prepareDataForAdRetrieval の例
/**
* `encodedOnDeviceSignals` is a Uint8Array and would contain
* the app signals emanating from device. For purpose of the
* demo, in our sample example, we assume that device is sending
* the signals with pair of bytes formatted as following:
* "<id><In app spending>". Where id corresponds to an ad category
* that user uses on device, and the in app spending is a measure
* of how much money the user has spent in this app category
* previously. In our example, id of 0 will correspond to a
* fitness ad category and a non-zero id will correspond to
* food app category -- though this info will be useful
* later in the B&A pipeline.
*
* Returns a JSON object indicating what type of ad(s) may be
* most relevant to the user. In a real setup ad techs might
* want to decode the signals as part of this script.
*
* Note: This example script makes use of only encoded device signals
* but adtech can take other signals into account as well to prepare
* the data that will be useful down stream for ad retrieval and
* bid generation. The max length of the app signals used in this
* sample example is arbitrarily limited to 4 bytes.
*/
function prepareDataForAdRetrieval(encodedOnDeviceSignals,
encodedOnDeviceSignalsVersion,
sellerAuctionSignals,
contextualSignals) {
if (encodedOnDeviceSignals.length === 0 || encodedOnDeviceSignals.length > 4 ||
encodedOnDeviceSignals.length % 2 !== 0) {
throw "Expected encoded signals length to be an even number in (0, 4]";
}
var preparedDataForAdRetrieval = {};
for (var i = 0; i < encodedOnDeviceSignals.length; i += 2) {
preparedDataForAdRetrieval[encodedOnDeviceSignals[i]] = encodedOnDeviceSignals[i + 1];
}
return preparedDataForAdRetrieval;
}
[購入者] 広告取得 UDF の例
この例では、広告取得サーバーが、上位 k 個の広告候補のそれぞれについてメタデータ(この例では各広告の ID ですが、後で入札単価を生成するのに役立つ他のデータを含めることもできます)を送信します。
function HandleRequest(requestMetadata, protectedSignals, deviceMetadata,
contextualSignals) {
return "[{\"adId\":\"0\"},{\"adId\":\"1\"}]"
[購入者] 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};
}
[購入者] 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 から対応するスコアリング シグナルへのマッピングを使用できるように、スコアリング シグナル KV サーバーを設定する必要があります。たとえば、https:/buyer-domain.com/get-fitness-app
と https:/buyer-domain.com/get-fastfood-app
が購入者によって返される場合、販売者は、https://key-value-server-endpoint.com?client_type=1&renderUrls=<render-url-returned-by-the-buyer>
で GET
を使用して SFE からクエリされたときに、次の例のようなスコアリング シグナルのレスポンスを受け取ることができます。
{
"renderUrls" : {
"https:/buyer-domain.com/get-fitness-app" : [
"1",
"2"
],
"https:/buyer-domain.com/get-fastfood-app" : [
"3",
"4"
]
}
}
[販売者] 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
};
}
[販売者] 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 サンプルアプリを作成しました。このサンプル リポジトリをご覧ください。