Attribution Reporting API geliştirici kılavuzu

Android'de Özel Korumalı Alan dokümanlarını okurken, çalıştığınız program sürümünü seçmek için Geliştirici Önizlemesi veya Beta düğmesini kullanın (talimatlar farklı olabilir).


Geri bildirim gönderin

Attribution Reporting API, taraflar arası kullanıcı tanımlayıcılarına bağımlılığı ortadan kaldırarak kullanıcı gizliliğini iyileştirmek ve uygulamalar arasında ilişkilendirme ile dönüşüm ölçümüne yönelik temel kullanım alanlarını desteklemek üzere tasarlanmıştır. Bu geliştirici kılavuzunda, bu tür etkinlikler için ilgili tetikleyicileri ve kaynakları kaydeden yöntemleri çağırarak reklam tıklamalarını, görüntülemeleri ve dönüşümleri kaydetmek amacıyla Attribution Reporting API'lerin nasıl yapılandırılıp test edileceği açıklanmaktadır.

Bu kılavuzda, sunucu uç noktalarının nasıl ayarlanacağı ve bu hizmetleri çağıran bir istemci uygulaması nasıl oluşturulacağı öğretilmektedir. Tasarım teklifinde, Attribution Reporting API'nin genel tasarımı hakkında daha fazla bilgi edinebilirsiniz.

Anahtar Terimler

  • İlişkilendirme kaynakları, tıklama veya görüntüleme sayısını ifade eder.
  • Tetikleyiciler, dönüşümlerle ilişkilendirilebilen etkinliklerdir.
  • Raporlar bir tetikleyici ve ilgili ilişkilendirme kaynağı hakkındaki verileri içerir. Bu raporlar, tetikleyici etkinliklere yanıt olarak gönderilir. Attribution Reporting API, etkinlik düzeyindeki raporları ve birleştirilebilir raporları destekler.

Başlamadan önce

Attribution Reporting API'yi kullanmak için aşağıdaki bölümlerde listelenen sunucu tarafı ve istemci tarafı görevlerini tamamlayın.

Attribution Reporting API uç noktalarını ayarlama

Attribution Reporting API, bir test cihazından veya emülatörden erişebileceğiniz bir uç nokta grubu gerektirir. Aşağıdaki sunucu tarafı görevlerinin her biri için bir uç nokta oluşturun:

Gerekli uç noktaları birkaç farklı yöntemle kurabilirsiniz:

  • Çalışmaya başlamanın en hızlı yolu, örnek kod depomuzdan OpenAPI v3 hizmet tanımlarını bir örnek veya mikro hizmet platformuna dağıtmaktır. Postman, Prism veya bu biçimi kabul eden başka bir sahte sunucu platformunu kullanabilirsiniz. Her uç noktayı dağıtın ve uygulamanızda kullanılacak URI'ları takip edin. Rapor teslimini doğrulamak için daha önce örnek veya sunucusuz platforma yapılan çağrılara bakın.
  • Spring Boot tabanlı Kotlin örneğini kullanarak kendi bağımsız sunucunuzu çalıştırın. Bu sunucuyu bulut sağlayıcınıza veya şirket altyapınıza dağıtın.
  • Uç noktaları mevcut sisteminize entegre etmek için hizmet tanımlarını örnek olarak kullanın.

Kaynak kaydını kabul et

Bu uç nokta, aşağıdakine benzer bir URI'den ele alınabilmelidir:

https://adtech.example/attribution_source

Bir istemci uygulaması bir ilişkilendirme kaynağı kaydettiğinde bu sunucu uç noktası için URI sağlar. Daha sonra Attribution Reporting API bir istekte bulunur ve aşağıdaki başlıklardan birini içerir:

  • Tıklama etkinlikleri için:

    Attribution-Reporting-Source-Info: navigation
    
  • Görüntüleme etkinlikleri için:

    Attribution-Reporting-Source-Info: event
    

Sunucu uç noktanızı aşağıdakilerle yanıt verecek şekilde yapılandırın:

// 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>

Aşağıda, örnek değerlerin eklendiği bir örnek verilmiştir:

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, reklam teknolojisi iş ortaklarının URI'lerini içeriyorsa Attribution Reporting API her bir URI'ye benzer bir istekte bulunur. Her reklam teknolojisi iş ortağı, aşağıdaki başlıklarla yanıt veren bir sunucu yapılandırmalıdır:

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.

Dönüşüm tetikleyicisi kaydını kabul edin

Bu uç nokta, aşağıdakine benzer bir URI'den ele alınabilmelidir:

https://adtech.example/attribution_trigger

Bir istemci uygulaması bir tetikleyici etkinliği kaydettiğinde bu sunucu uç noktası için URI sağlar. Daha sonra Attribution Reporting API bir istek gönderir ve aşağıdaki başlıklardan birini ekler:

Sunucu uç noktanızı aşağıdakilerle yanıt verecek şekilde yapılandırın:

// 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>

Aşağıda, örnek değerlerin eklendiği bir örnek verilmiştir:

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

Toplama anahtarı kimliği ve filtre dizesi başına 25 bayt sınırı vardır. Diğer bir deyişle, toplama anahtarı kimliklerinizin ve filtre dizelerinizin 25 karakteri aşmaması gerekir. Bu örnekte, campaignCounts 14 karakter olduğundan geçerli bir toplama anahtarı kimliğidir ve 1234 4 karakterdir. Bu nedenle geçerli bir filtre dizesidir. Toplama anahtarı kimliği veya filtre dizesi 25 karakteri aşarsa tetikleyici yoksayılır.

Attribution-Reporting-Redirect, reklam teknolojisi iş ortaklarının URI'lerini içeriyorsa Attribution Reporting API her bir URI'ye benzer bir istekte bulunur. Her reklam teknolojisi iş ortağı, aşağıdaki başlıklarla yanıt veren bir sunucu yapılandırmalıdır:

// 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.

Etkinlik düzeyindeki raporları kabul etme

Bu uç nokta, bir URI'den adreslenebilir olmalıdır. URI'ları kaydetme hakkında daha fazla bilgi için Özel Korumalı Alan hesabına kaydolma konusuna bakın. (URI, kaynak kaydını kabul etmek ve tetikleyici kaydını kabul etmek için kullanılan sunucuların kaynağından tahmin edilir.) Kaynak kaydını ve tetikleyici kaydını kabul eden uç noktalar için örnek URI'ler kullanıldığında bu uç noktanın URI'si:

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

Bu sunucuyu, aşağıdaki biçimi kullanan JSON isteklerini kabul edecek şekilde yapılandırın:

{
  "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]",
}

Hata ayıklama anahtarları, ilişkilendirme raporlarınız hakkında ek analizler sağlar. Bunları yapılandırma hakkında daha fazla bilgi edinin.

Birleştirilebilir raporları kabul edin

Bu uç nokta, bir URI'den adreslenebilir olmalıdır. URI'ları kaydetme hakkında daha fazla bilgi için Özel Korumalı Alan hesabına kaydolma konusuna bakın. (URI, kaynak kaydını kabul etmek ve tetikleyici kaydını kabul etmek için kullanılan sunucuların kaynağından tahmin edilir.) Kaynak kaydını ve tetikleyici kaydını kabul eden uç noktalar için örnek URI'ler kullanıldığında bu uç noktanın URI'si:

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

Birleştirilebilir raporlar için hem şifrelenmiş hem de şifrelenmemiş alanlar doldurulur. Şifrelenmiş raporlar, toplama hizmetiyle teste başlayabilmenizi sağlar. Şifrelenmemiş alan ise ayarlanan anahtar/değer çiftlerinin verileri yapılandırma şekliyle ilgili bilgi sağlar.

Bu sunucuyu, aşağıdaki biçimi kullanan JSON isteklerini kabul edecek şekilde yapılandırın:

{
  // 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]"
}

Hata ayıklama anahtarları, ilişkilendirme raporlarınız hakkında ek analizler sağlar. Bunları yapılandırma hakkında daha fazla bilgi edinin.

Android istemcisini kur

İstemci uygulaması, ilişkilendirme kaynaklarını ve tetikleyicileri kaydeder, etkinlik düzeyinde ve toplanabilir raporlar oluşturulmasını sağlar. Bir Android istemci cihazını veya emülatörü Attribution Reporting API'yi kullanmaya hazırlamak için aşağıdakileri yapın:

  1. Android'de Özel Korumalı Alan için geliştirme ortamınızı ayarlayın.
  2. Desteklenen bir cihaza sistem görüntüsü yükleyin veya Android'de Özel Korumalı Alan desteği içeren bir emülatör kurun.
  3. Aşağıdaki ADB komutunu çalıştırarak Attribution Reporting API'ye erişimi etkinleştirin. (API varsayılan olarak devre dışıdır.)

    adb shell device_config put adservices ppapi_app_allow_list \"\*\"
    
  4. Attribution Reporting API'yi yerel olarak test ediyorsanız (fiziksel olarak erişiminizin olduğu bir cihazda test etmek gibi) kaydı devre dışı bırakmak için şu komutu çalıştırın:

    adb shell device_config put adservices disable_measurement_enrollment_check "true"
    
  5. ACCESS_ADSERVICES_ATTRIBUTION iznini Android Manifest dosyanıza ekleyin ve uygulamanızın Attribution Reporting API'lerini kullanması için bir reklam hizmetleri yapılandırması oluşturun:

    <uses-permission android:name="android.permission.ACCESS_ADSERVICES_ATTRIBUTION" />
    
  6. (İsteğe bağlı) Hata ayıklama raporları almayı planlıyorsanız Android Manifest dosyanıza ACCESS_ADSERVICES_AD_ID iznini ekleyin:

    <uses-permission android:name="android.permission.ACCESS_ADSERVICES_AD_ID" />
    
  7. Manifest'inizin <application> öğesindeki bir reklam hizmetleri yapılandırmasına referans verin:

    <property android:name="android.adservices.AD_SERVICES_CONFIG"
              android:resource="@xml/ad_services_config" />
    
  8. Manifest'te referans verilen reklam hizmetleri XML kaynağını belirtin (ör. res/xml/ad_services_config.xml). Reklam hizmetleri izinleri ve SDK erişim kontrolü hakkında daha fazla bilgi

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

Reklam etkinliklerini kaydetme

Uygulamanız, kaynakları ve dönüşümleri gerçekleştikleri anda kaydetmeli ve doğru şekilde raporlanmalıdır. MeasurementManager sınıfı, ilişkilendirme kaynağı etkinliklerini ve dönüşüm tetikleyicilerini kaydetmenize yardımcı olacak yöntemler içerir.

İlişkilendirme kaynağı etkinliğini kaydetme

Bir reklam görüntülendiğinde veya tıklandığında yayıncı uygulaması, bir ilişkilendirme kaynağını kod snippet'inde gösterildiği gibi kaydetmek için registerSource() çağırır.

Attribution Reporting API aşağıdaki ilişkilendirme kaynağı etkinliği türlerini destekler:

  • Genellikle onClick() benzeri bir geri çağırma yöntemiyle kaydettiğiniz tıklama sayısı. İlgili tetikleyici etkinliği genellikle tıklama etkinliğinden kısa bir süre sonra gerçekleşir. Bu etkinlik türü, kullanıcı etkileşimi hakkında daha fazla bilgi sağlar ve bu nedenle yüksek öncelik vermek için iyi bir ilişkilendirme kaynağı türüdür.
  • Genellikle onAdShown() benzeri bir geri çağırma yöntemiyle kaydettiğiniz görüntülemeler. İlgili tetikleyici etkinliği, görüntüleme etkinliğinden saatler veya günler sonra gerçekleşebilir.

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);

Kayıttan sonra API, attributionSourceUri ile belirtilen adreste hizmet uç noktasına bir HTTP POST isteği gönderir. Uç noktanın yanıtı, destination, source_event_id, expiry ve source_priority değerlerini içerir.

Kaynak reklam teknolojisi kaynak kayıtlarını paylaşmak isterse orijinal ilişkilendirme kaynağı URI'si diğer reklam teknolojisi uç noktalarına yönlendirmeler içerebilir. Yönlendirmeler için geçerli olan sınırlar ve kurallar teknik teklifte ayrıntılı olarak açıklanmıştır.

registerSource ve registerTrigger için zincir bağlantı yönlendirmeleri desteği eklendi. API tüketicisi artık kayıt başlığına ek olarak 302 durum kodu ve ek kayıt için ziyaret edilecek sonraki URL'yi içeren "Location" üst bilgisini içeren sunucu yanıtı olarak bir HTTP yönlendirmesi sağlayabilir.

Papatya zincirinde yalnızca ilk ziyarette sağlanan "hedef" alanı kullanılır. Ziyaretlerin sayısı, "Attribution-Reporting-Redirect" başlıklarıyla aynı sınıra sahiptir. Bu yönlendirme desteği, mevcut "Attribution-Reporting-Redirect" desteğine ek olarak verilir ve her ikisi de mevcutsa "Attribution-Reporting-Redirect" tercih edilir.

Dönüşüm tetikleyici etkinliği kaydetme

Bir dönüşüm tetikleyicisi etkinliği kaydetmek için uygulamanızda registerTrigger() işlemini çağırın:

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)

Kayıttan sonra API, attributionTriggerUri ile belirtilen adreste hizmet uç noktasına bir HTTP POST isteği gönderir. Uç noktanın yanıtı, etkinlik ve toplu raporların değerlerini içerir.

Kaynak reklam teknolojisi platformu, tetikleyici kayıtlarının paylaşılmasına izin veriyorsa URI, diğer reklam teknolojisi platformlarına ait URI'lere yönlendirmeler içerebilir. Yönlendirmeler için geçerli olan sınırlar ve kurallar teknik teklifte ayrıntılı olarak açıklanmıştır.

Uygulamalar arası ve web ölçümü kaydetme

Kullanıcıdan tetikleyiciye uzanan yolculuğunda hem uygulamanın hem de tarayıcının bir parçası olduğu durumlarda, reklam etkinliklerinin kaydedilmesinde küçük farklar vardır. Kullanıcı bir uygulamada bir reklam görür ve dönüşüm için tarayıcıya yönlendirilirse kaynak, uygulama tarafından ve dönüşümü web tarayıcısı tarafından kaydedilir. Benzer bir şekilde, kullanıcı bir web tarayıcısında başlayıp dönüşüm için bir uygulamaya yönlendirilirse, tarayıcı kaynağı kaydeder ve uygulama da dönüşümü kaydeder.

Reklam teknolojilerinin web ve Android'de düzenlenme şeklinde farklılıklar olduğundan, tarayıcılarda yer aldıklarında kaynakları ve tetikleyicileri kaydetmek için yeni API'ler ekledik. Bu API'ler ile karşılık gelen uygulama tabanlı API'ler arasındaki temel fark, tarayıcının yönlendirmeleri izlemesini, tarayıcıya özel filtreler uygulamasını ve registerWebSource() veya registerWebTrigger() yöntemini çağırarak geçerli kayıtları platforma aktarmasını beklememizdir.

Aşağıdaki kod snippet'inde, tarayıcının kullanıcıyı bir uygulamaya yönlendirmeden önce bir ilişkilendirme kaynağı kaydetmek için yaptığı API çağrısının bir örneği gösterilmektedir:

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);

Aşağıdaki kod snippet'inde, kullanıcı uygulamadan yönlendirildikten sonra tarayıcının bir dönüşüm kaydetmek için yaptığı API çağrısının bir örneği gösterilmektedir:

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);

Gizlilik için ses ekleme

Etkinlik düzeyindeki raporlar hedef, ilişkilendirme kaynağı kimliği ve tetikleyici verilerini içerir. Bunlar, raporlama kaynağına orijinal (şifrelenmemiş) biçimde gönderilir. Kullanıcı gizliliğini korumak amacıyla, tek bir kullanıcının kimliğini tespit etmeyi zorlaştırmak için gürültü eklenebilir. Gürültülü etkinlik düzeyindeki raporlar, diferansiyel gizlilik çerçevesine uygun olarak oluşturulur ve gönderilir. Bunlar, farklı senaryolar için varsayılan gürültü yüzdesi değerleridir:

Kaynak türü

Kaynak hedef değeri

Kaynak kaydı başına bildirim olasılığı

Göster

Uygulama veya web

0,0000025

Göster

Uygulama ve web

0,0000042

Sonraki slayta geçin

Uygulama veya web

0,0024263

Sonraki slayta geçin

Uygulama ve web

0,0170218

Kaynakların hem uygulama hem de web hedeflerine dönüşüm sağlayabildiği uygulamadan web'e ilişkilendirme ölçümünde, etkinlik düzeyindeki raporlar tetikleyicinin uygulamada mı yoksa web'de mi gerçekleştiğini belirtebilir. Bu ek ayrıntıyı dengelemek amacıyla, oluşturulan sesli raporlar tıklamalar için yaklaşık 7 kat ve görüntülemeler için yaklaşık 1,7 kattır.

Bazı reklam teknolojileri, tetikleyicinin uygulamada mı yoksa web hedefinde mi gerçekleştiğini belirtmek için etkinlik düzeyinde raporları zorunlu kılmaz. Reklam teknisyenleri, paraziti azaltmak için Attribution-Reporting-Register-Source başlığı altındaki coarse_event_report_destinations alanını kullanabilir. coarse_event_report_destinations alanında belirtilen bir kaynak ilişkilendirmeyi kazanırsa sonuçta ortaya çıkan rapor, gerçek tetikleyicinin nerede gerçekleştiğiyle ilgili bir fark olmaksızın hem uygulama hem de web hedeflerini içerir.

Aşağıdaki örneklerde, kullanıcı bir reklamı tıklar ve bu kaynak API'ye kayıtlıdır. Daha sonra kullanıcı, hem reklamverenin uygulamasında hem de reklamverenin web sitesinde dönüşüm gerçekleştirir. Bu dönüşümlerin ikisi de tetikleyici olarak kaydedilir ve ilk tıklamayla ilişkilendirilir.

Tıklamaya dayalı kaynak kaydı HTTP üstbilgisi:

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"
}

Uygulamadan, paket adı com.advertiser.example olan bir tetikleyici kaydedildi:

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

eTLD+1 alan adına sahip web sitesindeki https://advertiser.com bir tarayıcıdan tetikleyici kaydedildi:

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

Elde edilen etkinlik düzeyinde raporlar oluşturulur. Her iki tetikleyicinin de kaynakla ilişkilendirildiği varsayıldığında, aşağıdaki etkinlik düzeyinde raporlar oluşturulur:

  {
    "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
  }

Rapor oluşturma ve yayınlama

Attribution Reporting API, sunucunuzdaki etkinlik düzeyindeki raporları ve birleştirilebilir raporları kabul eden uç noktalara raporlar gönderir.

Raporlama işlerini çalıştırmaya zorla

Bir ilişkilendirme kaynağı etkinliğini kaydettiğinizde veya bir tetikleyici etkinliği kaydettikten sonra sistem, raporlama işini çalıştırılacak şekilde planlar. Varsayılan olarak bu iş 4 saatte bir çalışır. Test amacıyla, raporlama işlerini çalıştırmaya zorlayabilir veya işler arasındaki aralıkları kısaltabilirsiniz.

İlişkilendirme işini zorla çalıştır:

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

Etkinlik düzeyinde raporlama işini çalıştırılmaya zorlayın:

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

Birleştirilebilir raporlama işini zorla çalıştır:

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

İşlerin ne zaman çalıştığını görmek için logcat'teki çıkışı kontrol edin. Şuna benzer bir görünümde olacaktır:

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

Raporların yayınlanmasını zorunlu kıl

Raporlama işi zorla çalıştırılsa bile sistem raporları yine planlanan teslimat sürelerine göre gönderir. Bu süreler birkaç saat ile birkaç gün arasında değişir. Test amacıyla, rapor teslimini başlatmak için cihazın sistem saatini planlanan gecikmelerden sonraya geçirebilirsiniz.

Sunucunuzdaki raporları doğrulama

Raporlar gönderildikten sonra, alınan raporları, sahte sunucu geçmişi veya özel sisteminiz gibi geçerli sunucu günlüklerini kontrol ederek teslimatı doğrulayın.

Toplu raporunuzun kodunu çözme

Toplu rapor alınırken debug_cleartext_payload alanı, toplu raporunuzun şifrelenmemiş bir sürümünü içerir. Raporunuzun bu sürümü şifrelenmemiş olsa da yine de kodunun çözülmesi gerekir.

Aşağıda, debug_cleartext_payload alanının içeriğinin kodunu iki adımda çözmeyle ilgili bir örnek verilmiştir: ilki Base 64 kod çözme yöntemini, ikincisi ise CBOR kod çözme yöntemini kullanarak.

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);
});

Test

Attribution Reporting API'yi kullanmaya başlamanıza yardımcı olması için GitHub'daki MeasurementSampleApp projesini kullanabilirsiniz. Bu örnek uygulama, ilişkilendirme kaynağı kaydını ve tetikleyici kaydını göstermektedir.

Sunucu uç noktaları için aşağıdaki referans kaynaklarını veya özel çözümünüzü göz önünde bulundurun:

  • MeasurementAdTechServerSpec, desteklenen bir sahte veya mikro hizmet platformlarına dağıtılabilen OpenAPI hizmet tanımları içerir.
  • MeasurementAdTechServer, Google App Engine için Spring Boot uygulamasına dayalı bir örnek sunucunun referans uygulamasını içerir.

Ön koşullar

Test cihazınızdan veya emülatörünüzden erişilebilen uzak uç noktalara örnek API'ler dağıtın. Test kolaylığı için MeasurementAdTechServerSpec ve MeasurementAdTechServer örnek projelerine bakın.

Test edilecek işlevler

Yakında eklenecek özellikler

Etkinlik düzeyinde esnek yapılandırma

Etkinlik düzeyinde raporlama için varsayılan yapılandırma, yardımcı program testlerinin başlatılması için önerilir ancak tüm kullanım alanları için ideal olmayabilir. Attribution Reporting API isteğe bağlı, daha esnek yapılandırmaları destekleyecektir. Böylece reklam teknolojileri, etkinlik düzeyindeki raporların yapısı üzerinde daha fazla kontrole sahip olur ve verilerden en iyi şekilde yararlanabilir. Bu ek esneklik, Attribution Reporting API'ye iki aşamada eklenecek:

  • 1. Aşama: Esnek etkinlik düzeyinde yapılandırma; 2. Aşama'nın alt kümesidir.
  • 2. Aşama: Etkinlik düzeyinde esnek yapılandırmanın tam sürümü.

1. Aşama: Lite esnek etkinlik düzeyi

Attribution-Reporting-Register-Source içindeki JSON dosyasına aşağıdaki iki isteğe bağlı parametreyi ekleyeceğiz:

  • 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>, ...]
  }
}

Özel yapılandırma örneği

Bu örnek yapılandırma, önceki raporlama dönemlerinde rapor almak için optimizasyon yapmak isteyen bir geliştiriciyi destekler.

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

2. Aşama: Tam esnek etkinlik düzeyi

1. Aşamada eklenen parametrelere ek olarak, Attribution-Reporting-Register-Source'teki JSON'ye trigger_specs isteğe bağlı ek parametresi de ekleyeceğiz.

{
  // 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>, ...]
  }
}

Bu yapılandırma, kaynak kaydı başına etkinlik düzeyindeki raporların çıkış alanını tam olarak belirtir. Her tetikleyici spesifikasyonu için aşağıdakileri tam olarak belirtiriz:

  • Eşleşen ölçütler grubu:
    • Bu spesifikasyonun geçerli olduğu tetikleyici verileri. Bu kaynak, yalnızca trigger_specs öğesinde belirtilen trigger_data değerlerinden birine sahip tetikleyicilerle eşleştirilmeye uygundur. Başka bir deyişle, tetikleyici bu kaynakla eşleştiyse ancak trigger_data, kaynak yapılandırmasındaki değerlerden biri değilse tetikleyici yok sayılır.
    • Belirli bir tetikleyici bu spesifikasyonla eşleştiğinde (event_report_windows kullanılarak). Daha önce bahsedilen iki eşleşme ölçütü başarısız olsa bile tetikleyicinin yine de toplanabilir raporların bir kaynağıyla eşleştirilebileceğini unutmayın.
  • Bir ilişkilendirme dönemindeki tüm tetikleyicileri özetlemek ve gruplandırmak için kullanılan özel bir algoritma. Böylece tetikleyiciler, belirli bir spesifikasyon için toplanan ancak gruplanmış değer olarak raporlanan bir value parametresi belirtebilir.

Tetikleyiciler event_trigger_data içindeki sözlüklere isteğe bağlı bir değer parametresi eklemeyi de destekleyecektir.

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

Her tetikleyici kaydı en fazla bir tetikleyici özelliğiyle eşleşir ve bununla ilişkili özet değerini günceller. Genel olarak, tetikleyici anında şunları yaparız:

  • Genel ilişkilendirme filtreleri uygulama.
  • Her tetikleyici spesifikasyonu için event_reporting_window özelliğini kullanarak bir eşleşme bulmak üzere spesifikasyondaki event_trigger_data öğesini değerlendirin. Herhangi bir tetikleyici spesifikasyonunun eksik event_report_windows alt alanı olması durumunda üst düzey event_reporting_windows, varsayılan değer olarak kullanılır.
  • İlişkilendirme için eşleşen ilk spesifikasyon seçilir ve özet değeri value artırılır.

Bir spesifikasyon için event_report_window tamamlandığında, özet değerini bir paketle eşler ve özet paketinde ilişkilendirilen tetikleyici değerlerinin neden olduğu her artış için etkinlik düzeyinde bir rapor göndeririz. Raporlarda ekstra bir alan (trigger_summary_bucket) bulunur.

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

Mevcut sürüme eşdeğer yapılandırmalar

Aşağıda, sırasıyla API'lerin geçerli etkinliği ve gezinme kaynakları için eşdeğer yapılandırmalar bulunmaktadır. Bu, özellikle gezinme kaynakları söz konusu olduğunda gürültü düzeylerinin, aynı epsilon değerlerini korumak için etkinlik kaynaklarına göre neden çok yüksek olduğunu gösterir: Gezinme kaynaklarında çıkış alanı çok daha geniştir.

Bazı parametrelerin varsayılan olarak ayarlanabildiği veya kısaltılabildiği için, eşdeğer olan birden fazla yapılandırma olabilir.

Eşdeğer etkinlik kaynakları
// 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>,
}
Eşdeğer gezinme kaynakları
// 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>,
}

Örnek özel yapılandırmalar

Aşağıda, varsayılanların dışında kalan bazı ek yapılandırmalar bulunmaktadır. Bu örneklerin tümünde, geliştirici dengeleri aşağıdakileri içerir:

  • gürültü seviyesini korumak için başka bir boyut artırmak amacıyla varsayılan yapılandırmanın bazı boyutlarının (tetikleyiciler, veri kardinalitesinin tetiklenmesi, #windows) azaltılması
  • Daha düşük gürültü seviyesi için varsayılan yapılandırmanın bazı boyutlarının (tetikleyiciler, veri kardinalitesini tetikleme, #windows) azaltılması

Rapor tetikleyici değer grupları

Bu örnek yapılandırmada, yalnızca tek bir raporlama döneminde (ör. 7 gün) değer verileri için optimizasyon yapmak ve daha az gürültüyle daha az raporlama aralığı takas etmek isteyen bir geliştiriciyi destekleriz. Bu örnekte, trigger_data değerini 0 dışında bir değere ayarlayan tetikleyiciler ilişkilendirme için uygun değildir.

{
  "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]
  }],
}

Tetikleyiciler, toplanıp paketlenen value alan grubuna kaydedilebilir. Örneğin, 1, 3 ve 4 değerlerine sahip kaynak kayıtlarından sonraki 7 gün içinde üç tetikleyici mevcutsa.

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

Değerler 8 olarak toplanır ve 7 gün + 1 saat sonra aşağıdaki raporlarda raporlanır:

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

Sonraki 7 gün içinde aşağıdaki tetikleyiciler kaydedilir:

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

Değerler 8 + 50 + 45 = 103 olarak toplanır. Bu, 14 gün + 1 saatte aşağıdaki raporları verir:

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

// Report 3
{
  ...
  "trigger_summary_bucket": [100, MAX_INT]
}
Rapor tetikleyici sayıları

Bu örnekte, geliştiricinin bir kaynağı 10'a kadar tetikleyici sayısı almak için nasıl yapılandırabileceği gösterilmektedir.

{
  "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 özelliğinin 0 olarak ayarlandığı ilişkilendirilmiş tetikleyiciler sayılır ve 10 ile sınırlandırılır. summary_window_operator saymaya ayarlandığından tetikleyici değeri yok sayılır. 4 tetikleyici kaydedilir ve kaynakla ilişkilendirilirse rapor aşağıdaki gibi görünür:

// 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]
}
Daha sık raporlamaya sahip ikili program

Bu örnek yapılandırma, ilk 10 gün içinde en az bir dönüşümün (değerden bağımsız olarak) gerçekleşip gerçekleşmediğini öğrenmek isteyen ancak varsayılandan daha sık aralıklarla rapor almak isteyen bir geliştiriciyi destekler. Yine bu örnekte, trigger_data değerini 0 dışında bir değere ayarlayan hiçbir tetikleyici ilişkilendirme için uygun değildir. Bu nedenle bu kullanım alanına ikili adı verilir.

{
  "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]
  }],
}
Tetikleyici özelliklerini kaynaktan kaynağa çeşitlendirin
{
  "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
}

Geliştiricilere, bu API uzantısı için kullanabilecekleri farklı kullanım alanları önermelerini öneririz. Bu açıklayıcıyı, bu kullanım alanları için örnek yapılandırmalarla güncelleyeceğiz.

Yönlendirmeler olmadan ağlar arası ilişkilendirme

Reklam teknolojileri, birden fazla ilişkilendirme kaynağı tetikleyicisini kaydetmek ve ağlar arası ilişkilendirme gerçekleştirmek için yönlendirmeleri kullanmalıdır. Bu özellik, farklı ağlarda yönlendirmelerin uygun olmadığı durumlarda ağlar arası ilişkilendirmeyi desteklemeye yardımcı olur. Daha fazla bilgi edinin.

Reklam teknolojileri, türetilmiş kaynaklar oluşturmak için diğer reklam teknolojileri tarafından kaydedilen hangi kaynakların seçildiğine bağlı olarak tetikleyici kayıt yanıtında yapılandırma gönderebilir. Türetilen bu kaynaklar daha sonra ilişkilendirme için kullanılır. Tetikleyici, türetilmiş bir kaynakla ilişkilendirilirse toplu raporlar oluşturulur. Türetilmiş kaynaklar için etkinlik raporu oluşturma işlemi desteklenmez.

Reklam teknolojileri, iş ortağı reklam teknolojileriyle paylaşmak istedikleri kayıtlı kaynaklarındaki aggregation_keys arasından seçim yapabilir. Bu anahtarlar, Attribution-Reporting-Register-Source kaynak kaydı başlığının altında bulunan isteğe bağlı shared_aggregation_keys alanında bildirilebilir:

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

Türetilen kaynaklar, Attribution-Reporting-Register-Trigger tetikleyici kaydı başlığı altındaki yapılandırmaya göre oluşturulur:

  // 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]"
    }
  ]

Örnek değerler eklenmiş bir sürümü burada bulabilirsiniz:

  "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"
    }
  ]

Kayıt başlığını tetiklemek için iki yeni isteğe bağlı alan eklendi. Bu alanlar, toplanabilir rapor anahtarlarında kazanan reklam teknolojisinin tanımlayıcısını etkinleştirir:

  • x_network_bit_mapping: Kayıt kimliğinden reklam teknolojisi tanımlayıcısı bit eşlemesine
  • x_network_data: Kazanan reklam teknolojisinin x_network_bit_mapping VEYA işlemi için tetikleyici temel parçasıyla göreli konum (sol kayma)
Örnek:
"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'nin kaynağı için rapor oluşturulurken oluşan tetikleyici temel parça hesaplaması şöyledir:

  • key_piece: 0x400 (010000000000)
  • key_offset: 12
  • AdtechB'nin enrollment_id değeri: 2 (010) (x_network_bit_mapping değerinden)
  • Sonuçta ortaya çıkan Tetikleyici Anahtarı: 0x400 | 0x2 << 12 = 0x2400

Sınırlamalar

SDK Çalışma Zamanı ile ilgili devam etmekte olan özelliklerin listesi için sürüm notlarını inceleyin.

Hataları ve sorunları bildirme

Geri bildirimleriniz, Android'de Özel Korumalı Alan için çok önemlidir. Karşılaştığınız sorunları veya Android'de Özel Korumalı Alan'ın iyileştirilmesiyle ilgili fikirlerinizi bize bildirebilirsiniz.