इस दस्तावेज़ में, Protected App Signals API के साथ एक्सपेरिमेंट शुरू करने के लिए डेवलपर की मदद की गई है. इसमें एपीआई के सभी कॉम्पोनेंट के बारे में बताया गया है. साथ ही, टेस्ट एनवायरमेंट सेट अप करने का तरीका बताया गया है. इसके अलावा, कॉन्फ़िगरेशन और स्क्रिप्ट के उदाहरण दिए गए हैं.
वर्शन इतिहास
जनवरी 2024
डेवलपर गाइड की पहली रिलीज़, जिसमें पीएएस एमवीपी रिलीज़ के बारे में बताया गया है
मार्च 2024
Android API की M-2024-05 रिलीज़ और सर्वर साइड कॉम्पोनेंट की अप्रैल 2024 की रिलीज़ के साथ काम करने के लिए, एपीआई में बदलाव किए गए हैं. सबसे अहम बदलाव:
- डिवाइस पर मौजूद एपीआई के लिए ज़रूरी अनुमतियों के बारे में जानकारी जोड़ी गई
 - डिवाइस पर मौजूद सिग्नल के कोटे को मैनेज करने के बारे में जानकारी जोड़ी गई
 - कॉन्टेक्स्ट के हिसाब से विज्ञापन दिखाने और डेटा बाहर भेजने की सुविधा से जुड़े बदलावों के साथ अपडेट किया गया 
generateBidसिग्नेचर reportWinके अपडेट किए गए दस्तावेज़, जिनमें डेटा बाहर भेजने की सुविधा भी शामिल है- विज्ञापन वापस पाने के एपीआई के दस्तावेज़ को अपडेट किया गया है. इसमें, BYOS विज्ञापन वापस पाने की सुविधा के लिए सहायता हटा दी गई है. साथ ही, विज्ञापन वापस पाने के यूडीएफ़ के बारे में जानकारी दी गई है
 
एपीआई के बारे में खास जानकारी
Protected Signals API में अलग-अलग सिस्टम पर एपीआई के अलग-अलग सबसेट शामिल होते हैं:
- Android API:
- सिग्नल क्यूरेशन एपीआई, जिसमें ये शामिल हैं:
 - Update Signals API
 - Signals Encoding API
 - Protected Auction Support API: इसका इस्तेमाल एसडीके टूल करते हैं. इससे Bidding and Auction (B&A) सर्वर पर सुरक्षित नीलामी की जा सकती है. इसके लिए, Protected App Signals का इस्तेमाल किया जाता है.
 
 - सर्वर-साइड एपीआई:
- Protected Auction API: यह बिडिंग और नीलामी वाले सर्वर में चलने वाली JS स्क्रिप्ट की एक सीरीज़ है. इस एपीआई की मदद से, सेलर और खरीदार, सुरक्षित नीलामी को लागू करने के लिए लॉजिक लिख सकते हैं.
 - विज्ञापन वापस पाने वाला एपीआई: यह एपीआई, विज्ञापन देने वाले व्यक्ति या कंपनी के बिडिंग सर्वर को उपलब्ध कराई गई कॉन्टेक्स्ट और उपयोगकर्ता की जानकारी के आधार पर, संभावित विज्ञापनों की सूची उपलब्ध कराता है.
 
 
Android क्लाइंट
क्लाइंट साइड पर, Protected App Signals में तीन अलग-अलग एपीआई होते हैं:
- अपडेट सिग्नल: यह Android सिस्टम API है. इससे डिवाइस पर सिग्नल को मैनेज किया जा सकता है.
 - सिग्नल एन्कोडिंग: यह एक JavaScript API है. इसका इस्तेमाल, नीलामी के दौरान सर्वर को भेजे जाने वाले सिग्नल तैयार करने के लिए किया जाता है.
 - Protected Auction Support: यह एक ऐसा एपीआई है जो बिडिंग और नीलामी के सर्वर पर Protected Auction को लागू करने में मदद करता है. यह एपीआई, Protected App Signals के लिए खास नहीं है. इसका इस्तेमाल Protected Audience API के लिए नीलामियों में भी किया जाता है.
 
Update Signals API
Update Signals API की मदद से, विज्ञापन टेक्नोलॉजी से जुड़ी कंपनियां, खरीदार की ओर से उपयोगकर्ता और ऐप्लिकेशन से जुड़े सिग्नल रजिस्टर कर सकती हैं. यह एपीआई, डेलिगेशन मॉडल पर काम करता है. कॉलर, एक यूआरआई उपलब्ध कराता है. फ़्रेमवर्क इस यूआरआई से, नीलामी में इस्तेमाल किए जाने वाले सिग्नल और उन सिग्नल को एन्कोड करने का लॉजिक फ़ेच करता है.
एपीआई के लिए, android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS
अनुमति ज़रूरी है.
updateSignals() API, यूआरआई से एक JSON ऑब्जेक्ट वापस लाएगा. इसमें यह जानकारी होगी कि कौनसे सिग्नल जोड़ने या हटाने हैं. साथ ही, यह भी बताया जाएगा कि नीलामी के लिए उन सिग्नल को कैसे तैयार करना है.
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 अनुरोध भेजता है. सिग्नल अपडेट के साथ-साथ, रिस्पॉन्स में ऐसा एंडपॉइंट शामिल हो सकता है जो रॉ सिग्नल को एन्कोड किए गए पेलोड में बदलने के लिए, एन्कोडिंग लॉजिक को होस्ट करता है. सिग्नल अपडेट, JSON फ़ॉर्मैट में होने चाहिए. इनमें ये कुंजियां हो सकती हैं:
JSON ऑब्जेक्ट के टॉप लेवल की कुंजियां, इन पांच निर्देशों में से किसी एक से मेल खानी चाहिए:
key  | 
    ब्यौरा  | 
  
  | 
    यह फ़ंक्शन, एक नया सिग्नल जोड़ता है. साथ ही, एक ही कुंजी वाले किसी भी मौजूदा सिग्नल को बदल देता है. वैल्यू यह एक JSON ऑब्जेक्ट है. इसमें कुंजियां, base 64 स्ट्रिंग होती हैं. ये स्ट्रिंग, उस कुंजी से जुड़ी होती हैं जिसे डालना है. वहीं, वैल्यू, base 64 स्ट्रिंग होती हैं. ये स्ट्रिंग, उस वैल्यू से जुड़ी होती हैं जिसे डालना है.  | 
  
  | 
    यह फ़ंक्शन, सिग्नल की टाइम सीरीज़ में एक या उससे ज़्यादा नए सिग्नल जोड़ता है और सबसे पुराने सिग्नल को हटा देता है अगर सीरीज़ का साइज़ तय सीमा से ज़्यादा है, तो नए सिग्नल के लिए जगह बनाने के लिए पुराने सिग्नल हटा दिए जाते हैं. इसकी वैल्यू एक JSON ऑब्जेक्ट होती है. इसमें कुंजियां, बेस 64 स्ट्रिंग होती हैं. ये स्ट्रिंग, उस कुंजी से जुड़ी होती हैं जिसे जोड़ना है. साथ ही, वैल्यू ऐसे ऑब्जेक्ट होती हैं जिनमें दो फ़ील्ड होते हैं: "values" और "maxSignals". "values": यह टाइम सीरीज़ में जोड़ने के लिए, सिग्नल वैल्यू से जुड़ी Base64 स्ट्रिंग की सूची होती है. "maxSignals": इस टाइम सीरीज़ में ज़्यादा से ज़्यादा कितनी वैल्यू इस्तेमाल की जा सकती हैं. अगर अगर किसी कुंजी से जुड़े सिग्नल की मौजूदा संख्या, maxSignals से ज़्यादा है, तो सबसे पुराने सिग्नल हटा दिए जाएंगे. ध्यान दें कि put से जोड़ी गई किसी कुंजी में वैल्यू जोड़ी जा सकती है. ध्यान दें कि तय की गई ज़्यादा से ज़्यादा वैल्यू से ज़्यादा वैल्यू जोड़ने पर, यह सुविधा काम नहीं करेगी.  | 
  
  | 
    यह फ़ंक्शन, एक नया सिग्नल सिर्फ़ तब जोड़ता है, जब एक ही कुंजी वाले कोई भी मौजूदा सिग्नल न हों. इसकी वैल्यू एक JSON ऑब्जेक्ट होती है. इसमें कुंजियां, base 64 स्ट्रिंग होती हैं. ये स्ट्रिंग, उस कुंजी से जुड़ी होती हैं जिसे डालना है. साथ ही, वैल्यू, base 64 स्ट्रिंग होती हैं. ये स्ट्रिंग, उस वैल्यू से जुड़ी होती हैं जिसे डालना है.  | 
  
  | 
    यह कुकी, किसी कुंजी के लिए सिग्नल को हटाती है. इसकी वैल्यू, base 64 स्ट्रिंग की एक सूची होती है. यह उन सिग्नल की कुंजियों से जुड़ी होती है जिन्हें मिटाना है.  | 
  
  | 
    यह एंडपॉइंट को अपडेट करने की कार्रवाई और एक यूआरआई उपलब्ध कराता है, जिसका इस्तेमाल किया जा सकता है एन्कोडिंग लॉजिक को वापस पाने के लिए. अपडेट करने की कार्रवाई के लिए सब-कुंजी "action" है. सिर्फ़ "REGISTER" वैल्यू का इस्तेमाल किया जा सकता है. इससे एनकोडर एंडपॉइंट रजिस्टर हो जाएगा. अगर इसे पहली बार दिया गया है, तो यह मौजूदा एंडपॉइंट को नए एंडपॉइंट से बदल देगा. "REGISTER" कार्रवाई के लिए, एंडपॉइंट देना ज़रूरी है.एनकोडर एंडपॉइंट देने के लिए सब-कुंजी "endpoint" है और वैल्यू यूआरआई है एंडपॉइंट के लिए स्ट्रिंग.  | 
  
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
खरीदारों को एक Java Script फ़ंक्शन देना होगा. इसका इस्तेमाल, डिवाइस पर सेव किए गए सिग्नल को एन्कोड करने के लिए किया जाएगा. इन सिग्नल को सुरक्षित नीलामी के दौरान सर्वर को भेजा जाएगा. खरीदार, इस स्क्रिप्ट को उपलब्ध करा सकते हैं. इसके लिए, उन्हें उस यूआरएल को जोड़ना होगा जहां से इसे फ़ेच किया जा सकता है. इसके लिए, UpdateSignal API के अनुरोध के किसी भी जवाब में "update_encoder" कुंजी का इस्तेमाल करें. स्क्रिप्ट का हस्ताक्षर ऐसा होगा:
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 के हर ऑब्जेक्ट में तीन फ़ील्ड होते हैं:
signal_value: यह UInt8Array है, जो सिग्नल की वैल्यू दिखाता है.creation_time: यह एक संख्या है, जो सिग्नल के बनाए जाने के समय को इपॉक-सेकंड में दिखाती है.package_name: यह स्ट्रिंग, उस पैकेज के नाम को दिखाती है जिसने सिग्नल बनाया है.
maxSize पैरामीटर एक संख्या है. यह आउटपुट के लिए, ऐरे के सबसे बड़े साइज़ के बारे में बताती है.
फ़ंक्शन को दो फ़ील्ड वाला ऑब्जेक्ट आउटपुट करना चाहिए:
status: स्क्रिप्ट के सही तरीके से चलने पर, इसकी वैल्यू 0 होनी चाहिए.results: यह maxSize से कम या इसके बराबर लंबाई वाला UInt8Array होना चाहिए. इस ऐरे को नीलामी के दौरान सर्वर को भेजा जाएगा. इसेprepareDataForAdRetrievalस्क्रिप्ट तैयार करेगी.
एनकोडिंग, विज्ञापन टेक्नोलॉजी कंपनियों को फ़ीचर इंजीनियरिंग की शुरुआती स्टेज उपलब्ध कराती है. इसमें वे अपने कस्टम लॉजिक के आधार पर, रॉ सिग्नल को एक साथ जोड़े गए वर्शन में कंप्रेस करने जैसे बदलाव कर सकती हैं. ध्यान दें कि ट्रस्टेड एक्ज़ीक्यूशन एनवायरमेंट (टीईई) में चल रही सुरक्षित नीलामी के दौरान, विज्ञापन टेक्नोलॉजी से जुड़े कस्टम लॉजिक के पास, एन्कोडिंग से जनरेट किए गए सिग्नल पेलोड को पढ़ने का ऐक्सेस होगा. कस्टम लॉजिक, जिसे उपयोगकर्ता के तय किए गए फ़ंक्शन (यूडीएफ़) के तौर पर जाना जाता है, खरीदार के B&A TEE में चलता है. इसके पास, एन्कोड किए गए सिग्नल और पब्लिशर ऐप्लिकेशन से मिले अन्य कॉन्टेक्स्ट के हिसाब से सिग्नल को पढ़ने का ऐक्सेस होगा. इससे विज्ञापन चुनने (विज्ञापन वापस पाने और बिडिंग) में मदद मिलेगी.
सिग्नल एन्कोडिंग
हर घंटे, जिन खरीदारों ने अपने रजिस्टर किए गए सिग्नल के साथ एन्कोडिंग लॉजिक दिया है उनके सिग्नल, नीलामी के पेलोड में एन्कोड किए जाएंगे. नीलामी के पेलोड के लिए बाइट ऐरे को डिवाइस पर सेव किया जाता है. साथ ही, इसे एन्क्रिप्ट (सुरक्षित) किया जाता है. इसे सेलर, विज्ञापन चुनने के डेटा के तौर पर इकट्ठा करेंगे, ताकि इसे Protected Auction में शामिल किया जा सके. जांच के लिए, इस कोडिंग को हर घंटे के हिसाब से ट्रिगर करने के बजाय, यहां दी गई कमांड चलाकर ट्रिगर किया जा सकता है:
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
डिवाइस पर, Protected App Signals के लिए नीलामी करना, Protected Audience के लिए नीलामी करने जैसा ही होता है.
Bidding and Auction Services
Server Side API में ये शामिल हैं:
- Protected Auction API: यह JS फ़ंक्शन या यूडीएफ़ की एक सीरीज़ है. खरीदार और विक्रेता, इसे अपने मालिकाना हक वाले B&A कॉम्पोनेंट पर डिप्लॉय कर सकते हैं. इससे बिडिंग और नीलामी के लॉजिक का पता चलता है.
 - Ad Retrieval API: खरीदार इस एपीआई को लागू कर सकते हैं. इसके लिए, उन्हें एक REST एंडपॉइंट लागू करना होगा. यह एंडपॉइंट, Protected App Signal ऑक्शन के लिए, विज्ञापन देने वाले लोगों या कंपनियों के सेट को उपलब्ध कराने के लिए ज़िम्मेदार होगा.
 
Protected Auction API
Protected Auction API में JS API या यूडीएफ़ शामिल होते हैं. खरीदार और विक्रेता इनका इस्तेमाल, नीलामी और बिडिंग के लॉजिक को लागू करने के लिए कर सकते हैं.
विज्ञापन टेक्नोलॉजी की सेवा देने वाली कंपनी के यूडीएफ़
prepareDataForAdRetrieval यूडीएफ़
TEE Ad Retrieval सेवा से विज्ञापन के संभावित उम्मीदवारों को फ़ेच करने के लिए, Protected App Signals का इस्तेमाल करने से पहले, खरीदारों को Protected App Signals और सेलर की ओर से उपलब्ध कराए गए अन्य डेटा को डिकोड और तैयार करना होगा. खरीदारों के 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
सबसे ज़्यादा के कैंडिडेट विज्ञापन दिखाए जाने के बाद, विज्ञापन के कैंडिडेट को खरीदार के कस्टम बिडिंग लॉजिक, 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>
    };
}
इस फ़ंक्शन का आउटपुट, विज्ञापन के लिए उपलब्ध किसी कैंडिडेट के लिए एक बिड होती है. इसे ProtectedAppSignalsAdWithBidMetadata के बराबर JSON के तौर पर दिखाया जाता है.
यह फ़ंक्शन दो ऐसे ऐरे भी दिखा सकता है जिन्हें reportWin में पास किया जाएगा, ताकि मॉडल ट्रेनिंग को चालू किया जा सके. इग्रेस और मॉडल ट्रेनिंग के बारे में ज़्यादा जानकारी के लिए, PAS के बारे में जानकारी देने वाले दस्तावेज़ का रिपोर्टिंग सेक्शन देखें
reportWin UDF
नीलामी खत्म होने पर, नीलामी सेवा, खरीदारों के लिए रिपोर्टिंग यूआरएल जनरेट करेगी. साथ ही, reportWin यूडीएफ़ (यह वही reportWin फ़ंक्शन है जिसका इस्तेमाल Protected Audiences के लिए किया जाता है) का इस्तेमाल करके बीकन रजिस्टर करेगी.
जब क्लाइंट विज्ञापन को रेंडर कर देगा, तब डिवाइस इसे पिंग करेगा.
इस तरीके का सिग्नेचर, Protected Audience वर्शन के सिग्नेचर जैसा ही होता है. हालांकि, इसमें दो अतिरिक्त पैरामीटर 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 यूडीएफ़
इस यूडीएफ़ की मदद से सेलर, जीतने वाले विज्ञापन की जानकारी के साथ इवेंट लेवल की रिपोर्टिंग कर सकता है.
function reportResult(auctionConfig, reporting_metadata) {
  // ...
  registerAdBeacon({"click", clickUrl,"view", viewUrl});
  sendReportTo(reportResultUrl);
  return signalsForWinner;
}
Ad Retrieval API
एमवीपी रिलीज़ में, विज्ञापन पाने की सेवा को खरीदार मैनेज और होस्ट करेगा. साथ ही, बिडिंग सेवा इस सेवा से विज्ञापन पाने वाले लोगों की जानकारी हासिल करेगी. अप्रैल 2024 से, विज्ञापन पाने वाले सर्वर को Trusted Execution Environment (TEE) में चलाना होगा. साथ ही, यह GRPC/proto इंटरफ़ेस को दिखाएगा. विज्ञापन टेक्नोलॉजी कंपनियों को यह सर्वर सेट अप करना होगा. साथ ही, B&A स्टैक डिप्लॉयमेंट के हिस्से के तौर पर इसका यूआरएल देना होगा. टीईई में चल रही इस सेवा को लागू करने की सुविधा, Privacy Sandbox के GitHub में उपलब्ध है. साथ ही, बाकी दस्तावेज़ों में हम यह मान रहे हैं कि डिप्लॉयमेंट में इसी कोड का इस्तेमाल किया गया है.
अप्रैल 2024 से, B&A वर्शन में कॉन्टेक्स्ट के हिसाब से पाथ विज्ञापन फिर से पाने की सुविधा काम करती है. इस मामले में, बिडिंग सर्वर को विज्ञापन आइडेंटिफ़ायर की एक सूची मिलेगी. इसे आरटीबी सर्वर ने नीलामी के कॉन्टेक्स्ट वाले हिस्से के दौरान भेजा था. इन आइडेंटिफ़ायर को TEE KV सर्वर पर भेजा जाएगा, ताकि विज्ञापन से जुड़ी सभी जानकारी को फ़ेच किया जा सके. इस जानकारी का इस्तेमाल बिडिंग के दौरान किया जाएगा. उदाहरण के लिए, विज्ञापन रेंडर करने का यूआरएल, मेटाडेटा, और विज्ञापन एम्बेड करने की सुविधा. इनका इस्तेमाल टॉप-के सिलेक्शन में किया जाएगा. इस दूसरे पाथ को डिप्लॉय करने के लिए, किसी खास लॉजिक की ज़रूरत नहीं होती. इसलिए, हम यहां सिर्फ़ यह बताएंगे कि टीईई पर आधारित विज्ञापन फिर से पाने के इस्तेमाल के उदाहरण को कैसे कॉन्फ़िगर किया जाए.
getCandidateAds यूडीएफ़
function getCandidateAds(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals, contextualAdIds,) {
    return adsMetadataString;
}
कहां:
requestMetadata: JSON. हर अनुरोध के लिए, यूडीएफ़ को सर्वर मेटाडेटा. फ़िलहाल, यह खाली है.preparedDataForAdRetrieval: इस फ़ील्ड का कॉन्टेंट, विज्ञापन पाने की रणनीति पर निर्भर करता है. संदर्भ के हिसाब से विज्ञापन पाने के मामले में , इस पैरामीटर में डिवाइस से मिलने वाले रॉ सिग्नल शामिल होंगे. साथ ही, इन्हें बिडिंग सेवा से पास किया जाएगा. विज्ञापन वापस पाने के सर्वर का इस्तेमाल करके टीईई विज्ञापन वापस पाने के मामले में, इस पैरामीटर मेंprepareDataForAdRetrievalयूडीएफ़ का नतीजा शामिल होगा. ध्यान दें: इस चरण में, सुरक्षित किए गए ऐप्लिकेशन के सिग्नल को डिकोड और अनएन्क्रिप्ट (सुरक्षित नहीं किया गया) किया जाएगा.deviceMetadata: JSON ऑब्जेक्ट में डिवाइस का मेटाडेटा होता है. इसे सेलर की विज्ञापन सेवा फ़ॉरवर्ड करती है. ज़्यादा जानकारी के लिए, B&A का दस्तावेज़ देखें.X-Accept-Language: डिवाइस पर इस्तेमाल की गई भाषा.X-User-Agent: डिवाइस पर इस्तेमाल किया गया उपयोगकर्ता एजेंट.X-BnA-Client-IP: डिवाइस का आईपी पता.
contextualSignals: यह स्ट्रिंग, कॉन्टेक्स्ट के हिसाब से बिडिंग करने वाले सर्वर से मिली है. इस सर्वर को एक ही डीएसपी मैनेज करता है. यूडीएफ़ को स्ट्रिंग को डिकोड करने और उसका इस्तेमाल करने में सक्षम होना चाहिए. सदर्भ के हिसाब से काम करने वाले सिग्नल में कोई भी जानकारी शामिल हो सकती है. जैसे, Protected App Signals का इस्तेमाल करके पास किए गए सुरक्षित एम्बेडिंग के लिए एमएल मॉडल के वर्शन की जानकारी.contextualAdIds: JSON ऑब्जेक्ट, जिसमें विज्ञापन आईडी की सूची शामिल होती है. हालांकि, यह सूची देना ज़रूरी नहीं है.
अगर UDF सही तरीके से काम करता है, तो उसे एक स्ट्रिंग दिखानी चाहिए. यह स्ट्रिंग, बिडिंग सर्वर को वापस भेज दी जाती है. इसके बाद, बिडिंग सर्वर इसे generateBid यूडीएफ़ को भेज देता है. हालांकि, स्ट्रिंग सिर्फ़ एक सामान्य स्ट्रिंग हो सकती है. हालांकि, ज़्यादातर मामलों में यह एक क्रमबद्ध ऑब्जेक्ट होना चाहिए. इसका स्कीमा, हर विज्ञापन टेक्नोलॉजी कंपनी खुद तय करती है.
स्कीमा पर कोई पाबंदी नहीं है. हालांकि, यह ज़रूरी है कि विज्ञापन टेक्नोलॉजी कंपनी का generateBid
लॉजिक, स्ट्रिंग को पहचान सके और उसका इस्तेमाल कर सके.
डेवलपमेंट के लिए सिस्टम सेट अप करना
Android
Android डेवलपमेंट एनवायरमेंट सेट अप करने के लिए, आपको ये काम करने होंगे:
- डेवलपर की झलक वाली 10 इमेज चलाने वाला कोई एम्युलेटर (सुझाया गया) या फ़िज़िकल डिवाइस बनाएं
 - यह कमांड चलाएं:
 
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity
इसके बाद, ऐप्लिकेशन के सुझावों के आधार पर दिखाए जाने वाले विज्ञापनों के लिए सहमति देने का विकल्प चुनें.
- ज़रूरी एपीआई चालू करने के लिए, यह कमांड चलाएं. आपको समय-समय पर इस कमांड को फिर से चलाना पड़ सकता है, क्योंकि बंद की गई सुविधा का डिफ़ॉल्ट कॉन्फ़िगरेशन समय-समय पर सिंक होता रहेगा.
 
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 सेवा स्टैक को डिप्लॉय करने से पहले, खरीदार की विज्ञापन टेक्नोलॉजी को यह काम करना होगा:
- पुष्टि करें कि उन्होंने विज्ञापन वापस पाने की अपनी टीईई सेवा को डिप्लॉय किया है. इसके लिए, ज़रूरी सेक्शन देखें.
 - पुष्टि करें कि विज्ञापन टेक्नोलॉजी के पास सभी ज़रूरी यूडीएफ़ (
prepareDataForAdRetrieval,generateBid,reportWin,getCandidateAds) तय किए गए हों और होस्ट किए गए हों. 
B&A के साथ Protected Audience की मदद से सुरक्षित नीलामी के काम करने के तरीके को समझना भी मददगार होगा, लेकिन यह ज़रूरी नहीं है.
Terraform कॉन्फ़िगरेशन
Protected App Signals का इस्तेमाल करने के लिए, विज्ञापन टेक्नोलॉजी कंपनियों को ये काम करने होंगे:
- B&A में, Protected App Signals की सुविधा चालू करें.
 - उन यूआरएल एंडपॉइंट के बारे में बताएं जिनसे 
prepareDataForAdRetrieval, generateBidऔरreportWinके लिए नए यूडीएफ़ फ़ेच किए जा सकते हैं. 
इसके अलावा, इस गाइड में यह माना गया है कि रीमार्केटिंग के लिए B&A का इस्तेमाल करने वाली विज्ञापन टेक्नोलॉजी कंपनियां, रीमार्केटिंग ऑक्शन के लिए सभी मौजूदा कॉन्फ़िगरेशन फ़्लैग को पहले की तरह सेट करती रहेंगी.
विज्ञापन टेक्नोलॉजी से जुड़ी सेवा देने वाली कंपनी के लिए खरीदार का कॉन्फ़िगरेशन
इस डेमो फ़ाइल को उदाहरण के तौर पर इस्तेमाल करके, खरीदारों को ये फ़्लैग सेट करने होंगे:
- Protected App Signals की सुविधा चालू करें: इस सुविधा को चालू करके, Protected App Signals का डेटा इकट्ठा किया जाता है.
 - Protected App Signals यूआरएल: इन्हें Protected App Signals सर्वर के यूआरएल पर सेट करें.
 
विज्ञापन टेक्नोलॉजी कंपनियों को इन फ़ील्ड के लिए, प्लेसहोल्डर में सही यूआरएल डालने होंगे:
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"
विज्ञापन टेक्नोलॉजी से जुड़ी सेवा देने वाली कंपनी का कॉन्फ़िगरेशन
इस डेमो फ़ाइल का इस्तेमाल करके, सेलर को यहां दिए गए फ़्लैग सेट करने होंगे. (ध्यान दें: यहां सिर्फ़ सुरक्षित ऐप्लिकेशन सिग्नल से जुड़ा कॉन्फ़िगरेशन हाइलाइट किया गया है). विज्ञापन टेक्नोलॉजी कंपनियों को यह पुष्टि करनी होगी कि उन्होंने प्लेसहोल्डर में सही यूआरएल डाले हैं:
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 सेवा के एक या दो इंस्टेंस डिप्लॉय करने की ज़रूरत होगी. हम टीईई के आधार पर विज्ञापन वापस पाने के लिए इस्तेमाल किए गए केवी इंस्टेंस को Ad Retrieval Server और कॉन्टेक्स्ट के हिसाब से पाथ के आधार पर विज्ञापन वापस पाने के लिए इस्तेमाल किए गए इंस्टेंस को KV Lookup Server के तौर पर दिखाएंगे.
दोनों ही मामलों में, सर्वर डिप्लॉयमेंट KV सर्वर GitHub में उपलब्ध दस्तावेज़ के मुताबिक होता है. दोनों मामलों में अंतर यह है कि लुकअप केस, बिना किसी अतिरिक्त कॉन्फ़िगरेशन के काम करता है. वहीं, फ़ेच करने वाले केस में, फ़ेच करने की लॉजिक को लागू करने के लिए, getCandidateAds यूडीएफ़ को डिप्लॉय करना ज़रूरी होता है. ज़्यादा जानकारी के लिए, KV सर्वर को शामिल करने की गाइड देखें. ध्यान दें कि B&A को उम्मीद है कि दोनों सेवाओं को बिडिंग सेवा की तरह ही सर्विस मेश में डिप्लॉय किया जाएगा.
सेटअप का उदाहरण
यहां दिए गए उदाहरण पर विचार करें: Protected App Signals API का इस्तेमाल करके, कोई विज्ञापन टेक्नोलॉजी कंपनी, ऐप्लिकेशन के इस्तेमाल के आधार पर काम के सिग्नल सेव करती है. हमारे उदाहरण में, ऐसे सिग्नल सेव किए जाते हैं जो कई ऐप्लिकेशन में की गई इन-ऐप्लिकेशन खरीदारी को दिखाते हैं. नीलामी के दौरान, एन्क्रिप्ट (सुरक्षित) किए गए सिग्नल इकट्ठा किए जाते हैं. इसके बाद, इन्हें B&A में चल रही Protected Audience API से जुड़ी नीलामी में पास किया जाता है. 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};
}
[खरीदार] 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;
}
[खरीदार] विज्ञापन के सैंपल पाने के लिए यूडीएफ़
हमारे उदाहरण में, विज्ञापन पाने वाला सर्वर, टॉप k विज्ञापन कैंडिडेट के लिए मेटाडेटा भेजता है.जैसे, इस उदाहरण में हर विज्ञापन के लिए आईडी. हालांकि, इसमें हर विज्ञापन के लिए अन्य डेटा भी शामिल हो सकता है, जो बाद में बिड जनरेट करने में मददगार हो सकता है.
function getCandidateAds(requestMetadata, protectedSignals, deviceMetadata,
                      contextualSignals,   contextualAdIds,) {
 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 यूडीएफ़, खरीदार को यह सूचना देता है कि उसने नीलामी जीत ली है.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                                       buyerReportingSignals, directFromSellerSignals,
                                       egressPayload,
                                       temporaryUnlimitedEgressPayload) {
  sendReportTo("https://buyer-controlled-domain.com/");
  registerAdBeacon({"clickEvent":"https://buyer-controlled-domain.com/clickEvent"});
  return;
}
[सेलर] केवी सर्वर सेटअप
सेलर को स्कोरिंग सिग्नल केवी सर्वर सेट अप करना होगा, ताकि विज्ञापन रेंडर करने वाले यूआरएल से स्कोरिंग सिग्नल तक मैपिंग उपलब्ध हो. उदाहरण के लिए: अगर खरीदार को 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 का इस्तेमाल करके एसएफ़ई से क्वेरी करने पर, सेलर को स्कोरिंग सिग्नल का यह उदाहरण मिल सकता है:
{
   "renderUrls" : {
      "https:/buyer-domain.com/get-fitness-app" : [
         "1",
         "2"
      ],
      "https:/buyer-domain.com/get-fastfood-app" : [
         "3",
         "4"
      ]
   }
}
[Seller] 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
  };
}
[Seller] reportResult का उदाहरण
function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
  let signalsForWinner = {};
    sendReportTo("https://seller-controlled-domain.com");
    registerAdBeacon({"clickEvent":
                    "https://seller-controlled-domain.com/clickEvent"});
    return signalsForWinner;
}
सैंपल ऐप्लिकेशन
इस फ़्लो का इस्तेमाल करने वाले ऐप्लिकेशन को बनाने के लिए, एपीआई का इस्तेमाल कैसे किया जा सकता है, इसका एक उदाहरण यहां दिया गया है. हमने Protected App Signals का एक सैंपल ऐप्लिकेशन बनाया है. यह इस सैंपल रिपॉज़िटरी में मिल सकता है.