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

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

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

يناير 2024

الإصدار الأول من دليل المطوّرين الذي يتوافق مع إصدار الحد الأدنى من المنتج القابل للتطبيق (MVP) من PAS

مارس 2024

تغييرات في واجهة برمجة التطبيقات لدعم إصدار Android API‏ M-2024-05 وإصدار مكونات الخادم في أبريل 2024 أبرز التغييرات:

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

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

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

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

عميل Android

من جهة العميل، تتألف مساحة Protected App Signals من ثلاث واجهات برمجة تطبيقات مختلفة:

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

Update Signals API

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

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

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

Executor executor = Executors.newCachedThreadPool();
ProtectedSignalsManager protectedSignalsManager
     =  ProtectedSignalsManager.get(context);

// Initialize a UpdateSignalsRequest
UpdateSignalsRequest updateSignalsRequest = new
  UpdateSignalsRequest.Builder(Uri.parse("https://example-adtech1.com/signals"))
      .build();

OutcomeReceiver<Object, Exception> outcomeReceiver = new OutcomeReceiver<Object, Exception>() {
  @Override
  public void onResult(Object o) {
    //Post-success actions
  }

  @Override
  public void onError(Exception error) {
    //Post-failure actions
  };

// Call updateSignals
protectedSignalsManager.updateSignals(updateSignalsRequest,
    executor,
    outcomeReceiver);

يرسل النظام الأساسي طلب https إلى معرّف الموارد المنتظم (URI) المقدَّم في الطلب لجلب آخر التعديلات على الإشارة. بالإضافة إلى تعديلات الإشارات، يمكن أن يتضمّن الرد نقطة نهاية تستضيف منطق الترميز لتحويل الإشارات الأولية إلى بيانات أساسية مرمّزة. من المتوقّع أن تكون تعديلات الإشارات بتنسيق JSON، ويمكن أن تتضمّن المفاتيح التالية:

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

المفتاح

الوصف

put

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

لأنّ هذا العنصر هو عنصر JSON تكون فيه المفاتيح عبارة عن سلاسل base 64 تتوافق مع المفتاح الذي سيتم إدخاله، والقيم عبارة عن سلاسل base 64 تتوافق مع القيمة التي سيتم إدخالها.

append

إضافة إشارة أو إشارات جديدة إلى سلسلة زمنية من الإشارات، وإزالة الأقدم

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

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

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

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

put_if_not_present

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

remove

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

update_encoder

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

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

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

واجهة برمجة التطبيقات لترميز الإشارات

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

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

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

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

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

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

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

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

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
إصدار منطق الترميز

عند تقديم طلب لتنزيل منطق برنامج الترميز المخصّص لتكنولوجيا الإعلان، يمكن لنقطة نهاية تكنولوجيا الإعلان الردّ برقم إصدار في عناوين الردّ. يتم الاحتفاظ بهذا الإصدار مع منطق الترميز على الجهاز. عند تشفير الإشارات الأولية، يتم الاحتفاظ بالحِمل المشفر مع الإصدار المستخدَم في التشفير. يتم أيضًا إرسال هذا الإصدار إلى خادم B&A أثناء &quot;المزاد المحمي&quot;، ما يتيح لتقنيات الإعلان مطابقة عروض الأسعار ومنطق الترميز استنادًا إلى الإصدار.

Response header for providing encoder version : X_ENCODER_VERSION

Protected Auction Support API

من جهة الجهاز، يكون إجراء مزاد لـ Protected App Signals مشابهًا لإجراء مزاد لشرائح جمهور محمية.

Bidding and Auction Services

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

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

Protected Auction API

تتألف Protected Auction API من واجهة برمجة تطبيقات JavaScript أو دوال محدّدة من قِبل المستخدمين يمكن للمشترين والبائعين استخدامها لتنفيذ منطق المزاد وعرض الأسعار.

حقول البيانات المحدّدة من المستخدِم لتقنية الإعلان الخاصة بالمشتري
دالة prepareDataForAdRetrieval المعرَّفة من قِبل المستخدم

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

// Inputs
// ------
// encodedOnDeviceSignals: A Uint8Array of bytes from the device.
// encodedOnDeviceSignalsVersion: An integer representing the encoded
//   version of the signals.
// sellerAuctionSignals: Information about auction (ad format, size) derived
//                       contextually.
// contextualSignals: Additional contextual signals that could help in
//                    generating bids.
//
// Outputs
// -------
// Returns a JSON structure to be used for retrieval.
// The structure of this object is left to the ad tech.
function prepareDataForAdRetrieval(encodedOnDeviceSignals,encodedOnDeviceSignalsVersion,sellerAuctionSignals,contextualSignals) {
   return {};
}
generateBid UDF

بعد عرض أفضل k إعلان مرشّح، يتم تمرير الإعلانات المرشّحة إلى منطق عروض الأسعار المخصّصة الخاص بالمشتري، generateBid 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 لإتاحة تدريب النموذج (لمزيد من التفاصيل حول الخروج وتدريب النموذج، يُرجى الرجوع إلى قسم التقارير في مستند شرح ميزة "الخصوصية المحسّنة").

reportWin UDF

عند انتهاء المزاد، ستنشئ خدمة المزاد عناوين URL لإعداد التقارير للمشترين وتسجّل إشارات باستخدام reportWin UDF (هذه هي الدالة نفسها reportWin المستخدَمة في Protected Audience). سيتم إرسال إشارة إلى هذا العنوان من الجهاز بعد أن يعرض العميل الإعلان. تتشابه توقيعات هذه الطريقة مع الإصدار من 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 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 الخاص بمبادرة حماية الخصوصية، وفي بقية المستندات، نفترض أنّ هذا هو الرمز المستخدَم في عملية النشر.

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

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

المكان:

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

يجب أن تعرض الدالة المعرَّفة من قِبل المستخدم سلسلة عند النجاح. يتم إرجاع السلسلة إلى خادم عروض الأسعار الذي يمرّرها بعد ذلك إلى دالة المستخدم المحدّدة (UDF) generateBid. على الرغم من أنّ السلسلة يمكن أن تكون سلسلة أساسية فقط، من المرجّح أن تكون كائنًا متسلسلاً يتم تحديد مخططه بواسطة كل تكنولوجيا إعلانية على حدة. لا توجد قيود على المخطط ما دام بإمكان منطق generateBid تكنولوجيا الإعلان التعرّف على السلسلة واستخدامها.

إعداد نظامك للتطوير

Android

لإعداد بيئة تطوير Android، عليك تنفيذ ما يلي:

  1. إنشاء محاكي (يُفضّل ذلك) أو جهاز فعلي يعمل بنسخة Developer Preview 10
  2. نفِّذ ما يلي:
adb shell am start -n com.google.android.adservices.api/com.android.adservices.ui.settings.activities.AdServicesSettingsMainActivity

بعد ذلك، حدِّد الخيار المعروض للموافقة على الإعلانات المقترَحة من التطبيق.

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

  • تأكَّد من أنّهم نشروا خدمة استرجاع الإعلانات في بيئة التنفيذ الموثوقة (راجع القسم ذي الصلة).
  • تأكَّد من أنّ تكنولوجيا الإعلان تتضمّن جميع وظائف المستخدم المحدّدة اللازمة (prepareDataForAdRetrieval وgenerateBid وreportWin وgetCandidateAds) المحدّدة والمستضافة.

سيكون من المفيد أيضًا فهم طريقة عمل &quot;المزاد المحمي&quot; مع Protected Audience مع B&A، ولكن هذا ليس إلزاميًا.

إعدادات Terraform

لاستخدام Protected App Signals، يجب أن تستوفي تكنولوجيات الإعلان الشروط التالية:

  • فعِّل ميزة "إشارات التطبيقات المحمية" في "إعلانات Google" و"إحصاءات 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 المستخدَم لاسترداد الإعلانات المستندة إلى TEE باسم Ad Retrieval Server، وإلى المثيل المستخدَم لاسترداد الإعلانات المستندة إلى المسار السياقي باسم KV Lookup Server.

في كلتا الحالتين، يتم نشر الخوادم وفقًا للمستندات المتاحة في مستودع GitHub لخادم KV، والفرق بين الحالتين هو أنّ حالة البحث تعمل بدون أي إعدادات إضافية، بينما تتطلّب حالة الاسترجاع نشر دالة getCandidateAds المعرَّفة من قِبل المستخدم لتنفيذ منطق الاسترجاع. لمزيد من التفاصيل، يمكنك الاطّلاع على دليل إعداد خادم KV. يُرجى العِلم أنّ فريق B&A يتوقّع نشر كلتا الخدمتَين في شبكة الخدمات نفسها التي يتم فيها نشر خدمة عروض الأسعار.

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

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

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

تضيف هذه السمة إشارة بمفتاح 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"
  }
}

مثال على [Buyer] 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\"}]"

مثال على [Buyers] generateBid

/**
 * This script receives the data returned by the ad retrieval service
 * in the `ads` argument. This argument is supposed to contain all
 * the Protected App Signals related ads and the metadata obtained from the retrieval
 * service.
 *
 * `preparedDataForAdRetrieval` argument contains the data returned
 * from the `prepareDataForAdRetrieval` UDF.
 *
 * This script is responsible for generating bids for the ads
 * collected from the retrieval service and ad techs can decide to
 * run a small inference model as part of this script in order to
 * decide the best bid given all the signals available to them.
 *
 * For the purpose of the demo, this sample script assumes
 * that ad retrieval service has sent us most relevant ads for the
 * user and this scripts decides on the ad render URL as well as
 * what value to bid for each ad based on the previously decoded
 * device signals. For simplicity sake, this script only considers
 * 2 types of app categories i.e. fitness and food.
 *
 * Note: Only one bid is returned among all the
 * input ad candidates.
 */
function generateBid(ads, sellerAuctionSignals, buyerSignals, preparedDataForAdRetrieval) {
  if (ads === null) {
    console.log("No ads obtained from the ad retrieval service")
    return {};
  }     
        
  const kFitnessAd = "0";
  const kFoodAd = "1";
  const kBuyerDomain = "https://buyer-domain.com";
        
  let resultingBid = 0;
  let resultingRender = kBuyerDomain + "/no-ad";
  for (let i = 0 ; i < ads.length; ++i) {
    let render = "";
    let bid = 0;
    switch (ads[i].adId) {
      case kFitnessAd:
        render = kBuyerDomain + "/get-fitness-app";
        bid = preparedDataForAdRetrieval[kFitnessAd];
        break;
      case kFoodAd:
        render = kBuyerDomain + "/get-fastfood-app";
        bid = preparedDataForAdRetrieval[kFoodAd];
        break;
      default:
        console.log("Unknown ad category");
        render = kBuyerDomain + "/no-ad";
        break;
    }
    console.log("Existing bid: " + resultingBid + ", incoming candidate bid: " + bid);
    if (bid > resultingBid) {
      resultingBid = bid;
      resultingRender = render;
    }
  }
  return {"render": resultingRender, "bid": resultingBid};
}

[المشترون] مثال على reportWin

reportWin يرسل UDF تقارير إلى المشتري تفيد بفوزه بالمزاد.

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

إعداد خادم [البائع] KV

على البائعين إعداد خادم قيم المفاتيح والإشارات الخاصة بالتقييم لكي تتوفّر عملية ربط من عناوين URL لعرض الإعلانات بالإشارات الخاصة بالتقييم المقابلة، على سبيل المثال: إذا كان المشتري سيعرض 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"
      ]
   }
}

[Seller] scoreAd example

/**
 * 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 يمكن العثور عليه في مستودع النماذج هذا.