คู่มือนักพัฒนาซอฟต์แวร์ Attribution Reporting API

ขณะที่คุณอ่าน Privacy Sandbox ใน Android ให้ใช้ปุ่มแสดงตัวอย่างสำหรับนักพัฒนาซอฟต์แวร์ หรือปุ่มเบต้าเพื่อเลือก เวอร์ชันของโปรแกรมที่คุณใช้งานอยู่ เนื่องจากวิธีการอาจแตกต่างกันไป


แสดงความคิดเห็น

Attribution Reporting API ได้รับการออกแบบมาเพื่อปรับปรุงความเป็นส่วนตัวของผู้ใช้โดย ลดการพึ่งพาตัวระบุผู้ใช้ข้ามฝ่ายต่างๆ และเพื่อรองรับ Use Case ที่สำคัญๆ สำหรับการระบุแหล่งที่มาและการวัด Conversion ในแอป คู่มือนักพัฒนาซอฟต์แวร์นี้ อธิบายวิธีกำหนดค่าและทดสอบ Attribution Reporting API เพื่อลงทะเบียน ยอดคลิกโฆษณา การดู และ Conversion โดยใช้วิธีการโทรที่บันทึกไว้ ทริกเกอร์และแหล่งที่มาของเหตุการณ์ดังกล่าว

คู่มือนี้จะสอนวิธีตั้งค่าปลายทางเซิร์ฟเวอร์และสร้างแอปไคลเอ็นต์ ที่โทรหาบริการเหล่านี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบโดยรวมของการระบุแหล่งที่มา Reporting API ในข้อเสนอการออกแบบ

คีย์เวิร์ด

  • แหล่งที่มาของการระบุแหล่งที่มาหมายถึงการคลิกหรือการดู
  • ทริกเกอร์คือเหตุการณ์ที่สามารถระบุแหล่งที่มาเป็น Conversion ได้
  • รายงานมีข้อมูลเกี่ยวกับทริกเกอร์และการระบุแหล่งที่มาที่เกี่ยวข้อง แหล่งที่มา รายงานเหล่านี้จะส่งเพื่อตอบสนองต่อเหตุการณ์ทริกเกอร์ Attribution Reporting API รองรับรายงานระดับเหตุการณ์ และ รายงานที่รวบรวมได้

ก่อนเริ่มต้น

หากต้องการใช้ Attribution Reporting API ให้กรอกข้อมูลฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ให้เสร็จสมบูรณ์ งานที่แสดงในส่วนต่อไปนี้

ตั้งค่าปลายทาง Attribution Reporting API

Attribution Reporting API ต้องการชุดปลายทางที่คุณเข้าถึงได้ จากอุปกรณ์ทดสอบหรือโปรแกรมจำลอง สร้างปลายทาง 1 รายการสำหรับแต่ละผลิตภัณฑ์ต่อไปนี้ งานฝั่งเซิร์ฟเวอร์

การตั้งค่าปลายทางที่จำเป็นมีหลายวิธี ได้แก่

  • วิธีที่รวดเร็วที่สุดในการเริ่มต้นใช้งานคือการติดตั้งใช้งาน คำจำกัดความของบริการ OpenAPI v3 จากโค้ดตัวอย่างของเรา ลงในแพลตฟอร์มจำลองหรือ Microservice คุณสามารถใช้ Postman, Prism หรือเซิร์ฟเวอร์จำลองอื่นๆ แพลตฟอร์มที่ยอมรับรูปแบบนี้ ทำให้ปลายทางแต่ละรายการใช้งานได้และติดตาม URI ที่จะใช้ในแอป หากต้องการยืนยันการส่งรายงาน โปรดไปที่การโทร กับแพลตฟอร์มจำลองหรือแบบ Serverless
  • เรียกใช้เซิร์ฟเวอร์สแตนด์อโลนของคุณเองโดยใช้การเปิดเครื่อง Spring Boot ตัวอย่างของ Kotlin ทำให้เซิร์ฟเวอร์นี้ใช้งานได้กับผู้ให้บริการคลาวด์หรือภายใน โครงสร้างพื้นฐาน
  • ใช้คำจำกัดความของบริการเป็นตัวอย่างเพื่อผสานรวมปลายทางเข้ากับ ระบบที่มีอยู่

ยอมรับการลงทะเบียนแหล่งที่มา

ปลายทางนี้ควรกำหนดที่อยู่ได้จาก URI ที่คล้ายกับตัวอย่างต่อไปนี้

https://adtech.example/attribution_source

เมื่อแอปไคลเอ็นต์ลงทะเบียนแหล่งที่มาของการระบุแหล่งที่มา แอปจะระบุ URI สำหรับ ปลายทางของเซิร์ฟเวอร์นี้ จากนั้น Attribution Reporting API จะส่งคำขอและ ประกอบด้วยส่วนหัวอย่างใดอย่างหนึ่งต่อไปนี้

  • สำหรับกิจกรรมการคลิก

    Attribution-Reporting-Source-Info: navigation
    
  • หากต้องการดูกิจกรรม ให้ทำดังนี้

    Attribution-Reporting-Source-Info: event
    

กําหนดค่าปลายทางเซิร์ฟเวอร์ให้ตอบสนองด้วยข้อมูลต่อไปนี้

// Metadata associated with attribution source.
Attribution-Reporting-Register-Source: {
  "destination": "[app package name]",
  "web_destination": "[eTLD+1]",
  "source_event_id": "[64 bit unsigned integer]",
  "expiry": "[64 bit signed integer]",
  "event_report_window": "[64-bit signed integer]",
  "aggregatable_report_window": "[64-bit signed integer]",
  "priority": "[64 bit signed integer]",
  "filter_data": {
    "[key name 1]": ["key1 value 1", "key1 value 2"],
    "[key name 2]": ["key2 value 1", "key2 value 2"],
    // Note: "source_type" key will be automatically generated as
    // one of {"navigation", "event"}.
  },
  // Attribution source metadata specifying histogram contributions in aggregate
  // report.
  "aggregation_keys": {
    "[key1 name]": "[key1 value]",
    "[key2 name]": "[key2 value]",
  },

    "debug_key": "[64-bit unsigned integer]",
    "debug_reporting": [boolean]
}
// Specify additional ad tech URLs to register this source with.
Attribution-Reporting-Redirect: <Ad Tech Partner URI 1>
Attribution-Reporting-Redirect: <Ad Tech Partner URI 2>

ตัวอย่างการเพิ่มค่าตัวอย่างมีดังนี้

Attribution-Reporting-Register-Source: {
  "destination": "android-app://com.example.advertiser",
  "source_event_id": "234",
  "expiry": "259200",
  "event_report_window": "172800",
  "aggregatable_report_window": "172800",
  "priority": "5",
  "filter_data": {
    "product_id": ["1234"]
  },
  "aggregation_keys": {
  // Generates a "0x159" key piece named (low order bits of the key) for the key
  // named "campaignCounts".
  // User saw an ad from campaign 345 (out of 511).
    "campaignCounts": "0x159",

  // Generates a "0x5" key piece (low order bits of the key) for the key named
  // "geoValue".
  // Source-side geo region = 5 (US), out of a possible ~100 regions.
    "geoValue": "0x5",
  },
  // Opts in to receiving verbose debug reports
  "debug_reporting": true
}

Attribution-Reporting-Redirect:
https://adtechpartner1.example?their_ad_click_id=567
Attribution-Reporting-Redirect:
https://adtechpartner2.example?their_ad_click_id=890

หาก Attribution-Reporting-Redirects มี URI ของพาร์ทเนอร์เทคโนโลยีโฆษณา จากนั้น Attribution Reporting API จะส่งคำขอที่คล้ายกันไปยัง URI แต่ละรายการ เทคโนโลยีโฆษณาแต่ละรายการ พาร์ทเนอร์ต้องกำหนดค่าเซิร์ฟเวอร์ที่ตอบสนองด้วยส่วนหัวเหล่านี้

Attribution-Reporting-Register-Source: {
  "destination": "[app package name]",
  "web_destination": "[eTLD+1]",
  "source_event_id": "[64 bit unsigned integer]",
  "expiry": "[64 bit signed integer]",
  "event_report_window": "[64-bit signed integer]",
  "aggregatable_report_window": "[64-bit signed integer]",
  "priority": "[64 bit signed integer]",
  "filter_data": {
    "[key name 1]": ["key1 value 1", "key1 value 2"],
    "[key name 2]": ["key2 value 1", "key2 value 2"],
    // Note: "source_type" key will be automatically generated as
    // one of {"navigation", "event"}.
  },
  "aggregation_keys": {
    "[key1 name]": "[key1 value]",
    "[key2 name]": "[key2 value]",
  }
}
// The Attribution-Reporting-Redirect header is ignored for ad tech partners.

ยอมรับการลงทะเบียนทริกเกอร์ Conversion

ปลายทางนี้ควรกำหนดที่อยู่ได้จาก URI ที่คล้ายกับตัวอย่างต่อไปนี้

https://adtech.example/attribution_trigger

เมื่อแอปไคลเอ็นต์ลงทะเบียนเหตุการณ์ทริกเกอร์ จะมีการระบุ URI ของเหตุการณ์นี้ ปลายทางของเซิร์ฟเวอร์ จากนั้น Attribution Reporting API จะส่งคำขอและรวม ส่วนหัวอย่างใดอย่างหนึ่งดังต่อไปนี้

กําหนดค่าปลายทางเซิร์ฟเวอร์ให้ตอบสนองด้วยข้อมูลต่อไปนี้

// Metadata associated with trigger.
Attribution-Reporting-Register-Trigger: {
  "event_trigger_data": [{
    // "trigger_data returned" in event reports is truncated to
    // the last 1 or 3 bits, based on conversion type.
    "trigger_data": "[unsigned 64-bit integer]",
    "priority": "[signed 64-bit integer]",
    "deduplication_key": "[signed 64-bit integer]",
    // "filter" and "not_filters" are optional fields which allow configuring
    // event trigger data based on source's filter_data. They consist of a
    // filter set, which is a list of filter maps. An event_trigger_data object
    // is ignored if none of the filter maps in the set match the source's
    // filter data.
    // Note: "source_type" can be used as a key in a filter map to filter based
    // on the source's "navigation" or "event" type. The first
    // Event-Trigger that matches (based on the filters/not_filters) will be
    // used for report generation. If none of the event-triggers match, no
    // event report will be generated.
    "filters": [{
      "[key name 1]": ["key1 value 1", "key1 value 2"],
      // If a key is missing from filters or source's filter_data, it won't be
      // used during matching.
      "[key name 2]": ["key2 value 1", "key2 value 2"],
    }],
    "not_filters":  [{
      "[key name 1]": ["key1 value 1", "key1 value 2"],
      // If a key is missing from not_filters or source's filter_data, it won't
      // be used during matching.
      "[key name 2]": ["key2 value 1", "key2 value 2"],
    }]
  }],
  // Specify a list of dictionaries that generates aggregation keys.
  "aggregatable_trigger_data": [
    // Each dictionary entry independently adds pieces to multiple source keys.
    {
      "key_piece": "[key piece value]",
      "source_keys": ["[key name the key piece value applies to]",
      ["list of IDs in source to match. Non-matching IDs are ignored"]]
      // filters/not_filters are optional fields similar to event trigger data
      // filter fields.
      "filters": [{
        "[key name 1]": ["key1 value 1", "key1 value 2"]
      }],
      "not_filters":  [{
          "[key name 1]": ["key1 value 1", "key1 value 2"],
          "[key name 2]": ["key2 value 1", "key2 value 2"],
      }]
    },
    ..
  ],
  // Specify an amount of an abstract value which can be integers in [1, 2^16]
  // to contribute to each key that is attached to aggregation keys in the
  // order they are generated.
  "aggregatable_values": [
     // Each source event can contribute a maximum of L1 = 2^16 to the
     // aggregate histogram.
    {
     "[key_name]": [value]
    },
    ..
  ],
  aggregatable_deduplication_keys: [{
  deduplication_key": [unsigned 64-bit integer],
    "filters": {
        "category": [filter_1, …, filter_H]
      },
    "not_filters": {
        "category": [filter_1, …, filter_J]
      }
  },
  ...
  {
  "deduplication_key": [unsigned 64-bit integer],
    "filters": {
        "category": [filter_1, …, filter_D]
      },
    "not_filters": {
        "category": [filter_1, …, filter_J]
      }
    }
  ]

  "debug_key": "[64-bit unsigned integer]",
  "debug_reporting": [boolean]

}
// Specify additional ad tech URLs to register this trigger with.
// Repeated Header field "Attribution-Reporting-Redirect"
Attribution-Reporting-Redirect: <Ad Tech Partner URI 1>
Attribution-Reporting-Redirect: <Ad Tech Partner URI 2>

ตัวอย่างการเพิ่มค่าตัวอย่างมีดังนี้

Attribution-Reporting-Register-Trigger: {
  "event_trigger_data": [{
    "trigger_data": "1122", // Returns 010 for CTCs and 0 for VTCs in reports.
    "priority": "3",
    "deduplication_key": "3344"
    "filters": [{ // Filter strings can not exceed 25 characters
      "product_id": ["1234"],
      "source_type": ["event"]
    }]
  },
  {
    "trigger_data": "4", // Returns 100 for CTCs and 0 for VTCs in reports.
    "priority": "3",
    "deduplication_key": "3344"
    "filters": [{ // Filter strings can not exceed 25 characters
      "product_id": ["1234"],
      "source_type": ["navigation"]
    }]
  }],
  "aggregatable_trigger_data": [
    // Each dictionary independently adds pieces to multiple source keys.
    {
      // Conversion type purchase = 2 at a 9-bit offset, i.e. 2 << 9.
      // A 9-bit offset is needed because there are 511 possible campaigns,
      // which takes up 9 bits in the resulting key.
      "key_piece": "0x400",// Conversion type purchase = 2
      // Apply this key piece to:
      "source_keys": ["campaignCounts"]
       // Filter strings can not exceed 25 characters
    },
    {
      // Purchase category shirts = 21 at a 7-bit offset, i.e. 21 << 7.
      // A 7-bit offset is needed because there are ~100 regions for the geo
      // key, which takes up 7 bits of space in the resulting key.
      "key_piece": "0xA80",
      // Apply this key piece to:
      "source_keys": ["geoValue", "nonMatchingIdsAreIgnored"]
      // source_key values must not exceed the limit of 25 characters
    }
  ],
  "aggregatable_values":
    {
      // Privacy budget for each key is L1 / 2 = 2^15 (32768).
      // Conversion count was 1.
      // Scale the count to use the full budget allocated: 1 * 32768 = 32768.
      "campaignCounts": 32768,

      // Purchase price was $52.
      // Purchase values for the app range from $1 to $1,024 (integers only).
      // Scaling factor applied is 32768 / 1024 = 32.
      // For $52 purchase, scale the value by 32 ($52 * 32 = $1,664).
      "geoValue": 1664
    }
  ,
  // aggregatable_deduplication_keys is an optional field. Up to 50 "keys"
  // can be included in the aggregatable_deduplication_keys list. Filters, not
  // filters, and deduplication_key are optional fields. If deduplication_key
  // is omitted, it will be treated as a null value. See
  // https://wicg.github.io/attribution-reporting-api/#triggering-aggregatable-attribution
  aggregatable_deduplication_keys:
  [
    {
    deduplication_key": 3,
        "filters": {
          "category": [A]
        }
    },
    {
    "deduplication_key": 4,
        "filters": {
          "category": [C, D]
        },
        "not_filters": {
          "category": [F]
        }
    }
  ]
  // Opts into receiving verbose debug reports
  "debug_reporting": true
}
Attribution-Reporting-Redirect:https://adtechpartner.example?app_install=567

ขีดจำกัดอยู่ที่ 25 ไบต์ต่อรหัสคีย์การรวมและสตริงตัวกรอง ช่วงเวลานี้ หมายความว่ารหัสคีย์การรวมและสตริงตัวกรองไม่ควรเกิน 25 รายการ อักขระ ในตัวอย่างนี้ campaignCounts คือ 14 อักขระ จึงเป็นอักขระที่ถูกต้อง รหัสคีย์การรวม และ 1234 คืออักขระ 4 ตัว จึงเป็นสตริงตัวกรองที่ถูกต้อง หากรหัสคีย์การรวมหรือสตริงตัวกรองยาวเกิน 25 อักขระ ทริกเกอร์จะ ถูกละเว้น

หาก Attribution-Reporting-Redirect มี URI ของพาร์ทเนอร์เทคโนโลยีโฆษณา จากนั้น Attribution Reporting API จะส่งคำขอที่คล้ายกันไปยัง URI แต่ละรายการ เทคโนโลยีโฆษณาแต่ละรายการ พาร์ทเนอร์ต้องกำหนดค่าเซิร์ฟเวอร์ที่ตอบสนองด้วยส่วนหัวเหล่านี้

// Metadata associated with trigger.
Attribution-Reporting-Register-Trigger: {
  "event_trigger_data": [{
    // "trigger_data" returned in event reports is truncated to
    // the last 1 or 3 bits, based on conversion type.
    "trigger_data": "[unsigned 64-bit integer]",
    "priority": "[signed 64-bit integer]",
    "deduplication_key": "[signed 64-bit integer]",
    // filter and not_filters are optional fields which allow configuring
    // different event trigger data based on source's filter_data. They
    // consist of a filter set, which is a list of filter maps. An
    // event_trigger_data object is ignored if none of the filter maps in the
    // set match the source's filter data. Note: "source_type" can be used as
    // a key in a filter map to filter based on the source's "navigation" or
    // "event" type. The first Event-Trigger that matches (based on the
    // filters/not_filters) will be used for report generation. If none of the
    // event-triggers match, no report will be generated.
    "filters": [{
      "[key name 1]": ["key1 value 1", "key1 value 2"],
      // If a key is missing from filters or source's filter_data, it will not be
      // used during matching.
      "[key name 2]": ["key2 value 1", "key2 value 2"],
    }],
    "not_filters":  [{
      "[key name 1]": ["key1 value 1", "key1 value 2"],
      // If a key is missing from not_filters or source's filter_data, it will not
      // be used during matching.
      "[key name 2]": ["key2 value 1", "key2 value 2"],
    }]
  }],
  "aggregatable_trigger_data": [
    // Each dictionary entry independently adds pieces to multiple source keys.
    {
      "key_piece": "[key piece value]",
      "source_keys": ["[key name the key piece value applies to]",
      ["list of IDs in source to match. Non-matching IDs are ignored"]],
      // filters/not_filters are optional fields similar to event trigger data
      // filter fields.
      "filters": [{
        "[key name 1]": ["key1 value 1", "key1 value 2"]
      }],
      "not_filters":  [{
          "[key name 1]": ["key1 value 1", "key1 value 2"],
          "[key name 2]": ["key2 value 1", "key2 value 2"],
      }]
    },
    ..
  ],
  // Specify an amount of an abstract value which can be integers in [1, 2^16] to
  // contribute to each key that is attached to aggregation keys in the order they
  // are generated.
  "aggregatable_values": [
    // Each source event can contribute a maximum of L1 = 2^16 to the aggregate
    // histogram.
    {
     "[key_name]": [value]
    }
  ]
}
// The Attribution-Reporting-Redirect header is ignored for ad tech partners.

ยอมรับรายงานระดับเหตุการณ์

ปลายทางนี้ควรกำหนดที่อยู่ได้จาก URI ดูหัวข้อลงทะเบียนใช้ความเป็นส่วนตัว บัญชีแซนด์บ็อกซ์สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการลงทะเบียน URI (URL คือ อนุมานได้จากต้นทางของเซิร์ฟเวอร์ที่ใช้สำหรับยอมรับการลงทะเบียนแหล่งที่มาและ กระตุ้นการลงทะเบียน) การใช้ URI ตัวอย่างสำหรับปลายทางที่ยอมรับแหล่งที่มา การลงทะเบียนและยอมรับการลงทะเบียนทริกเกอร์ URI ของปลายทางนี้คือ

https://adtech.example/.well-known/attribution-reporting/report-event-attribution

กำหนดค่าเซิร์ฟเวอร์นี้ให้ยอมรับคำขอ JSON ที่ใช้รูปแบบต่อไปนี้

{
  "attribution_destination": "android-app://com.advertiser.example",
  "source_event_id": "12345678",
  "trigger_data": "2",
  "report_id": "12324323",
  "source_type": "navigation",
  "randomized_trigger_rate": "0.02"
   [Optional] "source_debug_key": "[64-bit unsigned integer]",
   [Optional] "trigger_debug_key": "[64-bit unsigned integer]",
}

คีย์การแก้ไขข้อบกพร่องช่วยให้คุณได้รับข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับรายงานการระบุแหล่งที่มา ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า

ยอมรับรายงานที่รวบรวมได้

ปลายทางนี้ควรกำหนดที่อยู่ได้จาก URI ดูหัวข้อลงทะเบียนใช้ความเป็นส่วนตัว บัญชีแซนด์บ็อกซ์สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการลงทะเบียน URI (URL คือ อนุมานได้จากต้นทางของเซิร์ฟเวอร์ที่ใช้สำหรับยอมรับการลงทะเบียนแหล่งที่มาและ กระตุ้นการลงทะเบียน) การใช้ URI ตัวอย่างสำหรับปลายทางที่ยอมรับแหล่งที่มา การลงทะเบียนและยอมรับการลงทะเบียนทริกเกอร์ URI ของปลายทางนี้คือ

https://adtech.example/.well-known/attribution-reporting/report-aggregate-attribution

ระบบจะป้อนข้อมูลทั้งช่องที่เข้ารหัสและไม่เข้ารหัสเพื่อให้รวมข้อมูลได้ รายงาน รายงานที่เข้ารหัสจะช่วยให้คุณเริ่มต้นการทดสอบด้วยการรวม แต่ช่องที่ไม่เข้ารหัสจะให้ข้อมูลเชิงลึกเกี่ยวกับวิธีตั้งค่าคีย์-ค่า ก็คือการจัดโครงสร้างข้อมูล

กำหนดค่าเซิร์ฟเวอร์นี้ให้ยอมรับคำขอ JSON ที่ใช้รูปแบบต่อไปนี้

{
  // Info that the aggregation services also need encoded in JSON
  // for use with AEAD. Line breaks added for readability.
  "shared_info": "{
     \"api\":\"attribution-reporting\",
     \"attribution_destination\": \"android-app://com.advertiser.example.advertiser\",
     \"scheduled_report_time\":\"[timestamp in seconds]\",
     \"source_registration_time\": \"[timestamp in seconds]\",
     \"version\":\"[api version]\",
     \"report_id\":\"[UUID]\",
     \"reporting_origin\":\"https://reporter.example\" }",

  // In the current Developer Preview release, The "payload" and "key_id" fields
  // are not used because the platform does not yet encrypt aggregate reports.
  // Currently, the "debug_cleartext_payload" field holds unencrypted reports.
  "aggregation_service_payloads": [
    {
      "payload": "[base64 HPKE encrypted data readable only by the aggregation service]",
      "key_id": "[string identifying public key used to encrypt payload]",

      "debug_cleartext_payload": "[unencrypted payload]"
    },
  ],

  "source_debug_key": "[64 bit unsigned integer]",
  "trigger_debug_key": "[64 bit unsigned integer]"
}

คีย์การแก้ไขข้อบกพร่องช่วยให้คุณได้รับข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับรายงานการระบุแหล่งที่มา ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า

ตั้งค่าไคลเอ็นต์ Android

แอปไคลเอ็นต์จะลงทะเบียนแหล่งที่มาของการระบุแหล่งที่มาและทริกเกอร์ แล้วเปิดใช้ การสร้างรายงานระดับเหตุการณ์และที่รวบรวมได้ วิธีเตรียมไคลเอ็นต์ Android อุปกรณ์หรือโปรแกรมจำลองที่ใช้ Attribution Reporting API ได้ดังนี้

  1. ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์สำหรับ Privacy Sandbox ใน Android
  2. ติดตั้งอิมเมจระบบลงในอุปกรณ์ที่รองรับ หรือ ตั้งค่าโปรแกรมจําลองที่รองรับ Privacy Sandbox ใน Android
  3. เปิดใช้การเข้าถึง Attribution Reporting API โดยการเรียกใช้ฟังก์ชัน ด้วยคำสั่ง ADB (API จะถูกปิดใช้งานโดยค่าเริ่มต้น)

    adb shell device_config put adservices ppapi_app_allow_list \"\*\"
    
  4. หากคุณทดสอบ Attribution Reporting API ในระดับท้องถิ่น (เช่น การทดสอบเมื่อ อุปกรณ์ที่คุณมีสิทธิ์เข้าถึงทางกายภาพ) ให้เรียกใช้คำสั่งนี้เพื่อปิดใช้ การลงทะเบียน:

    adb shell device_config put adservices disable_measurement_enrollment_check "true"
    
  5. รวมสิทธิ์ ACCESS_ADSERVICES_ATTRIBUTION ใน Android ของคุณ ไฟล์ Manifest แล้วสร้างการกำหนดค่าบริการโฆษณาเพื่อให้แอปดำเนินการต่อไปนี้ได้ ใช้ Attribution Reporting API ดังนี้

    <uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION" />
    
  6. (ไม่บังคับ) หากคุณวางแผนที่จะรับรายงานการแก้ไขข้อบกพร่อง ให้ใส่ข้อมูลโค้ด สิทธิ์ ACCESS_ADSERVICES_AD_ID ในไฟล์ Android Manifest ของคุณ

    <uses-permission android:name="android.permission.ACCESS_ADSERVICES_AD_ID" />
    
  7. อ้างอิงการกำหนดค่าบริการโฆษณาในองค์ประกอบ <application> ของ ไฟล์ Manifest ของคุณ:

    <property android:name="android.adservices.AD_SERVICES_CONFIG"
              android:resource="@xml/ad_services_config" />
    
  8. ระบุทรัพยากร XML ของบริการโฆษณาที่อ้างอิงในไฟล์ Manifest เช่น res/xml/ad_services_config.xml ดูข้อมูลเพิ่มเติมเกี่ยวกับ สิทธิ์บริการโฆษณาและการควบคุมการเข้าถึง SDK

    <ad-services-config>
        <attribution allowAllToAccess="true" />
    </ad-services-config>
    

ลงทะเบียนเหตุการณ์โฆษณา

แอปควรบันทึกแหล่งที่มาและ Conversion ตามที่เกิดขึ้นเพื่อให้ ว่ามีการรายงานอย่างถูกต้อง วิธีการสำหรับฟีเจอร์ของชั้นเรียน MeasurementManager เพื่อช่วยในการลงทะเบียนเหตุการณ์แหล่งที่มาของการระบุแหล่งที่มา และ ทริกเกอร์ Conversion

ลงทะเบียนเหตุการณ์แหล่งที่มาของการระบุแหล่งที่มา

เมื่อมีการดูหรือคลิกโฆษณา แอปของผู้เผยแพร่โฆษณาจะเรียก registerSource() ไปยัง ลงทะเบียนแหล่งที่มาของการระบุแหล่งที่มาดังที่แสดงในข้อมูลโค้ด

Attribution Reporting API รองรับแหล่งที่มาของการระบุแหล่งที่มาประเภทต่อไปนี้ กิจกรรม:

  • การคลิก ซึ่งโดยทั่วไปคุณจะลงทะเบียนภายในเมธอด Callback ที่คล้ายกับ onClick() เหตุการณ์ทริกเกอร์ที่เกี่ยวข้องมักเกิดขึ้นไม่นานหลังจากเหตุการณ์ คลิกกิจกรรม เหตุการณ์ประเภทนี้ให้ข้อมูลเพิ่มเติมเกี่ยวกับผู้ใช้ การโต้ตอบ จึงเป็นแหล่งระบุแหล่งที่มาที่ดีในการให้ ที่มีลำดับความสำคัญสูง
  • การดู ซึ่งปกติคุณลงทะเบียนภายในเมธอด Callback คล้ายกับ onAdShown() เหตุการณ์ทริกเกอร์ที่เกี่ยวข้องอาจเกิดขึ้นหลายชั่วโมงหรือวัน หลังกิจกรรมการดู

Kotlin

companion object {
    private val CALLBACK_EXECUTOR = Executors.newCachedThreadPool()
}

val measurementManager = context.getSystemService(MeasurementManager::class.java)
var exampleClickEvent: InputEvent? = null

// Use the URI of the server-side endpoint that accepts attribution source
// registration.
val attributionSourceUri: Uri =
  Uri.parse("https://adtech.example/attribution_source?AD_TECH_PROVIDED_METADATA")

val future = CompletableFuture<Void>()

adView.setOnTouchListener(_: View?, event: MotionEvent?)) ->
    exampleClickEvent = event
    true
}

// Register Click Event
measurementManager.registerSource(
        attributionSourceUri,
        exampleClickEvent,
        CALLBACK_EXECUTOR,
        future::complete)

// Register View Event
measurementManager.registerSource(
        attributionSourceUri,
        null,
        CALLBACK_EXECUTOR,
        future::complete)

Java

private static final Executor CALLBACK_EXECUTOR = Executors.newCachedThreadPool();
private InputEvent exampleClickEvent;

MeasurementManager measurementManager =
        context.getSystemService(MeasurementManager.class);

// Use the URI of the server-side endpoint that accepts attribution source
// registration.
Uri attributionSourceUri =
Uri.parse("https://adtech.example/attribution_source?AD_TECH_PROVIDED_METADATA");

CompletableFuture<Void> future = new CompletableFuture<>();

adView.setOnTouchListener(v, event)) -> {
    exampleClickEvent = event;
    return true;
}

// Register Click Event
measurementManager.registerSource(attributionSourceUri, exampleClickEvent,
        CALLBACK_EXECUTOR, future::complete);

// Register View Event
measurementManager.registerSource(attributionSourceUri, null,
        CALLBACK_EXECUTOR, future::complete);

หลังจากลงทะเบียน API จะออกคำขอ HTTP POST ไปยังปลายทางบริการ ในที่อยู่ที่ระบุโดย attributionSourceUri ปลายทาง การตอบกลับมีค่าสำหรับ destination, source_event_id, expiry และ source_priority

หากเทคโนโลยีโฆษณาเริ่มต้นต้องการแชร์การลงทะเบียนแหล่งที่มา URI แหล่งที่มาของการระบุแหล่งที่มาจะรวมการเปลี่ยนเส้นทางไปยังปลายทางเทคโนโลยีโฆษณาอื่นๆ ได้ จำกัดสูงสุด และกฎที่เกี่ยวข้องกับการเปลี่ยนเส้นทางมีรายละเอียดใน ทางเทคนิค

เพิ่มการรองรับการเปลี่ยนเส้นทางสร้อยดอกเดซี่สำหรับ registerSource และ registerTrigger นอกจากส่วนหัวการลงทะเบียนแล้ว ผู้บริโภคที่ใช้ API ยังสามารถ ตอนนี้ให้เปลี่ยนเส้นทาง HTTP เป็นการตอบสนองของเซิร์ฟเวอร์ที่มีสถานะ 302 และ "ตำแหน่ง" ส่วนหัวที่มี URL ถัดไปสำหรับเข้าชม การลงทะเบียน

เฉพาะ "จุดหมาย" แรกที่ปรากฏในการเข้าชมครั้งแรก สร้อยดอกเดซี่ จำนวนการเข้าชมมีขีดจำกัดเท่ากับ "การระบุแหล่งที่มา-การรายงาน-เปลี่ยนเส้นทาง" ส่วนหัว การรองรับการเปลี่ยนเส้นทางนี้เป็นส่วนเสริม ไปเป็น "Attribution-Reporting-Redirect" ที่มีอยู่ การสนับสนุนหรือไม่ และหากทั้ง 2 บริการ แสดง "Attribution-Reporting-Redirect" การตั้งค่าเริ่มต้น

ลงทะเบียนเหตุการณ์ทริกเกอร์ Conversion

หากต้องการลงทะเบียนเหตุการณ์ทริกเกอร์ Conversion ให้เรียกใช้ registerTrigger() ในแอปของคุณ

Kotlin

companion object {
    private val CALLBACK_EXECUTOR = Executors.newCachedThreadPool()
}

val measurementManager = context.getSystemService(MeasurementManager::class.java)

// Use the URI of the server-side endpoint that accepts trigger registration.
val attributionTriggerUri: Uri =
    Uri.parse("https://adtech.example/trigger?AD_TECH_PROVIDED_METADATA")

val future = CompletableFuture<Void>()

// Register trigger (conversion)
measurementManager.registerTrigger(
        attributionTriggerUri,
        CALLBACK_EXECUTOR,
        future::complete)

Java

private static final Executor CALLBACK_EXECUTOR = Executors.newCachedThreadPool();

MeasurementManager measurementManager =
        context.getSystemService(MeasurementManager.class);

// Use the URI of the server-side endpoint that accepts trigger registration.
Uri attributionTriggerUri =
        Uri.parse("https://adtech.example/trigger?AD_TECH_PROVIDED_METADATA");

CompletableFuture<Void> future = new CompletableFuture<>();

// Register trigger (conversion)
measurementManager.registerTrigger(
        attributionTriggerUri,
        CALLBACK_EXECUTOR,
        future::complete)

หลังจากลงทะเบียน API จะออกคำขอ HTTP POST ไปยังปลายทางบริการ ในที่อยู่ที่ระบุโดย attributionTriggerUri การตอบกลับปลายทางจะรวมค่าสำหรับรายงานเหตุการณ์และรายงานสรุป

หากแพลตฟอร์มเทคโนโลยีโฆษณาต้นฉบับอนุญาตให้แชร์การลงทะเบียนทริกเกอร์ URI จะรวมการเปลี่ยนเส้นทางไปยัง URI ที่เป็นของแพลตฟอร์มเทคโนโลยีโฆษณาอื่นๆ ได้ ข้อจำกัดและกฎที่เกี่ยวข้องกับการเปลี่ยนเส้นทางมีรายละเอียดใน ทางเทคนิค

ลงทะเบียนการวัดข้ามแอปและเว็บ

ในกรณีที่ทั้งแอปและเบราว์เซอร์เกี่ยวข้องในองค์ประกอบ จากต้นฉบับไปยังทริกเกอร์ มีความแตกต่างเล็กน้อยใน การนำการลงทะเบียนเหตุการณ์โฆษณามาใช้ หากผู้ใช้เห็นโฆษณาในแอปและ เปลี่ยนเส้นทางไปยังเบราว์เซอร์สำหรับ Conversion แล้วแอปลงทะเบียนแหล่งที่มา และ Conversion ตามเว็บเบราว์เซอร์ ในทำนองเดียวกัน หากผู้ใช้เริ่มต้นบนเว็บ และไปยังแอปเพื่อทำ Conversion เบราว์เซอร์จะบันทึก และแอปจะบันทึก Conversion นั้น

เนื่องจากวิธีจัดระเบียบเทคโนโลยีโฆษณาบนเว็บและบน Android เราได้เพิ่ม API ใหม่เพื่อลงทะเบียนแหล่งที่มาและทริกเกอร์เมื่อ ในเบราว์เซอร์ ความแตกต่างสำคัญระหว่าง API เหล่านี้และ API ของแอปคือ เราคาดหวังว่าเบราว์เซอร์จะติดตามการเปลี่ยนเส้นทาง ใช้ ตัวกรองเฉพาะเบราว์เซอร์ และส่งการลงทะเบียนที่ถูกต้องไปยังแพลตฟอร์มโดย กำลังโทรหา registerWebSource() หรือ registerWebTrigger()

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างการเรียก API ที่เบราว์เซอร์ ลงทะเบียนแหล่งที่มาของการระบุแหล่งที่มาก่อนนำผู้ใช้ไปยังแอป

Kotlin

companion object {
    private val CALLBACK_EXECUTOR = Executors.newCachedThreadPool()
}

val measurementManager =
        context.getSystemService(MeasurementManager::class.java)
var exampleClickEvent: InputEvent? = null

// Use the URIs of the server-side endpoints that accept attribution source
// registration.
val sourceParam1 = WebSourceParams.Builder(Uri.parse(
        "https://adtech1.example/attribution_source?AD_TECH_PROVIDED_METADATA"))
// True, if debugging is allowed for the ad tech.
    .setDebugKeyAllowed(true)
    .build()

val sourceParam2 = WebSourceParams.Builder(Uri.parse(
        "https://adtech2.example/attribution_source?AD_TECH_PROVIDED_METADATA"))
    .setDebugKeyAllowed(false)
    .build()

val sourceParam3 = WebSourceParams.Builder(Uri.parse(
        "https://adtech3.example/attribution_source?AD_TECH_PROVIDED_METADATA"))
    .build()

val sourceParams = Arrays.asList(sourceParam1, sourceParam2, sourceParam3)
val publisherOrigin = Uri.parse("https://publisher.example")
val appDestination = Uri.parse("android-app://com.example.store")
val webDestination = Uri.parse("https://example.com")

val future = CompletableFuture<Void>()

adView.setOnTouchListener {_: View?, event: MotionEvent? ->
    exampleClickEvent = event
    true
}
val clickRegistrationRequest = WebSourceRegistrationRequest.Builder(
          sourceParams,
          publisherOrigin)
      .setAppDestination(appDestination)
      .setWebDestination(webDestination)
      .setInputEvent(event)
      .build()
val viewRegistrationRequest = WebSourceRegistrationRequest.Builder(
          sourceParams,
          publisherOrigin)
      .setAppDestination(appDestination)
      .setWebDestination(webDestination)
      .setInputEvent(null)
      .build()

// Register a web source for a click event.
measurementManager.registerWebSource(
        clickRegistrationRequest,
        CALLBACK_EXECUTOR,
        future::complete)

// Register a web source for a view event.
measurementManager.registerWebSource(
        viewRegistrationRequest,
        CALLBACK_EXECUTOR,
        future::complete)

Java

private static final Executor CALLBACK_EXECUTOR =
        Executors.newCachedThreadPool();
private InputEvent exampleClickEvent;

MeasurementManager measurementManager =
        context.getSystemService(MeasurementManager.class);

// Use the URIs of the server-side endpoints that accept attribution source
// registration.
WebSourceParams sourceParam1 = WebSourceParams.Builder(Uri.parse(
        "https://adtech1.example/attribution_source?AD_TECH_PROVIDED_METADATA"))
    // True, if debugging is allowed for the ad tech.
    .setDebugKeyAllowed(true)
    .build();

WebSourceParams sourceParam2 = WebSourceParams.Builder(Uri.parse(
        "https://adtech2.example/attribution_source?AD_TECH_PROVIDED_METADATA"))
    .setDebugKeyAllowed(false)
    .build();

WebSourceParams sourceParam3 = WebSourceParams.Builder(Uri.parse(
        "https://adtech3.example/attribution_source?AD_TECH_PROVIDED_METADATA"))
    .build();

List<WebSourceParams> sourceParams =
        Arrays.asList(sourceParam1, sourceParam2, sourceParam3);
Uri publisherOrigin = Uri.parse("https://publisher.example");
Uri appDestination = Uri.parse("android-app://com.example.store");
Uri webDestination = Uri.parse("https://example.com");

CompletableFuture<Void> future = new CompletableFuture<>();

adView.setOnTouchListener(v, event) -> {
    exampleClickEvent = event;
    return true;
}

WebSourceRegistrationRequest clickRegistrationRequest =
        new WebSourceRegistrationRequest.Builder(sourceParams, publisherOrigin)
    .setAppDestination(appDestination)
    .setWebDestination(webDestination)
    .setInputEvent(event)
    .build();
WebSourceRegistrationRequest viewRegistrationRequest =
        new WebSourceRegistrationRequest.Builder(sourceParams, publisherOrigin)
    .setAppDestination(appDestination)
    .setWebDestination(webDestination)
    .setInputEvent(null)
    .build();

// Register a web source for a click event.
measurementManager.registerWebSource(clickRegistrationRequest,
        CALLBACK_EXECUTOR, future::complete);

// Register a web source for a view event.
measurementManager.registerWebSource(viewRegistrationRequest,
        CALLBACK_EXECUTOR, future::complete);

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างการเรียก API ที่เบราว์เซอร์ บันทึก Conversion หลังจากระบบนําผู้ใช้จากแอป

Kotlin

companion object {
    private val CALLBACK_EXECUTOR = Executors.newCachedThreadPool()
}

val measurementManager = context.getSystemService(MeasurementManager::class.java)

// Use the URIs of the server-side endpoints that accept trigger registration.
val triggerParam1 = WebTriggerParams.Builder(Uri.parse(
        "https://adtech1.example/trigger?AD_TECH_PROVIDED_METADATA"))
    // True, if debugging is allowed for the ad tech.
    .setDebugKeyAllowed(true)
    .build()

val triggerParam2 = WebTriggerParams.Builder(Uri.parse(
        "https://adtech2.example/trigger?AD_TECH_PROVIDED_METADATA"))
    .setDebugKeyAllowed(false)
    .build()

val triggerParams = Arrays.asList(triggerParam1, triggerParam2)
val advertiserOrigin = Uri.parse("https://advertiser.example")

val future = CompletableFuture<Void>()

val triggerRegistrationRequest = WebTriggerRegistrationRequest.Builder(
        triggerParams,
        advertiserOrigin)
    .build()

// Register the web trigger (conversion).
measurementManager.registerWebTrigger(
    triggerRegistrationRequest,
    CALLBACK_EXECUTOR,
    future::complete)

Java

private static final Executor CALLBACK_EXECUTOR =
        Executors.newCachedThreadPool();

MeasurementManager measurementManager =
        context.getSystemService(MeasurementManager.class);

// Use the URIs of the server-side endpoints that accept trigger registration.
WebTriggerParams triggerParam1 = WebTriggerParams.Builder(Uri.parse(
        "https://adtech1.example/trigger?AD_TECH_PROVIDED_METADATA"))
    // True, if debugging is allowed for the ad tech.
    .setDebugKeyAllowed(true)
    .build();

WebTriggerParams triggerParam2 = WebTriggerParams.Builder(Uri.parse(
        "https://adtech2.example/trigger?AD_TECH_PROVIDED_METADATA"))
    .setDebugKeyAllowed(false)
    .build();

List<WebTriggerParams> triggerParams =
        Arrays.asList(triggerParam1, triggerParam2);
Uri advertiserOrigin = Uri.parse("https://advertiser.example");

CompletableFuture<Void> future = new CompletableFuture<>();

WebTriggerRegistrationRequest triggerRegistrationRequest =
        new WebTriggerRegistrationRequest.Builder(
            triggerParams, advertiserOrigin)
    .build();

// Register the web trigger (conversion).
measurementManager.registerWebTrigger( triggerRegistrationRequest,
        CALLBACK_EXECUTOR, future::complete);

การเพิ่มเสียงรบกวนเพื่อความเป็นส่วนตัว

รายงานระดับเหตุการณ์มีปลายทาง รหัสแหล่งที่มาของการระบุแหล่งที่มา และทริกเกอร์ โดยจะส่งให้การรายงานในรูปแบบที่ถูกต้อง (ไม่ได้เข้ารหัส) อาจมีการเพิ่มเสียงรบกวนเพื่อให้ใช้งานยากขึ้นเพื่อปกป้องความเป็นส่วนตัวของผู้ใช้ เพื่อระบุผู้ใช้แต่ละราย ระบบจะสร้างรายงานระดับเหตุการณ์ที่มีการแจ้งเตือนและ ส่งตามเฟรมเวิร์ก Differential Privacy ค่าเหล่านี้คือเปอร์เซ็นต์สัญญาณรบกวนเริ่มต้นสำหรับสถานการณ์ต่างๆ

ประเภทแหล่งที่มา

ค่าปลายทางต้นทาง

ความน่าจะเป็นของรายงานแบบไม่ใส่ข้อมูลต่อการลงทะเบียนแหล่งที่มา

ดู

แอปหรือเว็บ

0.0000025

ดู

แอปและเว็บ

0.0000042

คลิก

แอปหรือเว็บ

0.0024263

คลิก

แอปและเว็บ

0.0170218

ในการวัดผลการระบุแหล่งที่มาจากแอปไปยังเว็บ ซึ่งแหล่งที่มาสามารถเพิ่ม Conversion ได้ ทั้งปลายทางแอปและเว็บ รายงานระดับเหตุการณ์สามารถระบุได้ว่า เกิดขึ้นในแอปหรือเว็บ เพื่อเป็นการชดเชยรายละเอียดเพิ่มเติมนี้ รายงานที่มีเสียงที่น่าสงสัยที่สร้างขึ้นจะมีการคลิกสูงสุดประมาณ 7 เท่า และจำนวนการดูประมาณ 1.7 เท่า

เทคโนโลยีโฆษณาบางอย่างไม่จำเป็นต้องใช้รายงานระดับเหตุการณ์เพื่อระบุว่าทริกเกอร์ เกิดขึ้นบนแอปหรือเว็บ เทคโนโลยีโฆษณาสามารถใช้ coarse_event_report_destinations ใต้ Attribution-Reporting-Register-Source เพื่อลดเสียงรบกวน หากแหล่งที่มาที่มี ฟิลด์ coarse_event_report_destinations ที่ระบุจะชนะการระบุแหล่งที่มา รายงานที่ได้จะรวมทั้งปลายทางแอปและเว็บโดยไม่มีความแตกต่างดังนี้ ไปยังตำแหน่งที่ทริกเกอร์จริงเกิดขึ้น

ในตัวอย่างต่อไปนี้ ผู้ใช้คลิกโฆษณาและแหล่งที่มาดังกล่าวได้รับการลงทะเบียน ด้วย API จากนั้นผู้ใช้ทำ Conversion ทั้งในแอปของผู้ลงโฆษณาและ เว็บไซต์ของผู้ลงโฆษณา ระบบบันทึก Conversion ทั้ง 2 รายการนี้เป็นทริกเกอร์และ ที่มาจากคลิกแรก

ส่วนหัว HTTP ของการลงทะเบียนแหล่งที่มาที่อิงการคลิก:

Attribution-Reporting-Register-Source: {
    "destination": "android-app://com.advertiser.example",
    "web_destination": "https://advertiser.com",
    "source_event_id": "234",
    "expiry": "60000",
    "priority": "5",
    // Ad tech opts out of receiving app-web destination distinction
    // in event report, avoids additional noise
    "coarse_event_report_destinations": "true"
}

มีการลงทะเบียนทริกเกอร์จากแอปด้วยชื่อแพ็กเกจ com.advertiser.example:

Attribution-Reporting-Register-Trigger: {
    "event_trigger_data": [{
    "trigger_data": "1",
    "priority": "1"
    }],
}

ทริกเกอร์ได้รับการลงทะเบียนจากเบราว์เซอร์จากเว็บไซต์ที่มีโดเมน eTLD+1 https://advertiser.com:

Attribution-Reporting-Register-Trigger: {
    "event_trigger_data": [{
    "trigger_data": "2",
    "priority": "2"
    }],
}

ระบบจะสร้างรายงานระดับเหตุการณ์ที่เป็นผลลัพธ์ สมมติว่าทริกเกอร์ทั้ง 2 ตัว ระบบจะสร้างรายงานระดับเหตุการณ์ต่อไปนี้ซึ่งมาจากแหล่งที่มา

  {
    "attribution_destination": ["android-app://com.advertiser.example,https://advertiser.com"],
    "scheduled_report_time": "800176400",
    "source_event_id": "53234",
    "trigger_data": "1",
    // Can be "event" if source were registered by user viewing the ad
    "source_type": "navigation",
    // Would be 0.0170218 without coarse_event_report_destinations as true in the source
    "randomized_trigger_rate": 0.0024263
  }

สร้างและส่งรายงาน

Attribution Reporting API จะส่งรายงานไปยังปลายทางในเซิร์ฟเวอร์ซึ่ง ยอมรับรายงานระดับเหตุการณ์และรายงานที่รวบรวมได้

บังคับเรียกใช้งานการรายงาน

หลังจากที่คุณลงทะเบียนเหตุการณ์แหล่งที่มาของการระบุแหล่งที่มาหรือลงทะเบียนเหตุการณ์ทริกเกอร์ ระบบจะกำหนดเวลาให้งานการรายงานทำงาน งานนี้จะเรียกใช้ทุก 4 โดยค่าเริ่มต้น ชั่วโมง สำหรับการทดสอบ คุณสามารถบังคับให้งานการรายงานทำงานหรือย่อให้สั้นลงได้ ช่วงเวลาระหว่างงาน

บังคับให้งานการระบุแหล่งที่มาทำงาน:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 5

บังคับให้งานการรายงานระดับเหตุการณ์ทํางาน

adb shell cmd jobscheduler run -f com.google.android.adservices.api 3

บังคับให้งานการรายงานที่รวมได้ทำงาน

adb shell cmd jobscheduler run -f com.google.android.adservices.api 7

ตรวจสอบเอาต์พุตใน Logcat เพื่อดูว่างานทำงานแล้วเมื่อใด ควรมีรูปแบบ ดังตัวอย่างต่อไปนี้

JobScheduler: executeRunCommand(): com.google.android.adservices.api/0 5 s=false f=true

บังคับการส่งรายงาน

แม้ว่าระบบจะบังคับให้งานการรายงานทำงาน แต่ระบบยังคงส่งรายงาน ตามเวลานำส่งที่กำหนดไว้ ซึ่งมีตั้งแต่ 2-3 หลายชั่วโมงจนถึงหลายวัน หากต้องการทดสอบ คุณสามารถทำให้ระบบของอุปกรณ์ก้าวหน้าขึ้นได้ ก่อนการเริ่มส่งรายงานล่าช้าตามกำหนด

ยืนยันรายงานในเซิร์ฟเวอร์

เมื่อส่งรายงานแล้ว ให้ยืนยันการส่งโดยตรวจสอบรายงานที่ได้รับ ที่เกี่ยวข้อง บันทึกของเซิร์ฟเวอร์ เช่น ประวัติเซิร์ฟเวอร์จำลองหรือระบบที่กำหนดเองของคุณ

ถอดรหัสรายงานสรุป

เมื่อได้รับรายงานสรุป ช่อง debug_cleartext_payload การคงไว้ชั่วคราว รายงานสรุปรวมฉบับที่ไม่ได้เข้ารหัส ขณะที่เวอร์ชันนี้ ไม่ได้เข้ารหัส ก็ยังคงต้องถอดรหัส

ด้านล่างเป็นตัวอย่างการถอดรหัสเนื้อหาของ debug_cleartext_payload มี 2 ขั้นตอน ได้แก่ ครั้งแรกใช้การถอดรหัส Base 64 และขั้นตอนที่ 2 ใช้ CBOR การถอดรหัส

String base64DebugPayload  = "omRkYXRhgqJldmFsdWVEAAAGgGZidWNrZXRQAAAAAAAAAAAAAAAAAAAKhaJldmFsdWVEAACAAGZidWNrZXRQAAAAAAAAAAAAAAAAAAAFWWlvcGVyYXRpb25paGlzdG9ncmFt";
byte[] cborEncoded = Base64.getDecoder().decode(base64DebugPayload);

// CbodDecoder comes from this library https://github.com/c-rack/cbor-java
final List<DataItem> dataItems = new CborDecoder(new ByteArrayInputStream(cborEncoded)).decode();

// In here you can see the contents, but the value will be something like:
// Data items: [{ data: [{ value: co.nstant.in.cbor.model.ByteString@a8b5c07a,
//   bucket: co.nstant.in.cbor.model.ByteString@f812097d },
//   { value: co.nstant.in.cbor.model.ByteString@a8b5dfc0,
//   bucket: co.nstant.in.cbor.model.ByteString@f8120934 }], operation: histogram }]
Log.d("Data items : " + dataItems);

// In order to see the value for bucket and value, you can traverse the data
// and get their values, something like this:
final Map payload = (Map) dataItems.get(0);
final Array payloadArray = (Array) payload.get(new UnicodeString("data"));

payloadArray.getDataItems().forEach(i -> {
    BigInteger value = new BigInteger(((ByteString) ((Map)i).get(new UnicodeString("value"))).getBytes());
    BigInteger bucket = new BigInteger(((ByteString) ((Map)i).get(new UnicodeString("bucket"))).getBytes());
    Log.d("value : " + value + " ;bucket : " + bucket);
});

การทดสอบ

หากต้องการเริ่มต้นใช้งาน Attribution Reporting API คุณสามารถใช้ โปรเจ็กต์ MeasurementSampleApp ใน GitHub ตัวอย่างแอปนี้จะสาธิต การลงทะเบียนแหล่งที่มาของการระบุแหล่งที่มาและการลงทะเบียนทริกเกอร์

สำหรับปลายทางเซิร์ฟเวอร์ ให้พิจารณาใช้แหล่งข้อมูลอ้างอิงต่อไปนี้หรือกำหนด โซลูชัน:

  • MeasurementAdTechServerSpec ประกอบด้วยคำจำกัดความของบริการ OpenAPI ซึ่งสามารถทำให้ใช้งานได้กับแพลตฟอร์มจำลองหรือ Microservice ที่รองรับ
  • MeasurementAdTechServer ประกอบด้วยการใช้งานข้อมูลอ้างอิงของการจำลอง เซิร์ฟเวอร์ตามแอป Spring Boot สำหรับ Google App Engine

ข้อกำหนดเบื้องต้น

ทำให้ API จำลองใช้งานได้บนปลายทางระยะไกลที่เข้าถึงได้จากอุปกรณ์ทดสอบ หรือ โปรแกรมจำลอง เพื่อให้ทดสอบได้ง่าย โปรดดู MeasurementAdTechServerSpec และ MeasurementAdTechServer ตัวอย่างโปรเจ็กต์

ฟังก์ชันการทำงานที่จะทดสอบ

  • ใช้แหล่งที่มาของการระบุแหล่งที่มาและการลงทะเบียนทริกเกอร์ Conversion โปรดตรวจสอบว่า ปลายทางฝั่งเซิร์ฟเวอร์ตอบสนองด้วยรูปแบบที่ถูกต้อง
  • ดำเนินการงานการรายงาน
  • ยืนยันการส่งรายงานในแบ็กเอนด์หรือคอนโซลของเซิร์ฟเวอร์ทดสอบ

ฟีเจอร์ที่กำลังจะเปิดตัว

การกำหนดค่าระดับเหตุการณ์ที่ยืดหยุ่น

ขอแนะนำให้กำหนดค่าเริ่มต้นสำหรับการรายงานระดับเหตุการณ์เพื่อเริ่มต้น ทดสอบยูทิลิตีต่างๆ แต่อาจไม่เหมาะกับ Use Case ทุกกรณี การระบุแหล่งที่มา Reporting API จะรองรับการกำหนดค่าที่ไม่บังคับและมีความยืดหยุ่นมากขึ้นเพื่อให้โฆษณา ได้เพิ่มการควบคุมโครงสร้างรายงานระดับเหตุการณ์และ สามารถสร้างประโยชน์สูงสุดจากข้อมูลได้ ความยืดหยุ่นเพิ่มเติมนี้จะ ที่กำลังจะเปิดตัวใน Attribution Reporting API 2 ระยะ ดังนี้

  • ระยะที่ 1: การกำหนดค่าระดับเหตุการณ์ที่ยืดหยุ่น Lite เซ็ตย่อยของเฟส 2.
  • ระยะที่ 2: เวอร์ชันเต็มของการกำหนดค่าระดับเหตุการณ์ที่ยืดหยุ่น

ระยะที่ 1: ระดับเหตุการณ์ที่ยืดหยุ่นแบบ Lite

เราจะเพิ่มพารามิเตอร์ที่ไม่บังคับ 2 รายการต่อไปนี้ลงใน JSON ใน Attribution-Reporting-Register-Source:

  • max_event_level_reports
  • event_report_windows
{
  ...
  // Optional. This is a parameter that acts across all trigger types for the
  // lifetime of this source. It restricts the total number of event-level
  // reports that this source can generate. After this maximum is hit, the
  // source is no longer capable of producing any new data. The use of
  // priority in the trigger attribution algorithm in the case of multiple
  // attributable triggers remains unchanged. Defaults to 3 for navigation
  // sources and 1 for event sources
  "max_event_level_reports": <int>,

  // Optional. Represents a series of time windows, starting at 0. Reports
  // for this source will be delivered an hour after the end of each window.
  // Time is encoded as seconds after source registration. If
  // event_report_windows is omitted, will use the default windows. This
  // field is mutually exclusive with the existing `event_report_window` field.
  // // End time is exclusive.
  "event_report_windows": {
    "start_time": <int>,
    "end_times": [<int>, ...]
  }
}

ตัวอย่างการกำหนดค่าที่กำหนดเอง

การกำหนดค่าตัวอย่างนี้สนับสนุนนักพัฒนาซอฟต์แวร์ที่ต้องการเพิ่มประสิทธิภาพ การรับรายงานในหน้าต่างการรายงานก่อนหน้า

{
  ...
  "max_event_level_reports": 2,
  "event_report_windows": {
    "end_times": [7200, 43200, 86400] // 2 hours, 12 hours, 1 day in seconds
  }
}

ระยะที่ 2: ระดับเหตุการณ์ที่ยืดหยุ่นโดยสมบูรณ์

นอกจากพารามิเตอร์ที่เพิ่มเข้ามาในขั้นตอนที่ 1 แล้ว เราจะเพิ่มแอตทริบิวต์ พารามิเตอร์ที่ไม่บังคับเพิ่มเติม trigger_specs ไปยัง JSON ใน Attribution-Reporting-Register-Source

{
  // A trigger spec is a set of matching criteria, along with a scheme to
  // generate bucketized output based on accumulated values across multiple
  // triggers within the specified event_report_window. There will be a limit on
  // the number of specs possible to define for a source.
  "trigger_specs": [{
    // This spec will only apply to registrations that set one of the given
    // trigger data values (non-negative integers) in the list.
    // trigger_data will still appear in the event-level report.
    "trigger_data": [<int>, ...]

    // Represents a series of time windows, starting at the source registration
    // time. Reports for this spec will be delivered an hour after the end of
    // each window. Time is encoded as seconds after source registration.
    // end_times must consist of strictly increasing positive integers.
    //
    // Note: specs with identical trigger_data cannot have overlapping windows;
    // this ensures that triggers match at most one spec. If
    // event_report_windows is omitted, will use the "event_report_window" or
    // "event_report_windows" field specified at the global level for the source
    // (or the default windows if none are specified). End time is exclusive.
    "event_report_windows": {
      "start_time": <int>,
      "end_times": [<int>, ...],
    }

    // Represents an operator that summarizes the triggers within a window
    // count: number of triggers attributed within a window
    // value_sum: sum of the value of triggers within a window
    // The summary is reported as an index into a bucketization scheme. Defaults
    // to "count"
    "summary_window_operator": <one of "count" or "value_sum">,

    // Represents a bucketization of the integers from [0, MAX_INT], encoded as
    // a list of integers where new buckets begin (excluding 0 which is
    // implicitly included).
    // It must consist of strictly increasing positive integers.
    //
    // e.g. [5, 10, 100] encodes the following ranges:
    // [[0, 4], [5, 9], [10, 99], [100, MAX_INT]]
    //
    // At the end of each reporting window, triggers will be summarized into an
    // integer which slots into one of these ranges. Reports will be sent for
    // every new range boundary that is crossed. Reports will never be sent for
    // the range that includes 0, as every source is initialized in this range.
    //
    // If omitted, then represents a trivial mapping
    // [1, 2, ... , MAX_INT]
    // With MAX_INT being the maximum int value defined by the browser.
    "summary_buckets": [<bucket start>, ...]
  }, {
    // Next trigger_spec
  } ...],

  // See description in phase 1.
  "max_event_level_reports": <int>
  // See description in phase 1.
  "event_report_windows": {
    "start_time": <int>,
    "end_times": [<int>, ...]
  }
}

การกำหนดค่านี้จะระบุพื้นที่เอาต์พุตของรายงานระดับเหตุการณ์ทั้งหมด ต่อการลงทะเบียนแหล่งที่มา สำหรับข้อกำหนดของทริกเกอร์ทั้งหมด เราระบุอย่างครบถ้วนดังนี้

  • ชุดเกณฑ์การจับคู่มีดังนี้
    • ข้อกำหนดนี้มีผลกับข้อมูลทริกเกอร์ใด แหล่งที่มานี้ มีสิทธิ์จับคู่กับทริกเกอร์ที่มีหนึ่งใน ค่า trigger_data ใน trigger_specs กล่าวคือ หาก ทริกเกอร์จะจับคู่แหล่งที่มานี้ แต่ trigger_data ไม่ใช่ 1 ของค่าในการกำหนดค่าของแหล่งที่มา ระบบจะไม่สนใจทริกเกอร์
    • เมื่อทริกเกอร์ที่เจาะจงตรงกับข้อกำหนดนี้ (โดยใช้ event_report_windows) โปรดทราบว่าทริกเกอร์อาจยังจับคู่ได้ ที่มีแหล่งที่มาสำหรับรายงานที่รวบรวมได้แม้ว่าจะล้มเหลวในทั้ง 2 รายการที่ตรงกัน เกณฑ์ที่กล่าวถึงก่อนหน้านี้
  • อัลกอริทึมที่เฉพาะเจาะจงสำหรับการสรุปและเก็บข้อมูลทริกเกอร์ทั้งหมดภายใน กรอบเวลาการระบุแหล่งที่มา การดำเนินการนี้จะอนุญาตให้ทริกเกอร์ระบุพารามิเตอร์ value ที่จะถูกสรุปเป็นข้อมูลจำเพาะที่เจาะจง แต่รายงานเป็นค่าที่ฝากไว้

ทริกเกอร์ยังรองรับการเพิ่มพารามิเตอร์ค่าที่ไม่บังคับใน พจนานุกรมภายใน event_trigger_data

{
  "event_trigger_data": [
    {
      "trigger_data": "2",
      "value": 100,  // Defaults to 1
      "filters": ...
    },
    ...
  ]
}

การลงทะเบียนทริกเกอร์ทุกรายการจะตรงกับข้อมูลจำเพาะของทริกเกอร์และอัปเดตไม่เกิน 1 รายการ ค่าสรุปที่เชื่อมโยง ในระดับสูง เมื่อถึงเวลาทริกเกอร์ เราจะ:

  • ใช้ตัวกรองการระบุแหล่งที่มาส่วนกลาง
  • สำหรับข้อมูลจำเพาะของทริกเกอร์ทั้งหมด ให้ประเมิน event_trigger_data ในข้อมูลจำเพาะเพื่อหา ที่ตรงกัน โดยใช้ event_reporting_window ของข้อกำหนด ระดับบนสุด event_reporting_windows ทำหน้าที่เป็นค่าเริ่มต้นในกรณีที่มีข้อมูลจำเพาะของทริกเกอร์ ฟิลด์ย่อย event_report_windows ที่ขาดหายไป
  • ระบบจะเลือกข้อกำหนดที่ตรงกันรายการแรกสำหรับการระบุแหล่งที่มา และค่าสรุปคือ เพิ่มขึ้น value

เมื่อ event_report_window สำหรับข้อมูลจำเพาะเสร็จสมบูรณ์แล้ว เราจะแมปข้อมูลสรุป ลงในที่เก็บข้อมูล และส่งรายงานระดับเหตุการณ์สำหรับทุกๆ ที่เพิ่มขึ้น ที่เก็บข้อมูลสรุปที่เกิดจากค่าทริกเกอร์ที่มีการระบุแหล่งที่มา รายงานต่างๆ จะมาพร้อม ฟิลด์เพิ่มเติม trigger_summary_bucket

{
  ...
  "trigger_summary_bucket": [<bucket start>, <bucket end>],
}

การกำหนดค่าที่เทียบเท่ากับเวอร์ชันปัจจุบัน

ต่อไปนี้คือการกำหนดค่าที่เทียบเท่าสำหรับเหตุการณ์ปัจจุบันของ API และ แหล่งที่มาการนำทางตามลำดับ โดยเฉพาะอย่างยิ่งสำหรับ แหล่งการนำทาง แสดงสาเหตุที่ระดับสัญญาณรบกวนสูงเมื่อเทียบกับแหล่งที่มาของเหตุการณ์ คงค่า epsilon เดิมไว้: แหล่งที่มาของการนำทางมีเอาต์พุตที่ใหญ่กว่ามาก พื้นที่ทำงาน

อาจมีการกําหนดค่าหลายรายการที่เทียบเท่ากัน สามารถตั้งพารามิเตอร์บางตัวเป็นค่าเริ่มต้นหรือตัดทอนได้

แหล่งที่มาของเหตุการณ์ที่เทียบเท่า
// Note: most of the fields here are not required to be explicitly listed.
// Here we list them explicitly just for clarity.
{
  "trigger_specs": [
  {
    "trigger_data": [0, 1],
    "event_report_windows": {
      "end_times": [<30 days>]
    },
    "summary_window_operator": "count",
    "summary_buckets": [1],
  }],
  "max_event_level_reports": 1,
  ...
  // expiry must be greater than or equal to the last element of the end_times
  "expiry": <30 days>,
}
แหล่งที่มาของการนำทางที่เทียบเท่า
// Note: most of the fields here are not required to be explicitly listed.
// Here we list them explicitly just for clarity.
{
  "trigger_specs": [
  {
    "trigger_data": [0, 1, 2, 3, 4, 5, 6, 7],
    "event_report_windows": {
      "end_times": [<2 days>, <7 days>, <30 days>]
    },
    "summary_window_operator": "count",
    "summary_buckets": [1, 2, 3],
  }],
  "max_event_level_reports": 3,
  ...
  // expiry must be greater than or equal to the last element of the end_times
  "expiry": <30 days>,
}

ตัวอย่างการกำหนดค่าที่กำหนดเอง

ด้านล่างนี้เป็นการกำหนดค่าเพิ่มเติมนอกเหนือจากค่าเริ่มต้น ในทุกข้อที่กล่าวมา ตัวอย่างข้อดีของนักพัฒนาแอป ได้แก่

  • การลดมิติข้อมูลบางส่วนของการกำหนดค่าเริ่มต้น (#triggers, ข้อมูลทริกเกอร์ Cardinality, #windows) สําหรับเพิ่มอีก 1 รายการเพื่อรักษาระดับสัญญาณรบกวน
  • การลดมิติข้อมูลบางส่วนของการกำหนดค่าเริ่มต้น (#triggers, ข้อมูลทริกเกอร์ Cardinality, #windows) สำหรับระดับสัญญาณรบกวนที่ลดลง

ที่เก็บข้อมูลค่าทริกเกอร์รายงาน

การกำหนดค่าตัวอย่างนี้รองรับนักพัฒนาซอฟต์แวร์ที่ต้องการเพิ่มประสิทธิภาพให้กับมูลค่า ข้อมูลสำหรับกรอบเวลาการรายงานเพียงหน้าต่างเดียว (เช่น 7 วัน) ทำให้ซื้อขายรายงานน้อยลง หน้าต่างสำหรับรบกวนการทำงานน้อยลง ในตัวอย่างนี้ ทริกเกอร์ที่ตั้งค่า trigger_data เป็น ค่าอื่นที่ไม่ใช่ 0 ไม่มีสิทธิ์ระบุแหล่งที่มา

{
  "trigger_specs": [
  {
    "trigger_data": [0],
    "event_report_windows": {
      "end_times": [604800, 1209600] // 7 days, 14 days represented in seconds
    },
    "summary_window_operator": "value_sum",
    "summary_buckets": [5, 10, 100]
  }],
}

สามารถลงทะเบียนทริกเกอร์ด้วยชุดช่อง value ซึ่งสรุปแล้ว ที่เก็บข้อมูล เช่น ถ้ามีตัวทริกเกอร์ 3 ตัวภายใน 7 วันนับจากวันที่แหล่งที่มา การจดทะเบียนที่มีค่า 1, 3 และ 4

{ "event_trigger_data": [{"trigger_data": "0", "value": 1}] }
{ "event_trigger_data": [{"trigger_data": "0", "value": 3}] }
{ "event_trigger_data": [{"trigger_data": "0", "value": 4}] }

ค่าจะถูกรวมเป็น 8 และรายงานในรายงานต่อไปนี้หลังจากผ่านไป 7 วัน + 1 ชั่วโมง:

// Report 1
{
  ...
  "trigger_summary_bucket": [5, 9]
}

ในอีก 7 วันต่อมา ทริกเกอร์ต่อไปนี้จะได้รับการบันทึก

{ "event_trigger_data": [{"trigger_data": "0", "value": 50}] }
{ "event_trigger_data": [{"trigger_data": "0", "value": 45}] }

ผลรวมค่าต่างๆ จะเป็น 8 + 50 + 45 = 103 ซึ่งจะให้รายงานต่อไปนี้ที่ 14 วัน + 1 ชั่วโมง:

// Report 2
{
  ...
  "trigger_summary_bucket": [10, 99]
},

// Report 3
{
  ...
  "trigger_summary_bucket": [100, MAX_INT]
}
จำนวนทริกเกอร์รายงาน

ตัวอย่างนี้แสดงให้เห็นวิธีที่นักพัฒนาซอฟต์แวร์สามารถกำหนดค่าแหล่งที่มาเพื่อให้ได้รับจำนวน สูงสุด 10 ตัว

{
  "trigger_specs": [
  {
    "trigger_data": [0],
    "event_report_windows": {
      "end_times": [604800] // 7 days represented in seconds
    },
    // This field could be omitted to save bandwidth since the default is "count"
    "summary_window_operator": "count",
    "summary_buckets": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  }],
}

ระบบจะนับทริกเกอร์ที่มีการระบุแหล่งที่มาซึ่งมี trigger_data ซึ่งตั้งค่าเป็น 0 และจำกัดที่ 10 ทริกเกอร์ ระบบละเว้นค่าทริกเกอร์เนื่องจากมีการตั้งค่า summary_window_operator ให้นับ ถ้า บันทึกทริกเกอร์ 4 รายการและระบุแหล่งที่มาว่ามาจากแหล่งที่มา รายงานจะมีลักษณะเช่นนี้ ดังนี้

// Report 1
{
  ...
  "trigger_summary_bucket": [1, 1]
}
// Report 2
{
  ...
  "trigger_summary_bucket": [2, 2]
}
// Report 3
{
  ...
  "trigger_summary_bucket": [3, 3]
}
// Report 4
{
  ...
  "trigger_summary_bucket": [4, 4]
}
ไบนารีที่มีการรายงานบ่อยกว่า

การกำหนดค่าตัวอย่างนี้สนับสนุนนักพัฒนาซอฟต์แวร์ที่ต้องการทราบว่า มี Conversion เกิดขึ้นอย่างน้อย 1 รายการในช่วง 10 วันแรก (โดยไม่คำนึงถึงมูลค่า) แต่ ต้องการรับรายงานในระยะเวลาที่บ่อยกว่าค่าเริ่มต้น ขอย้ำอีกครั้งว่า ตัวอย่างนี้ทริกเกอร์ใดๆ ที่ตั้งค่า trigger_data เป็นค่าอื่นที่ไม่ใช่ 0 ไม่มีสิทธิ์ระบุแหล่งที่มา ด้วยเหตุนี้ เราจึงเรียกกรณีการใช้งานนี้ว่า ไบนารี

{
  "trigger_specs": [
  {
    "trigger_data": [0],
    "event_report_windows": {
      // 1 day, 2 days, 3 days, 5 days, 7 days, 10 days represented in seconds
      "end_times": [86400, 172800, 259200, 432000, 604800, 864000]
    },
    // This field could be omitted to save bandwidth since the default is "count"
    "summary_window_operator": "count",
    "summary_buckets": [1]
  }],
}
เปลี่ยนข้อกำหนดของทริกเกอร์จากแหล่งที่มาหนึ่งถึงแหล่งที่มา
{
  "trigger_specs": [
  {
    "trigger_data": [0, 1, 2, 3],
    "event_report_windows": {
      "end_times": [172800, 604800, 2592000] // 2 days, 7 days, 30 days represented in seconds
    }
  }],
  "max_event_level_reports": 3
}
{
  "trigger_specs": [
  {
    "trigger_data": [4, 5, 6, 7],
    "event_report_windows": {
      "end_times": [172800, 604800, 2592000] // 2 days, 7 days, 30 days represented in seconds
    }
  }],
  "max_event_level_reports": 3
}

เราขอแนะนำให้นักพัฒนาแอปแนะนำกรณีการใช้งานแบบต่างๆ สำหรับการดำเนินการนี้ ส่วนขยาย API และเราจะอัปเดตคำอธิบายนี้พร้อมด้วยตัวอย่างการกำหนดค่าสำหรับ Use Case เหล่านั้น

การระบุแหล่งที่มาข้ามเครือข่ายโดยไม่มีการเปลี่ยนเส้นทาง

เทคโนโลยีโฆษณาควรใช้การเปลี่ยนเส้นทางเพื่อลงทะเบียนทริกเกอร์แหล่งที่มาของการระบุแหล่งที่มาหลายรายการ และใช้การระบุแหล่งที่มาข้ามเครือข่าย ฟีเจอร์นี้ช่วยให้การสนับสนุน การระบุแหล่งที่มาข้ามเครือข่ายที่ไม่สามารถเปลี่ยนเส้นทางข้ามเครือข่ายได้ ดูข้อมูลเพิ่มเติม

เทคโนโลยีโฆษณาสามารถส่งการกำหนดค่าในการตอบกลับทริกเกอร์การลงทะเบียนโดยอิงตาม เลือกแหล่งที่มาที่ลงทะเบียนโดยเทคโนโลยีโฆษณาอื่นๆ เพื่อสร้างข้อมูลที่ได้รับ แหล่งที่มา จากนั้นจะใช้แหล่งที่มาที่ได้มาเหล่านี้สำหรับการระบุแหล่งที่มา รายงานเชิงสถิติ จะสร้างขึ้นหากทริกเกอร์มีการระบุแหล่งที่มาไปยังแหล่งที่มาที่ได้รับ รายงานเหตุการณ์ ระบบไม่รองรับการสร้างสำหรับแหล่งที่มาที่ดึงมา

เทคโนโลยีโฆษณาสามารถเลือกจาก aggregation_keys ในแหล่งที่มาที่ลงทะเบียนซึ่ง พวกเขาตั้งใจที่จะแชร์ กับเทคโนโลยีโฆษณาของพาร์ทเนอร์ คีย์เหล่านี้สามารถประกาศได้ใน ช่อง shared_aggregation_keys ที่ไม่บังคับ อยู่ใต้การลงทะเบียนแหล่งที่มา ส่วนหัว Attribution-Reporting-Register-Source:

"shared_aggregation_keys": ["[key name1]", "[key name2]"]

ระบบจะสร้างแหล่งที่มาที่ได้รับตามการกำหนดค่าภายใต้ทริกเกอร์ ส่วนหัวการลงทะเบียน Attribution-Reporting-Register-Trigger:

  // Specifies the configuration based on which derived sources should be
  // generated. Those derived sources will be included for source matching at the
  // time of attribution. For example, if adtech2 is registering a trigger with an
  // attribution_config with source_network as adtech1, available sources
  // registered by adtech1 will be considered with additional filtering criteria
  // applied to that set as mentioned in the attribution_config. Derived
  // sources can have different values to priority, post_install_exclusivity_window
  // etc.

  "attribution_config": [
    {
      // Derived sources are created from this adtech's registered sources
      "source_network": "[original source's adtech enrollment ID]",
      //(optional) Filter sources whose priority falls in this range
      "source_priority_range": {
        "start": [priority filter lower bound],
        "end": [priority filter upper bound]
      },
      // (optional) Filter sources whose at least one of filter maps matches these
      // filters
      "source_filters": {
        "key name 1": ["key1 value 1"]
      },
      // (optional) Filter sources whose none of filter map matches these
      // filters
        "source_not_filters": {
          "key name 1": ["key1 value 1"]
        },
      // (optional) Apply this priority to the generated derived sources
      "priority": "[64 bit signed integer]",
      // (optional) The derived source will have expiry set as this or parent
      // source's, whichever is earlier
      "expiry": "[64 bit signed integer]",
      // (optional) set on the derived source
      "filter_data": {
        "key name 1": ["key1 value 1"]
      },
      // (optional) set on the derived source
      "post_install_exclusivity_window": "[64-bit unsigned integer]"
    }
  ]

เวอร์ชันที่มีการเพิ่มค่าตัวอย่างมีดังต่อไปนี้

  "attribution_config": [
    {
      "source_network": "adtech1-enrollment-id",
      "source_priority_range": {
        "start": 50,
        "end": 100
      },
      "source_filters": {
        "source_type": ["NAVIGATION"]
      },
      "source_not_filters": {
        "product_id": ["789"]
      },
      "priority": "30",
      "expiry": "78901",
      // (optional) set on the derived source
      "filter_data": {
        "product_id": ["1234"]
        },
      // (optional) set on the derived source
      "post_install_exclusivity_window": "7890"
    }
  ]

เพิ่มช่องที่ไม่บังคับใหม่ 2 ช่องเพื่อทริกเกอร์ส่วนหัวการลงทะเบียน ฟิลด์เหล่านี้ เปิดใช้ตัวระบุของเทคโนโลยีโฆษณาที่ชนะในคีย์รายงานที่รวบรวมได้

  • x_network_bit_mapping: รหัสการลงทะเบียนไปยังการแมปบิตตัวระบุเทคโนโลยีโฆษณา
  • x_network_data: ออฟเซ็ต (ลูกศรซ้าย) สำหรับเทคโนโลยีโฆษณาที่ชนะ x_network_bit_mapping หรือการดำเนินการที่มีส่วนคีย์ทริกเกอร์
ตัวอย่าง
"Attribution-Reporting-Register-Trigger": {
  "attribution_config": [...],
  "aggregatable_trigger_data": [
    {
     "key_piece": "0x400",
     "source_keys": ["campaignCounts"]
      "x_network_data" : {
        "key_offset" : 12 // [64 bit unsigned integer]
      }
    }
    …
  ]
  …
  "x_network_bit_mapping": {
   // This mapping is used to generate trigger key pieces with AdTech identifier
   // bits. eg. If AdTechA's sources wins the attribution then 0x1 here will be
   // OR'd with the trigger key pieces to generate the final key piece.
    "AdTechA-enrollment_id": "0x1", // Identifier bits in hex for A
    "AdTechB-enrollment_id": "0x2"  // Identifier bits in hex for B
  }
  …
}

ต่อไปนี้เป็นผลลัพธ์สำหรับการคำนวณชิ้นส่วนคีย์เมื่อสร้างรายงานสำหรับ แหล่งที่มาของ AdTechB:

  • key_piece: 0x400 (010000000000)
  • key_offset: 12
  • ค่า enrollment_id ของ AdtechB: 2 (010) (จาก x_network_bit_mapping)
  • คีย์ส่วนสำคัญของทริกเกอร์ผลลัพธ์: 0x400 | 0x2 << 12 = 0x2400

ข้อจำกัด

ดูรายการความสามารถที่กำลังดำเนินการอยู่สำหรับรันไทม์ของ SDK ได้ที่ บันทึกประจำรุ่น

รายงานข้อบกพร่องและปัญหา

ความคิดเห็นของคุณเป็นส่วนสำคัญของ Privacy Sandbox ใน Android โปรดแจ้งให้เราทราบ ของปัญหาที่คุณพบหรือแนวคิดในการปรับปรุง Privacy Sandbox บน Android