Attribution Reporting API geliştirici kılavuzu

Android'de Özel Korumalı Alan dokümanlarını okurken, talimatlar değişiklik gösterebileceğinden, üzerinde çalıştığınız program sürümünü seçmek için Geliştirici Önizlemesi veya Beta düğmesini kullanın.


Attribution Reporting API, kullanıcı gizliliğini iyileştirmek için Taraflar arası kullanıcı tanımlayıcılarına bağımlılığı ortadan kaldırmak ve temel kullanım alanlarını desteklemek ölçüm için sıfırdan tasarlandı. Bu geliştirici kılavuzunda, bu tür etkinliklerle ilgili ilgili tetikleyicileri ve kaynakları kaydeden yöntemleri çağırarak reklam tıklamalarını, görüntülemelerini ve dönüşümlerini kaydetmek için Attribution Reporting API'lerin nasıl yapılandırılacağı ve test edileceği açıklanmaktadır.

Bu kılavuzda, sunucu uç noktalarını nasıl ayarlayacağınız ve bu hizmetleri çağıran bir istemci uygulaması nasıl oluşturacağınız açıklanmaktadır. İlişkilendirmenin genel tasarımı hakkında daha fazla bilgi Tasarım teklifindeki Reporting API.

Anahtar Terimler

  • İlişkilendirme kaynakları, tıklamaları veya görüntülemeleri ifade eder.
  • Tetikleyiciler, dönüşümlerle ilişkilendirilebilecek etkinliklerdir.
  • Raporlar, bir tetikleyici ve ilgili ilişkilendirmeyle ilgili verileri içerir. kaynak. Bu raporlar, tetikleyici etkinliklere yanıt olarak gönderilir. İlgili içeriği oluşturmak için kullanılan Attribution Reporting API, etkinlik düzeyindeki raporları ve birleştirilebilir raporlar.

Başlamadan önce

İlişkilendirme Raporlama API'sini kullanmak için aşağıdaki bölümlerde listelenen sunucu tarafı ve istemci tarafı görevleri tamamlayın.

Attribution Reporting API uç noktalarını ayarlama

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

Gerekli uç noktaları ayarlamak için kullanılabilecek birkaç yöntem vardır:

  • Başlayıp çalışmaya başlamanın en hızlı yolu, örnek kod deposumuzdaki OpenAPI v3 hizmet tanımlarını bir örnek veya mikro hizmet platformuna dağıtmaktır. Tekliflerinizi otomatikleştirmek ve optimize etmek için Postman, Prism veya başka bir sahte sunucu bu biçimi kabul eden bir platform. Her bir uç noktayı dağıtın ve takip edin uygulamanızda kullanılacak URI'lar. Rapor teslimini doğrulamak için benzerlikler daha iyidir.
  • 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 dahili altyapınıza dağıtın.
  • Uç noktaları mevcut sisteminize entegre etmek için hizmet tanımlarını örnek olarak kullanın.
ziyaret edin.

Kaynak kaydını kabul etme

Bu uç nokta, aşağıdakine benzer bir URI'dan adreslenebilir:

https://adtech.example/attribution_source

Bir istemci uygulaması bir ilişkilendirme kaynağını kaydettiğinde, uygulamanın Search Ads 360'taki bu sunucu uç noktasını oluşturur. İlişkilendirme Raporlama API'si daha sonra bir istek gönderir ve aşağıdaki başlıklardan birini ekler:

  • Tıklama etkinlikleri için:

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

    Attribution-Reporting-Source-Info: event
    

Sunucu uç noktanızı aşağıdaki 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>

Örnek değerlerin eklendiği bir örneği aşağıda bulabilirsiniz:

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 Daha sonra Attribution Reporting API her URI'ye benzer bir istek gönderir. Tüm reklam teknolojileri iş ortağının şu başlıklarla yanıt veren bir sunucu yapılandırması gerekir:

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 tetikleyici kaydını kabul etme

Bu uç nokta, aşağıdakine benzer bir URI'den adreslenebilir olmalıdır:

https://adtech.example/attribution_trigger

Bir istemci uygulaması tetikleyici etkinliği kaydettiğinde bu sunucu uç noktasının URI'sini sağlar. Ardından İlişkilendirme Raporlama API'si bir istek gönderir ve aşağıdaki başlıklardan birini ekler:

Sunucu uç noktanızı aşağıdakileri yanıtlayacak ş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. Bu toplama anahtarı kimliklerinizin ve filtre dizelerinizin 25'i geçmemesi gerektiği anlamına gelir. karakteri ekleyin. Bu örnekte, campaignCounts 14 karakter olduğu için geçerli bir toplama anahtarı kimliği ve 1234 4 karakter olduğundan geçerli bir filtre dizesidir. Toplama anahtarı kimliği veya filtre dizesi 25 karakteri aşarsa tetikleyici yoksayıldı.

Attribution-Reporting-Redirect, reklam teknolojisi iş ortaklarının URI'lerini içeriyorsa İlişkilendirme Raporlama API'si her URI için benzer bir istek gönderir. Her reklam teknolojisi iş ortağı, aşağıdaki üst bilgilerle 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. Gizlilik için kaydolma Korumalı alan hesabı'nı ziyaret edin. (URI kaynak kaydını kabul etmek ve kontrol etmek için kullanılan sunucuların kaydı tetikler.) Kaynak kaydını kabul eden ve tetikleyici kaydını kabul eden uç noktalar için örnek URI'leri kullanarak bu uç noktanın URI'si şu şekildedir:

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ızla ilgili ek analizler elde etmenizi sağlar. Bunları yapılandırma hakkında daha fazla bilgi edinin.

Toplanabilir raporları kabul etme

Bu uç nokta, URI'den adreslenebilir olmalıdır. Gizlilik için kaydolma Korumalı alan hesabı'nı ziyaret edin. (URI, kaynak kaydını kabul etmek ve tetikleyici kaydı başlatmak için kullanılan sunucuların kaynağından anlaşılır.) Kaynağı kabul eden uç noktalar için örnek URI'leri kullanma kaydı ve tetikleyici kaydını kabul edin ise bu uç noktanın URI'sı şöyledir:

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

Hem şifrelenmiş hem de şifrelenmemiş alanlar, birleştirilebilir raporlar için doldurulur. Şifrelenmiş raporlar, toplama hizmetini kullanarak test yapmaya başlamanıza olanak tanır. Şifrelenmemiş alan ise ayarlanan anahtar/değer çiftlerinin verileri yapılandırma şekli hakkında 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ızla ilgili ek analizler elde etmenizi sağlar. Bunları yapılandırma hakkında daha fazla bilgi edinin.

Android istemcisini kurma

Müşteri uygulaması, ilişkilendirme kaynaklarını ve tetikleyicileri kaydeder, etkinlik düzeyinde ve toplanabilir rapor oluşturmayı etkinleştirir. Bir Android istemci cihazını veya emülatörünü Attribution Reporting API'yi kullanmak üzere 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 resmi yükleyin veya Android'de Privacy Sandbox desteği içeren bir emülatör oluşturun.
  3. Attribution Reporting API'ye erişimi etkinleştirmek için aşağıdaki ADB komutunu kullanır. (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 (ör. fiziksel olarak erişiminiz olan bir cihazda test ediyorsanız) 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. AndroidManifest dosyanıza ACCESS_ADSERVICES_ATTRIBUTION iznini ekleyin ve uygulamanızın Attribution Reporting API'lerini kullanabilmesi için 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. Şu öğenin <application> öğesinde bir reklam hizmetleri yapılandırmasına başvuruda bulun: manifest dosyanız:

    <property android:name="android.adservices.AD_SERVICES_CONFIG"
              android:resource="@xml/ad_services_config" />
    
  8. Manifest'te başvurulan reklam hizmetleri XML kaynağını belirtin. Örneğin, res/xml/ad_services_config.xml Reklam hizmetleri izinleri ve SDK erişim denetimi hakkında daha fazla bilgi edinin.

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

Reklam etkinliklerini kaydetme

Uygulamanız, doğru şekilde raporlanmaları için kaynakları ve dönüşümleri gerçekleştikleri sırada kaydetmelidir. MeasurementManager sınıfında yöntemler var. ve ilişkilendirme kaynağı etkinliklerini kaydetmenize dönüşüm tetikleyicileri.

İlişkilendirme kaynağı etkinliği kaydetme

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

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

  • Genellikle onClick()'ye benzer bir geri arama yönteminde kaydettiğiniz tıklamalar. İlgili tetikleyici etkinlik genellikle tıklama etkinliğinden kısa süre sonra gerçekleşir. Bu etkinlik türü, kullanıcı hakkında daha fazla bilgi sağlar ve bu nedenle doğru bir değer vermek için iyi bir ilişkilendirme yüksek öncelikli.
  • Genellikle onAdShown()'e benzer bir geri arama yönteminde kaydettiğiniz görüntüleme sayısı. Karşılık gelen tetikleme etkinliği saatler veya günler sürebilir görüntüleme etkinliğinden sonra gelir.

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, hizmet uç noktasına bir HTTP POST isteği gönderir attributionSourceUri tarafından belirtilen adrestedir. 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 istiyorsa orijinal ilişkilendirme kaynağı URI'si diğer reklam teknolojisi uç noktalarına yönlendirmeler içerebilir. Yönlendirmeler için geçerli sınırlar ve kurallar teknik teklifte ayrıntılı olarak açıklanmıştır.

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

Yalnızca "hedef" ilk ziyarette sağlanan alan kullanılıyor bir zincir atmış oluyorsunuz. Ziyaret sayısı, "Attribution-Reporting-Redirect" başlıklarıyla aynı sınıra sahiptir. Bu yönlendirme desteği, mevcut "Attribution-Reporting-Redirect"i kullanarak ve her ikisi de mevcut, "Attribution-Reporting-Redirect" üzerine de konuştuk.

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

Bir dönüşüm tetikleyici etkinliği kaydetmek için uygulamanızda registerTrigger() komutunu ç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ıt işleminden sonra API, attributionTriggerUri tarafından belirtilen adresteki hizmet uç noktasına bir HTTP POST isteği gönderir. Uç noktasını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 ve web arasında ölçüm kaydetme

Hem uygulamanın hem de tarayıcının, kullanıcının arasında küçük farklar vardır. Reklam etkinliklerini kaydetme işleminin uygulanması. Kullanıcı bir uygulamada bir reklam görür ve dönüşüm için tarayıcıya yönlendirilir, kaynak uygulama tarafından kaydedilir web tarayıcısı tarafından gerçekleştirilen dönüşümü ifade eder. Benzer şekilde, bir kullanıcı bir web tarayıcısında başlar ve dönüşüm için bir uygulamaya yönlendirilirse tarayıcı kaynağı, uygulama ise dönüşümü kaydeder.

Reklam teknolojilerinin web'deki ve internetteki organizasyon şekilleri arasında farklılıklar olduğundan, Android için farklı cihazlarda kaynak ve tetikleyicileri kaydetmek için yeni API'ler bir yer. Bu API'ler ile karşılık gelen temel alan API'ler, tarayıcının yönlendirmeleri izlemesini bekleriz. tarayıcıya özgü filtrelerle birlikte geçerli kayıtları, registerWebSource() veya registerWebTrigger() aranıyor.

Aşağıdaki kod snippet'inde, tarayıcının kullanıcıyı bir uygulamaya yönlendirmeden önce ilişkilendirme kaynağını kaydetmek için yaptığı API çağrısı ö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'i, tarayıcının desteklediği API çağrısına ait Kullanıcı uygulamadan yönlendirildikten sonra bir dönüşüm kaydetmek için kullandığı araçlar:

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 gürültü ekleme

Etkinlik düzeyindeki raporlar hedef, ilişkilendirme kaynağı kimliği ve tetikleyici verilerini içerir. Bunlar, raporlamaya orijinal (şifrelenmemiş) biçimde gönderilir kaynak. Kullanıcı gizliliğini korumak amacıyla gürültü eklenebilir. benzersiz bir tanımlayıcıdır. Gürültü eklenmiş etkinlik düzeyindeki raporlar, diferansiyel gizlilik çerçevesine uygun olarak oluşturulur ve gönderilir. Farklı senaryolar için varsayılan gürültü yüzdesi değerleri şunlardır:

Kaynak türü

Kaynak hedef değeri

Kaynak kaydı başına gürültülü rapor olasılığı

Göster

Uygulama veya web

0,0000025

Göster

Uygulama ve web

0,0000042

Tıklama

Uygulama veya web

0,0024263

Tıklama

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ı telafi etmek için oluşturulan gürültülü raporlar, tıklamalar için yaklaşık 7 kat ve görüntülemeler için yaklaşık 1,7 kat daha fazladır.

Bazı reklam teknolojileri, tetikleyicinin uygulamada mı yoksa web hedefine mi gerçekleştiğini belirtmek için etkinlik düzeyinde raporlara ihtiyaç duymaz. Reklam teknolojileri coarse_event_report_destinations alanı Gürültüyü azaltmak için Attribution-Reporting-Register-Source başlık. Bir kaynak belirtilen coarse_event_report_destinations alanı ilişkilendirmeyi kazanır, sonuçta ortaya çıkan rapor, nerede gerçekleştiğini biliyorsunuz.

Aşağıdaki örneklerde, kullanıcı bir reklamı tıklar ve bu kaynak API'ye kaydedilir. Daha sonra kullanıcı, hem reklamveren uygulamasında hem de reklamverenin web sitesine. Bu dönüşümlerin her ikisi de tetikleyici olarak kaydedilir ve ilk tıklamayla ilişkilendirilir.

Tıklama tabanlı 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 com.advertiser.example paket adıyla bir tetikleyici kaydedilir:

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

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

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

Elde edilen etkinlik düzeyinde raporlar oluşturulur. Her iki tetikleyicinin de kaynağa 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 uç noktalara Etkinlik düzeyinde raporları ve birleştirilebilir raporları kabul edin.

Raporlama işlerini çalışmaya zorla

Bir ilişkilendirme kaynağı etkinliğini veya tetikleyici etkinliği kaydettikten sonra raporlama işinin çalışmasını planlar. Bu iş varsayılan olarak 4 saatte bir çalışır. Test amacıyla raporlama işlerini çalıştırılmaya zorlayabilir veya işlerinizin sayısını kısaltabilirsiniz. izin verir.

İlişkilendirme işini çalışmaya zorla:

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

Etkinlik düzeyinde raporlama işinin çalıştırılmasını zorunlu kılın:

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

Toplanabilir raporlama işinin çalıştırılmasını zorlama:

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. Aşağıdaki gibi görünecektir:

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

Raporların teslim edilmesinin zorunlu kılınması

Raporlama işi zorla çalıştırılmış olsa bile sistem, raporları planlanmış teslimat sürelerine göre göndermeye devam eder. Bu süreler birkaç saat ile birkaç gün arasında değişir. Test amacıyla cihaz sistemini ilerletebilirsiniz planlanan gecikmelerden sonra beklenmesi gereken süreyi kısaltır.

Sunucunuzdaki raporları doğrulama

Raporlar gönderildikten sonra, alınan raporları ve geçerli sunucu günlüklerini (ör. örnek sunucu geçmişi veya özel sisteminiz) 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ü kullanın. Raporunuzun bu sürümü şifrelenmiş olmasa da kodun çözülmesi gerekir.

Aşağıda, debug_cleartext_payload alanının içeriğinin iki adımda kodunun çözüldüğü bir örnek verilmiştir: İlk adımda Base64 kod çözme, ikinci adımda ise CBOR kod çözme kullanılmıştır.

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 projesine gidin. Bu örnek uygulamada gösterilenler: ilişkilendirme kaynağı kaydı ve tetikleyici kaydı.

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

  • MeasurementAdTechServerSpec, OpenAPI hizmet tanımlarını, Bu API, desteklenen örnek veya mikro hizmet platformlarına dağıtılabilir.
  • 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örden erişilebilen uzak uç noktalara örnek API'ler dağıtın. Testi kolaylaştırmak için MeasurementAdTechServerSpec ve MeasurementAdTechServer örnek projelerine bakın.

Test edilecek işlevsellik

Yakında kullanıma sunulacak özellikler

Etkinlik düzeyinde esnek yapılandırma

Yardımcı program testini başlatmak için etkinlik düzeyinde raporlama için varsayılan yapılandırma önerilir ancak bu yapılandırma tüm kullanım alanları için ideal olmayabilir. Attribution Reporting API, reklam teknolojilerinin etkinlik düzeyindeki raporlarının yapısı üzerinde daha fazla kontrol sahibi olması ve verilerin faydasını en üst düzeye çıkarabilmesi için isteğe bağlı, daha esnek yapılandırmaları destekleyecektir. Bu ekstra esneklik, Attribution Reporting API iki aşamada kullanıma sunulacaktır:

  • 1. Aşama: Basit esnek etkinlik düzeyi yapılandırması; 2. Aşama'nın alt kümesi.
  • 2. Aşama: Esnek etkinlik düzeyinde yapılandırmanın tam sürümü.

1. Aşama: Basit ve esnek etkinlik düzeyi

Attribution-Reporting-Register-Source içinde JSON'a aşağıdaki iki isteğe bağlı parametreyi ekleriz:

  • 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, raporları daha erken raporlama dönemlerinde almak için optimizasyon yapmak isteyen geliştiricileri 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şama'da eklenen parametrelere ek olarak isteğe bağlı ek parametre olan trigger_specs, Attribution-Reporting-Register-Source.

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

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

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

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

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

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

  • Eşleşme ölçütleri grubu:
    • Bu spesifikasyonun geçerli olduğu tetikleyici verileri. Bu kaynak yalnızca belirtilen tetikleyicilerden birine sahip tetikleyicilerle eşleştirilmeye uygun olmalıdır: trigger_specs içindeki trigger_data değerleri. Diğer bir deyişle, tetikleyici bu kaynakla eşleşecek olsaydı ancak trigger_data değeri, kaynağın yapılandırmasında yer alan değerlerden biri değilse tetikleyici yoksayılır.
    • Belirli bir tetikleyici bu spesifikasyonla eşleştiğinde ( event_report_windows) bilgileri gösterilir. Tetikleyicinin hâlâ eşleşebileceğini unutmayın iki eşleşme başarısız olmasına rağmen toplanabilir raporlar için bir kaynak içerir kriterlere göre belirlenir.
  • İçerdeki tüm tetikleyicileri özetlemek ve gruplandırmak için kullanılan özel bir algoritma ilişkilendirme dönemidir. Bu sayede tetikleyiciler, belirli bir özellik için toplanan ancak gruplandırılmış bir değer olarak raporlanan bir value parametresi belirtebilir.

Tetikleyiciler event_trigger_data içindeki sözlükler.

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

Her tetikleyici kaydı, en fazla bir tetikleyici spesifikasyonu ve güncellemeyle eşleşir. ilişkili özet değerine ayarlanır. Genel olarak, tetikleme zamanında şunları yaparız:

  • Genel ilişkilendirme filtreleri uygulayın.
  • Her tetikleyici spesifikasyonu için spesifikasyondaki event_trigger_data'yi değerlendirerek eşleşmesi gerekir.event_reporting_window Üst düzey event_reporting_windows, herhangi bir tetikleyici spesifikasyonunun eksik event_report_windows alt alanı olması durumunda varsayılan değer olarak işlev görür.
  • İlişkilendirme için ilk eşleşen özellik seçilir ve özet değer: value oranında artırıldı.

Bir spesifikasyonla ilgili event_report_window tamamlandığında ilgili spesifikasyonun özetini eşleriz. bir pakete ekler ve tüm artış için etkinlik düzeyinde bir rapor gönderir ilişkilendirilen tetikleyici değerlerinden kaynaklanan özet paketi. Raporlar bir ekstra alan, trigger_summary_bucket.

{
  ...
  "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 mevcut etkinliği ve gezinme kaynakları için eşdeğer yapılandırmalar verilmiştir. Özellikle gezinme kaynakları için bu, aynı epsilon değerlerini korumak amacıyla etkinlik kaynaklarına kıyasla neden bu kadar yüksek gürültü seviyelerinin olduğunu gösterir: Gezinme kaynaklarının çok daha büyük bir çıkış alanı vardır.

Eşdeğer birden fazla yapılandırmanın mevcut olması mümkündür: bazı parametrelerin varsayılan olarak ayarlanabileceği veya kısaltılabileceği anlamına gelir.

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 verilmiştir. Tüm bu örneklerde geliştirici için değiş tokuş edilecekler şunlardır:

  • varsayılan yapılandırmanın bazı boyutlarını azaltma (#tetikleyiciler, tetikleyici veriler kardinalite, #windows) kullanarak gürültü düzeyini korumak amacıyla başka bir değeri artırmak için
  • Varsayılan yapılandırmadaki bazı boyutları azaltarak (ör. #triggers, tetikleyici veri kardinalitesi, #windows) gürültü düzeyini düşürme

Tetikleyici değer gruplarını raporlama

Bu örnek yapılandırma, değer için optimizasyon yapmak isteyen bir geliştiriciyi destekler. yalnızca bir raporlama aralığı (ör. 7 gün) için veri içerir, daha az raporlama pencerelerin önüne geçmeyi amaçlar. Bu örnekte, trigger_data değerini 0 dışında bir değere ayarlayan tüm 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, toplanan ve gruplandırılan value alan kümesine kaydedilebilir. Örneğin, kaynaktan sonraki 7 gün içinde üç tetikleyici varsa değerleri 1, 3 ve 4 değerleriyle kaydedilir.

{ "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'e 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 işlem, başlangıç düzeyinde aşağıdaki raporları oluşturur: 14 gün + 1 saat:

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

// Report 3
{
  ...
  "trigger_summary_bucket": [100, MAX_INT]
}
Tetikleyici sayılarını raporlama

Bu örnekte, bir geliştiricinin toplam etkinlik sayısını görüntülemek için bir kaynağı nasıl yapılandırabileceği 10'a kadar tetiklenir.

{
  "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ği 0 olarak ayarlanmış ilişkilendirilmiş tetikleyiciler sayılır ve 10 ile sınırlandırılır. summary_window_operator sayma olarak ayarlandığından tetikleyici değeri yoksayılır. 4 tetikleyici kaydedilip kaynağa 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 raporlama sağlayan ikili program

Bu örnek yapılandırma, aynı zamanda ilk 10 günde en az bir dönüşüm gerçekleşmiş (değerden bağımsız olarak), ancak varsayılan ayardan daha sık aralıklarla rapor almak istiyor. Bu örnekte Bu örnekte, trigger_data öğesini 0 dışında bir değere ayarlayan herhangi bir tetikleyici ilişkilendirmeye uygun değil. Bu nedenle, söz konusu kullanım alanı binary değerleridir.

{
  "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 özellikleri kaynaktan kaynağa değişiklik gösterebilir.
{
  "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ştiricileri bu API uzantısı için kullanabilecekleri farklı kullanım alanlarını önermeye teşvik ediyoruz. Bu kullanım alanlarına yönelik örnek yapılandırmalarla bu açıklamayı güncelleyeceğiz.

Yönlendirmesiz ağlar arası ilişkilendirme

Reklam teknolojileri, birden fazla ilişkilendirme kaynağı tetikleyicisini kaydetmek için yönlendirmeleri kullanmalıdır. ve ağlar arası ilişkilendirme yapmanızı sağlar. Bu özellik, Yönlendirmelerin ağlar arasında uygun olmadığı ağlar arası ilişkilendirme. Daha fazla bilgi edinin.

Reklam teknolojileri, tetikleyici kayıt yanıtında türetilmiş verileri üretmek için diğer reklam teknolojileri tarafından kaydedilen kaynakların seçildiği kaynaklar; Bu türetilen kaynaklar daha sonra ilişkilendirme için kullanılır. Raporları birleştir Tetikleyici, türetilmiş bir kaynakla ilişkilendirilirse oluşturulur. Türetilmiş kaynaklar için etkinlik raporu oluşturma desteklenmez.

Reklam teknolojileri, kayıtlı kaynaklarındaki aggregation_keys arasından seçim yapabilir. iş ortağı reklam teknolojileriyle paylaşmayı planlıyorlar. Bu anahtarlar isteğe bağlı shared_aggregation_keys alanı (kaynak kaydının altında bulunur) başlık Attribution-Reporting-Register-Source:

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

Türetilen kaynaklar, tetikleyicinin altındaki yapılandırmaya göre oluşturulur kayıt başlığı 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]"
    }
  ]

Örnek değerlerin eklendiği bir sürümü aşağıda 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 kazanan reklam teknolojisinin tanımlayıcısını toplanabilir rapor anahtarlarında etkinleştirin:

  • x_network_bit_mapping: Kayıt kimliği ile reklam teknolojisi tanımlayıcısı bit eşleme
  • x_network_data: Kazanan reklam teknolojisinin tetikleyici anahtar parçasıyla OR işlemi için ofset (sol kaydırma)x_network_bit_mapping
Ö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
  }
  
}

Şu kampanya için rapor oluştururken elde edilen tetikleyici anahtar parçası hesaplaması: AdTechB'nin kaynağı:

  • key_piece: 0x400 (010000000000)
  • key_offset: 12
  • AdtechB'nin enrollment_id değeri: 2 (010) (şu değerden x_network_bit_mapping)
  • Sonuç Tetikleyici Anahtarı parçası: 0x400 | 0x2 << 12 = 0x2400

Sınırlamalar

SDK Çalışma Zamanı ile ilgili devam eden özelliklerin listesi için sürüm notları gibidir.

Hataları ve sorunları bildirme

Geri bildiriminiz, Android'de Özel Korumalı Alan'ın önemli bir parçasıdır. Karşılaştığınız sorunları veya Android'de Özel Korumalı Alan'ı iyileştirmeye yönelik fikirlerinizi bizimle paylaşın.