راهنمای توسعه دهنده برنامه Protected Signals

برای کمک به توسعه‌دهندگان برای شروع آزمایش با Protected App Signals API، این سند تمام API‌های موجود در سطح API را شرح می‌دهد، نحوه راه‌اندازی یک محیط آزمایشی را توضیح می‌دهد و نمونه‌هایی از پیکربندی و اسکریپت‌ها را ارائه می‌دهد.

تاریخچه نسخه

ژانویه 2024

اولین نسخه از راهنمای توسعه دهنده که از انتشار PAS MVP پشتیبانی می کند

مارس 2024

تغییرات در API برای پشتیبانی از نسخه M-2024-05 API Android و انتشار آوریل 2024 اجزای سمت سرور. قابل توجه ترین تغییرات:

  • جزئیات مربوط به مجوزهای مورد نیاز برای API روی دستگاه اضافه شد
  • جزئیات مربوط به مدیریت سهمیه سیگنال های روی دستگاه اضافه شد
  • امضای generateBid با تغییرات مربوط به بازیابی آگهی متنی و پشتیبانی خروج به روز شد
  • اسناد reportWin به روز شده از جمله پشتیبانی خروج
  • اسناد API Retrieval Ad Retrieval را به روز کنید که پشتیبانی از بازیابی تبلیغات BYOS را حذف می کند و UDF بازیابی آگهی را مستند می کند

نمای کلی API

سطح API Protected Signals شامل زیر مجموعه های مختلف API در سیستم های مختلف است:

  • API های اندروید:
    • Signal Curation API، متشکل از:
    • به روز رسانی Signals API
    • Signals Encoding API
    • Protected Auction Support API: توسط SDKها برای اجرای حراج محافظت شده در سرورهای Bidding and Auction (B&A) با استفاده از Protected App Signals.
  • API های سمت سرور:
    • Protected Auction API: مجموعه ای از اسکریپت های JS که در سرورهای Bidding و Auction اجرا می شوند. این API فروشندگان و خریداران را قادر می سازد تا منطق پیاده سازی حراج محافظت شده را بنویسند.
    • Ad Retrieval API: مسئول ارائه لیستی از تبلیغات نامزد با توجه به اطلاعات متنی و کاربر است که در اختیار سرور پیشنهاد خریدار قرار گرفته است.

کلاینت اندروید

در سمت کلاینت، سطح Protected App Signals از سه API مختلف تشکیل شده است:

  • به روز رسانی سیگنال ها: یک API سیستم Android برای فعال کردن کنترل سیگنال ها در دستگاه.
  • رمزگذاری سیگنال ها: یک API جاوا اسکریپت برای آماده سازی سیگنال ها برای ارسال به سرور در طول حراج.
  • پشتیبانی از حراج محافظت شده: یک API برای پشتیبانی از اجرای حراج محافظت شده در سرورهای مزایده و مزایده. این API مختص Protected App Signals نیست و همچنین برای پشتیبانی از مزایده های Protected Audience API استفاده می شود.

به روز رسانی Signals API

Update Signals API توانایی ثبت سیگنال های مربوط به کاربر و برنامه را از طرف خریدار به فناوری های تبلیغاتی ارائه می دهد. 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 است که در آن کلیدها رشته های پایه 64 مربوط به کلید مورد نظر و مقادیر پایه 64 رشته متناظر با مقدار برای قرار دادن هستند.

append

یک سیگنال/سیگنال جدید به یک سری زمانی سیگنال اضافه می کند و قدیمی ترین آنها را حذف می کند

سیگنال می دهد که اگر اندازه سری از حداکثر داده شده بیشتر شود، فضا را برای موارد جدید باز می کند. مقدار برای این یک شی JSON است که در آن کلیدها رشته های پایه 64 مربوط به کلیدی هستند که باید به آن اضافه شود و مقادیر اشیایی با دو فیلد هستند: "values" و "maxSignals".

"مقدار": لیستی از رشته های پایه 64 مربوط به مقادیر سیگنال برای الحاق به سری های زمانی.

"maxSignals": حداکثر تعداد مقادیر مجاز در این سری زمانی. اگر

تعداد فعلی سیگنال های مرتبط با کلید از maxSignals بیشتر است. قدیمی ترین سیگنال ها حذف خواهند شد. توجه داشته باشید که می توانید به کلید اضافه شده توسط put اضافه کنید. توجه داشته باشید که اضافه کردن بیش از حداکثر تعداد مقادیر باعث خرابی می شود.

put_if_not_present

فقط در صورتی سیگنال جدید اضافه می کند که سیگنال های موجود با همان کلید وجود نداشته باشد. مقدار برای این یک شی JSON است که در آن کلیدها رشته های پایه 64 مربوط به کلید مورد نظر و مقادیر پایه 64 رشته متناظر با مقدار برای قرار دادن هستند.

remove

سیگنال یک کلید را حذف می کند. مقدار این لیستی از رشته های پایه 64 مربوط به کلیدهای سیگنال هایی است که باید حذف شوند.

update_encoder

عملکردی برای به‌روزرسانی نقطه پایانی و یک URI ارائه می‌دهد که می‌توان از آن استفاده کرد

برای بازیابی یک منطق رمزگذاری کلید فرعی برای ارائه یک اقدام به روز رسانی "عمل" و

مقادیری که در حال حاضر پشتیبانی می‌شوند فقط «REGISTER» هستند که در صورت ارائه برای اولین بار، نقطه پایان رمزگذار را ثبت می‌کند یا نقطه پایانی موجود را با نقطه پایانی ارائه‌شده جدید بازنویسی می‌کند. ارائه نقطه پایانی برای عمل "REGISTER" مورد نیاز است. کلید فرعی برای ارائه نقطه پایانی رمزگذار "نقطه پایان" و مقدار آن 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 خارج می کند. فرآیند اخراج به منظور کاهش دفعات اخراج، اجازه می دهد تا برای مدت کوتاهی از سهمیه فراتر رود.

Signals Encoding API

خریداران موظفند یک تابع جاوا اسکریپت را برای رمزگذاری سیگنال‌های ذخیره شده در دستگاه برای ارسال به سرور در طول حراج محافظت شده ارائه کنند. خریداران می‌توانند این اسکریپت را با افزودن نشانی اینترنتی که از طریق کلید «update_encoder» در هر یک از پاسخ‌ها به درخواست UpdateSignal API واکشی می‌شود، ارائه کنند. اسکریپت دارای امضای زیر خواهد بود:

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 نقشه ای از کلیدها به شکل UInt8Arrays با اندازه 4 تا لیست اشیاء سیگنال های برنامه محافظت شده است. هر شیء Protected App Signals دارای سه فیلد است:

  • signal_value : UInt8Array که مقدار سیگنال را نشان می دهد.
  • creation_time : عددی که زمان ایجاد سیگنال ها را بر حسب دوره-ثانیه نشان می دهد.
  • package_name : رشته ای که نشان دهنده نام بسته ای است که سیگنال را ایجاد کرده است.

پارامتر maxSize عددی است که بزرگترین اندازه مجاز آرایه را برای خروجی توصیف می کند.

تابع باید یک شی با دو فیلد خروجی دهد:

  • status : اگر اسکریپت با موفقیت اجرا شد، باید 0 باشد.
  • results : باید یک آرایه UInt8 با طول کمتر یا مساوی 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

Protected Auction Support API

در سمت دستگاه، اجرای حراج برای سیگنال‌های برنامه محافظت‌شده مانند اجرای حراج برای مخاطبان محافظت‌شده است.

خدمات مناقصه و مزایده

API های سمت سرور عبارتند از:

  • Protected Auction API: مجموعه‌ای از توابع JS یا UDF که خریداران و فروشندگان می‌توانند بر روی اجزای B&A خود مستقر کنند تا مناقصه و منطق حراج را تعیین کنند.
  • API بازیابی آگهی: خریداران می‌توانند این API را با پیاده‌سازی نقطه پایانی REST که مسئول ارائه مجموعه‌ای از تبلیغات نامزد برای حراج سیگنال برنامه محافظت‌شده است، پیاده‌سازی کنند.

API حراج محافظت شده

Protected Auction API از JS API یا UDF تشکیل شده است که خریداران و فروشندگان می توانند از آنها برای اجرای منطق حراج و مناقصه خود استفاده کنند.

UDFهای فناوری آگهی خریدار
UDF را آماده داده ForAdRetrieval

قبل از اینکه سیگنال‌های برنامه محافظت‌شده برای واکشی آگهی‌ها از سرویس بازیابی آگهی TEE استفاده شوند، خریداران باید سیگنال‌های برنامه محافظت‌شده و سایر داده‌های ارائه‌شده توسط فروشنده را رمزگشایی و آماده کنند. خریداران خروجی prepareDataForAdRetrieval را به سرویس بازیابی تبلیغات ارسال می کنند تا کاندیدای برتر تبلیغات را برای مناقصه بازیابی کند .

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

خروجی این تابع یک پیشنهاد منفرد برای یک نامزد آگهی است که به صورت JSON معادل ProtectedAppSignalsAdWithBidMetadata نشان داده می شود. این تابع همچنین می‌تواند دو آرایه را برگرداند که سپس برای فعال کردن آموزش مدل به reportWin ارسال می‌شوند (برای جزئیات بیشتر در مورد آموزش egress و مدل به بخش گزارش در توضیح PAS مراجعه کنید).

گزارشWin UDF

هنگامی که یک حراج به پایان می رسد، سرویس حراج URL های گزارش برای خریداران ایجاد می کند و چراغ های نشانی را با استفاده از reportWin UDF ثبت می کند (این همان تابع reportWin است که برای مخاطبان محافظت شده استفاده می شود) . هنگامی که تبلیغ توسط مشتری ارائه شد، این مورد توسط دستگاه پینگ می شود. امضای این روش تقریباً مشابه نسخه Protected Audience است به جز دو پارامتر اضافی 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};
}
گزارش نتیجه UDF

این 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 ارسال می‌شوند تا تمام اطلاعات مربوط به آگهی را که در مرحله مناقصه استفاده می‌شود (به‌عنوان مثال ad-render-url، ابرداده‌ها و جاسازی‌های آگهی برای استفاده در انتخاب top-k) واکشی می‌شوند. این مسیر دوم برای استقرار نیازی به منطق خاصی ندارد، بنابراین ما در اینجا فقط نحوه پیکربندی مورد استفاده بازیابی آگهی مبتنی بر TEE را مستند می کنیم.

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

جایی که:

  • requestMetadata : JSON. فراداده هر درخواست سرور به UDF. فعلا خالیه
  • preparedDataForAdRetrieval : محتوای این قسمت به استراتژی بازیابی آگهی بستگی دارد. در صورت بازیابی آگهی متنی، این پارامتر حاوی سیگنال‌های خامی است که از دستگاه منشأ گرفته و از سرویس مناقصه ارسال می‌شود. در صورت بازیابی آگهی TEE با استفاده از سرور بازیابی آگهی، این پارامتر حاوی نتیجه UDF prepareDataForAdRetrieval خواهد بود. توجه: در این مرحله سیگنال های برنامه محافظت شده رمزگشایی و رمزگذاری نمی شوند.
  • deviceMetadata : شی JSON حاوی فراداده دستگاه است که توسط سرویس آگهی فروشنده بازارسال شده است. برای جزئیات بیشتر به مستندات B&A مراجعه کنید.
    • X-Accept-Language : زبان مورد استفاده در دستگاه.
    • X-User-Agent : عامل کاربر مورد استفاده در دستگاه.
    • X-BnA-Client-IP : آدرس IP دستگاه.
  • contextualSignals : رشته دلخواه از سرور پیشنهادی متنی که توسط همان DSP اداره می شود نشات می گیرد. انتظار می رود UDF بتواند رشته را رمزگشایی کرده و از آن استفاده کند. سیگنال‌های متنی ممکن است حاوی اطلاعاتی مانند اطلاعات نسخه مدل ML برای جاسازی محافظت‌شده باشد که با استفاده از سیگنال‌های برنامه محافظت‌شده ارسال می‌شود.

UDF باید یک رشته موفقیت را بازگرداند. رشته به سرور مناقصه برگردانده می شود و سپس آن را به generateBid UDF ارسال می کند. اگرچه رشته می تواند فقط یک رشته ساده باشد، به احتمال زیاد رشته باید یک شیء سریالی باشد که طرحواره آن توسط هر فناوری تبلیغاتی به تنهایی تعریف می شود. هیچ محدودیتی در طرحواره وجود ندارد تا زمانی که منطق generateBid فناوری تبلیغات بتواند رشته را تشخیص دهد و از آن استفاده کند.

سیستم خود را برای توسعه تنظیم کنید

اندروید

برای راه اندازی محیط توسعه اندروید خود باید موارد زیر را انجام دهید:

  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 خود را مستقر کرده اند (به بخش مربوطه مراجعه کنید).
  • اطمینان حاصل کنید که فناوری تبلیغات همه UDF های لازم ( prepareDataForAdRetrieval ، generateBid ، reportWin ، HandleRequest ) تعریف و میزبانی شده است.

درک نحوه عملکرد حراج محافظت شده با مخاطب محافظت شده با B&A نیز مفید خواهد بود، اما اجباری نیست.

پیکربندی Terraform

برای استفاده از سیگنال‌های برنامه محافظت‌شده، کارشناسان تبلیغات باید:

  • پشتیبانی Protected App Signals را در B&A فعال کنید.
  • نقاط پایانی URL را ارائه کنید که از آنها می توان UDF های جدید برای prepareDataForAdRetrieval, generateBid و reportWin را واکشی کرد.

به‌علاوه، این راهنما فرض می‌کند که فناوری‌های تبلیغاتی که می‌خواهند از B&A برای بازاریابی مجدد استفاده کنند، به تنظیم همه پرچم‌های پیکربندی موجود برای حراج بازاریابی مجدد به طور معمول ادامه می‌دهند.

پیکربندی فناوری آگهی خریدار

با استفاده از این فایل دمو به عنوان مثال، خریداران باید پرچم های زیر را تنظیم کنند:

  • فعال کردن سیگنال های برنامه محافظت شده : برای جمع آوری داده های سیگنال های برنامه محافظت شده فعال است.
  • نشانی‌های اینترنتی سیگنال‌های برنامه محافظت‌شده : نشانی‌های اینترنتی سرورهای سیگنال‌های برنامه محافظت‌شده را تنظیم کنید.

تکنسین های تبلیغاتی باید 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 اشاره خواهیم کرد.

در هر دو مورد، استقرار سرورها از مستندات موجود در سرور KV GitHub پیروی می کند، تفاوت بین این دو مورد در این است که مورد جستجو بدون هیچ گونه پیکربندی اضافی کار می کند، در حالی که بازیابی به استقرار HandleRequest UDF برای پیاده سازی نیاز دارد. منطق بازیابی برای جزئیات بیشتر به راهنمای نصب سرور KV نگاهی بیندازید. توجه داشته باشید که B&A انتظار دارد که هر دو سرویس در همان مش سرویس به عنوان سرویس مناقصه مستقر شوند.

راه اندازی مثال

سناریوی زیر را در نظر بگیرید: با استفاده از Protected App Signals API، یک فناوری تبلیغاتی سیگنال‌های مرتبط را بر اساس استفاده از برنامه کاربر ذخیره می‌کند. در مثال ما، سیگنال هایی ذخیره می شوند که نشان دهنده خریدهای درون برنامه ای از چندین برنامه هستند. در طول حراج، سیگنال‌های رمزگذاری شده جمع‌آوری می‌شوند و به حراج محافظت‌شده در حال اجرا در B&A ارسال می‌شوند. UDF های خریدار که در 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, 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

در مثال ما، سرور بازیابی آگهی، ابرداده (یعنی شناسه برای هر آگهی در این مثال، اما می‌تواند حاوی داده‌های دیگری برای هر یک باشد که می‌تواند در ایجاد پیشنهادهای بعدی مفید باشد) را برای هر یک از کاندیدای برتر آگهی ارسال می‌کند.

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

[خریداران] نمونه Bid را تولید می کنند

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

[خریداران] گزارشWin مثال

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

فروشندگان باید یک سرور 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> ، سیگنال‌های امتیازدهی زیر را داشته باشد. 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"
      ]
   }
}

[فروشنده] 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
  };
}

[فروشنده] گزارش نمونه نتیجه

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 ایجاد کرده ایم که در این مخزن نمونه یافت می شود.