واجهة برمجة تطبيقات محاكاة عرض الأسعار في الوقت الفعلي (TRTTLEDOVE)

كجزء من مبادرة حماية الخصوصية، اقترح Chrome TURTLEDOVE، وهو واجهة برمجة تطبيقات داخل المتصفّح تهدف إلى السماح للمعلنين وشركات تكنولوجيا الإعلانات بعرض إعلانات تستهدف الاهتمامات بدون الاعتماد على ملفات تعريف الارتباط التابعة لجهات خارجية، وبالتالي حماية المستخدمين من التتبّع عبر المواقع الإلكترونية. قبل تنفيذ Chrome لـ TURTLEDOVE، يقدم فريق عروض الأسعار في الوقت الفعلي (RTB) من Google محاكاة TURTLEDOVE لواجهة برمجة تطبيقات الخادم، والتي تسمح لشركاء "عرض الأسعار في الوقت الفعلي" (RTB) (الشراة المعتمَدون وشركاء "عرض الأسعار المفتوح") بتجربة واجهة برمجة التطبيقات. وتتيح هذه المحاكاة للشركاء وGoogle التعرُّف على فعالية التدفق على غرار نمط TOURTLEDOVE، وتقديم تعليقات ذات صلة حول التحسينات المحتملة لواجهة برمجة التطبيقات في المنتديات العامة، وتسهيل الانتقال إلى دعم الإعلانات المخصصة بدون الاعتماد على ملفات تعريف الارتباط للجهات الخارجية.

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

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

تدفق

مخطط انسيابي

  1. يعمل نظام عروض الأسعار في الوقت الفعلي (RTB) مع المعلنين لإنشاء مجموعات اهتمام والحفاظ عليها واستضافتها لكل معلن وعضو في مجموعات الاهتمامات هذه.
  2. وعند زيارة المستخدم لصفحة ويب للناشر، سيعمل متصفح المستخدم على تنزيل علامة إعلان Google. يطلب متصفّح المستخدم إعلانًا من منصّة ناشري Google.
  3. يقدم نظام عروض الأسعار في الوقت الفعلي (RTB) وظيفة واحدة أو أكثر من عروض الأسعار (مثل دوال جافا سكريبت) قبل الوقت إلى Google. (راجع القسم: وظائف عروض الأسعار).
  4. بالنسبة إلى الجزء الصغير من الطلبات في نطاق التجربة، ترسل Google طلبات عروض أسعار سياقية وطلبات عروض أسعار مستندة إلى الاهتمامات منفصلة لكل عرض سعر مشارك في التجربة (راجع القسم: طلبات عروض الأسعار).
  5. يستخدم نظام عروض الأسعار رقم تعريف المستخدم المستعار الذي يتوفّر في طلب عرض أسعار مجموعة الاهتمام ويربطه بمجموعات الاهتمامات المقابلة. سيعمل نظام عروض الأسعار في الوقت الفعلي (RTB) على عرض الردود على عروض الأسعار حسب المحتوى والردود على عروض الأسعار المستندة إلى الاهتمامات (راجع القسم: الردود على عروض الأسعار).
    1. ستكون استجابات عروض الأسعار السياقية مشابهة لاستجابة عروض الأسعار الحالية مع عرض أسعار صفري أو أكثر بالإضافة إلى ذلك، يمكن أن تتضمّن استجابة عروض الأسعار السياقية إشارات سياقية مخصّصة لنظام عروض الأسعار والتي سيتم تقديمها إلى وظيفة عروض الأسعار كإدخال.
    2. لن تحدد الردود على عروض الأسعار المستندة إلى الاهتمامات عرض أسعار ولكنها ستحدد اسم وظيفة عرض السعر. ستنفّذ Google وظيفة عروض الأسعار للحصول على عرض سعر.
  6. تُجري Google مزادًا من جانب الخادم مع المرشحين التاليين:

    1. عروض الأسعار من استجابة المحتوى.
    2. عروض الأسعار من استجابة مجموعة الاهتمام والتي تم حساب أسعار عروض الأسعار من خلال تشغيل وظائف عروض الأسعار.
    3. عروض الأسعار العادية من أنظمة عروض الأسعار الأخرى.

    لاحظ أن هذا هو مزاد اليوم نفسه.

  7. تعرض Google إعلانًا فائزًا في متصفح المستخدم، والذي يتم عرضه بشكل طبيعي.

وظائف عروض الأسعار

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

واجهة وظائف عروض الأسعار

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

يجب أن تقبل دالة عروض الأسعار كائنًا فارغًا وتعرضه على أنّه معامِل الإدخال، حيث يتم إدخال إدخال فارغ إلى دوال عروض الأسعار أثناء تهيئتها لمرة واحدة. في وقت الإعداد، يتم إنشاء لقطة لوظيفة عرض الأسعار واستدعاءها عدة مرات للسماح لأداة التجميع أثناء التشغيل (JIT) بتحسين النقاط الساخنة في الشفرة.

/**
 * Returns a bid price CPM for a given ad candidate.
 *
 * @param {Object} inputs an object with the
 *                 following named fields:
 *                   - openrtbContextualBidRequest or googleContextualBidRequest
 *                   - customContextualSignal
 *                   - interestBasedBidData
 */
function biddingFunction(inputs) {
  ...
  return inputs.interestBasedBidData.cpm
      * inputs.customContextualSignals.placementMultiplier;
}

تتضمن الحقول المُعنونة في وسيطة الكائن inputs (تخضع للتغيير أثناء تقدم التجربة):

openrtbContextualBidRequest (JS Object) طلب عرض أسعار المحتوى في بروتوكول OpenRTB. ويجب أن يتجاهل مقدّمو العروض الذين يستخدمون بروتوكول "عرض الأسعار في الوقت الفعلي (RTB)" للمشترين المعتمَدين هذا الإدخال، ويجب ألا يستخدموه في وظائف عروض الأسعار.
googleContextualBidRequest (JS Object) طلب عرض سعر السياق في بروتوكول "الشراة المعتمَدون من Google". ويجب أن تتجاهل أنظمة عروض الأسعار التي تستخدم بروتوكول OpenRTB هذا الإدخال، ويجب ألا تستخدمها في وظائف عروض الأسعار.
customContextualSignal (عنصر JavaScript) بيانات مخصّصة يقدّمها نظام عروض الأسعار في استجابة عرض السعر السياقي. يحدد نظام عروض الأسعار التنسيق.
interestBasedBidData (عنصر JavaScript) بيانات مخصّصة يقدّمها نظام عروض الأسعار في استجابة عرض السعر لمجموعة الاهتمامات. يحدد نظام عروض الأسعار التنسيق.

إدارة دوال عروض الأسعار من خلال واجهة برمجة تطبيقات

يسمح مورد واجهة برمجة التطبيقات التجريبي هذا لمقدمي عروض الأسعار بتحميل وظائف عروض الأسعار إلى Google وإدارة هذه الدوال.

نقطة نهاية الخدمة الأساسية: https://realtimebidding.googleapis.com

المورد: وظيفة عروض الأسعار

{
  "name": string,
  "biddingFunction": string
}

يمثّل الحقل name اسم دالة عروض الأسعار ويجب أن يتّبع التنسيق التالي: bidders/{bidderAccountId}/biddingFunctions/{biddingFunctionName}، حيث يتم اختيار biddingFunctionName بواسطة مقدّم عروض أسعار.

الحقل biddingFunction هو رمز مصدر JavaScript لدالة عروض الأسعار، مع استيفاء المتطلبات التالية:

  • الحجم أقل من 5 مبيبايت.
  • أن يستوفي متطلبات واجهة وظيفة عروض الأسعار.
  • يجب أن تتيح التنفيذ بدون أي إدخالات أثناء الإنشاء الأولي في وضع الحماية.

مثال:

{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;})"
}

إنشاء دالة عروض أسعار

ستتوفّر إحدى وظائف عروض الأسعار للاستخدام في استجابات مجموعات الاهتمامات في غضون ساعة تقريبًا بعد طلب البيانات من واجهة برمجة التطبيقات CreateBidFunction الناجحة.

POST https://realtimebidding.googleapis.com/v1alpha/{parent=bidders/*}/biddingFunctions
معلمات المسار
parent سلسلة بتنسيق bidders/{bidderAccountId}
Body: وظيفة عروض الأسعار المطلوب إنشاؤها
{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;})"
}
الاستجابة (وظيفة عروض الأسعار)
{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;};)"
}

سرد وظائف عروض الأسعار الحالية

GET https://realtimebidding.googleapis.com/v1alpha/bidders/{bidderAccountId}/biddingFunctions
معلمات المسار
parent سلسلة بتنسيق bidders/{bidderAccountId}.
معامِلات طلب البحث
pageToken رمز مميز للسلسلة يحدد صفحة النتائج التي يجب أن يعرضها الخادم. ويتم تلقّي هذه القيمة من استجابة مكالمة سابقة على ListBiddingFunctions إذا كانت النتائج لا تلائم صفحة واحدة.
الإجابة
{
  "biddingFunctions": [
    {
      object (BiddingFunction)
    }
  ],
  "nextPageToken": string
}
مثال على مكالمة
GET https://realtimebidding.googleapis.com/v1alpha/bidders/123456789/biddingFunctions

TURTLEDOVE محاكاة لتغييرات بروتوكول RTB للمحاكاة

بروتوكول RTB الخاص بالشراة المعتمَدين

طلبات عروض الأسعار

سيبدو طلب عرض السعر السياقي في التجربة مماثلاً لطلبات عروض الأسعار التقليدية ولكن مع تنقيح معرّفات المستخدمين غير محددة الهوية.

// All fields will be filled unless otherwise specified.
message BidRequest {
  // Fields below would not be populated in the experiment
  optional string google_user_id = ...;
  optional uint32 cookie_version = ...;
  optional int32 cookie_age_seconds = ...;
  optional bytes hosted_match_data = ...;
  optional string session_id = ...;

  // Contextual fields below will be populated
  optional string publisher_id = ...;
  optional string url = ...;
  ...
  message Mobile {
    // Device advertising identifiers below would not be populated
    // in the contextual requests in the experiment
    optional bytes encrypted_advertising_id = ...;
    optional bytes advertising_id = ...;
    ...
    optional bytes encrypted_hashed_idfa = ...;
    optional bytes hashed_idfa = ...;
    ...
  }
  ...
  message AdSlot {
    message MatchingAdData {
      repeated int64 billing_id = ...;
      ...
    }
    ...
  }
  repeated AdSlot adslot = ...;
  ...
}

مثلاً:

{
  id: "_\321\326\000\n\301\207\n\323\n\227",
  ip: "S\030\347",
  user_agent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
  publisher_country: "RU",
  geo_criteria_id: 9061060,
   adslot: [{
    id: 1,
    ad_block_key: 3613182520,
    width:   [240,200,120],
    height:   [400,200,240],
    matching_ad_data:   [{
      billing_id:     [923487589],
      minimum_cpm_micros: 850000
    }]
  }]
}

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

// Most fields would not be populated in the experiment unless otherwise specified.
message BidRequest {
   // Will be provided, subject to the existing privacy controls.
  optional string google_user_id = ...;
  optional uint32 cookie_version = ...;
  optional int32 cookie_age_seconds = ...;
  optional bytes hosted_match_data = ...;

  message AdSlot {
    // Will be filled.
    repeated int32 width = ...;
    repeated int32 height = ...;
    optional ConsentedProvidersSettings consented_providers_settings = ...;
    optional bool regs_gdpr = ...;
    optional bool regs_lgpd = ...;

    message MatchingAdData {
      // Will be filled.
      repeated int64 billing_id = ...;
      ...
    }
    ...
  }
  repeated AdSlot adslot = ...;
  ...
}

مثلاً:

id: "_\322\207\000\003\320\n\031\177C\307\215\035"
adslot {
  id: 1
  width: 1200
  height: 60
  consented_providers_settings {
    consented_providers: 292
    tcf_consent_string: "CO-eDrRO-eDrREkAAAAAAAAeYwf95y3p-wzhheMCY70-vv__7v3ff_3g"
  }
  regs_gdpr: true
  matching_ad_data {
    billing_id: 9833784997
  }
}
google_user_id: "ABCDEF1"
hosted_match_data: "ABCABCABC2"

الردود على عروض الأسعار

يمكن أن تحتوي استجابة عرض السعر على المحتوى على بيانات سياقية مخصّصة لعروض الأسعار بشكل عشوائي يتم تمريره إلى دالة عروض الأسعار لاحقًا.

message BidResponse {
  message Ad {
    message AdSlot {
      required int64 max_cpm_micros = ...;
      ...
    }
    repeated AdSlot adslot = ...;
    ...
  }
  repeated Ad ad = ...;
  // Contains contextual signals that will be passed to the bidding function.
  // This can be any JSON value. For example:
  // {"foo": "bar", "base": [1, 2, 3]}
  optional google.protobuf.Value custom_contextual_signal = ...;

  ...
}

على سبيل المثال:

ad {
  html_snippet: "<iframe src=\"http://example.com/something" width=\"300\" height=\"250\" scrolling=\"no\" frameBorder=\"0\" ></iframe>"
  adslot {
    id: 1
    max_cpm_micros: 100000
    billing_id: 1234567890
  }
  click_through_url: "https://www.example.com.pl"
  attribute: 47
  buyer_creative_id: "FFI399F3HI9HFH"
  width: 300
  height: 250
  impression_tracking_url: "http://example.com/impression"
}
custom_contextual_signal {
 struct_value {
   fields {
     name: "string_data_name"
     value {
       string_value: "string_value_1"
     }
   }
   fields {
     name: "bool_data_name"
     value {
       bool_value: true
     }
   }
 }
}
processing_time_ms: 1

عرض سعر يستند إلى مجموعة الاهتمامات

سيحتوي كل عرض سعر في استجابة عرض أسعار مجموعة الاهتمامات على مرجع لوظيفة عرض الأسعار حسب اسمه. سيتم تقديم عروض الأسعار مسبقًا من قِبل نظام عروض الأسعار.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
message BidResponse {
  // Ad HTML code that will be rendered normally upon winning.
  optional string html_snippet = ...;

  message Ad {
    message AdSlot {
      // Should not be populated for interest group-based bids.
      required int64 max_cpm_micros = ...;
      ...
    }
    repeated AdSlot adslot = ...;

    // Will be filled.
    // This is the bidding function name that references a bidding function
    // that is provided ahead of time through Bidding functions API resource.
    optional string bidding_function_name = ...;

    // Contains interest group-related data that will be passed
    // to the bidding function. This can be any JSON value.
    optional google.protobuf.Value interest_group_data = ...;
    ...
  }
  repeated Ad ad = ...;
  ...
}

مثلاً:

ad {
  html_snippet: "<iframe src=\"http://example.com/something" width=\"300\" height=\"250\" scrolling=\"no\" frameBorder=\"0\" ></iframe>"
  adslot {
    id: 1
    max_cpm_micros: 0
    billing_id: 1234567890
    bidding_function_name: "bidders/123/biddingFunctions/my_bidding_function_1"
    interest_group_data {
      struct_value {
        fields {
          name: "string_data_name"
          value {
            string_value: "string_value_1"
          }
        }
        fields {
          name: "bool_data_name"
          value {
            bool_value: true
          }
        }
      }
    }
  }
  click_through_url: "https://www.example.com.pl"
  attribute: 47
  buyer_creative_id: "FFI399F3HI9HFH"
  width: 300
  height: 250
  impression_tracking_url: "http://example.com/impression"
}
processing_time_ms: 1

OpenRTB

طلبات عروض الأسعار

طلب سياقي (بتنسيق JSON)
// All fields will be filled unless otherwise specified.
{
  // Fields below would not be populated in the experiment
  "user": {...}

  "device": {
    // Fields below would not be populated in the experiment
    "ifa": ...
    "dpidsha1": ...
    "dpidmd5": ...


    // Other fields will not be affected by the experiment
    ...
  }

  // Other fields will not be affected by the experiment
  ...
}
طلب يستند إلى الاهتمامات (بتنسيق JSON)
// Most fields would not be populated in the experiment unless otherwise specified.
{
  // Will be provided, subject to the existing privacy controls.
  "user": {
    "id": "BFEUKH3"
    "buyeruid": "FEI3F3I29"
    "ext": {
      "consented_providers": [ 292 ]
      "tcf_consent_string": "CO-eDrRO-eDrREkAAilsbO2dYGD9Pn8HT3ZCY70-vv__7v3ff_3g"
    }
  }

  "imp": {
    // Will be provided, subject to the existing privacy controls.
    "banner": {
      "w": ...
      "h": ...
    }

    "ext": {
      // Will be provided, subject to the existing privacy controls.
      "billing_id": [...]

      // Other fields will not be provided by the experiment
      ...
    }
  }
}

الردود على عروض الأسعار

يمكن أن تتضمن استجابة عرض سعر الإعلان على شبكة المحتوى بيانات سياقية مخصصة عن عروض الأسعار والتي سيتم تمريرها إلى دالة عروض الأسعار لاحقًا.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
{
  ...
  "seatbid": [{
     "bid": [...],
     ...
  }],
  ...
  "ext": {
    // Contains contextual signals that will be passed to the bidding function.
    // This signal can be any JSON blob. For example:
    // {"foo", "bar", "base": [1, 2, 3]}
    "custom_contextual_signal": ...
  }
}

رد على عرض أسعار يستند إلى مجموعة الاهتمامات

سيحتوي كل عرض سعر في استجابة عرض أسعار مجموعة الاهتمامات على مرجع لوظيفة عرض الأسعار حسب اسمه. سيتم تقديم عروض الأسعار مسبقًا من قِبل نظام عروض الأسعار.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
{
  "bid": [{
       "id": ...
       ...
       "ext": {
         // This is the bidding function name that references a bidding function
         // that is provided ahead of time through Bidding functions API resource.
         "bidding_function_name": ...

         // Contains interest group related data that will be passed to the
         // bidding function.
         // This signal can be any JSON blob. For example:
         // {"foo", "bar", "base": [1, 2, 3]}
         "interest_group_data": ...
       }
    }
    ...
  ]
}