دليل مطوّري "إشارات التطبيقات المحمية"

لمساعدة المطوّرين على بدء تجربة واجهة برمجة التطبيقات Protected App Signals API، يصف هذا المستند جميع واجهات برمجة التطبيقات ضمن واجهة برمجة التطبيقات، ويوضّح بالتفصيل كيفية إعداد بيئة اختبار، ويقدّم أمثلة على الإعدادات والملفّات النصية.

سجلّ التعديلات

كانون الثاني (يناير) 2024

الإصدار الأول من دليل المطوّر الذي يتيح استخدام الإصدار الأول من "شركاء المحتوى في خرائط Google"

آذار (مارس) 2024

تغييرات في واجهة برمجة التطبيقات لتتوافق مع إصدار M-2024-05 من واجهة برمجة تطبيقات Android وإصدار نيسان (أبريل) 2024 من المكوّنات على الجانب الخادم في ما يلي أهم التغييرات:

  • تمت إضافة تفاصيل عن الأذونات المطلوبة لواجهة برمجة التطبيقات على الجهاز
  • تمت إضافة تفاصيل حول إدارة حصة الإشارات على الجهاز
  • توقيع generateBid معدَّل يتضمّن تغييرات متعلّقة بدعم استرجاع الإعلانات المعروضة استنادًا إلى السياق ومغادرة النطاق
  • مستندات reportWin المعدَّلة التي تتضمّن دعمًا لإمكانية الخروج
  • تعديل مستندات Ad Retrieval API لإزالة إمكانية استرداد الإعلانات باستخدام BYOS وتوثيق دالة UDF لاسترداد الإعلانات

نظرة عامة على واجهة برمجة التطبيقات

تتضمّن مساحة عرض Protected Signals API مجموعات فرعية مختلفة من واجهة برمجة التطبيقات على أنظمة مختلفة:

  • واجهات برمجة تطبيقات Android:
    • واجهة برمجة التطبيقات Signal Curation API، وتتألف من:
    • Update Signals API
    • واجهة برمجة التطبيقات Signals Encoding API
    • Protected Auction Support API: لاستخدامها من قِبل حِزم تطوير البرامج (SDK) لتشغيل المزاد المحمي على خوادم عروض الأسعار والمزادات باستخدام إشارات التطبيقات المحمية.
  • واجهات برمجة التطبيقات من جهة الخادم:
    • Protected Auction API: سلسلة من النصوص البرمجية لـ JavaScript التي تعمل في خادمَي عروض الأسعار والميزادات تتيح واجهة برمجة التطبيقات هذه للبائعين والمشترين كتابة المنطق لتطبيق المزاد المحمي.
    • Ad Retrieval API: تتحمّل هذه الواجهة مسؤولية توفير قائمة بالإعلانات المرشحة استنادًا إلى معلومات السياق والمستخدِم التي تتوفّر لخادم عروض أسعار المشتري.

عميل Android

من جهة العميل، تتألف واجهة برمجة التطبيقات في "إشارات التطبيقات المحمية" من ثلاث واجهات برمجة تطبيقات مختلفة:

  • Update Signals: واجهة برمجة تطبيقات لنظام Android تتيح تنظيم الإشارات على الجهاز
  • ترميز الإشارات: واجهة برمجة تطبيقات JavaScript لإعداد الإشارات التي سيتم إرسالها إلى المعالج أثناء المزاد
  • واجهة برمجة تطبيقات لدعم تنفيذ مزاد محمي على خوادم عروض الأسعار والمزادات لا تقتصر واجهة برمجة التطبيقات هذه على إشارات التطبيقات المحمية، بل تُستخدَم أيضًا لدعم المزادات في Protected Audience API.

Update Signals API

توفّر Update Signals API لتكنولوجيات الإعلان إمكانية تسجيل الإشارات المتعلّقة بالمستخدِم والتطبيق بالنيابة عن أحد المشترين. تعمل واجهة برمجة التطبيقات وفقًا لنموذج التفويض. يقدّم المُرسِل معرّفًا لمورد منتظم (URI) يسترجع منه إطار العمل الإشارات المقابلة والطريقة لترميز هذه الإشارات لاستخدامها في المزاد.

تتطلّب واجهة برمجة التطبيقات إذن android.permission.ACCESS_ADSERVICES_PROTECTED_SIGNALS.

ستسترجع updateSignals() API ملفًا بتنسيق JSON من عنوان URL يصف الإشارات التي يجب إضافتها أو إزالتها، وكيفية إعداد هذه الإشارات للمزاد.

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) المقدَّم في الطلب من أجل جلب updates. بالإضافة إلى تعديلات الإشارات، يمكن أن يتضمّن الردّ نقطة نهاية تُستضيف منطق التشفير لتحويل الإشارات الأوّلية إلى حمولة مشفّرة. من المتوقّع أن تكون تعديلات الإشارات بتنسيق JSON ويمكن أن تحتوي على المفاتيح التالية:

يجب أن تتطابق مفاتيح المستوى الأعلى لكائن JSON مع أحد الأوامر الخمسة التالية:

مفتاح

الوصف

put

تُضيف إشارة جديدة، وتُلغي أي إشارات حالية باستخدام المفتاح نفسه. القيمة

هذا هو عنصر JSON حيث تكون المفاتيح سلاسل base64 تتوافق مع المفتاح الذي سيتم وضعه، والقيم هي سلسلة base64 تتوافق مع القيمة التي سيتم وضعها.

append

إلحاق إشارات جديدة بسلسلة زمنية من الإشارات، مع إزالة الإشارات الأقدم

إشارات لإخلاء مساحة للعناصر الجديدة إذا تجاوز حجم السلسلة الحد الأقصى المحدَّد القيمة لهذا العنصر هي عنصر JSON تكون فيه المفاتيح سلاسل قاعدة 64 تتوافق مع المفتاح الذي تريد إلحاقه، والقيم هي عناصر تتضمّن حقلين: "values" و "maxSignals".

"values": قائمة بسلاسل base64 تتوافق مع قيم الإشارات لإلحاقها بالسلسلة الزمنية

"maxSignals": الحد الأقصى لعدد القيم المسموح بها في هذه السلسلة الزمنية. إذا

إذا تجاوز العدد الحالي للإشارات المرتبطة بالمفتاح maxSignals، ستتم إزالة الإشارات الأقدم. يُرجى العِلم أنّه يمكنك إلحاق قيمة بمفتاح تمت إضافته باستخدام put. يُرجى العِلم أنّ إلحاق أكثر من الحد الأقصى لعدد القيم سيؤدي إلى تعذُّر إكمال العملية.

put_if_not_present

لا تُضيف إشارة جديدة إلا إذا لم تكن هناك إشارات حالية بالمفتاح نفسه. القيمة لهذه السمة هي عنصر JSON تكون فيه المفاتيح سلاسل بترميز Base64 تتوافق مع المفتاح المطلوب وضعه، والقيم هي سلاسل بترميز Base64 تتوافق مع القيمة المطلوب وضعها.

remove

إزالة إشارة مفتاح وتكون القيمة عبارة عن قائمة بسلاسل base 64 تتوافق مع مفاتيح الإشارات التي يجب حذفها.

update_encoder

يوفّر إجراءً لتعديل نقطة النهاية ومعرف موارد منتظم (URI) يمكن استخدامه.

لاسترداد منطق ترميز. المفتاح الفرعي لتقديم إجراء تعديل هو "action"

القيم المسموح بها حاليًا هي "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 الإشارات باستخدام استراتيجية "الوصول أولاً إلى أقدم العناصر". ستسمح عملية الإخلاء بتجاوز الحصة قليلاً لفترات زمنية قصيرة لخفض وتيرة عمليات الإخلاء.

واجهة برمجة التطبيقات Signals Encoding API

على المشترين تقديم دالة Java Script لاستخدامها في ترميز العلامات المخزّنة على الجهاز لإرسالها إلى الخادم أثناء "المزاد المحمي". يمكن للمشترين تقديم هذا النص البرمجي عن طريق إضافة عنوان URL الذي يمكن جلبه من خلاله باستخدام المفتاح "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 إلى قوائم عناصر "إشارات التطبيقات المحمية". يحتوي كلّ عنصر من عناصر "إشارات التطبيقات المحمية" على ثلاثة حقول:

  • signal_value: تمثل UInt8Array قيمة الإشارة.
  • creation_time: رقم يمثّل وقت إنشاء الإشارات بالثواني الكاملة
  • package_name: سلسلة تمثّل اسم الحزمة التي أنشأت الإشارة

المعلمة maxSize هي رقم يصف أكبر حجم مسموح به للصفيف للناتج.

من المفترض أن تُخرج الدالة عنصرًا يتضمّن حقلَين:

  • status: من المفترض أن يكون 0 إذا تم تنفيذ النص البرمجي بنجاح.
  • results: يجب أن يكون UInt8Array بطول أقل من أو يساوي maxSize. سيتم إرسال هذه الصفيف إلى الخادم أثناء المزادات، وسيتم إعدادها بواسطة نص برمجي prepareDataForAdRetrieval.

يقدّم الترميز لتكنولوجيات الإعلان مرحلة أولية من هندسة الميزات، حيث يمكنهم إجراء عمليات تحويل، مثل ضغط الإشارات الأولية إلى نُسخ متسلسلة استنادًا إلى منطقهم المخصّص. يُرجى العلم أنّه أثناء تنفيذ "المزاد المحمي" في بيئة التنفيذ الموثوق بها (TEE)، سيتم منح منطق تكنولوجيا الإعلان المخصّص إذن الوصول للقراءة إلى حِزم بيانات الإشارات التي يتم إنشاؤها من خلال عملية الترميز. إنّ المنطق المخصّص، المعروف باسم دالة محدّدة من المستخدِم (UDF)، الذي يتم تشغيله في وحدة TEE لعرض الإعلانات والإعلانات الديناميكية للمشتري، سيحصل على إذن بالقراءة للإشارات المشفّرة والإشارات السياقية الأخرى التي يوفّرها تطبيق الناشر لتنفيذ اختيار الإعلان (استرداد الإعلان و bidding).

ترميز الإشارات

كل ساعة، يتم ترميز إشارات المشترين الذين قدّموا منطق ترميز مع إشاراتهم المسجّلة في حمولة مزاد.ويتم الاحتفاظ بصفيف الوحدات المبرمَجة لحمولة المزاد على الجهاز، ويتم تشفيره وسيكون من قِبل البائعين كجزء من بيانات اختيار الإعلانات ليتم تضمينه كجزء من المزاد المحمي. لأغراض الاختبار، يمكنك بدء عملية الترميز هذه خارج إيقاعها الزمني كل ساعة من خلال تنفيذ الأمر التالي:

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

على مستوى الجهاز، يُعدّ إجراء مزاد للإشارات المحمية للتطبيقات هو إجراء مماثل لإجراء مزاد للجماهير المحمية.

Bidding and Auction Services

تشمل واجهات برمجة التطبيقات من جهة الخادم ما يلي:

  • Protected Auction API: سلسلة من دوالّ JavaScript أو دوالّ المستخدم المخصّصة التي يمكن للمشترين والبائعين نشرها على مكوّنات B&A التي يملكونها لتحديد عروض الأسعار ومنطق المزاد
  • Ad Retrieval API: يمكن للمشترين تنفيذ واجهة برمجة التطبيقات هذه من خلال تنفيذ نقطة نهاية REST ستكون مسؤولة عن توفير مجموعة من الإعلانات المرشّحة لمزاد "إشارات التطبيقات المحمية".

Protected Auction API

تتألّف Protected Auction API من JS API أو وظائف تحديد البيانات (UDF) التي يمكن للمشترين والبائعين استخدامها لتنفيذ منطق المزاد وعروض الأسعار.

متغيرات المستخدم النهائي في تكنولوجيا الإعلان الخاصة بالمشتري
دالة UDF prepareDataForAdRetrieval

قبل استخدام "إشارات التطبيقات المحمية" لجلب الإعلانات المُحتمَلة من خدمة "استرداد الإعلانات" في TEE، على المشترين فك ترميز "إشارات التطبيقات المحمية" وغيرها من البيانات المقدَّمة من البائع وإعدادها. يتم تمرير ناتج دالة المستخدم (UDF) الخاصة بالمشترين إلى خدمة استرداد الإعلانات من أجل استرداد أهم k إعلان مرشح لتقديم عروض الأسعار.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 {};
}
دالة 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 لتفعيل تدريب النموذج (لمزيد من التفاصيل حول الخروج وتدريب النموذج، يُرجى الرجوع إلى قسم إعداد التقارير في الشرح الموجز لـ PAS).

دالة reportWin UDF

عند انتهاء المزاد، ستنشئ خدمة المزاد عناوين URL لإعداد التقارير للمشترين وتُسجّل العلامات باستخدام reportWin UDF (وهي دالّة reportWin نفسها المستخدَمة مع شرائح الجمهور المحمية). سيرسل الجهاز طلبًا للاتصال بهذا العنوان بعد أن يعرض العميل الإعلان. يشبه توقيع هذه الطريقة الإصدار "الجمهور المحمي" تقريبًا باستثناء مَعلمتَين إضافيتَين egressPayload و temporaryUnlimitedEgressPayload اللتين تُستخدَمَان لتفعيل تدريب النموذج ويتم ملؤهما بالنتائج الواردة من generateBid.

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
متغيرات الإعلانات الديناميكية غير المحدّدة من البائعين في تكنولوجيا الإعلان
دالة UDF الخاصة بـ 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;
}

Ad Retrieval API

في إصدار المنتج القابل للاستخدام، ستكون خدمة استرداد الإعلانات مُدارة ومُستضافة من قِبل المشترِي، وستسترجع خدمة عروض الأسعار الإعلانات المُحتمَلة من هذه الخدمة. اعتبارًا من نيسان (أبريل) 2024، يجب تشغيل خادم استرداد الإعلانات في بيئة تنفيذ موثوق بها (TEE) وسيعرِض واجهة GRPC/proto. على شركات تكنولوجيا الإعلان إعداد هذا الخادم وتقديم عنوان URL الخاص به كجزء من عملية نشر منظومة B&A. يتوفّر في GitHub ضمن "مبادرة حماية الخصوصية" تطبيق لهذه الخدمة التي تعمل في TEE، ونفترض في بقية مستندات أنّ هذا هو الرمز البرمجي المستخدَم في عملية النشر.

اعتبارًا من نيسان (أبريل) 2024، تتيح إصدارات B&A استرجاع الإعلانات المتعلّقة بالمسار السياقي. في هذه الحالة، سيتلقّى خادم عروض الأسعار قائمة بعلامات الإعلانات التي أرسلها خادم عروض الأسعار أثناء الجزء السياقي من المزاد. سيتم إرسال المعرّفات إلى خادم TEE KV لجلب جميع المعلومات المتعلّقة بالإعلان والتي سيتم استخدامها أثناء مرحلة عرض الأسعار (على سبيل المثال، عنوان URL لعرض الإعلان والبيانات الوصفية وعمليات تضمين الإعلانات التي سيتم استخدامها في اختيار كبار المعلِنين). لا يحتاج هذا المسار الثاني إلى أي منطق محدّد لتنفيذه، لذا سنوثّق هنا فقط كيفية ضبط حالة استخدام استرداد الإعلانات المستندة إلى TEE.

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

المكان:

  • requestMetadata: تنسيق JSON البيانات الوصفية لكل طلب من خادم إلى دالة UDF لا تتوفّر حاليًا.
  • preparedDataForAdRetrieval: يعتمد محتوى هذا الحقل على استراتيجية retrieving strategy (استرداد الإعلانات). في حال استرجاع الإعلانات السياقية، ستحتوي هذه المَعلمة على الإشارات الأوّلية التي تأتي من الجهاز، ويتم تمريرها من خدمة عروض الأسعار. في حال استرداد إعلان TEE باستخدام خادم استرداد الإعلانات، ستحتوي هذه المَعلمة على نتيجة دالة prepareDataForAdRetrieval UDF. ملاحظة: في هذه المرحلة، سيتم فك ترميز إشارات التطبيقات المحمية وإزالة التشفير عنها.
  • deviceMetadata: عنصر JSON يحتوي على البيانات الوصفية للجهاز التي أعادت توجيهها "خدمة الإعلانات" الخاصة بالبائع. يُرجى الاطّلاع على مستندات B&A للحصول على مزيد من التفاصيل.
    • X-Accept-Language: اللغة المستخدَمة على الجهاز
    • X-User-Agent: وكيل المستخدم المستخدَم على الجهاز
    • X-BnA-Client-IP: عنوان IP للجهاز
  • contextualSignals: سلسلة عشوائية مصدرها خادم عروض الأسعار السياقية الذي تديره منصّة إدارة الأداء (DSP) نفسها. من المتوقّع أن يتمكّن دالة UDF من فك ترميز السلسلة واستخدامها. قد تحتوي "المؤشرات السياقية" على أي معلومات، مثل معلومات إصدار نموذج الذكاء الاصطناعي لعمليات التضمين المحمية التي تم تمريرها باستخدام "مؤشرات التطبيقات المحمية".
  • contextualAdIds: عنصر JSON يحتوي على قائمة اختيارية بأرقام تعريف الإعلانات

يجب أن تُرجع الدالة UDF سلسلة في حال نجاحها. يتمّ عرض السلسلة على خادم عروض الأسعار الذي يمرّرها بعد ذلك إلى دالة generateBid UDF. على الرغم من أنّ السلسلة يمكن أن تكون سلسلة بسيطة، من المرجّح أن تكون السلسلة عنصرًا متسلسلاً يحدّد مخطّطه كلّ تكنولوجيا إعلانية بمفردها. ما مِن قيود على المخطّط ما دام 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. شغِّل الأمر التالي لتفعيل واجهات برمجة التطبيقات ذات الصلة. قد تحتاج إلى إعادة تنفيذ هذا الإجراء من حين لآخر لأنّ الإعداد التلقائي للميزة "غير مفعَّلة" سيتم مزامنته دوريًا.
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

لاستخدام ميزة "إشارات التطبيقات المحمية"، يجب أن تستوفي تقنيات الإعلان الشروط التالية:

  • فعِّل ميزة "إشارات التطبيقات المحمية" في "الإعلانات على شبكة البحث" و"شبكة Google الإعلانية".
  • قدِّم نقاط نهاية عناوين URL التي يمكن من خلالها جلب الدوالّ التعريفية الجديدة لكلّ من prepareDataForAdRetrieval, generateBid وreportWin.

بالإضافة إلى ذلك، يفترض هذا الدليل أنّ تكنولوجيات الإعلان التي تريد استخدام ميزة "الحملات على شبكة البحث" لهدف إعادة التسويق ستستمر في ضبط جميع علامات الإعدادات الحالية لمزاد إعادة التسويق كالمعتاد.

إعداد تقنية الإعلان لدى المشتري

باستخدام هذا الملف التجريبي كمثال، على المشترين ضبط العلامات التالية:

  • تفعيل "إشارات التطبيقات المحمية": تم تفعيلها لجمع بيانات "إشارات التطبيقات المحمية".
  • عناوين URL لإشارات التطبيقات المحمية: اضبطها على عناوين 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"

إعدادات تقنية الإعلان الخاصة بالبائع

باستخدام ملف الإصدار التجريبي هذا كمثال، على البائعين ضبط العلامات التالية: (ملاحظة: يتم تمييز الإعدادات المتعلّقة بميزة "إشارات التطبيقات المحمية" فقط هنا). على تكنولوجيات الإعلان التأكّد من استبدال عناوين 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 UDF لتنفيذ منطق استرجاع المعلومات. لمزيد من التفاصيل، اطّلِع على دليل إعداد خادم KV. يُرجى العِلم أنّ فريق B&A يتوقّع أن يتم نشر كلتا الخدمتَين في شبكة الخدمات نفسها التي تتضمّن خدمة عروض الأسعار.

مثال على الإعداد

لنفترض السيناريو التالي: باستخدام Protected App Signals API، تخزِّن تكنولوجيا عرض الإعلانات الإشارات ذات الصلة استنادًا إلى استخدام المستخدم للتطبيق. في مثالنا، يتم تخزين إشارات تُمثّل عمليات شراء داخل التطبيقات من عدة تطبيقات. خلال أحد المزادات، يتم جمع الإشارات المشفّرة وتمريرها إلى مزاد محمي يجري في B&A. تستخدِم دوالّ المستخدِم الخاصة بالمشتري التي يتمّ تشغيلها في "حملات بحث Google" الإشارات لجلب إعلانات المرشحة واحتساب عرض سعر.

[المشتري] أمثلة على الإشارات

تضيف إشارة بمفتاح 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, 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 إعلان مُرشّح.

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 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>:

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

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

نموذج تطبيق

على سبيل المثال، لشرح كيفية استخدام واجهة برمجة التطبيقات لإنشاء تطبيق يستخدم مسارًا بسيطًا كما هو موضّح أعلاه، أنشأنا نموذج تطبيق "إشارات التطبيقات المحمية" الذي يمكن العثور عليه في هذا النموذج من المستودع.