ขณะอ่านเอกสารประกอบเกี่ยวกับ Privacy Sandbox บน Android ให้ใช้ปุ่มDeveloper Preview หรือเบต้าเพื่อเลือก เวอร์ชันโปรแกรมที่คุณกำลังใช้งาน เนื่องจากวิธีการอาจแตกต่างกัน
Attribution Reporting API ได้รับการออกแบบมาเพื่อปรับปรุงความเป็นส่วนตัวของผู้ใช้โดย ยกเลิกการพึ่งพาตัวระบุผู้ใช้ข้ามฝ่ายต่างๆ รวมถึงเพื่อรองรับ Use Case ที่สำคัญๆ สำหรับการวัดการระบุแหล่งที่มาและการวัด Conversion ในแอป คู่มือสำหรับนักพัฒนาซอฟต์แวร์นี้ อธิบายวิธีกำหนดค่าและทดสอบ Attribution Reporting API เพื่อลงทะเบียน การคลิกโฆษณา การดู และ Conversion โดยการเรียกใช้เมธอดที่ลงทะเบียนทริกเกอร์และแหล่งที่มาที่เกี่ยวข้อง สำหรับเหตุการณ์ดังกล่าว
คู่มือนี้จะสอนวิธีตั้งค่าปลายทางของเซิร์ฟเวอร์และสร้างแอปไคลเอ็นต์ ที่เรียกใช้บริการเหล่านี้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการออกแบบโดยรวมของ Attribution Reporting API ได้ในข้อเสนอการออกแบบ
คีย์เวิร์ด
- แหล่งที่มาของการระบุแหล่งที่มาหมายถึงการคลิกหรือการดู
- ทริกเกอร์คือเหตุการณ์ที่ระบุแหล่งที่มาของ Conversion ได้
- รายงานมีข้อมูลเกี่ยวกับทริกเกอร์และแหล่งที่มาของการระบุแหล่งที่มาที่เกี่ยวข้อง ระบบจะส่งรายงานเหล่านี้เพื่อตอบสนองต่อเหตุการณ์ทริกเกอร์ Attribution Reporting API รองรับรายงานระดับเหตุการณ์และ รายงานที่รวบรวมได้
ก่อนเริ่มต้น
หากต้องการใช้ Attribution Reporting API ให้ทําภารกิจฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ ที่ระบุไว้ในส่วนต่อไปนี้ให้เสร็จสมบูรณ์
ตั้งค่าปลายทางของ Attribution Reporting API
Attribution Reporting API ต้องมีชุดอุปกรณ์ปลายทางที่คุณเข้าถึงได้ จากอุปกรณ์ทดสอบหรือโปรแกรมจำลอง สร้างปลายทาง 1 รายการสำหรับงานฝั่งเซิร์ฟเวอร์ต่อไปนี้แต่ละรายการ
- ลงทะเบียนแหล่งที่มาของการระบุแหล่งที่มา (การดูหรือการคลิก)
- ลงทะเบียนทริกเกอร์ (Conversion)
- ยอมรับรายงานระดับเหตุการณ์
- ยอมรับรายงานที่รวบรวมได้
การตั้งค่าปลายทางที่จำเป็นทำได้หลายวิธี ดังนี้
- วิธีที่เร็วที่สุดในการเริ่มต้นใช้งานคือการติดตั้งใช้งานคำจำกัดความของบริการ OpenAPI v3 จากที่เก็บโค้ดตัวอย่างของเราไปยังแพลตฟอร์มจำลองหรือแพลตฟอร์มไมโครเซอร์วิส คุณใช้ Postman, Prism หรือแพลตฟอร์มเซิร์ฟเวอร์จำลองอื่นๆ ที่ยอมรับรูปแบบนี้ได้ ติดตั้งใช้งานแต่ละอุปกรณ์ปลายทางและติดตาม URI เพื่อใช้ในแอป หากต้องการยืนยันการนำส่งรายงาน ให้ดูการเรียก ที่ทำก่อนหน้านี้ไปยังแพลตฟอร์มจำลองหรือแบบไร้เซิร์ฟเวอร์
- เรียกใช้เซิร์ฟเวอร์แบบสแตนด์อโลนของคุณเองโดยใช้ตัวอย่าง Kotlin ที่อิงตาม Spring Boot ติดตั้งใช้งานเซิร์ฟเวอร์นี้ในผู้ให้บริการระบบคลาวด์หรือโครงสร้างพื้นฐานภายใน
- ใช้คำจำกัดความของบริการเป็นตัวอย่างในการผสานรวมปลายทางเข้ากับระบบที่มีอยู่
ยอมรับการลงทะเบียนแหล่งที่มา
ปลายทางนี้ควรเข้าถึงได้จาก 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't 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't 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't 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 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"],
}]
}],
"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 ได้ที่ลงทะเบียนบัญชี Privacy Sandbox (ระบบจะอนุมาน URI จากต้นทางของเซิร์ฟเวอร์ที่ใช้สำหรับการยอมรับการลงทะเบียนแหล่งที่มาและการลงทะเบียนทริกเกอร์) เมื่อใช้ 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 ได้ที่ลงทะเบียนบัญชี Privacy Sandbox (ระบบจะอนุมาน URI จากต้นทางของเซิร์ฟเวอร์ที่ใช้สำหรับการยอมรับการลงทะเบียนแหล่งที่มาและการลงทะเบียนทริกเกอร์) เมื่อใช้ 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 doesn't yet encrypt aggregate reports.
// 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 ให้ทำดังนี้
- ตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์สำหรับ Privacy Sandbox ใน Android
- ติดตั้งอิมเมจระบบลงในอุปกรณ์ที่รองรับหรือ ตั้งค่าโปรแกรมจำลองที่รองรับ Privacy Sandbox ใน Android
เปิดใช้สิทธิ์เข้าถึง Attribution Reporting API โดยเรียกใช้คำสั่ง ADB ต่อไปนี้ (API จะปิดใช้โดยค่าเริ่มต้น)
adb shell device_config put adservices ppapi_app_allow_list \"\*\"หากคุณกำลังทดสอบ Attribution Reporting API ในเครื่อง (เช่น ทดสอบใน อุปกรณ์ที่คุณมีสิทธิ์เข้าถึงทางกายภาพ) ให้เรียกใช้คำสั่งนี้เพื่อปิดใช้ การลงทะเบียน
adb shell device_config put adservices disable_measurement_enrollment_check "true"ใส่สิทธิ์
ACCESS_ADSERVICES_ATTRIBUTIONในไฟล์ Android Manifest และสร้างการกำหนดค่าบริการโฆษณาสำหรับแอปเพื่อใช้ Attribution Reporting API โดยทำดังนี้<uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION" />(ไม่บังคับ) หากวางแผนที่จะรับรายงานการแก้ไขข้อบกพร่อง ให้รวมสิทธิ์
ACCESS_ADSERVICES_AD_IDไว้ในไฟล์ Android Manifest<uses-permission android:name="android.permission.ACCESS_ADSERVICES_AD_ID" />อ้างอิงการกำหนดค่าบริการโฆษณาในองค์ประกอบ
<application>ของ ไฟล์ Manifest<property android:name="android.adservices.AD_SERVICES_CONFIG" android:resource="@xml/ad_services_config" />ระบุทรัพยากร 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 รองรับเหตุการณ์แหล่งที่มาของการระบุแหล่งที่มาประเภทต่อไปนี้
- การคลิก ซึ่งโดยปกติแล้วคุณจะลงทะเบียนภายในเมธอดการเรียกกลับที่คล้ายกับ
onClick()โดยปกติแล้ว เหตุการณ์ทริกเกอร์ที่เกี่ยวข้องจะเกิดขึ้นหลังจากเหตุการณ์คลิกไม่นาน เหตุการณ์ประเภทนี้ให้ข้อมูลเพิ่มเติมเกี่ยวกับการโต้ตอบของผู้ใช้ จึงเป็นแหล่งที่มาของการระบุแหล่งที่มาที่ดีที่ควรให้ ลำดับความสำคัญสูง มุมมอง ซึ่งโดยปกติแล้วคุณจะลงทะเบียนภายในเมธอดการเรียกกลับที่คล้ายกับ
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
และส่วนหัว "Location" พร้อม URL ถัดไปที่จะเข้าชมเพื่อลงทะเบียนเพิ่มเติมได้ด้วย
ระบบจะใช้เฉพาะช่อง "ปลายทาง" ที่ระบุในการเข้าชมครั้งแรกสุด ในเชนการเปลี่ยนเส้นทาง จำนวนการเข้าชมมีขีดจำกัดเดียวกับส่วนหัว "Attribution-Reporting-Redirect" การรองรับการเปลี่ยนเส้นทางนี้เป็นการรองรับเพิ่มเติม จากการรองรับ "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);
การเพิ่มสัญญาณรบกวนเพื่อความเป็นส่วนตัว
รายงานระดับเหตุการณ์มีข้อมูลปลายทาง รหัสแหล่งที่มาของการระบุแหล่งที่มา และทริกเกอร์ โดยจะส่งในรูปแบบเดิม (ไม่ได้เข้ารหัส) ไปยังแหล่งที่มารายงาน เพื่อปกป้องความเป็นส่วนตัวของผู้ใช้ คุณสามารถเพิ่มสัญญาณรบกวนเพื่อให้ระบุตัวตนของผู้ใช้แต่ละรายได้ยากขึ้น ระบบจะสร้างและส่งรายงานระดับเหตุการณ์ที่มีการเพิ่ม Noise ตามกรอบความเป็นส่วนตัวเชิงแตกต่าง ค่าเปอร์เซ็นต์สัญญาณรบกวนเริ่มต้นสำหรับสถานการณ์ต่างๆ มีดังนี้
ประเภทแหล่งข้อมูล |
มูลค่าแหล่งที่มาของปลายทาง |
ความน่าจะเป็นของรายงานที่มีการเพิ่มสัญญาณรบกวนต่อการลงทะเบียนแหล่งที่มา |
ดู |
ทั้งแอปและเว็บ |
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 ขั้นตอน ขั้นตอนแรกใช้การถอดรหัส Base64 และขั้นตอนที่สองใช้การถอดรหัส 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 บางอย่าง Attribution Reporting API จะรองรับการกำหนดค่าที่ยืดหยุ่นมากขึ้นและไม่บังคับ เพื่อให้เทคโนโลยีโฆษณาสามารถควบคุมโครงสร้างของรายงานระดับเหตุการณ์ได้มากขึ้นและเพิ่มประโยชน์ของข้อมูลได้สูงสุด ความยืดหยุ่นเพิ่มเติมนี้จะ นำมาใช้ใน Attribution Reporting API ใน 2 ระยะ ดังนี้
- เฟส 1: การกำหนดค่าระดับเหตุการณ์แบบยืดหยุ่น Lite ซึ่งเป็นส่วนย่อยของเฟส 2
- ระยะที่ 2: การกำหนดค่าระดับเหตุการณ์แบบยืดหยุ่นเวอร์ชันเต็ม
ระยะที่ 1: ระดับเหตุการณ์แบบยืดหยุ่น Lite
เราจะเพิ่มพารามิเตอร์ที่ไม่บังคับ 2 รายการต่อไปนี้ลงใน JSON ใน
Attribution-Reporting-Register-Source
max_event_level_reportsevent_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 makes sure 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ไม่ใช่ค่าใดค่าหนึ่งในการกำหนดค่าของแหล่งที่มา ระบบจะไม่สนใจทริกเกอร์ - เมื่อทริกเกอร์ที่เฉพาะเจาะจงตรงกับข้อกำหนดนี้ (ใช้
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สำหรับข้อกำหนดเสร็จสมบูรณ์แล้ว เราจะแมปค่าสรุป
กับที่เก็บข้อมูล และส่งรายงานระดับเหตุการณ์สำหรับการเพิ่มขึ้นทุกครั้งในที่เก็บข้อมูลสรุป
ที่เกิดจากค่าทริกเกอร์ที่มา รายงานจะมีฟิลด์เพิ่มเติม 1 รายการคือ trigger_summary_bucket
{
...
"trigger_summary_bucket": [<bucket start>, <bucket end>],
}
การกำหนดค่าที่เทียบเท่ากับเวอร์ชันปัจจุบัน
การกำหนดค่าต่อไปนี้เทียบเท่ากับการกำหนดค่าสำหรับเหตุการณ์ปัจจุบันของ API และแหล่งที่มาของการนําทางตามลําดับ โดยเฉพาะอย่างยิ่งสำหรับแหล่งที่มาของการนําทาง สิ่งนี้จะแสดงให้เห็นว่าเหตุใดระดับสัญญาณรบกวนจึงสูงมากเมื่อเทียบกับแหล่งที่มาของเหตุการณ์เพื่อรักษาค่าเอปซิลอนเดียวกันไว้ เนื่องจากแหล่งที่มาของการนําทางมีพื้นที่เอาต์พุตที่ใหญ่กว่ามาก
การกำหนดค่าหลายรายการอาจเทียบเท่ากันได้ เนื่องจากพารามิเตอร์บางรายการสามารถตั้งค่าเป็นค่าเริ่มต้นหรือตัดออกได้
แหล่งที่มาของเหตุการณ์ที่เทียบเท่า
// 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>,
}
ตัวอย่างการกำหนดค่าที่กำหนดเอง
ต่อไปนี้คือการกำหนดค่าเพิ่มเติมบางอย่างที่อยู่นอกเหนือค่าเริ่มต้น ในตัวอย่างทั้งหมดนี้ การแลกเปลี่ยนของนักพัฒนาแอป ได้แก่
- ลดมิติข้อมูลบางอย่างของการกำหนดค่าเริ่มต้น (#ทริกเกอร์, ข้อมูลทริกเกอร์ Cardinality, #หน้าต่าง) เพื่อเพิ่มอีกมิติข้อมูลหนึ่งเพื่อรักษาระดับสัญญาณรบกวน
- ลดมิติข้อมูลบางอย่างของการกำหนดค่าเริ่มต้น (#ทริกเกอร์, ข้อมูลทริกเกอร์ คาร์ดินาลิตี, #หน้าต่าง) เพื่อลดระดับสัญญาณรบกวน
รายงานกลุ่มมูลค่าทริกเกอร์
การกำหนดค่าตัวอย่างนี้รองรับนักพัฒนาแอปที่ต้องการเพิ่มประสิทธิภาพสำหรับข้อมูลมูลค่า
สำหรับกรอบเวลาการรายงานเพียง 1 กรอบ (เช่น 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
}
เราขอแนะนำให้นักพัฒนาแอปเสนอ Use Case ต่างๆ ที่อาจมีสำหรับการขยาย 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หรือการดำเนินการ OR กับชิ้นส่วนคีย์ทริกเกอร์
ตัวอย่าง
"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 ad tech identifier
// bits. eg. If Ad Tech-A's sources wins the attribution then 0x1 here will be
// OR'd with the trigger key pieces to generate the final key piece.
"Ad-Tech-A-enrollment_id": "0x1", // Identifier bits in hex for A
"Ad-Tech-B-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