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

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

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

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

الإصدار الأول من دليل المطوِّر الذي يدعم إصدار PAS MVP

آذار (مارس) 2024

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

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

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

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

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

برنامج Android

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

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

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

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

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

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

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

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

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

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

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

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

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

مفتاح

الوصف

put

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

بالنسبة إلى هذا الكائن JSON حيث تكون المفاتيح عبارة عن سلاسل من الأساس 64 المقابلة للمفتاح المطلوب وضعه والقيم هي سلسلة Base 64 المقابلة للقيمة المراد وضعها.

append

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

لإفساح المجال للإعلانات الجديدة إذا تجاوز حجم السلسلة الحد الأقصى المعين. قيمة هذه السمة هي كائن JSON حيث تكون المفاتيح عبارة عن سلاسل أساسية 64 تتوافق مع المفتاح المطلوب إلحاقه والقيم هي كائنات تحتوي على حقلين: "القيم" و"maxSignals".

"القيم": قائمة بسلاسل الأساس 64 المقابلة لقيم الإشارة المطلوب إلحاقها بالسلسلة الزمنية

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

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

put_if_not_present

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

remove

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

update_encoder

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

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

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

لنقطة النهاية.

سيظهر نموذج طلب JSON على النحو التالي:

{
    "put": {
        "AAAAAQ==": "AAAAZQ==",
        "AAAAAg==": "AAAAZg=="
    },
    "append": {
        "AAAAAw==": {
            "values": [
                "AAAAZw=="
            ],
            "max_signals": 3
        }
    },
    "put_if_not_present": {
        "AAAABA==": "AAAAaQ==",
        "AAAABQ==": "AAAAag=="
    },
    "update_encoder": {
        "action": "REGISTER",
        "endpoint": "https://adtech1.com/Protected App Signals_encode_script.js"
    }
}

سيكون للإشارات حصة على الجهاز تتراوح بين 10 و15 كيلوبايت. بمجرد بلوغ الحصة تم تجاوزه، سيستخلص PPAPI الإشارات باستخدام استراتيجية FIFO. عملية الإخلاء تجاوز الحصة قليلاً خلال فترات زمنية قصيرة في من أجل تقليل تكرار عمليات الإخلاء.

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

يُطلب من المشترين تقديم دالة Java Script لاستخدامها في ترميز إشارات مخزنة على الجهاز لإرسالها إلى الخادم أثناء المزاد: يمكن للمشترين تقديم هذا النص البرمجي عن طريق إضافة عنوان URL حيث يمكن تم استرجاعه من استخدام المفتاح "update_encoder". في أي من الردود على طلب واجهة برمجة التطبيقات UpdateSignal سيكون للنص البرمجي التوقيع التالي:

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 أقل من أو مساويًا لحجمها. سيتم إرسال هذه الصفيفة إلى الخادم خلال المزادات، ويتم إعدادها بواسطة نص برمجي واحد (prepareDataForAdRetrieval).

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

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

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

adb shell cmd jobscheduler run -f com.google.android.adservices.api 29
إنشاء نُسخ منطق برنامج الترميز

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

Response header for providing encoder version : X_ENCODER_VERSION

واجهة برمجة التطبيقات Protected Auction Support API

من جانب الجهاز، يُعد إجراء مزاد لإشارات التطبيقات المحمية نفسه إجراء مزاد للجماهير المحمية.

خدمات عروض الأسعار والمزادات

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

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

واجهة Protected Auction API

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

المعرّفات الفريدة لتكنولوجيا إعلانات المشترين
المعرّف الفريد العمومي في حزمة "تجهيز بيانات ForAdRetrieval"

قبل استخدام "إشارات التطبيقات المحمية" لاسترجاع الإعلانات المرشّحة من بيئة التنفيذ الموثوقة (TEE) خدمة استرداد الإعلانات، وعلى المشترين فك ترميز إشارات التطبيقات المحمية وإعدادها والبيانات الأخرى التي يقدّمها البائع ناتج UDF للمشترين هو 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 لتفعيل تدريب النموذج (للحصول على مزيد من التفاصيل حول الخروج وتدريب النموذج يُرجى الرجوع إلى قسم إعداد التقارير في شرح "خادم الإعلانات من Google")

أمر reportWin UDF

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

// Inputs / Outputs
// ----------------
// See detailed documentation here.
function reportWin(auctionSignals, perBuyerSignals, signalsForWinner,
                   buyerReportingSignals,
                   egressPayload, temporaryUnlimitedEgressPayload) {
  // ...
}
المعرّفات الفريدة لتكنولوجيا إعلانات البائعين
نتيجة الإعلان بدون جدل

يستخدم البائعون هذه المعرّف الفريد العمومي لتحديد الإعلانات التي يتلقّونها. من المشترين سيفوز بالمزاد.

function scoreAd(adMetadata, bid, auctionConfig,
                 trustedScoringSignals, bid_metadata) {
  // ...
  return {desirability: desirabilityScoreForThisAd,
              allowComponentAuction: true_or_false};
}
أمر UDF لنتيجة التقرير

تسمح هذه المؤسسة للبائع بتنفيذ مستوى الحدث (في النهاية). لإعداد التقارير وتقديم المعلومات المتعلقة بالإعلان الفائز.

function reportResult(auctionConfig, reporting_metadata) {
  // ...
  registerAdBeacon({"click", clickUrl,"view", viewUrl});
  sendReportTo(reportResultUrl);
  return signalsForWinner;
}

واجهة برمجة تطبيقات Ad Retrieval API

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

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

الاسم المعرِّف الفريد للطلب
function HandleRequest(requestMetadata, preparedDataForAdRetrieval,
                      deviceMetadata, contextualSignals) {
    return adsMetadataString;
}

المكان:

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

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

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

Android

لإعداد بيئة تطوير Android، عليك إجراء ما يلي:

  1. إنشاء محاكي (مفضّل) أو جهاز فعلي يشغّل نسخة معاينة المطوّر 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 الخاصة بها (راجع قسم ذي صلة).
  • تأكَّد من أنّ تكنولوجيا الإعلان تتضمّن جميع المعرّفات الفريدة (UDF) اللازمة. (prepareDataForAdRetrieval وgenerateBid وreportWin وHandleRequest) محددة واستضافتها.

فهم كيفية عمل "المزاد المحمي مع الجمهور المحمي" مع وتكون B&A مفيدة أيضًا ولكنها ليست إلزامية.

إعدادات Terraform

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

  • تفعيل دعم "إشارات التطبيقات المحمية" في B&A
  • قدِّم نقاط نهاية عنوان URL التي يمكن جلب المعرّفات الفريدة الجديدة لها prepareDataForAdRetrieval, generateBid وreportWin.

إضافةً إلى ذلك، يفترض هذا الدليل أن تقنيات الإعلان التي تريد استخدام B&A أن تجديد النشاط التسويقي سيستمر في تعيين جميع علامات التهيئة الحالية مزاد تجديد النشاط التسويقي كالمعتاد.

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

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

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

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

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

ننصحك باتّباع السيناريو التالي: استخدام واجهة برمجة التطبيقات Protected App Signals API، وهي تقنية متعلّقة بالإعلانات تخزِّن الإشارات ذات الصلة استنادًا إلى استخدام المستخدم للتطبيق. في مثالنا، الإشارات هي التي تمثل عمليات شراء داخل التطبيق من عدة تطبيقات. خلال المزاد، يتم جمع الإشارات المشفرة وتمريرها إلى مزاد محمي يعمل في B&A. تستخدم المعرّفات الفريدة للمشتري، التي يتم عرضها في 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 [المشتري]

ترميز كل إشارة إلى 2 بايت، يكون البايت الأول هو البايت الأول من مفتاح الإشارة والبايت الثاني هو البايت الأول من قيمة الإشارة.

function encodeSignals(signals, maxSize) {
  // if there are no signals don't write a payload
  if (signals.size === 0) {
      return {};
  }

  let result = new Uint8Array(signals.size * 2);
  let index = 0;
  
  for (const [key, values] of signals.entries()) {
    result[index++] = key[0];
    result[index++] = values[0].signal_value[0];
  }
  
  return { 'status': 0, 'results': result};
}

[مشتري] مثال على readyDataForAdRetrieval

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

[المشترون] معرّف فريد عالمي لاسترجاع الإعلانات

وفي المثال الذي ذكرناه، يرسل خادم استرجاع الإعلانات بيانات وصفية (أي رقم تعريف لكل إعلان في هذا المثال ولكن يمكن أن يحتوي على بيانات أخرى لكل منها والتي يمكن أن تكون مفيدة في إنشاء عروض أسعار في وقت لاحق) لكل من أفضل آلاف الإعلانات المرشحة.

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

[المشترون] مثال على إنشاء عرض السعر

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

[بائع] إعداد خادم 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"
      ]
   }
}

مثال على إعلان نقاط [البائع]

/**
 * This module generates a random desirability score for the Protected App
 * Signals ad in this example. In a production deployment,
 * however, the sellers would want to use all the available signals to generate
 * a score for the ad.
 */
function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function scoreAd(adMetadata, bid, auctionConfig,
                                   trustedScoringSignals, deviceSignals,
                                   directFromSellerSignals) {
  return {
    "desirability": getRandomInt(10000),
    "allowComponentAuction": false
  };
}

مثال على نتيجة تقرير [البائع]

function reportResult(auctionConfig, sellerReportingSignals, directFromSellerSignals){
  let signalsForWinner = {};
    sendReportTo("https://seller-controlled-domain.com");
    registerAdBeacon({"clickEvent":
                    "https://seller-controlled-domain.com/clickEvent"});
    return signalsForWinner;
}

نموذج تطبيق

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