সুরক্ষিত শ্রোতা API বিকাশকারী গাইড

আপনি Android ডকুমেন্টেশনের গোপনীয়তা স্যান্ডবক্সের মাধ্যমে পড়ার সময়, আপনি যে প্রোগ্রামটির সাথে কাজ করছেন সেটি নির্বাচন করতে বিকাশকারী পূর্বরূপ বা বিটা বোতামটি ব্যবহার করুন, কারণ নির্দেশাবলী পরিবর্তিত হতে পারে।


অ্যান্ড্রয়েডের সুরক্ষিত দর্শক API (পূর্বে FLEDGE নামে পরিচিত) কাস্টম অডিয়েন্স API এবং বিজ্ঞাপন নির্বাচন API অন্তর্ভুক্ত করে। বিজ্ঞাপন প্রযুক্তির প্ল্যাটফর্ম এবং বিজ্ঞাপনদাতারা এই APIগুলি ব্যবহার করে পূর্ববর্তী অ্যাপের ব্যস্ততার উপর ভিত্তি করে কাস্টমাইজড বিজ্ঞাপন পরিবেশন করতে পারে যা অ্যাপ জুড়ে শনাক্তকারীর শেয়ারিং সীমাবদ্ধ করে এবং তৃতীয় পক্ষের সাথে ব্যবহারকারীর অ্যাপ ইন্টারঅ্যাকশন তথ্য শেয়ার করা সীমাবদ্ধ করে।

কাস্টম অডিয়েন্স এপিআই "কাস্টম অডিয়েন্স" অ্যাবস্ট্রাকশনের চারপাশে কেন্দ্রীভূত হয়, যা সাধারণ উদ্দেশ্য সহ ব্যবহারকারীদের একটি গোষ্ঠীর প্রতিনিধিত্ব করে। একজন বিজ্ঞাপনদাতা একজন ব্যবহারকারীকে একটি কাস্টম দর্শকের সাথে নিবন্ধন করতে পারেন এবং এর সাথে প্রাসঙ্গিক বিজ্ঞাপন সংযুক্ত করতে পারেন৷ এই তথ্য স্থানীয়ভাবে সংরক্ষণ করা হয় এবং বিজ্ঞাপনদাতা বিড, বিজ্ঞাপন ফিল্টারিং, এবং বিজ্ঞাপন রেন্ডারিং জানাতে ব্যবহার করা যেতে পারে।

বিজ্ঞাপন নির্বাচন API একটি কাঠামো প্রদান করে যা একাধিক বিকাশকারীকে কাস্টম দর্শকদের জন্য স্থানীয়ভাবে একটি নিলাম চালানোর অনুমতি দেয়। এটি অর্জন করতে, সিস্টেমটি কাস্টম দর্শকদের সাথে সম্পর্কিত প্রাসঙ্গিক বিজ্ঞাপনগুলি বিবেচনা করে এবং বিজ্ঞাপন প্রযুক্তি প্ল্যাটফর্ম ডিভাইসে ফেরত দেওয়া বিজ্ঞাপনগুলির উপর অতিরিক্ত প্রক্রিয়াকরণ করে।

বিজ্ঞাপন প্রযুক্তি প্ল্যাটফর্মগুলি ব্যবহারকারীর গোপনীয়তা রক্ষা করে এমন রিমার্কেটিং বাস্তবায়নের জন্য এই APIগুলিকে একীভূত করতে পারে। অ্যাপ ইনস্টল বিজ্ঞাপন সহ অতিরিক্ত ব্যবহারের ক্ষেত্রে সমর্থন ভবিষ্যতে প্রকাশের জন্য পরিকল্পনা করা হয়েছে। ডিজাইন প্রস্তাবে Android-এ Protected Audience API সম্পর্কে আরও জানুন।

এই নির্দেশিকাটি বর্ণনা করে যে কীভাবে Android এ Protected Audience API-এর সাথে কাজ করতে হয় তা করতে হবে:

  1. কাস্টম দর্শকদের পরিচালনা করুন
  2. একটি ডিভাইসে বিজ্ঞাপন নির্বাচন সেট আপ করুন এবং চালান
  3. বিজ্ঞাপন ইম্প্রেশন রিপোর্ট করুন

আপনি শুরু করার আগে

আপনি শুরু করার আগে, নিম্নলিখিতগুলি সম্পূর্ণ করুন:

  1. অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের জন্য আপনার বিকাশের পরিবেশ সেট আপ করুন
  2. হয় একটি সমর্থিত ডিভাইসে একটি সিস্টেম ইমেজ ইনস্টল করুন বা Android-এ গোপনীয়তা স্যান্ডবক্সের জন্য সমর্থন অন্তর্ভুক্ত করে এমন একটি এমুলেটর সেট আপ করুন
  3. একটি টার্মিনালে, নিম্নলিখিত adb কমান্ডের সাহায্যে সুরক্ষিত দর্শক API (ডিফল্টরূপে নিষ্ক্রিয়) অ্যাক্সেস সক্ষম করুন

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. একটি টার্মিনালে, নিম্নলিখিত adb কমান্ড দিয়ে বীকন রিপোর্টিং সক্ষম করুন।

     adb shell device_config put adservices fledge_beacon_reporting_metrics_enabled true
     adb shell device_config put adservices fledge_register_ad_beacon_enabled true
    
  5. আপনার অ্যাপ ম্যানিফেস্টে একটি ACCESS_ADSERVICES_CUSTOM_AUDIENCE অনুমতি অন্তর্ভুক্ত করুন:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  6. আপনার ম্যানিফেস্টের <application> অ্যাপ্লিকেশন> উপাদানে একটি বিজ্ঞাপন পরিষেবা কনফিগারেশন উল্লেখ করুন:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  7. আপনার ম্যানিফেস্টে উল্লেখ করা বিজ্ঞাপন পরিষেবাগুলির XML সংস্থানগুলি নির্দিষ্ট করুন, যেমন res/xml/ad_services_config.xmlবিজ্ঞাপন পরিষেবার অনুমতি এবং SDK অ্যাক্সেস নিয়ন্ত্রণ সম্পর্কে আরও জানুন

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  8. ডিফল্টরূপে, বিজ্ঞাপন নির্বাচন API একটি নিলাম বা ইমপ্রেশন রিপোর্টিং স্ক্রিপ্ট বরাদ্দ করতে পারে এমন মেমরির সর্বাধিক পরিমাণের উপর সীমা প্রয়োগ করে। মেমরি সীমাবদ্ধতা বৈশিষ্ট্যটির জন্য WebView সংস্করণ 105.0.5195.58 বা উচ্চতর প্রয়োজন৷ প্ল্যাটফর্মটি একটি সংস্করণ চেক প্রয়োগ করে এবং এটি সন্তুষ্ট না হলে selectAds এবং reportImpression API তে কল করে। এটি সেট আপ করার জন্য দুটি বিকল্প রয়েছে:

    • বিকল্প 1: এই চেকটি নিষ্ক্রিয় করতে নিম্নলিখিত adb কমান্ডটি চালান:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • বিকল্প 2: গুগল প্লে স্টোর থেকে ওয়েবভিউ বিটা ইনস্টল করুন। এটি পূর্বে উল্লিখিত সংস্করণের সমান বা বেশি হতে হবে।

একটি কাস্টম শ্রোতা যোগদান করুন

একটি কাস্টম শ্রোতা একটি বিজ্ঞাপনদাতা অ্যাপ দ্বারা সিদ্ধান্ত অনুযায়ী সাধারণ অভিপ্রায় বা আগ্রহ সহ ব্যবহারকারীদের একটি গোষ্ঠীর প্রতিনিধিত্ব করে৷ একটি অ্যাপ বা SDK একটি নির্দিষ্ট শ্রোতাকে নির্দেশ করতে একটি কাস্টম শ্রোতা ব্যবহার করতে পারে, যেমন কেউ শপিং কার্টে আইটেম রেখে গেছে। অ্যাসিঙ্ক্রোনাসভাবে একটি কাস্টম দর্শক তৈরি করতে বা যোগ দিতে, নিম্নলিখিতগুলি করুন:

  1. CustomAudienceManager অবজেক্ট শুরু করুন।
  2. ক্রেতার প্যাকেজ এবং একটি প্রাসঙ্গিক নামের মতো মূল পরামিতিগুলি নির্দিষ্ট করে একটি CustomAudience অবজেক্ট তৈরি করুন৷ তারপর, CustomAudience অবজেক্টের সাথে JoinCustomAudienceRequest অবজেক্ট শুরু করুন।
  3. JoinCustomAudienceRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টের সাথে অ্যাসিঙ্ক্রোনাস joinCustomAudience() কল করুন।

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a custom audience.
val audience = CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build()

// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build();

// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver);

নিম্নলিখিত পরামিতিগুলির সমন্বয় একটি ডিভাইসে প্রতিটি CustomAudience অবজেক্টকে স্বতন্ত্রভাবে সনাক্ত করে:

  • owner : মালিক অ্যাপের প্যাকেজের নাম। এটি পরোক্ষভাবে কলার অ্যাপের প্যাকেজ নামের সাথে সেট করা আছে।
  • buyer : ক্রেতা বিজ্ঞাপন নেটওয়ার্কের শনাক্তকারী যা এই কাস্টম দর্শকদের জন্য বিজ্ঞাপন পরিচালনা করে।
  • name : কাস্টম দর্শকদের জন্য একটি নির্বিচারে নাম বা শনাক্তকারী৷

CustomAudience এর একটি ভিন্ন উদাহরণের সাথে বারবার joinCustomAudience() কল করা owner, buyer এবং name প্যারামিটারের সাথে বিদ্যমান CustomAudience আপডেট করে। গোপনীয়তা রক্ষায় সহায়তা করার জন্য, API-এর ফলাফল "সৃষ্টি" এবং "আপডেট" এর মধ্যে পার্থক্য করে না।

উপরন্তু, এই প্রয়োজনীয় পরামিতিগুলির সাথে CustomAudience তৈরি করতে হবে:

একটি CustomAudience অবজেক্টের জন্য ঐচ্ছিক পরামিতি অন্তর্ভুক্ত হতে পারে:

  • অ্যাক্টিভেশন সময় : একজন কাস্টম শ্রোতা শুধুমাত্র তার সক্রিয়করণের সময় পরে বিজ্ঞাপন নির্বাচন এবং দৈনিক আপডেটে অংশগ্রহণ করতে পারে। উদাহরণস্বরূপ, একটি অ্যাপের ল্যাপসড ব্যবহারকারীদের জড়িত করার জন্য এটি কার্যকর হতে পারে।
  • মেয়াদ শেষ হওয়ার সময় : একটি ভবিষ্যত সময় যার পরে ডিভাইস থেকে কাস্টম দর্শকদের সরানো হয়।
  • ব্যবহারকারীর বিডিং সংকেত : একটি JSON স্ট্রিং যাতে ব্যবহারকারীর সংকেত থাকে, যেমন ব্যবহারকারীর পছন্দের লোকেল, যা একজন ক্রেতার বিডিং লজিক জাভাস্ক্রিপ্ট বিজ্ঞাপন নির্বাচন প্রক্রিয়ার সময় বিড তৈরি করতে ব্যবহার করে। এই ফর্ম্যাট বিজ্ঞাপন প্রযুক্তি প্ল্যাটফর্মগুলিকে প্ল্যাটফর্ম জুড়ে কোড পুনরায় ব্যবহার করতে সাহায্য করে এবং জাভাস্ক্রিপ্ট ফাংশনে ব্যবহার সহজ করে।
  • বিশ্বস্ত বিডিং ডেটা : একটি HTTPS URL এবং বিজ্ঞাপন নির্বাচন প্রক্রিয়ার সময় ব্যবহৃত স্ট্রিংয়ের একটি তালিকা যা একটি বিশ্বস্ত কী/মান পরিষেবা থেকে বিডিং সংকেত নিয়ে আসে।
  • বিজ্ঞাপন : বিজ্ঞাপন নির্বাচনে অংশগ্রহণকারী বিজ্ঞাপনের সাথে সম্পর্কিত AdData বস্তুর একটি তালিকা। প্রতিটি AdData অবজেক্ট এর মধ্যে থাকে:
    • রেন্ডার URL : একটি HTTPS URL যা চূড়ান্ত বিজ্ঞাপন রেন্ডার করার জন্য জিজ্ঞাসা করা হয়।
    • মেটাডেটা : একটি JSON অবজেক্ট বিজ্ঞাপন নির্বাচন প্রক্রিয়ার সময় ক্রেতা বিডিং লজিক দ্বারা গ্রাস করা তথ্য ধারণকারী একটি স্ট্রিং হিসাবে সিরিয়াল করা হয়।
    • বিজ্ঞাপন ফিল্টার : একটি ক্লাস যাতে বিজ্ঞাপন নির্বাচনের সময় অ্যাপ ইনস্টল বিজ্ঞাপন ফিল্টারিং এবং ফ্রিকোয়েন্সি ক্যাপিংয়ের জন্য প্রয়োজনীয় সমস্ত তথ্য থাকে।

এখানে একটি CustomAudience অবজেক্ট ইনস্ট্যান্টেশনের একটি উদাহরণ রয়েছে:

কোটলিন

// Minimal initialization of a CustomAudience object
val customAudience: CustomAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build()

জাভা

// Minimal initialization of a CustomAudience object
CustomAudience customAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build();

joinCustomAudience() ফলাফল পরিচালনা করুন

অ্যাসিঙ্ক্রোনাস joinCustomAudience() পদ্ধতি API কলের ফলাফলকে সংকেত দিতে OutcomeReceiver অবজেক্ট ব্যবহার করে।

  • onResult() কলব্যাকটি বোঝায় যে কাস্টম দর্শক সফলভাবে তৈরি বা আপডেট হয়েছে।
  • onError() কলব্যাক দুটি সম্ভাব্য শর্তকে নির্দেশ করে।
    • JoinCustomAudienceRequest যদি ভুল আর্গুমেন্ট দিয়ে শুরু করা হয়, তাহলে AdServicesException কারণ হিসেবে একটি IllegalArgumentException নির্দেশ করে।
    • অন্যান্য সমস্ত ত্রুটি কারণ হিসাবে একটি IllegalStateException সহ একটি AdServicesException পায়।

এখানে joinCustomAudience() এর ফলাফল পরিচালনা করার একটি উদাহরণ রয়েছে:

কোটলিন

var callback: OutcomeReceiver<Void, AdServicesException> =
    object : OutcomeReceiver<Void, AdServicesException> {
    override fun onResult(result: Void) {
        Log.i("CustomAudience", "Completed joinCustomAudience")
    }

    override fun onError(error: AdServicesException) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error)
    }
};

জাভা

OutcomeReceiver callback = new OutcomeReceiver<Void, AdServicesException>() {
    @Override
    public void onResult(@NonNull Void result) {
        Log.i("CustomAudience", "Completed joinCustomAudience");
    }

    @Override
    public void onError(@NonNull AdServicesException error) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error);
    }
};

একটি কাস্টম শ্রোতা ছেড়ে

ব্যবহারকারী যদি প্রদত্ত কাস্টম দর্শকদের জন্য ব্যবসার মানদণ্ড আর সন্তুষ্ট না করে, তাহলে একটি অ্যাপ বা SDK ডিভাইস থেকে কাস্টম দর্শকদের সরাতে leaveCustomAudience() কল করতে পারে। একটি CustomAudience এর অনন্য প্যারামিটারের উপর ভিত্তি করে সরাতে, নিম্নলিখিতগুলি করুন:

  1. CustomAudienceManager অবজেক্ট শুরু করুন।
  2. কাস্টম দর্শকের buyer এবং name দিয়ে LeaveCustomAudienceRequest আরম্ভ করুন। এই ইনপুট ক্ষেত্রগুলি সম্পর্কে আরও জানতে, পড়ুন " একটি কাস্টম দর্শকদের সাথে যোগ দিন "।
  3. LeaveCustomAudienceRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টের সাথে অ্যাসিঙ্ক্রোনাস leaveCustomAudience() পদ্ধতিতে কল করুন।

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
    LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build()

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
    new LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build();

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver);

joinCustomAudience() কল করার মতো, OutcomeReceiver একটি API কলের সমাপ্তির সংকেত দেয়। গোপনীয়তা রক্ষায় সাহায্য করার জন্য, একটি ত্রুটির ফলাফল অভ্যন্তরীণ ত্রুটি এবং অবৈধ আর্গুমেন্টের মধ্যে পার্থক্য করে না। onResult() কলব্যাক কল করা হয় যখন API কল সম্পূর্ণ হয়, একটি মিলিত কাস্টম দর্শক সফলভাবে সরানো হয় বা না হয়।

বিজ্ঞাপন নির্বাচন চালান

বিজ্ঞাপন নির্বাচন করতে সুরক্ষিত দর্শক API ব্যবহার করতে, selectAds() পদ্ধতিতে কল করুন:

  1. একটি AdSelectionManager অবজেক্ট শুরু করুন।
  2. একটি AdSelectionConfig অবজেক্ট তৈরি করুন।
  3. AdSelectionConfig অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টের সাথে অ্যাসিঙ্ক্রোনাস selectAds() পদ্ধতিতে কল করুন।

কোটলিন

val adSelectionManager: AdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionConfig
val adSelectionConfig: AdSelectionConfig =
  AdSelectionConfig.Builder().setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(
        contextualAds.getBuyer(), contextualAds
      )
    ).build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
  adSelectionConfig, executor, outcomeReceiver
)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionConfig
AdSelectionConfig adSelectionConfig =
  new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(contextualAds.getBuyer(), contextualAds)
    )
    .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(adSelectionConfig, executor, outcomeReceiver);

selectAds() পদ্ধতির একটি AdSelectionConfig ইনপুট প্রয়োজন, যেখানে আপনাকে অবশ্যই নিম্নলিখিত প্রয়োজনীয় প্যারামিটারগুলি নির্দিষ্ট করতে হবে:

  • বিক্রেতা : বিজ্ঞাপন নির্বাচন শুরু করে বিক্রেতার বিজ্ঞাপন নেটওয়ার্কের শনাক্তকারী।
  • ডিসিশন লজিক ইউআরএল : বিক্রেতা বিজ্ঞাপন নেটওয়ার্কের জাভাস্ক্রিপ্ট লজিক পাওয়ার জন্য একটি HTTPS ইউআরএল জিজ্ঞাসা করা হয়েছে।
    • HTTPS URL : বিক্রেতা বিজ্ঞাপন নেটওয়ার্কের জাভাস্ক্রিপ্ট লজিক পাওয়ার জন্য জিজ্ঞাসা করা হয়েছে। প্রয়োজনীয় ফাংশন স্বাক্ষর দেখুন।
    • প্রি-বিল্ট ইউআরআই : যা FLEDGE-এর বিজ্ঞাপন নির্বাচন বিন্যাস অনুসরণ করে। IllegalArgumentException নিক্ষেপ করা হয়, যদি একটি অসমর্থিত বা বিকৃত পূর্বনির্মাণ ইউরি পাস করা হয়।
  • কাস্টম শ্রোতা ক্রেতা : ক্রেতা বিজ্ঞাপন নেটওয়ার্কের জন্য শনাক্তকারীর একটি সম্পূর্ণ তালিকা যা বিক্রেতার দ্বারা বিজ্ঞাপন নির্বাচন প্রক্রিয়ায় অংশগ্রহণের অনুমতি দেওয়া হয়। এই ক্রেতা শনাক্তকারীরা অংশগ্রহণকারী কাস্টম দর্শকদের CustomAudience.getBuyer() এর সাথে মিলে যায়।

আরও কাস্টমাইজড বিজ্ঞাপন নির্বাচনের জন্য নিম্নলিখিত প্যারামিটারগুলি ঐচ্ছিকভাবে নির্দিষ্ট করা যেতে পারে:

  • বিজ্ঞাপন নির্বাচনের সংকেত : একটি JSON অবজেক্ট, একটি স্ট্রিং হিসাবে ক্রমিককৃত, ক্রেতা বিডিং লজিক জাভাস্ক্রিপ্ট CustomAudience.getBiddingLogicUrl() থেকে আনা সংকেতগুলি ধারণ করে।
  • বিক্রেতা সংকেত : একটি JSON অবজেক্ট, একটি স্ট্রিং হিসাবে ক্রমিককৃত, যেখানে AdSelectionConfig.getDecisionLogicUrl() থেকে বিক্রেতার আনা জাভাস্ক্রিপ্ট সিদ্ধান্ত যুক্তি দ্বারা গ্রাস করা সংকেত রয়েছে।
  • ক্রেতার প্রতি সংকেত : JSON অবজেক্টের একটি মানচিত্র, স্ট্রিং হিসাবে ক্রমিক করা হয়েছে, যাতে CustomAudience.getBiddingLogicUrl() থেকে আনা নির্দিষ্ট ক্রেতাদের বিডিং লজিক JavaScript দ্বারা গ্রাস করার সংকেত রয়েছে, যা অংশগ্রহণকারী কাস্টম দর্শকদের ক্রেতা ক্ষেত্র দ্বারা চিহ্নিত করা হয়।
  • প্রাসঙ্গিক বিজ্ঞাপন: বিজ্ঞাপন প্রার্থীদের একটি সংগ্রহ যা একটি নিলামের সময় ক্রেতাদের কাছ থেকে সরাসরি সংগ্রহ করা হয় যা একটি সুরক্ষিত দর্শক নিলামের বাইরে ঘটে।

একবার একটি বিজ্ঞাপন নির্বাচন করা হলে, ফলাফল, বিড এবং সংকেতগুলি রিপোর্ট করার জন্য অভ্যন্তরীণভাবে বজায় থাকে। OutcomeReceiver.onResult() কলব্যাক একটি AdSelectionOutcome প্রদান করে যাতে রয়েছে:

  • বিজয়ী বিজ্ঞাপনের জন্য একটি রেন্ডার URL, AdData.getRenderUrl() থেকে প্রাপ্ত।
  • ডিভাইস ব্যবহারকারীর জন্য অনন্য একটি বিজ্ঞাপন নির্বাচন আইডি। এই আইডি বিজ্ঞাপন ছাপ রিপোর্ট করার জন্য ব্যবহার করা হয়.

যদি অবৈধ আর্গুমেন্ট, টাইমআউট বা অত্যধিক রিসোর্স খরচের কারণে বিজ্ঞাপন নির্বাচন সফলভাবে সম্পন্ন করা না যায়, OutcomeReceiver.onError() কলব্যাক নিম্নলিখিত আচরণগুলির সাথে একটি AdServicesException প্রদান করে:

  • যদি বিজ্ঞাপন নির্বাচনটি অবৈধ আর্গুমেন্ট দিয়ে শুরু করা হয়, তাহলে AdServicesException কারণ হিসেবে একটি IllegalArgumentException নির্দেশ করে।
  • অন্যান্য সমস্ত ত্রুটি কারণ হিসাবে একটি IllegalStateException সহ একটি AdServicesException পায়।

প্রাসঙ্গিক বিজ্ঞাপন

সুরক্ষিত শ্রোতা একটি সুরক্ষিত নিলামে প্রাসঙ্গিক বিজ্ঞাপনগুলিকে অন্তর্ভুক্ত করতে পারে৷ প্রাসঙ্গিক বিজ্ঞাপনগুলিকে বিজ্ঞাপন প্রযুক্তি সার্ভারে নির্বাচন করতে হবে এবং সুরক্ষিত দর্শক API-এর বাইরে ডিভাইসে ফিরে আসতে হবে। প্রাসঙ্গিক বিজ্ঞাপনগুলি তখন AdSelectionConfig ব্যবহার করে নিলামে অন্তর্ভুক্ত করা যেতে পারে যেখানে তারা নেতিবাচক বিজ্ঞাপন ফিল্টারিংয়ের যোগ্যতা সহ ডিভাইস বিজ্ঞাপনের মতোই কাজ করে। সুরক্ষিত দর্শক নিলাম শেষ হয়ে গেলে, আপনাকে reportImpression() আহ্বান করতে হবে। এটি একটি ডিভাইসে বিজয়ী বিজ্ঞাপন পাওয়ার জন্য, ইম্প্রেশন রিপোর্টিংয়ের মতো একই প্যাটার্নে বিজয়ী প্রাসঙ্গিক বিজ্ঞাপনে reportWin() কল করে। প্রতিটি প্রাসঙ্গিক বিজ্ঞাপনের একজন ক্রেতা, একটি বিড, রিপোর্টিং লজিকের একটি লিঙ্ক, একটি রেন্ডার URL এবং বিজ্ঞাপন মেটাডেটা প্রয়োজন৷

অ্যাপে প্রাসঙ্গিক বিজ্ঞাপন স্থাপন করতে, টার্গেট অ্যাপটিকে একটি ContextualAds অবজেক্ট তৈরি করতে হবে:

কোটলিন

val contextualAds: ContextualAds =
  Builder().setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
    //Pass in your valid app install ads
    .setDecisionLogicUri(mContextualLogicUri)
    .setAdsWithBid(appInstallAd)
    .build()

জাভা

ContextualAds contextualAds = new ContextualAds.Builder()
  .setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
  .setDecisionLogicUri(mContextualLogicUri)
  //Pass in your valid app install ads
  .setAdsWithBid(appInstallAd)
  .build();

আপনার AdSelectionConfig তৈরি করার সময় এর ফলে ContextualAds অবজেক্টটি পাস করা যেতে পারে:

কোটলিন

// Create a new ad
val noFilterAd: AdData = Builder()
  .setMetadata(JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build()
val noFilterAdWithBid = AdWithBid(noFilterAd, NO_FILTER_BID)
contextualAds.getAdsWithBid().add(noFilterAdWithBid)

জাভা

// Create a new ad
AdData noFilterAd = new AdData.Builder()
  .setMetadata(new JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build();
AdWithBid noFilterAdWithBid = new AdWithBid(noFilterAd, NO_FILTER_BID);
contextualAds.getAdsWithBid().add(noFilterAdWithBid);

অ্যাপ ইনস্টল বিজ্ঞাপন ফিল্টারিং

অ্যাপ ইনস্টল বিজ্ঞাপন ফিল্টারিং আপনাকে ডিভাইসে ইতিমধ্যে ইনস্টল করা অ্যাপগুলির জন্য ইনস্টলেশন বিজ্ঞাপনগুলি ফিল্টার করতে সহায়তা করে।

এই প্রক্রিয়ার প্রথম ধাপ হল কোন বিজ্ঞাপনদাতাদের ইনস্টল করা প্যাকেজে ফিল্টার করার ক্ষমতা আছে তা নির্ধারণ করা। আপনি একটি বিজ্ঞাপন দিয়ে লক্ষ্য করতে চান এমন অ্যাপে এটি ঘটতে হবে।

কোটলিন

//Create a request for setting the app install advertisers
val adtech = AdTechIdentifier.fromString("your.enrolled.uri")
val adtechSet = setOf(adtech)
val request = SetAppInstallAdvertisersRequest(adtechSet)

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  object : OutcomeReceiver<Any?, Exception?>() {
    fun onResult(@NonNull ignoredResult: Any?) {
      Log.v("[your tag]", "Updated app install advertisers")
    }

    fun onError(@NonNull error: Exception?) {
      Log.e("[your tag]", "Failed to update app install advertisers", error)
    }
  })

জাভা

//Create a request for setting the app install advertisers
AdTechIdentifier adtech = AdTechIdentifier.fromString("your.enrolled.uri");
Set<AdTechIdentifier> adtechSet = Collections.singleton(adtech);
SetAppInstallAdvertisersRequest request = new SetAppInstallAdvertisersRequest(adtechSet);

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  new OutcomeReceiver<Object, Exception>() {
    @Override
    public void onResult(@NonNull Object ignoredResult) {
      Log.v("[your tag]", "Updated app install advertisers");
    }

    @Override
    public void onError(@NonNull Exception error) {
      Log.e("[your tag]", "Failed to update app install advertisers", error);
    }
  });

যখন পূর্ববর্তী কোডটি কার্যকর হয়, তখন পাস করা বিজ্ঞাপনদাতারা তাদের বিড জেনারেশনের সময় আপনার নির্দিষ্ট করা ইনস্টল করা অ্যাপগুলিকে ফিল্টার করতে সক্ষম হয়। আপনি যদি এই অ্যাপের ইনস্টল স্থিতিতে অ্যাক্সেস থেকে কোনও বিজ্ঞাপনদাতাকে সরাতে চান তবে বিজ্ঞাপনদাতার তথ্য সরিয়ে দিয়ে এই কোডটি আবার চালান৷

পরবর্তী ধাপ হল প্রকাশক অ্যাপের মধ্যে বিজ্ঞাপন ফিল্টারিং সেট আপ করা। যে পক্ষটি প্রকাশক অ্যাপের ভিতরে বিজ্ঞাপন পরিবেশন করে (সম্ভবত একটি সাপ্লাই-সাইড SDK হতে পারে) তাদের অবশ্যই তাদের AdFilters অবজেক্ট শুরু করতে হবে যাতে তারা কোন অ্যাপগুলির সাথে সম্পর্কিত বিজ্ঞাপনগুলি ফিল্টার আউট করতে চায় সে সম্পর্কে তথ্য সহ:

কোটলিন

// Instantiate AdFilters object with package names.
val filters: AdFilters = Builder().setAppInstallFilters(
    Builder().setPackageNames(setOf("example.target.app")).build()
  ).build()

জাভা

// Instantiate AdFilters object with package names.
AdFilters filters = new AdFilters.Builder()
.setAppInstallFilters(
  new AppInstallFilters.Builder()
  .setPackageNames(Collections.singleton("example.target.app"))
  .build())
.build();

ডিমান্ড-সাইড প্রকাশকরা তাদের কাস্টম শ্রোতাদের মধ্যে বিদ্যমান বিজ্ঞাপনগুলির জন্য একটি AdFilter সেট করতে পারে।

একটি নতুন AdData অবজেক্ট ইনস্ট্যান্টিয়েট করার সময়েও AdFilters পাস করা যেতে পারে:

কোটলিন

// Instantiate an AdData object with the AdFilters created in the
// previous example.
val appInstallAd: AdData =
  Builder().setMetadata("{ ... }") // Valid JSON string
    .setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters).build()

জাভা

// Instantiate an AdData object with the AdFilters created in the
// previous example.
AdData appInstallAd = new AdData.Builder()
.setMetadata("{ ... }") // Valid JSON string
.setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters)
    .build();

ফ্রিকোয়েন্সি ক্যাপ ফিল্টারিং

ফ্রিকোয়েন্সি ক্যাপ ফিল্টারিং বিজ্ঞাপন প্রযুক্তিকে একটি বিজ্ঞাপন দেখানোর সংখ্যা সীমিত করতে সক্ষম করে। ফ্রিকোয়েন্সি ক্যাপ ফিল্টারিং বিজ্ঞাপনের অত্যধিক এক্সপোজার হ্রাস করে এবং প্রদত্ত বিজ্ঞাপন প্রচারের জন্য বিকল্প বিজ্ঞাপন নির্বাচনকে অপ্টিমাইজ করে।

ফ্রিকোয়েন্সি ক্যাপ ফিল্টারের দুটি প্রধান উপাদান রয়েছে: বিজ্ঞাপন ইভেন্টের ধরন এবং বিজ্ঞাপন কাউন্টার কী। উপলব্ধ বিজ্ঞাপন ইভেন্টের ধরনগুলি ব্যবহার করা যেতে পারে:

  • জয় : একটি জয় ইভেন্ট নির্দেশ করে যে বিজ্ঞাপনটি একটি নিলাম জিতেছে। উইন ইভেন্টগুলি সুরক্ষিত শ্রোতা API দ্বারা স্বয়ংক্রিয়ভাবে আপডেট হয় এবং বিকাশকারী সরাসরি কল করতে পারে না। উইন ডেটা শুধুমাত্র প্রদত্ত কাস্টম দর্শকদের মধ্যে বিজ্ঞাপনগুলিতে দৃশ্যমান।
  • ইমপ্রেশন : reportImpression থেকে আলাদা, একটি অন-ডিভাইস কলার (এসএসপি বা এমএমপি) তাদের বেছে নেওয়া কোডের পয়েন্টে ইমপ্রেশন ইভেন্ট আহ্বান করতে updateAdCounterHistogram() ব্যবহার করে। ইম্প্রেশন ইভেন্টগুলি একটি প্রদত্ত ডিএসপি-এর অন্তর্গত সমস্ত বিজ্ঞাপনে দৃশ্যমান, এবং একই কাস্টম দর্শকদের মধ্যে বিজ্ঞাপনের মধ্যে সীমাবদ্ধ নয়৷
  • দেখুন : ইভেন্টটি অন-ডিভাইস কলার (এসএসপি বা এমএমপি) দ্বারা একটি কোডের একটি পয়েন্টে আহ্বান করা হয় যেটি তারা updateAdCounterHistogram() জন্য একটি কল ব্যবহার করে বেছে নেয়। দেখুন ইভেন্টগুলি একটি প্রদত্ত DSP-এর অন্তর্গত সমস্ত বিজ্ঞাপনে দৃশ্যমান এবং একই কাস্টম অডিয়েন্সের বিজ্ঞাপনগুলিতে সীমাবদ্ধ নয়৷
  • ক্লিক করুন : ইভেন্টটি অন-ডিভাইস কলার (এসএসপি বা এমএমপি) দ্বারা একটি কোডের বিন্দুতে আহ্বান করা হয় যা তারা updateAdCounterHistogram() জন্য একটি কল ব্যবহার করে বেছে নেয়। ক্লিক ইভেন্টগুলি একটি প্রদত্ত DSP-এর অন্তর্গত সমস্ত বিজ্ঞাপনে দৃশ্যমান এবং একই কাস্টম অডিয়েন্সের বিজ্ঞাপনগুলিতে সীমাবদ্ধ নয়৷

প্রকাশক অ্যাপে, ডিভাইসে উপস্থিতি আছে এমন একটি SSP বা MMP বিজ্ঞাপন ইভেন্টগুলিকে আহ্বান করে৷ যখন updateAdCounterHistogram() কল করা হয়, তখন একটি ফ্রিকোয়েন্সি ক্যাপ ফিল্টারের কাউন্টার বৃদ্ধি করা হয় যাতে ভবিষ্যতে নিলামে একটি প্রদত্ত বিজ্ঞাপনে ব্যবহারকারীর এক্সপোজার সম্পর্কে আপ টু ডেট তথ্য থাকে। বিজ্ঞাপন ইভেন্টের ধরনগুলি সংশ্লিষ্ট ব্যবহারকারীর ক্রিয়াকলাপের সাথে জোর করে আবদ্ধ করা হয় না এবং কলকারীদের তাদের ইভেন্ট সিস্টেম গঠনে সহায়তা করার জন্য নির্দেশিকা দেওয়া হয়। একটি ইভেন্টের সময় বিজ্ঞাপন কাউন্টার বাড়াতে, ডিভাইসে অভিনেতা বিজয়ী বিজ্ঞাপন নিলামের বিজ্ঞাপন নির্বাচন আইডি প্রদান করে।

বিজ্ঞাপন কাউন্টার কীগুলি একজন ক্রেতা বিজ্ঞাপন প্রযুক্তি দ্বারা নির্ধারিত 32-বিট স্বাক্ষরিত পূর্ণসংখ্যার নির্বিচারে, এবং তারা ডিএসপি দ্বারা সংজ্ঞায়িত বিজ্ঞাপনগুলির একটি নির্দিষ্ট সেটের সাথে সঙ্গতিপূর্ণ। যেহেতু বিজ্ঞাপন কাউন্টার কীগুলি শুধুমাত্র একটি প্রদত্ত DSP-এর অন্তর্গত বিজ্ঞাপনগুলির মধ্যে সীমাবদ্ধ, তাই এই কীগুলি অন্য বিজ্ঞাপন প্রযুক্তির হিস্টোগ্রামের সাথে ওভারল্যাপ না করেই নির্বাচন করা যেতে পারে৷ বিজ্ঞাপন কাউন্টার কীগুলি ভবিষ্যতের নিলাম থেকে বিজ্ঞাপনগুলি ফিল্টার করার জন্য একটি ডিএসপি-এর বিজ্ঞাপন জুড়ে বা নির্দিষ্ট কাস্টম দর্শকদের মধ্যে ডিএসপি-নির্দিষ্ট শনাক্তকারী বৃদ্ধি করতে ব্যবহৃত হয়।

প্রদত্ত ক্রেতা বিজ্ঞাপন প্রযুক্তির অন্যান্য বিজ্ঞাপনের সাথে তাদের ইন্টারঅ্যাকশনের উপর ভিত্তি করে প্রদত্ত ব্যবহারকারীর কাছে আকর্ষণীয় হতে পারে এমন বিজ্ঞাপনগুলিকে অগ্রাধিকার দেওয়ার জন্য কাউন্টার কীগুলি ব্যবহার করা যেতে পারে। উদাহরণ স্বরূপ, একটি বিজ্ঞাপন যেটি বিজ্ঞাপন নিলাম, ভিউ এবং ক্লিক জয়ের মাধ্যমে উচ্চ স্তরের ব্যস্ততা পেয়েছে, একটি অনুমানকৃত ডেটা পয়েন্টকে উপস্থাপন করে৷ এই বিষয়টিকে আরও ব্যাখ্যা করার জন্য: বাম হাতের গল্ফ ক্লাবগুলির একটি বিজ্ঞাপন ইঙ্গিত দিতে পারে যে ব্যবহারকারী ডান হাতের গলফ ক্লাবগুলিতে আগ্রহী হবেন না৷ একটি ফ্রিকোয়েন্সি ক্যাপ ফিল্টার সেট একটি কাউন্টার কী বাম-হাতের বিজ্ঞাপনের জন্য নির্ধারিত ডান হাতের ক্লাবগুলির জন্য বিজ্ঞাপনগুলিকে ফিল্টার করতে পারে৷

আপনার নিলামে ফ্রিকোয়েন্সি ক্যাপিং ব্যবহার করতে, আপনাকে প্রথমে নীচে দেখানো হিসাবে KeyedFrequencyCap অবজেক্ট তৈরি করতে হবে:

কোটলিন

// Value used when incrementing frequency counter
val adCounterKey = 123

// Frequency cap exceeded after 2 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 2, Duration.ofSeconds(10)
).build()

// Frequency cap exceeded after 1 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 1, Duration.ofSeconds(10)
).build()

জাভা

// Value used when incrementing frequency counter
int adCounterKey = 123;

// Frequency cap exceeded after 2 counts
KeyedFrequencyCap keyedFrequencyCapForImpression =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 2, Duration.ofSeconds(10)
  ).build();

// Frequency Cap exceeded after 1 counts
KeyedFrequencyCap keyedFrequencyCapForClick =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 1, Duration.ofSeconds(10)
  ).build();

KeyedFrequencyCap অবজেক্ট তৈরি হয়ে গেলে, আপনি সেগুলিকে একটি AdFilters অবজেক্টে পাঠাতে পারেন।

কোটলিন

val filters: AdFilters = Builder()
  .setFrequencyCapFilters(
    Builder()
      .setKeyedFrequencyCapsForImpressionEvents(
        ImmutableObject.of(keyedFrequencyCapForImpression)
      )
      .setKeyedFrequencyCapsForClickEvents(
        ImmutableObject.of(keyedFrequencyCapForClick)
      )
  ).build()

জাভা

AdFilters filters = new AdFilters.Builder()
    .setFrequencyCapFilters(new FrequencyCapFilters.Builder()
        .setKeyedFrequencyCapsForImpressionEvents(
            ImmutableObject.of(keyedFrequencyCapForImpression)
        )
        .setKeyedFrequencyCapsForClickEvents(
            ImmutableObject.of(keyedFrequencyCapForClick)
        )
    ).build();

যখন AdFilters অবজেক্টটি ফ্রিকোয়েন্সি ক্যাপ ফিল্টার দিয়ে পপুলেট করা হয়, তখন কাস্টম অডিয়েন্স তৈরি হলে এটি পাস করা যেতে পারে:

কোটলিন

// Initialize a custom audience.
val audience: CustomAudience = Builder()
  .setBuyer(buyer)
  .setName(name)
  .setAds(
    listOf(
      Builder()
        .setRenderUri(renderUri)
        .setMetadata(JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()
    )
  ).build()

জাভা

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setAds(Collections.singletonList(new AdData.Builder()
        .setRenderUri(renderUri)
        .setMetadata(new JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()))
    .build();

যখন ফ্রিকোয়েন্সি ক্যাপ ফিল্টারগুলি কাস্টম দর্শকদের মধ্যে প্রয়োগ করা হয়, তখন SSP প্রয়োজনীয় ক্লিক, ভিউ বা ইমপ্রেশন ইভেন্টগুলিকে আহ্বান করতে পারে।

কোটলিন

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

val request: UpdateAdCounterHistogramRequest = Builder(
  adSelectionId,
  FrequencyCapFilters.AD_EVENT_TYPE_CLICK,  //CLICK, VIEW, or IMPRESSION
  callerAdTech
).build()

জাভা

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

UpdateAdCounterHistogramRequest request =
  new UpdateAdCounterHistogramRequest.Builder(
      adSelectionId,
      FrequencyCapFilters.AD_EVENT_TYPE_CLICK, //CLICK, VIEW, or IMPRESSION
      callerAdTech
).build();

যে বিজ্ঞাপনগুলি তাদের প্রি-সেট ফ্রিকোয়েন্সি ক্যাপ ফিল্টার সীমাতে আঘাত করেছে সেগুলি নিলাম থেকে ফিল্টার করা হয়৷ ডিভাইসে নিলামের জন্য বিডিং লজিক কার্যকর হওয়ার আগে ফিল্টারিং হয় এবং বিডিং ও নিলাম পরিষেবা নিলামের জন্য পেলোড তৈরি হয় বিজ্ঞাপন ওভার এক্সপোজার কমানোর সময় লক্ষ্য করা।

নেটওয়ার্ক কল ছাড়াই প্রাসঙ্গিক বিজ্ঞাপন ফিল্টারিং

ডিভাইসে কোনো রিমার্কেটিং চাহিদা না থাকলে, আপনি নেটওয়ার্ক কল ছাড়াই প্রাসঙ্গিক বিজ্ঞাপনের জন্য বিজ্ঞাপন নির্বাচন চালাতে পারেন। প্রি-বিল্ট ইউআরআই এবং বিড সহ প্রাসঙ্গিক বিজ্ঞাপনগুলির একটি তালিকা সহ, প্ল্যাটফর্মটি বিডিং লজিক, বিডিং সিগন্যাল এবং স্কোরিং সিগন্যাল পুনরুদ্ধার করা এড়িয়ে যেতে পারে। সর্বোচ্চ বিড সহ প্রাসঙ্গিক বিজ্ঞাপন নির্বাচন করতে প্ল্যাটফর্মটি একটি পূর্বনির্মাণ ইউআরআই ব্যবহার করে।

লেটেন্সি উন্নত করতে, বিজ্ঞাপন প্রযুক্তিগুলি একটি বিজ্ঞাপন নির্বাচন ফ্লো চালাতে পারে যাতে নেটওয়ার্ক কল ছাড়াই বিজ্ঞাপন ফিল্টারিং কার্যকারিতা সহ প্রাসঙ্গিক বিজ্ঞাপন অন্তর্ভুক্ত থাকে। সংকেত স্কোর করার জন্য পূর্বনির্মাণ ইউআরআই ব্যবহার করে এটি অর্জন করা হয়। scoreAds বাস্তবায়নের তালিকার জন্য সমর্থিত পূর্বনির্মাণ ইউআরআই ব্যবহারের ক্ষেত্রে এবং নাম বিভাগটি পড়ুন।

নেটওয়ার্ক কল ছাড়াই বিজ্ঞাপন নির্বাচন চালানোর জন্য:

  1. বিজ্ঞাপন ফিল্টারিং সেট আপ করুন
  2. আপনার প্রাসঙ্গিক বিজ্ঞাপন তৈরি করুন
  3. নিম্নলিখিতগুলির সাথে একটি AdSelectionConfig অবজেক্ট তৈরি করুন:

    1. ক্রেতাদের একটি খালি তালিকা
    2. সর্বোচ্চ বিড নির্বাচন করতে একটি পূর্বনির্মাণ URI
    3. প্রাসঙ্গিক বিজ্ঞাপন
    4. স্কোরিং সংকেতের জন্য একটি খালি URI। খালি URI ইঙ্গিত করার জন্য অনুমোদিত যে আপনি স্কোর করার জন্য বিশ্বস্ত সংকেতগুলি আনতে ব্যবহার করতে চান না:
    Uri prebuiltURIScoringUri = Uri.parse("ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=your.registered.uri/reporting");
    // Initialize AdSelectionConfig
    AdSelectionConfig adSelectionConfig =
      new AdSelectionConfig.Builder()
        .setSeller(seller)
        .setDecisionLogicUri(prebuiltURIScoringUri)
        .setCustomAudienceBuyers(Collections.emptyList())
        .setAdSelectionSignals(adSelectionSignals)
        .setSellerSignals(sellerSignals)
        .setPerBuyerSignals(perBuyerSignals)
        .setBuyerContextualAds(buyerContextualAds)
        .setTrustedScoringSignalsUri(Uri.EMPTY)
        .build();
    
  4. বিজ্ঞাপন নির্বাচন চালান:

    adSelectionManager.selectAds(
        adSelectionConfig,
        executor,
        outcomeReceiver);
    

প্রিবিল্ট ইউআরআই ব্যবহার করার সময় আপনার নিজস্ব রিপোর্টিং জাভাস্ক্রিপ্ট চালান

আজ, প্রাইভেসি স্যান্ডবক্স প্ল্যাটফর্মে শুধুমাত্র একটি প্রাথমিক রিপোর্টিং জাভাস্ক্রিপ্ট ইমপ্লিমেন্টেশন প্রি-বিল্ট ইউআরআই-এর জন্য উপলব্ধ। কম লেটেন্সি বিজ্ঞাপন নির্বাচনের জন্য প্রি-বিল্ট ইউআরআই ব্যবহার করার সময় আপনি যদি নিজের রিপোর্টিং জাভাস্ক্রিপ্ট চালাতে চান, তাহলে আপনি বিজ্ঞাপন নির্বাচন এবং রিপোর্টিং রানের মধ্যে DecisionLogicUri ওভাররাইড করতে পারেন।

  1. প্রিবিল্ট ইউআরআই ব্যবহার করে প্রাসঙ্গিক বিজ্ঞাপনের জন্য বিজ্ঞাপন নির্বাচন চালানোর পদক্ষেপগুলি চালান
  2. রিপোর্টিং চালানোর আগে আপনার AdSelectionConfig এর একটি কপি তৈরি করুন

    adSelectionConfigWithYourReportingJS = adSelectionConfig.cloneToBuilder()
      // Replace <urlToFetchYourReportingJS> with your own URL:
      .setDecisionLogicUri(Uri.parse(<urlToFetchYourReportingJS>))
      .build();
    
  3. ইমপ্রেশন রিপোর্টিং চালান

    // adSelectionId is from the result of the previous selectAds run
    ReportImpressionRequest request = new ReportImpressionRequest(
      adSelectionId,
      adSelectionConfigWithYourReportingJS);
    adSelectionManager.reportImpression(
      request,
      executor,
      outcomeReceiver);
    

জলপ্রপাত মধ্যস্থতা চালান

জলপ্রপাত মধ্যস্থতার জন্য একাধিক তৃতীয় পক্ষের SDK (3P নেটওয়ার্ক) প্রয়োজন একটি প্রথম পক্ষের SDK মধ্যস্থতা নেটওয়ার্ক দ্বারা সাজানো। জলপ্রপাতের মধ্যস্থতা একইভাবে করা হয় তা নির্বিশেষে যে নিলামটি ডিভাইসে হয়েছে বা বিডিং এবং নিলাম পরিষেবাগুলিতে (বিএন্ডএ) হয়েছে৷

3P নেটওয়ার্ক

3P নেটওয়ার্কগুলিকে একটি অ্যাডাপ্টার সরবরাহ করতে হবে যা মধ্যস্থতা নেটওয়ার্ককে একটি নিলাম চালানোর জন্য প্রয়োজনীয় পদ্ধতিগুলি আহ্বান করতে দেয়:

  • বিজ্ঞাপন নির্বাচন চালান
  • ইমপ্রেশন রিপোর্ট করুন

এখানে একটি মধ্যস্থতা নেটওয়ার্ক অ্যাডাপ্টারের একটি উদাহরণ:

কোটলিন

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

    init {
        adSelectionManager = context.getSystemService(AdSelectionManager::class.java)
    }

    fun selectAds() {...}

    fun reportImpressions() {...}
}

জাভা

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

    public NetworkAdaptor() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void selectAds() {...}

    public void reportImpressions() {...}
}

প্রতিটি SDK-এর নিজস্ব বিজ্ঞাপন নির্বাচন পরিষেবা পরিচালক এবং ক্লায়েন্ট এবং তাদের নিজস্ব selectAds এবং reportImpressions বাস্তবায়ন রয়েছে। SDK প্রদানকারীরা ডিভাইসে নিলামের জন্য বিজ্ঞাপন নির্বাচন কীভাবে চালাতে হয় বা B&A নিলামের জন্য B&A ব্যাখ্যাকারীর বিভাগগুলি উল্লেখ করতে পারেন। বিজ্ঞাপন ইম্প্রেশন রিপোর্ট করার পদ্ধতি অনুসরণ করুন (প্রতিবেদনের জন্য একক SSP ইম্প্রেশন রিপোর্টিং অনুসরণ করুন।

মধ্যস্থতা নেটওয়ার্ক

3P নেটওয়ার্কের মতো, মধ্যস্থতা নেটওয়ার্কের জন্য selectAds এবং reportImpression বাস্তবায়ন প্রয়োজন। আরও তথ্যের জন্য কীভাবে বিজ্ঞাপন নির্বাচন চালাতে হয় এবং কীভাবে বিজ্ঞাপনের ইম্প্রেশন রিপোর্ট করতে হয় সে বিষয়ে বিভাগগুলি পড়ুন।

মধ্যস্থতা নেটওয়ার্কগুলি মধ্যস্থতা চেইন চালানোর জন্য এবং নিজেদেরকে মধ্যস্থতা শৃঙ্খলে স্থাপন করার জন্য দায়ী। পরবর্তী বিভাগে এই প্রক্রিয়াটি কীভাবে সেট আপ এবং চালানো যায় তা কভার করে।

মধ্যস্থতা চেইন এবং বিড ফ্লোর পুনরুদ্ধার করুন

মধ্যস্থতা নেটওয়ার্ক প্রথম পক্ষের (1P) প্রাসঙ্গিক বিজ্ঞাপন, মধ্যস্থতা চেইন এবং তৃতীয় পক্ষের নেটওয়ার্কগুলির বিড ফ্লোর (3P) পুনরুদ্ধারের জন্য দায়ী৷ মধ্যস্থতা নেটওয়ার্ক দ্বারা সম্পাদিত প্রাসঙ্গিক বিজ্ঞাপনগুলি পুনরুদ্ধার করার অনুরোধে এটি ঘটতে পারে। মধ্যস্থতা শৃঙ্খল নির্ধারণ করে কিভাবে 3P নেটওয়ার্কের মাধ্যমে পুনরাবৃত্তি করতে হয় এবং বিড ফ্লোরগুলিকে adSelectionSignals হিসাবে নিলাম প্রক্রিয়ায় পাস করা যেতে পারে।

মধ্যস্থতা শৃঙ্খলে নেটওয়ার্ক স্থাপন

একটি মধ্যস্থতা SDK তাদের 1P বিজ্ঞাপন বিডের লাইভ eCPM-এর উপর ভিত্তি করে মধ্যস্থতা শৃঙ্খলে নিজেকে স্থাপন করতে পারে। সুরক্ষিত দর্শক API-এ, বিজ্ঞাপন বিডগুলি অস্বচ্ছ। একটি মধ্যস্থতা SDK-এর AdSelectionFromOutcomesConfig ব্যবহার করা উচিত একটি প্রদত্ত 1P বিজ্ঞাপনের বিডকে চেইনের পরবর্তী 3P নেটওয়ার্কের বিড ফ্লোরের সাথে তুলনা করতে। যদি 1P বিড বিড ফ্লোর থেকে বেশি হয় তাহলে এর মানে হল মধ্যস্থতা SDK সেই 3P নেটওয়ার্কের সামনে রাখা হয়েছে।

বিজ্ঞাপন নির্বাচন চালান

একটি 1P বিজ্ঞাপন প্রার্থী পুনরুদ্ধার করতে, মধ্যস্থতা নেটওয়ার্ক একটি ডিভাইসে নিলাম চালানোর বিজ্ঞাপন নির্বাচন বিভাগে পদক্ষেপগুলি অনুসরণ করতে পারে৷ এটি একটি 1P বিজ্ঞাপন প্রার্থী, একটি বিড এবং একটি AdSelectionId তৈরি করে যা মধ্যস্থতা প্রক্রিয়ায় ব্যবহৃত হয়।

একটি AdSelectionFromOutcomesConfig তৈরি করুন

একটি AdSelectionFromOutcomesConfig মধ্যস্থতা নেটওয়ার্ককে AdSelectionIds (আগের নিলামের ফলাফল), বিজ্ঞাপন নির্বাচন সংকেত এবং একটি URI জাভাস্ক্রিপ্ট আনার একটি তালিকা পাস করতে দেয় যা একাধিক প্রার্থীর থেকে একটি বিজ্ঞাপন নির্বাচন করে। AdSelectionIds-এর তালিকা তাদের বিড সহ এবং সিগন্যালগুলি জাভাস্ক্রিপ্টে পাঠানো হয় যেটি AdSelectionIds যদি বিড ফ্লোরকে হারায়, অথবা যদি মধ্যস্থতা শৃঙ্খল চলতে থাকে তবে কোনওটিই ফেরত দিতে পারে৷

মধ্যস্থতা নেটওয়ার্ক পূর্ববর্তী বিভাগ থেকে 1P AdSelectionId ব্যবহার করে একটি AdSelectionFromOutcomesConfig তৈরি করে এবং 3P নেটওয়ার্কের জন্য বিড ফ্লোর বিবেচনা করা হচ্ছে। মধ্যস্থতা চেইনের প্রতিটি ধাপের জন্য একটি নতুন AdSelectionFromOutcomesConfig তৈরি করা উচিত।

কোটলিন

fun  runSelectOutcome(
    adSelectionClient : AdSelectionClient,
    outcome1p : AdSelectionOutcome,
    network3p : NetworkAdapter) : ListenableFuture<AdSelectionOutcome?> {
    val config = AdSelectionFromOutcomesConfig.Builder()
        .setSeller(seller)
        .setAdSelectionIds(listOf(outcome1p))
        .setSelectionSignals({"bid_floor": bid_floor})
        .setSelectionLogicUri(selectionLogicUri)
        .build()
    return adSelectionClient.selectAds(config)
}

জাভা

public ListenableFuture<AdSelectionOutcome> runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) {
    AdSelectionFromOutcomesConfig config = new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .build();

    return adSelectionClient.selectAds(config){}
}

জলপ্রপাত মধ্যস্থতার জন্য selectAds() পদ্ধতি ওভাররাইডের জন্য একটি AdSelectionFromOutcomesConfig ইনপুট প্রয়োজন, যেখানে আপনাকে নিম্নলিখিত প্রয়োজনীয় পরামিতিগুলি নির্দিষ্ট করতে হবে:

  • বিক্রেতা : বিজ্ঞাপন নির্বাচন শুরু করে বিক্রেতার বিজ্ঞাপন নেটওয়ার্কের শনাক্তকারী।
  • AdSelectionIds : একটি 1P বিজ্ঞাপনের জন্য চালানো পূর্ববর্তী selectAds() একটি সিঙ্গলটন তালিকা।
  • বিজ্ঞাপন নির্বাচন সংকেত : একটি JSON অবজেক্ট, একটি স্ট্রিং হিসাবে ক্রমিক, ক্রেতা বিডিং লজিক দ্বারা ব্যবহার করার জন্য সংকেত ধারণকারী। এই ক্ষেত্রে, প্রদত্ত 3P নেটওয়ার্কের জন্য পুনরুদ্ধার করা বিড ফ্লোর অন্তর্ভুক্ত করুন।
  • নির্বাচন লজিক ইউআরআই : একটি বিজয়ী বিজ্ঞাপন নির্বাচন করার জন্য মধ্যস্থতা নেটওয়ার্কের জাভাস্ক্রিপ্ট আনতে বিজ্ঞাপন নির্বাচনের সময় একটি HTTPS URL জিজ্ঞাসা করা হয়। এই জাভাস্ক্রিপ্টে প্রয়োজনীয় ফাংশন স্বাক্ষর দেখুন। বিড ফ্লোরের চেয়ে বেশি হলে জাভাস্ক্রিপ্টের 3P বিজ্ঞাপনটি ফেরত দেওয়া উচিত, অথবা অন্যথায় null ফেরত দেওয়া উচিত। এটি মধ্যস্থতা SDK-কে একটি বিজয়ী পাওয়া গেলে মধ্যস্থতা শৃঙ্খল ছেঁটে ফেলার অনুমতি দেয়৷

AdSelectionOutcomesConfig তৈরি করে, 3P নেটওয়ার্কের selectAds() পদ্ধতিতে কল করুন যেটি চেইনে প্রথমে আছে।

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
  AdSelectionFromOutcomesConfig.Builder()
    .setSeller(seller)
    .setAdSelectionIds(listof(outcome1p))
    .setSelectionSignals({"bid_floor": bid_floor})
    .setSelectionLogicUri(selectionLogicUri)
    .setAdSelectionIds(outcomeIds)
    .build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
        new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .setAdSelectionIds(outcomeIds)
            .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver);

অর্কেস্ট্রেট জলপ্রপাত মধ্যস্থতা

নিম্নোক্ত মধ্যস্থতা প্রক্রিয়ার মাধ্যমে চালানোর জন্য অপারেশনের ক্রম।

  1. 1P বিজ্ঞাপন নির্বাচন চালান।
  2. মধ্যস্থতা চেইন উপর পুনরাবৃত্তি. প্রতিটি 3P নেটওয়ার্কের জন্য, নিম্নলিখিতগুলি করুন:
    1. 1P outcomeId এবং 3P SDK এর বিড ফ্লোর সহ AdSelectionFromOutcomeConfig তৈরি করুন৷
    2. আগের ধাপ থেকে কনফিগারেশন সহ selectAds() কল করুন।
    3. ফলাফল খালি না হলে, বিজ্ঞাপন ফেরত.
    4. বর্তমান SDK নেটওয়ার্ক অ্যাডাপ্টারের selectAds() পদ্ধতিতে কল করুন। ফলাফল খালি না হলে, বিজ্ঞাপন ফেরত.
  3. চেইন থেকে কোন বিজয়ী পাওয়া না গেলে, 1P বিজ্ঞাপনটি ফেরত দিন।

কোটলিন

fun runWaterfallMediation(mediationChain : List<NetworkAdapter>)
  : Pair<AdSelectionOutcome, NetworkAdapter> {
    val outcome1p = runAdSelection()

    var outcome : AdSelectionOutcome
    for(network3p in mediationChain) {
      outcome = runSelectOutcome(outcome1p, network3p)
      if (outcome1p.hasOutcome() && outcome.hasOutcome()) {
          return Pair(outcome, this)
      }

      outcome = network3p.runAdSelection()
      if(outcome.hasOutcome()) {
          return Pair(outcome, network3p)
      }
    }
  return Pair(outcome1p, this)
}

জাভা

class MediationNetwork {
    AdSelectionManager adSelectionManager;

    public MediationNetwork() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void runAdSelection() {...}

    public void reportImpressions() {...}

    public Pair<AdSelectionOutcome, NetworkAdapter> runWaterfallMediation(
            List<NetworkAdapter> mediationChain) {
        AdSelectionOutcome outcome1p = runAdSelection();

        AdSelectionOutcome outcome;
        for(NetworkAdapter network3p: mediationChain) {
            if (outcome1p.hasOutcome() &&
              (outcome = runSelectOutcome(outcome1p, network3p)).hasOutcome()) {
                return new Pair<>(outcome, this);
            }

            if((outcome = network3p.runAdSelection()).hasOutcome()) {
                return new Pair<>(outcome, network3p);
            }
        }
        return new Pair<>(outcome1p, this);
    }

    /* Runs comparison by creating an AdSelectionFromOutcomesConfig */
    public AdSelectionOutcome runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) { ... }
}

বিজ্ঞাপন ইম্প্রেশন রিপোর্ট করুন

কিভাবে নিলাম চালানো হয় তার উপর নির্ভর করে একটি বিজ্ঞাপন ইম্প্রেশন রিপোর্ট করার জন্য দুটি প্রবাহ আছে। আপনি যদি একক এসএসপি হন একটি নিলাম চালাচ্ছেন, তাহলে এই বিভাগটি অনুসরণ করুন। আপনি যদি জলপ্রপাত মধ্যস্থতা বাস্তবায়ন করতে যাচ্ছেন, জলপ্রপাত মধ্যস্থতা ইম্প্রেশন রিপোর্টিং বিভাগে পাওয়া ধাপগুলি অনুসরণ করুন৷

একক SSP ছাপ রিপোর্টিং

বিজ্ঞাপন নির্বাচনের কার্যপ্রবাহ থেকে একটি বিজয়ী বিজ্ঞাপন বেছে নেওয়ার পরে, আপনি AdSelectionManager.reportImpression() পদ্ধতির মাধ্যমে অংশগ্রহণকারী বাই-সাইড এবং সেল-সাইড প্ল্যাটফর্মগুলিতে ইমপ্রেশনের রিপোর্ট করতে পারেন। একটি বিজ্ঞাপন ছাপ রিপোর্ট করতে:

  1. একটি AdSelectionManager অবজেক্ট শুরু করুন।
  2. বিজ্ঞাপন নির্বাচন আইডি দিয়ে একটি ReportImpressionRequest অবজেক্ট তৈরি করুন।
  3. ReportImpressionRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টের সাথে অ্যাসিঙ্ক্রোনাস reportImpression() পদ্ধতিতে কল করুন।

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportImpressionRequest
ReportImpressionRequest reportImpressionRequest =
        new ReportImpressionRequest.Builder()
                .setAdSelectionId(adSelectionId)
                .setAdSelectionConfig(adSelectionConfig)
                .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver);

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize a ReportImpressionRequest
val adSelectionConfig: ReportImpressionRequest =
    ReportImpressionRequest.Builder()
        .setAdSelectionId(adSelectionId)
        .setAdSelectionConfig(adSelectionConfig)
        .build()

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver)

নিম্নলিখিত প্রয়োজনীয় পরামিতিগুলির সাথে ReportImpressionRequest আরম্ভ করুন:

  • বিজ্ঞাপন নির্বাচন আইডি : একটি আইডি শুধুমাত্র একজন ডিভাইস ব্যবহারকারীর জন্য অনন্য যা একটি সফল বিজ্ঞাপন নির্বাচনকে চিহ্নিত করে।
  • বিজ্ঞাপন নির্বাচন কনফিগারেশন : প্রদত্ত বিজ্ঞাপন নির্বাচন আইডি দ্বারা চিহ্নিত selectAds() কলে ব্যবহৃত একই কনফিগারেশন।

অ্যাসিঙ্ক্রোনাস reportImpression() পদ্ধতি API কলের ফলাফলকে সংকেত দিতে OutcomeReceiver অবজেক্ট ব্যবহার করে।

  • onResult() কলব্যাক ইঙ্গিত করে যে ইমপ্রেশন রিপোর্টিং ইউআরএল তৈরি করা হয়েছে এবং অনুরোধটি নির্ধারিত হয়েছে কিনা।
  • onError() কলব্যাক নিম্নলিখিত সম্ভাব্য শর্তগুলি নির্দেশ করে:
    • যদি কলটি একটি অবৈধ ইনপুট আর্গুমেন্ট দিয়ে শুরু করা হয়, তাহলে AdServicesException কারণ হিসেবে একটি IllegalArgumentException নির্দেশ করে।
    • অন্যান্য সমস্ত ত্রুটি কারণ হিসাবে একটি IllegalStateException সহ একটি AdServicesException পায়।

জলপ্রপাত মধ্যস্থতা ছাপ রিপোর্টিং

একটি মধ্যস্থতা SDK-কে তাদের রিপোর্টিং ফ্লো ট্রিগার করতে বিজয়ী SDK-এর ট্র্যাক রাখতে হবে। একটি মধ্যস্থতা শৃঙ্খলে অংশগ্রহণকারী SDKগুলিকে তাদের নিজস্ব প্রতিবেদন প্রবাহকে ট্রিগার করার জন্য মধ্যস্থতাকারীর জন্য একটি পদ্ধতি প্রদান করা উচিত। একটি মধ্যস্থতামূলক নিলামে অংশগ্রহণকারী একটি SDK তাদের নিজস্ব প্রতিবেদন বাস্তবায়ন করতে উপরের পদক্ষেপগুলি অনুসরণ করতে পারে৷

SSPs এই 3P SDK কোডের উদাহরণটি কীভাবে মধ্যস্থতা প্রবাহে যোগ দিতে হবে তার প্রোটোটাইপ হিসাবে ব্যবহার করতে পারে:

Pair<AdSelectionOutcome, NetworkAdapter> winnerOutcomeAndNetwork =
         mediationSdk.orchestrateMediation(mediationChain);

if (winner.first.hasOutcome()) {
      winner.second.reportImpressions(winner.first.getAdSelectionId());

ইমপ্রেশন রিপোর্টিং এন্ডপয়েন্ট

রিপোর্ট ইম্প্রেশন API বিক্রয়-সাইড প্ল্যাটফর্ম এবং বিজয়ী বাই-সাইড প্ল্যাটফর্ম দ্বারা প্রদত্ত শেষ পয়েন্টগুলিতে HTTPS GET অনুরোধগুলি ইস্যু করে:

বাই-সাইড প্ল্যাটফর্ম এন্ডপয়েন্ট:

  • এপিআই ক্রেতা-প্রদত্ত জাভাস্ক্রিপ্ট আনতে কাস্টম অডিয়েন্সে নির্দিষ্ট করা বিডিং লজিক ইউআরএল ব্যবহার করে যাতে একটি ইম্প্রেশন রিপোর্টিং ইউআরএল ফেরত দেওয়ার জন্য লজিক রয়েছে।
  • reportWin() জাভাস্ক্রিপ্ট ফাংশন চালু করুন, যা ক্রেতার ইম্প্রেশন রিপোর্টিং ইউআরএল ফেরত দেবে বলে আশা করা হচ্ছে।

সেল-সাইড প্ল্যাটফর্ম এন্ডপয়েন্ট:

  • বিক্রেতার সিদ্ধান্ত লজিক জাভাস্ক্রিপ্ট আনতে AdSelectionConfig অবজেক্টে নির্দিষ্ট করা ডিসিশন লজিক ইউআরএল ব্যবহার করুন।
  • reportResult() JavaScript ফাংশন চালু করুন, যা বিক্রেতার ইম্প্রেশন রিপোর্টিং URL ফেরত দেবে বলে আশা করা হচ্ছে।

বিডিং এবং নিলাম পরিষেবা রিপোর্টিং

বিডিং এবং নিলাম পরিষেবাগুলিতে সম্পাদিত একটি নিলামে সার্ভার-সাইড নিলাম থেকে এনক্রিপ্ট করা প্রতিক্রিয়া অন্তর্ভুক্ত বিজ্ঞাপন ইন্টারঅ্যাকশন রিপোর্টিংয়ের জন্য তৈরি করা URL সহ সমস্ত প্রয়োজনীয় রিপোর্টিং তথ্য থাকবে৷ যখন প্রতিক্রিয়া ডিক্রিপ্ট করা হয়, উপযুক্ত ইউআরএলগুলি প্ল্যাটফর্মের সাথে নিবন্ধিত হয়, তাই বিজ্ঞাপন এবং ইম্প্রেশন রিপোর্টিং উপরে তালিকাভুক্ত একই পদক্ষেপগুলি অনুসরণ করে।

সেরা প্রচেষ্টা ইমপ্রেশন রিপোর্টিং

reportImpression() পদ্ধতিটি প্রতিবেদনের সর্বোত্তম প্রচেষ্টা সম্পূর্ণ করার জন্য ডিজাইন করা হয়েছে।

বিজ্ঞাপন ইন্টারঅ্যাকশন রিপোর্ট করুন

সুরক্ষিত শ্রোতা একটি রেন্ডার করা বিজ্ঞাপনের জন্য আরও দানাদার মিথস্ক্রিয়া সম্পর্কে রিপোর্ট করতে সহায়তা প্রদান করে। এতে ভিউ টাইম, ক্লিক, হোভার বা অন্য যেকোন দরকারী মেট্রিক যা সংগ্রহ করা যেতে পারে এর মত ইন্টারঅ্যাকশন অন্তর্ভুক্ত থাকতে পারে। এই রিপোর্টগুলি পাওয়ার প্রক্রিয়াটির জন্য দুটি ধাপ প্রয়োজন। প্রথমত, ক্রেতা এবং বিক্রেতাদের অবশ্যই তাদের রিপোর্টিং জাভাস্ক্রিপ্টে এই রিপোর্টগুলি পেতে নিবন্ধন করতে হবে৷ তারপর, ক্লায়েন্টকে এই ঘটনাগুলি রিপোর্ট করতে হবে।

ইন্টারঅ্যাকশন ইভেন্টগুলি পেতে নিবন্ধন করা হচ্ছে

ইন্টারঅ্যাকশন ইভেন্টের জন্য নিবন্ধন করা হয় ক্রেতার reportWin() এবং বিক্রেতার reportResult() জাভাস্ক্রিপ্ট ফাংশনে প্ল্যাটফর্ম দ্বারা প্রদত্ত একটি জাভাস্ক্রিপ্ট ফাংশন ব্যবহার করে: registerAdBeacon । একটি ইভেন্ট রিপোর্ট পাওয়ার জন্য নিবন্ধন করতে, আপনার রিপোর্টিং জাভাস্ক্রিপ্ট থেকে প্ল্যাটফর্ম JavaScript ফাংশনকে কল করুন। নিম্নলিখিত স্নিপেটটি একজন ক্রেতার reportWin() ব্যবহার করছে, কিন্তু একই পন্থা reportResult() ক্ষেত্রে প্রযোজ্য।

reportWin(
  adSelectionSignals,
  perBuyerSignals,
  signalsForBuyer,
  contextualSignals,
  customAudienceSignals) {
    ...
    // Calculate reportingUri, clickUri, viewUri, and hoverUri

    registerAdBeacon({"click": clickUri, "view": viewUri, "hover": hoverUri});

    return reportingUri;
}

মিথস্ক্রিয়া ঘটনা রিপোর্টিং

একটি ইম্প্রেশন রিপোর্ট করার পরে, ক্লায়েন্টরা পূর্বে নিবন্ধিত বিজয়ী বাই-সাইড এবং সেল-সাইড প্ল্যাটফর্মগুলিতে AdSelectionManager.reportInteraction() পদ্ধতির মাধ্যমে ইন্টারঅ্যাকশনের রিপোর্ট করতে পারে। একটি বিজ্ঞাপন ইভেন্ট রিপোর্ট করতে:

  1. একটি AdSelectionManager অবজেক্ট শুরু করুন।
  2. বিজ্ঞাপন নির্বাচন আইডি, ইন্টারঅ্যাকশন কী, ইন্টারঅ্যাকশন ডেটা এবং রিপোর্টিং গন্তব্য সহ একটি ReportInteractionRequest অবজেক্ট তৈরি করুন।
  3. request অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টের সাথে অ্যাসিঙ্ক্রোনাস reportInteraction() পদ্ধতিতে কল করুন।
AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportInteractionRequest
ReportInteractionRequest request =
  new ReportInteractionRequest.Builder()
    .setAdSelectionId(adSelectionId)
    .setInteractionKey("view")
    .setInteractionData("{ viewTimeInSeconds : 1 }") // Can be any string
    .setReportingDestinations(
      FLAG_REPORTING_DESTINATION_BUYER | FLAG_REPORTING_DESTINATION_SELLER
    )
    .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportInteraction(
  reportImpressionRequest,
  executor,
  outcomeReceiver);

নিম্নলিখিত প্রয়োজনীয় পরামিতিগুলির সাথে ReportInteractionRequest আরম্ভ করুন:

  • বিজ্ঞাপন নির্বাচন আইডি : একটি বিজ্ঞাপন নির্বাচন আইডি পূর্বে ফিরে আসা AdSelectionOutcome থেকে পুনরুদ্ধার করা হয়েছে।
  • ইন্টারঅ্যাকশন কী : ক্লায়েন্ট দ্বারা সংজ্ঞায়িত একটি স্ট্রিং কী রিপোর্ট করা কর্ম বর্ণনা করে। এটি অবশ্যই রিপোর্টিং জাভাস্ক্রিপ্ট ফাংশনে বিক্রেতা বা ক্রেতার দ্বারা নিবন্ধিত কীটির সাথে মেলে।
  • ইন্টারঅ্যাকশন ডেটা : ইভেন্ট রিপোর্টের সাথে অন্তর্ভুক্ত করা ডেটা ধারণকারী একটি স্ট্রিং, রিপোর্টিং সার্ভারে পোস্ট করা হবে।
  • রিপোর্টিং গন্তব্য : একটি বিট মাস্ক নির্দিষ্ট করে যে ঘটনাগুলি ক্রেতা, বিক্রেতা বা উভয়কেই রিপোর্ট করা উচিত। এই পতাকাগুলি প্ল্যাটফর্ম দ্বারা সরবরাহ করা হয় এবং বিটওয়াইজ অপারেশন ব্যবহার করে চূড়ান্ত গন্তব্য মাস্ক তৈরি করা যেতে পারে। একটি গন্তব্যে রিপোর্ট করতে, আপনি সরাসরি প্ল্যাটফর্ম দ্বারা প্রদত্ত পতাকা ব্যবহার করতে পারেন। একাধিক গন্তব্যে রিপোর্ট করতে, আপনি পতাকা মান একত্রিত করতে bitwise OR ( | ) ব্যবহার করতে পারেন।

অ্যাসিঙ্ক্রোনাস reportInteraction() পদ্ধতি API কলের ফলাফলকে সংকেত দিতে OutcomeReceiver অবজেক্ট ব্যবহার করে।

  • onResult() কলব্যাক নির্দেশ করে যে রিপোর্ট ইন্টারঅ্যাকশন কলটি বৈধ।
  • onError() কলব্যাক নিম্নলিখিত সম্ভাব্য শর্তগুলি নির্দেশ করে:
    • অ্যাপটি ব্যাকগ্রাউন্ডে চলাকালীন কল করা হলে, ব্যর্থতার বিবরণ সহ একটি IllegalStateException ফেরত দেওয়া হয়।
    • ক্লায়েন্ট reportInteraction() কল করা থেকে থ্রোটল হলে, একটি LimitExceededException ফেরত দেওয়া হয়।
    • যদি প্যাকেজটি গোপনীয়তা সংরক্ষণ API কল করার জন্য নথিভুক্ত না হয়, একটি SecurityException() ফেরত দেওয়া হয়।
    • অ্যাপ রিপোর্টিং ইন্টারঅ্যাকশনগুলি selectAds() নামের অ্যাপ থেকে আলাদা হলে, একটি IllegalStateException ফেরত দেওয়া হয়।
  • যদি ব্যবহারকারী গোপনীয়তা স্যান্ডবক্স এপিআই সক্ষম করতে সম্মতি না দেয় তবে কলটি নীরবে ব্যর্থ হবে৷

ইন্টারঅ্যাকশন রিপোর্টিং এন্ডপয়েন্ট

রিপোর্ট ইন্টারঅ্যাকশন API বিক্রি-সাইড প্ল্যাটফর্ম এবং বিজয়ী বাই-সাইড প্ল্যাটফর্ম দ্বারা প্রদত্ত শেষ পয়েন্টগুলিতে HTTPS POST অনুরোধগুলি জারি করে৷ সুরক্ষিত অডিয়েন্স জাভাস্ক্রিপ্ট রিপোর্টিংয়ে ঘোষিত ইউআরআই-এর সাথে ইন্টারঅ্যাকশন কীগুলির সাথে মিলবে এবং রিপোর্ট করা প্রতিটি ইন্টারঅ্যাকশনের জন্য প্রতিটি শেষ পয়েন্টে একটি POST অনুরোধ জারি করবে। অনুরোধের বিষয়বস্তুর ধরন হল সরল পাঠ্য যার মূল অংশটি ইন্টারঅ্যাকশন ডেটা।

সেরা প্রচেষ্টা মিথস্ক্রিয়া রিপোর্টিং

reportInteraction() এইচটিটিপি পোস্টের মাধ্যমে প্রতিবেদনের সর্বোত্তম প্রভাব সমাপ্তির জন্য ডিজাইন করা হয়েছে।

দৈনিক পটভূমি আপডেট

কাস্টম শ্রোতা তৈরি করার সময়, আপনার অ্যাপ্লিকেশন বা এসডিকে কাস্টম শ্রোতা মেটাডেটা শুরু করতে পারে। অতিরিক্তভাবে, প্ল্যাটফর্মটি দৈনিক ব্যাকগ্রাউন্ড আপডেট প্রক্রিয়া সহ কাস্টম শ্রোতা মেটাডেটার নিম্নলিখিত টুকরোগুলি আপডেট করতে পারে।

  • ব্যবহারকারী বিড সংকেত
  • বিশ্বস্ত বিডিং ডেটা
  • AdData তালিকা

এই প্রক্রিয়াটি কাস্টম দর্শকদের মধ্যে সংজ্ঞায়িত দৈনিক আপডেট ইউআরএল এর বিপরীতে প্রশ্নগুলি এবং ইউআরএল একটি জেএসএন প্রতিক্রিয়া ফিরিয়ে দিতে পারে।

  • জেএসওএন প্রতিক্রিয়াতে সমর্থিত মেটাডেটা ক্ষেত্রগুলির যে কোনওটি আপডেট করা দরকার।
  • প্রতিটি জেএসএন ক্ষেত্রটি স্বাধীনভাবে বৈধ করা হয়। ক্লায়েন্ট কোনও ত্রুটিযুক্ত ক্ষেত্রগুলিকে উপেক্ষা করে যার ফলস্বরূপ প্রতিক্রিয়াতে সেই নির্দিষ্ট ক্ষেত্রে কোনও আপডেট হয় না।
  • একটি খালি এইচটিটিপি প্রতিক্রিয়া বা একটি খালি জসন অবজেক্ট " {} " এর ফলে কোনও মেটাডেটা আপডেট হয় না।
  • প্রতিক্রিয়া বার্তার আকার অবশ্যই 10 কেবি -র মধ্যে সীমাবদ্ধ থাকতে হবে।
  • সমস্ত ইউআরআই এইচটিটিপিএস ব্যবহার করতে হবে।
  • trusted_bidding_uri অবশ্যই ক্রেতার মতো একই ইটিএলডি+1 ভাগ করে নিতে হবে।

উদাহরণ: ব্যাকগ্রাউন্ড দৈনিক আপডেটের জন্য json প্রতিক্রিয়া

{
    "user_bidding_signals" : { ... },  // Valid JSON object
    "trusted_bidding_data" : {
        "trusted_bidding_uri" : 'example-dsp1-key-value-service.com',
        "trusted_bidding_keys" : [ 'campaign123', 'campaign456', ... ]
    },
    'ads' : [
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign123.html',
            'metadata' : { ... }  // Valid JSON object
        },
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign456.html',
            'metadata' : { ... }  // Valid JSON object
        },
        ...
    ]
}

বিজ্ঞাপন নির্বাচনের জন্য জাভাস্ক্রিপ্ট

বিজ্ঞাপন নির্বাচন ওয়ার্কফ্লো ক্রেতা-সরবরাহিত এবং বিক্রেতা-সরবরাহিত জাভাস্ক্রিপ্টের সম্পাদনকে অর্কেস্টেট করে।

ক্রেতা-সরবরাহিত জাভাস্ক্রিপ্ট কাস্টম দর্শকদের মধ্যে নির্দিষ্ট বিডিং লজিক ইউআরএল থেকে আনা হয়েছে। ফিরে আসা জাভাস্ক্রিপ্টে নিম্নলিখিত ফাংশনগুলি অন্তর্ভুক্ত করা উচিত:

বিক্রেতা সরবরাহিত জাভাস্ক্রিপ্ট বিজ্ঞাপন নির্বাচন এপিআইয়ের জন্য AdSelectionConfig প্যারামিটারে নির্দিষ্ট করা সিদ্ধান্তের যুক্তিযুক্ত ইউআরএল থেকে আনা হয়। ফিরে আসা জাভাস্ক্রিপ্টে নিম্নলিখিত ফাংশনগুলি অন্তর্ভুক্ত করা উচিত:

জেনারেটবিড ()

function generateBid(
  ad,
  auction_signals,
  per_buyer_signals,
  trusted_bidding_signals,
  contextual_signals,
  user_signals,
  custom_audience_bidding_signals) {
  return {'status': 0, 'ad': ad, 'bid': ad.metadata.result };
}

ইনপুট পরামিতি:

  • ad : ফর্ম্যাট var ad = { 'render_url': url, 'metadata': json_metadata };
  • auction_signals, per_buyer_signals : নিলাম কনফিগারেশন অবজেক্টে জসন অবজেক্ট নির্দিষ্ট
  • custom_audience_bidding_signals : প্ল্যাটফর্ম দ্বারা উত্পাদিত জেএসএন অবজেক্ট। এই জসন অবজেক্টের ফর্ম্যাটটি হ'ল:

    var custom_audience_signals = {
      "owner":"ca_owner",
      "buyer":"ca_buyer",
      "name":"ca_name",
      "activation_time":"ca_activation_time_epoch_ms",
      "expiration_time":"ca_expiration_time_epoch_ms",
      "user_bidding_signals":"ca_user_bidding_signals"
    }
    

    কোথায়:

    • owner , buyer এবং name বিজ্ঞাপন নির্বাচনে অংশ নেওয়া কাস্টম দর্শকদের একই নাম সহ সম্পত্তি থেকে নেওয়া হয়
    • activation_time এবং expiration_time হ'ল ইউনিক্স এপোকের পরে কয়েক সেকেন্ড হিসাবে প্রকাশিত কাস্টম দর্শকদের সক্রিয়করণ এবং মেয়াদোত্তীকরণের সময়
    • ca_user_bidding_signals একটি জেএসএন স্ট্রিং যা ব্যবহারকারী সময়ে CustomAudience userBiddingSignals ক্ষেত্রে নির্দিষ্ট করা হয়েছে
    • trusted_bidding_signals, contextual_signals এবং user_signals হ'ল জেএসএন অবজেক্ট। এগুলি খালি বস্তু হিসাবে পাস করা হয় এবং ভবিষ্যতের রিলিজগুলিতে পূরণ করা হবে। তাদের ফর্ম্যাটটি প্ল্যাটফর্ম দ্বারা প্রয়োগ করা হয় না এবং বিজ্ঞাপন প্রযুক্তি দ্বারা পরিচালিত হয়।

ফলাফল:

  • ad : বিডটি উল্লেখ করে। স্ক্রিপ্টটি বিভিন্ন মেটাডেটা দিয়ে প্রাপ্ত বিজ্ঞাপনটির একটি অনুলিপি ফেরত দেওয়ার অনুমতি রয়েছে। বিজ্ঞাপনটির render_url সম্পত্তিটি আনল্টারড হবে বলে আশা করা হচ্ছে।
  • bid : এই বিজ্ঞাপনের জন্য বিড মান উপস্থাপন করে একটি ভাসমান মান
  • status : একটি পূর্ণসংখ্যার মান যা হতে পারে:
    • 0 : একটি সফল সম্পাদনের জন্য
    • 1 : (বা কোনও শূন্য মান) যদি কোনও ইনপুট সংকেত অবৈধ থাকে। যদি কোনও শূন্য-মান জেনেট-বিড দ্বারা ফিরে আসে তবে বিডিং প্রক্রিয়াটি সমস্ত সিএ বিজ্ঞাপনের জন্য অবৈধ হয়

স্কোরেড ()

function scoreAd(
  ad,
  bid,
  ad_selection_config,
  seller_signals,
  trusted_scoring_signals,
  contextual_signal,
  user_signal,
  custom_audience_signal) {
    return {'status': 0, 'score': score };
}

ইনপুট পরামিতি:

  • ad : generateBid ডকুমেন্টেশন দেখুন
  • bid : বিজ্ঞাপনের জন্য বিড মান
  • ad_selection_config : selectAds এপিআইয়ের AdSelectionConfig প্যারামিটার উপস্থাপন করে এমন একটি জেএসএন অবজেক্ট। বিন্যাস হল:

    var ad_selection_config = {
      'seller': 'seller',
      'decision_logic_url': 'url_of_decision_logic',
      'custom_audience_buyers': ['buyer1', 'buyer2'],
      'auction_signals': auction_signals,
      'per_buyer_signals': per_buyer_signals,
      'contextual_ads': [ad1, ad2]
    }
    
  • seller_signals : json অবজেক্টস sellerSignals AdSelectionConfig এপিআই প্যারামিটার থেকে পড়ে

  • trusted_scoring_signal : AdSelectionConfig এপিআই প্যারামিটারে adSelectionSignals ক্ষেত্র থেকে পড়ুন

  • contextual_signals, user_signals : জেএসএন অবজেক্টস। এগুলি বর্তমানে খালি বস্তু হিসাবে পাস করা হয়েছে এবং ভবিষ্যতের রিলিজগুলিতে পূরণ করা হবে। তাদের ফর্ম্যাটটি প্ল্যাটফর্ম দ্বারা প্রয়োগ করা হয় না এবং বিজ্ঞাপন প্রযুক্তি দ্বারা পরিচালিত হয়।

  • per_buyer_signals : বর্তমান কাস্টম শ্রোতা ক্রেতা হিসাবে কী হিসাবে ব্যবহার করে AdSelectionConfig এপিআই প্যারামিটারে perBuyerSignal মানচিত্র থেকে জসন অবজেক্টটি পড়ুন। খালি যদি মানচিত্রে প্রদত্ত ক্রেতার জন্য কোনও এন্ট্রি না থাকে।

আউটপুট:

  • score : এই বিজ্ঞাপনের জন্য স্কোর মান উপস্থাপন করে একটি ভাসমান মান
  • status : একটি পূর্ণসংখ্যার মান যা হতে পারে:
    • 0: একটি সফল সম্পাদনের জন্য
    • 1: যদি customAudienceSignals অবৈধ হয়
    • 2: যদি AdSelectionConfig অবৈধ হয়
    • 3: অন্য কোনও সংকেত যদি অবৈধ হয় তবে
    • যে কোনও শূন্য-মান মান প্রক্রিয়াটির ব্যর্থতার কারণ করে, মানটি নিক্ষিপ্ত ব্যতিক্রমের ধরণ নির্ধারণ করে

সিলেক্টআউটকাম ()

function selectOutcome(
  outcomes,
  selection_signals) {
    return {'status': 0, 'result': null};
}

ইনপুট পরামিতি:

  • outcomes : একটি জসন অবজেক্ট {"id": id_string, "bid": bid_double}
  • selection_signals : নিলাম কনফিগারেশন অবজেক্টে নির্দিষ্ট করা JSON অবজেক্টস

আউটপুট:

  • status : 0 সাফল্যের জন্য, ব্যর্থতার জন্য শূন্য নয়
  • result : একটি ফলাফল পাস বা নাল

সাংবাদিক ()

function reportResult(ad_selection_config, render_url, bid, contextual_signals) {
   return {
      'status': status,
      'results': {'signals_for_buyer': signals_for_buyer, 'reporting_url': reporting_url }
   };
}

ইনপুট পরামিতি:

  • ad_selection_config : scoreAds ডকুমেন্টেশন দেখুন
  • render_url : বিজয়ী বিজ্ঞাপনের রেন্ডার ইউআরএল
  • bid : বিজয়ী বিজ্ঞাপনের জন্য বিড দেওয়া
  • contextual_signals : generateBid ডকুমেন্টেশন দেখুন

আউটপুট:

  • status: 0 এবং ব্যর্থতার জন্য শূন্য
  • results : একটি জসন অবজেক্টস রয়েছে:
    • signals_for_buyer : একটি জেএসএন অবজেক্ট যা reportWin ফাংশনে পাস করা হয়
    • reporting_url : ক্রেতার কাছে ছাপটি অবহিত করার জন্য প্ল্যাটফর্ম দ্বারা ব্যবহৃত একটি ইউআরএল

রিপোর্টউইন ()

function reportWin(
   ad_selection_signals,
   per_buyer_signals,
   signals_for_buyer,
   contextual_signals,
   custom_audience_signals) {
   return {'status': 0, 'results': {'reporting_url': reporting_url } };
}

ইনপুট পরামিতি:

  • ad_selection_signals, per_buyer_signals : scoreAd জন্য ডকুমেন্টেশন দেখুন
  • signals_for_buyer : একটি জসন অবজেক্টটি reportResult দ্বারা ফিরে এসেছিল
  • contextual_signals, custom_audience_signals : generateBid জন্য ডকুমেন্টেশন দেখুন

আউটপুট:

  • status: 0 এবং ব্যর্থতার জন্য শূন্য
  • results : একটি জসন অবজেক্ট রয়েছে:
    • reporting_url : একটি ইউআরএল যা প্ল্যাটফর্ম দ্বারা বিক্রেতার কাছে ছাপটি অবহিত করার জন্য ব্যবহৃত হয়

রেজিস্টারএডবিয়াকন ()

function registerAdBeacon(
  beacons
)

ইনপুট পরামিতি :

  • beacons : ইন্টারঅ্যাকশন কীগুলির কী-মান জোড়া এবং ইউআরআই রিপোর্টিংযুক্ত একটি অবজেক্ট। বিন্যাস হল:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key : ইভেন্টের প্রতিনিধিত্বকারী একটি স্ট্রিং। এটি প্ল্যাটফর্মটি পরে ব্যবহার করা হয় যখন ইভেন্টের ইন্টারঅ্যাকশনগুলি প্রতিবেদন করার জন্য reporting_uri অবহিত করা উচিত। এই কীটি ক্রেতা বা বিক্রেতা নিবন্ধন করছে এবং বিক্রেতা কী রিপোর্ট করছে তার মধ্যে মেলে।
    • reporting_uri : ইভেন্টের প্রতিবেদনগুলি পাওয়ার জন্য একটি ইউআরআই। এটি ইভেন্টের ধরণের রিপোর্ট হওয়ার সাথে নির্দিষ্ট হওয়া উচিত। ইভেন্টের সাথে প্রতিবেদন করা কোনও ডেটা হ্যান্ডেল করার জন্য এটি অবশ্যই একটি পোস্ট অনুরোধ গ্রহণ করতে হবে।

    যেমন:

      let beacons = {
        'click': 'https://reporting.example.com/click_event',
        'view': 'https://reporting.example.com/view_event'
      }
    

বিজ্ঞাপন নির্বাচন প্রিপবিল্ট ইউআরআইএস

প্রাক -বিল্ট ইউআরআইএস বিজ্ঞাপন প্রযুক্তিগুলিকে AdSelectionConfig এবং AdSelectionFromOutcomesConfig ক্লাসে বিজ্ঞাপন নির্বাচনের সিদ্ধান্ত যুক্তির জন্য জাভাস্ক্রিপ্ট ফাংশন নিয়োগ করার ক্ষমতা দেয়। প্রি বিল্ট ইউআরআইএসের সাথে সম্পর্কিত জাভাস্ক্রিপ্টটি ডাউনলোড করতে নেটওয়ার্ক কলগুলির প্রয়োজন হয় না। বিজ্ঞাপন প্রযুক্তিগুলি জাভাস্ক্রিপ্টটি হোস্ট করার জন্য একটি তালিকাভুক্ত ডোমেন সেট আপ না করেই প্রিলিল্ট ইউআরআই ব্যবহার করতে পারে।

নিম্নলিখিত ফর্ম্যাটটি ব্যবহার করে একটি প্রিপবিল্ট ইউআরআই নির্মিত হয়:

ad-selection-prebuilt:<use-case>/<name>?<required-script-generation-parameters>

গোপনীয়তা স্যান্ডবক্স প্ল্যাটফর্ম রানটাইমে এই ইউআরআই থেকে তথ্য ব্যবহার করে জাভাস্ক্রিপ্ট সরবরাহ করে।

যদি একটি IllegalArgumentException নিক্ষেপ করা হয়:

  • প্রয়োজনীয় পরামিতিগুলির কোনওটি ইউআরআইতে উপস্থিত নেই
  • ইউআরআই -তে অচেনা পরামিতি রয়েছে

সমর্থিত প্রিপবিল্ট ইউআরআই ব্যবহারের কেস এবং নাম

কেস 1 ব্যবহার করুন: বিজ্ঞাপন-নির্বাচন

ad-selection ব্যবহারের ক্ষেত্রে প্রি বিল্ট ইউআরআইগুলি selectAds(AdSelectionConfig) প্রবাহে সমর্থিত।

প্রাক-বিল্ট ইউআরআই নাম: highest-bid-wins

এই প্রাক -বিল্ট ইউআরআই একটি জাভাস্ক্রিপ্ট সরবরাহ করে যা বিডের পরে সর্বোচ্চ বিডের সাথে বিজ্ঞাপনটি বেছে নেয়। এটি বিজয়ীর render_uri এবং bid প্রতিবেদন করার জন্য একটি প্রাথমিক প্রতিবেদন ফাংশন সরবরাহ করে।

প্রয়োজনীয় পরামিতি

reportingUrl : বেস রিপোর্টিং ইউআরএল যা render_uri এবং বিজয়ী বিজ্ঞাপনের bid সাথে প্যারামিটারাইজড:

<reportingUrl>?render_uri=<renderUriOfWinnigAd>&bid=<bidOfWinningAd>

ব্যবহার

যদি আপনার বেস রিপোর্টিং ইউআরএলটি https://www.ssp.com/reporting হয় তবে প্রিপিল্ট ইউআরআই হবে:

`ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=https://www.ssp.com/reporting`

কেস 2 ব্যবহার করুন: বিজ্ঞাপন-নির্বাচন থেকে ফলাফল

ad-selection-from-outcomes অধীনে প্রাক-বিল্ট ইউআরআইগুলি ব্যবহার করে কেস কেস ব্যবহার করে selectAds(AdSelectionFromOutcomesConfig) ওয়ার্কফ্লোকে সমর্থন করে।

প্রি বিল্ট ইউআরআই নাম: waterfall-mediation-truncation

waterfall-mediation-truncation প্রাক-বিল্ড ইউআরআই জাভাস্ক্রিপ্ট সরবরাহ করে যা জলপ্রপাতের মধ্যস্থতা ছাঁটাইয়ের যুক্তি প্রয়োগ করে যেখানে জাভাস্ক্রিপ্টটি প্রথম পক্ষের বিজ্ঞাপনটি ফেরত দেয় যদি bid bid floor চেয়ে বেশি বা সমান হয় এবং অন্যথায় null ফিরে আসে।

প্রয়োজনীয় পরামিতি

bidFloor : মধ্যস্থতা এসডিকে এর বিজ্ঞাপনের সাথে তুলনা করা getSelectionSignals() এ বিড ফ্লোরের মানটির কীটি পাস হয়েছে।

ব্যবহার

যদি আপনার বিজ্ঞাপন নির্বাচনের সংকেতগুলি {"bid_floor": 10} তবে ফলস্বরূপ প্রাক -বিল্ড ইউআরআই হবে:

`ad-selection-prebuilt://ad-selection-from-outcomes/waterfall-mediation-truncation/?bidFloor=bid_floor`

টেস্টিং

সুরক্ষিত শ্রোতাদের এপিআই দিয়ে আপনাকে শুরু করতে সহায়তা করার জন্য, আমরা কোটলিন এবং জাভাতে নমুনা অ্যাপ্লিকেশন তৈরি করেছি, যা গিথুবে পাওয়া যায়।

পূর্বশর্ত

সুরক্ষিত শ্রোতাদের এপিআইয়ের বিজ্ঞাপন নির্বাচন এবং ছাপ প্রতিবেদনের সময় কিছু জাভাস্ক্রিপ্ট প্রয়োজন। পরীক্ষার পরিবেশে এই জাভাস্ক্রিপ্ট সরবরাহ করার দুটি পদ্ধতি রয়েছে:

  • প্রয়োজনীয় এইচটিটিপিএস এন্ডপয়েন্টগুলি সহ একটি সার্ভার চালান যা জাভাস্ক্রিপ্টটি ফেরত দেয়
  • স্থানীয় উত্স থেকে প্রয়োজনীয় কোড সরবরাহ করে রিমোট আনতে ওভাররাইড করুন

হয় পদ্ধতির জন্য ইমপ্রেশন রিপোর্টিং পরিচালনা করতে একটি এইচটিটিপিএস এন্ডপয়েন্ট স্থাপন করা প্রয়োজন।

এইচটিটিপিএস এন্ডপয়েন্টস

বিজ্ঞাপন নির্বাচন এবং ইমপ্রেশন রিপোর্টিং পরীক্ষা করার জন্য, আপনার পরীক্ষার ডিভাইস বা এমুলেটর অ্যাক্সেস করতে পারে এমন 7 টি এইচটিটিপিএস এন্ডপয়েন্টগুলি সেট আপ করতে হবে:

  1. ক্রেতা শেষ পয়েন্ট যা বিডিং লজিক জাভাস্ক্রিপ্ট পরিবেশন করে।
  2. একটি শেষ পয়েন্ট যা বিডিং সংকেত পরিবেশন করে।
  3. বিক্রেতার শেষ পয়েন্ট যা সিদ্ধান্তের যুক্তি জাভাস্ক্রিপ্ট পরিবেশন করে।
  4. একটি শেষ পয়েন্ট যা স্কোরিং সংকেত পরিবেশন করে।
  5. বিজয়ী ক্রেতা ইমপ্রেশন রিপোর্টিং এন্ডপয়েন্ট।
  6. বিক্রেতা ইমপ্রেশন রিপোর্টিং শেষ পয়েন্ট।
  7. কাস্টম দর্শকদের জন্য দৈনিক আপডেটগুলি পরিবেশন করার জন্য একটি শেষ পয়েন্ট।

সুবিধার জন্য, গিটহাব রেপো পরীক্ষার উদ্দেশ্যে বেসিক জাভাস্ক্রিপ্ট কোড সরবরাহ করে। এটিতে ওপেনাপি পরিষেবা সংজ্ঞাও অন্তর্ভুক্ত রয়েছে যা সমর্থিত মক বা মাইক্রোসার্ভেসিস প্ল্যাটফর্মে স্থাপন করা যেতে পারে। আরও তথ্যের জন্য, প্রকল্পটি দেখুন।

জাভাস্ক্রিপ্টের রিমোট আনতে ওভাররাইড করুন

এই বৈশিষ্ট্যটি শেষ থেকে শেষ পরীক্ষার জন্য ব্যবহার করার উদ্দেশ্যে। রিমোট আনতে ওভাররাইড করতে, আপনার অ্যাপ্লিকেশনটি অবশ্যই বিকাশকারী বিকল্পগুলি সক্ষম করে ডিবাগ মোডে চলতে হবে।

আপনার অ্যাপ্লিকেশনটির জন্য ডিবাগ মোড সক্ষম করতে, আপনার অ্যান্ড্রয়েডম্যানিফেস্ট.এক্সএমএল -এ অ্যাপ্লিকেশন বৈশিষ্ট্যে নিম্নলিখিত লাইনটি যুক্ত করুন:

<application
  android:debuggable="true">

এই ওভাররাইডগুলি কীভাবে ব্যবহার করবেন তার উদাহরণের জন্য, দয়া করে গিটহাবের সুরক্ষিত শ্রোতা এপিআই নমুনা অ্যাপটি দেখুন।

বিডিং, স্কোরিং সিদ্ধান্ত এবং প্রতিবেদনের মতো বিজ্ঞাপন নির্বাচনের রুটিনগুলি পরিচালনা করতে আপনার নিজের কাস্টম জাভাস্ক্রিপ্ট যুক্ত করতে হবে। আপনি বেসিক জাভাস্ক্রিপ্ট কোড উদাহরণগুলি খুঁজে পেতে পারেন যা গিটহাব রেপোতে প্রয়োজনীয় সমস্ত অনুরোধগুলি পরিচালনা করে। সুরক্ষিত শ্রোতা এপিআই নমুনা অ্যাপ্লিকেশনটি প্রদর্শন করে যে কীভাবে সেই ফাইল থেকে কোড পড়তে হয় এবং এটি ওভাররাইড হিসাবে ব্যবহারের জন্য প্রস্তুত করতে হয়।

সেলস-সাইড এবং ক্রয়-সাইড জাভাস্ক্রিপ্টটি স্বাধীনভাবে আনার পক্ষে ওভাররাইড করা সম্ভব, যদিও আপনার যে কোনও জাভাস্ক্রিপ্ট আপনি ওভাররাইড সরবরাহ করছেন না সে জন্য আপনার এইচটিটিপিএস এন্ডপয়েন্টের প্রয়োজন। এই কেসগুলি পরিচালনা করে এমন কোনও সার্ভার কীভাবে সেট আপ করবেন সে সম্পর্কে তথ্যের জন্য দয়া করে রিডমিকে দেখুন।

আপনার প্যাকেজের মালিকানাধীন কাস্টম শ্রোতাদের জন্য জাভাস্ক্রিপ্ট আনতে কেবল ওভাররাইড করা সম্ভব।

ওভাররাইড বিক্রয়-সাইড জাভাস্ক্রিপ্ট

বিক্রয়-সাইড জাভাস্ক্রিপ্টের একটি ওভাররাইড সেট আপ করতে, নিম্নলিখিত কোড উদাহরণ হিসাবে প্রদর্শিত হিসাবে নিম্নলিখিতগুলি করুন:

  1. একটি AdSelectionManager অবজেক্ট আরম্ভ করুন।
  2. AdSelectionManager অবজেক্ট থেকে TestAdSelectionManager একটি রেফারেন্স পান।
  3. একটি AdSelectionConfig অবজেক্ট তৈরি করুন।
  4. AdSelectionConfig অবজেক্ট এবং আপনি ওভাররাইড হিসাবে ব্যবহার করার ইচ্ছা জাভাস্ক্রিপ্টকে উপস্থাপন করে এমন একটি String সহ একটি AddAdSelectionOverrideRequest তৈরি করুন।
  5. AddAdSelectionOverrideRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টগুলির সাথে অ্যাসিঙ্ক্রোনাস overrideAdSelectionConfigRemoteInfo() পদ্ধতিতে কল করুন।

কোটলিন

val testAdSelectionManager: TestAdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java).getTestAdSelectionManager()

// Initialize AdSelectionConfig =
val adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build()

// Initialize AddAddSelectionOverrideRequest
val request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build()

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestAdSelectionManager testAdSelectionManager =
  context.getSystemService(AdSelectionManager.class).getTestAdSelectionManager();

// Initialize AdSelectionConfig =
AdSelectionConfig adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build();

// Initialize AddAddSelectionOverrideRequest
AddAdSelectionOverrideRequest request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build();

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver);

AdSelectionConfig প্রতিটি ক্ষেত্র কী উপস্থাপন করে সে সম্পর্কে আরও তথ্যের জন্য রান বিজ্ঞাপন নির্বাচন বিভাগটি দেখুন। মূল পার্থক্যটি হ'ল সিদ্ধান্তটি লজিকিউরলকে স্থানধারক মান হিসাবে সেট করা যেতে পারে কারণ এটি উপেক্ষা করা হবে।

বিজ্ঞাপন নির্বাচনের সময় ব্যবহৃত জাভাস্ক্রিপ্টটি ওভাররাইড করার জন্য, decisionLogicJs অবশ্যই সঠিক বিক্রেতা-সাইড ফাংশন স্বাক্ষর থাকতে হবে। স্ট্রিং হিসাবে জাভাস্ক্রিপ্ট ফাইলটি কীভাবে পড়তে হয় তার উদাহরণের জন্য, দয়া করে গিটহাবের সুরক্ষিত শ্রোতা এপিআই নমুনা অ্যাপটি দেখুন।

অ্যাসিঙ্ক্রোনাস overrideAdSelectionConfigRemoteInfo() পদ্ধতিটি এপিআই কলটির ফলাফলের সংকেত দিতে OutcomeReceiver অবজেক্টটি ব্যবহার করে।

onResult() কলব্যাকটি বোঝায় যে ওভাররাইডটি সফলভাবে প্রয়োগ করা হয়েছিল। selectAds() এর ভবিষ্যতের কলগুলি আপনি ওভাররাইড হিসাবে যে সিদ্ধান্ত এবং রিপোর্টিং যুক্তি ব্যবহার করেছেন তা ব্যবহার করবে।

onError() কলব্যাক দুটি সম্ভাব্য শর্তকে বোঝায়:

  • যদি ওভাররাইডটি অবৈধ যুক্তিগুলির সাথে চেষ্টা করা হয় তবে AdServiceException কারণ হিসাবে একটি IllegalArgumentException নির্দেশ করে।
  • যদি ওভাররাইডটি কোনও অ্যাপ্লিকেশনটি বিকাশকারী বিকল্পগুলি সক্ষম করে ডিবাগ মোডে না চলার সাথে চেষ্টা করা হয় তবে AdServiceException IllegalStateException কারণ হিসাবে নির্দেশ করে।

বিক্রয়-সাইড ওভাররাইডগুলি পুনরায় সেট করুন

এই বিভাগটি ধরে নিয়েছে যে আপনি বিক্রয়-পক্ষের জাভাস্ক্রিপ্টকে ওভাররাইড করেছেন এবং পূর্ববর্তী বিভাগে ব্যবহৃত TestAdSelectionManager এবং AdSelectionConfig একটি রেফারেন্স রয়েছে।

সমস্ত AdSelectionConfigs জন্য ওভাররাইডগুলি পুনরায় সেট করার জন্য:

  1. প্রাসঙ্গিক OutcomeReceiver অবজেক্টের সাথে অ্যাসিঙ্ক্রোনাস resetAllAdSelectionConfigRemoteOverrides() পদ্ধতিতে কল করুন।

কোটলিন

// Resets overrides for all AdSelectionConfigs
testAadSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
  outComeReceiver)

জাভা

// Resets overrides for all AdSelectionConfigs
testAdSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
    outComeReceiver);

আপনি বিক্রয়-পক্ষের ওভাররাইডগুলি পুনরায় সেট করার পরে, selectAds() প্রয়োজনীয় জাভাস্ক্রিপ্টটি আনার চেষ্টা করার জন্য AdSelectionConfig যে কোনও সিদ্ধান্ত গ্রহণ করুন লজিকুরল ব্যবহার করুন।

যদি resetAllAdSelectionConfigRemoteOverrides() এর কলটি ব্যর্থ হয়, তবে OutComeReceiver.onError() কলব্যাক একটি AdServiceException সরবরাহ করে। যদি ওভাররাইডগুলি অপসারণের চেষ্টা করা হয় তবে কোনও অ্যাপ্লিকেশনটি ডেভেলপার বিকল্পগুলি সক্ষম করে ডিবাগ মোডে চলমান না দিয়ে চেষ্টা করা হয়, AdServiceException IllegalStateException কারণ হিসাবে নির্দেশ করে।

ওভাররাইড বাই-সাইড জাভাস্ক্রিপ্ট

  1. একটি কাস্টম দর্শকদের সাথে যোগ দিতে পদক্ষেপগুলি অনুসরণ করুন
  2. আপনি ওভাররাইড হিসাবে বিডিং লজিক এবং ডেটা ব্যবহার করতে চান এমন ডেটা ছাড়াও আপনি যে কাস্টম দর্শকদের ওভাররাইড করতে চান তার সাথে ক্রেতা এবং নামের সাথে একটি AddCustomAudienceOverrideRequest তৈরি করুন
  3. AddCustomAudienceOverrideRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টগুলির সাথে অ্যাসিঙ্ক্রোনাস overrideCustomAudienceRemoteInfo() পদ্ধতিটি কল করুন

কোটলিন

val testCustomAudienceManager: TestCustomAudienceManager =
  context.getSystemService(CustomAudienceManager::class.java).getTestCustomAudienceManager()

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
val request = AddCustomAudienceOverrideRequest.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setBiddingLogicJs(biddingLogicJS)
    .setTrustedBiddingSignals(trustedBiddingSignals)
    .build()

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestCustomAudienceManager testCustomAudienceManager =
  context.getSystemService(CustomAudienceManager.class).getTestCustomAudienceManager();

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
AddCustomAudienceOverrideRequest request =
    AddCustomAudienceOverrideRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .setBiddingLogicJs(biddingLogicJS)
        .setTrustedBiddingSignals(trustedBiddingSignals)
        .build();

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver);

ক্রেতা এবং নামের জন্য মানগুলি কাস্টম শ্রোতা তৈরি করতে ব্যবহৃত একই। এই ক্ষেত্রগুলি সম্পর্কে আরও জানুন

অতিরিক্তভাবে, আপনি দুটি অতিরিক্ত পরামিতি নির্দিষ্ট করতে পারেন:

  • biddingLogicJs : জাভাস্ক্রিপ্ট যা বিজ্ঞাপন নির্বাচনের সময় ব্যবহৃত ক্রেতার যুক্তি ধারণ করে। এই জাভাস্ক্রিপ্টে প্রয়োজনীয় ফাংশন স্বাক্ষরগুলি দেখুন।
  • trustedBiddingSignals : বিজ্ঞাপন নির্বাচনের সময় বিডিং সংকেত ব্যবহার করা হবে। পরীক্ষার উদ্দেশ্যে এটি একটি খালি স্ট্রিং হতে পারে।

অ্যাসিঙ্ক্রোনাস overrideCustomAudienceRemoteInfo() পদ্ধতিটি এপিআই কলের ফলাফলের সংকেত দিতে OutcomeReceiver অবজেক্টটি ব্যবহার করে।

onResult() কলব্যাকটি বোঝায় যে ওভাররাইডটি সফলভাবে প্রয়োগ করা হয়েছিল। পরবর্তীকালে selectAds() আপনি ওভাররাইড হিসাবে যে বিডিং এবং রিপোর্টিং লজিকটি পাস করেছেন তা ব্যবহার করুন।

onError() কলব্যাক দুটি সম্ভাব্য শর্তকে বোঝায়।

  • যদি ওভাররাইডটি অবৈধ যুক্তিগুলির সাথে চেষ্টা করা হয় তবে AdServiceException কারণ হিসাবে একটি IllegalArgumentException নির্দেশ করে।
  • যদি ওভাররাইডটি কোনও অ্যাপ্লিকেশনটি বিকাশকারী বিকল্পগুলি সক্ষম করে ডিবাগ মোডে না চলার সাথে চেষ্টা করা হয় তবে AdServiceException IllegalStateException কারণ হিসাবে নির্দেশ করে।

ক্রয়-সাইড ওভাররাইডগুলি পুনরায় সেট করুন

এই বিভাগটি ধরে নিয়েছে যে আপনি ক্রয়-সাইড জাভাস্ক্রিপ্টটিকে ওভাররাইড করেছেন এবং আপনার পূর্ববর্তী বিভাগে ব্যবহৃত TestCustomAudienceManager একটি রেফারেন্স রয়েছে।

সমস্ত কাস্টম শ্রোতাদের জন্য ওভাররাইডগুলি পুনরায় সেট করতে:

  1. প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টগুলির সাথে অ্যাসিঙ্ক্রোনাস resetAllCustomAudienceOverrides() পদ্ধতিতে কল করুন।

কোটলিন

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

জাভা

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

আপনি বাই-সাইড ওভাররাইডগুলি পুনরায় সেট করার পরে, পরবর্তীকালে selectAds() যা কিছু biddingLogicUrl এবং trustedBiddingData ব্যবহার করুন প্রয়োজনীয় জাভাস্ক্রিপ্টটি আনার চেষ্টা করার জন্য CustomAudience সংরক্ষণ করা হয়।

যদি resetCustomAudienceRemoteInfoOverride() এর কলটি ব্যর্থ হয়, তবে OutComeReceiver.onError() কলব্যাক একটি AdServiceException সরবরাহ করে। যদি ওভাররাইডগুলি অপসারণের চেষ্টা করা হয় যে কোনও অ্যাপ্লিকেশনটি বিকাশকারী বিকল্পগুলি সক্ষম করে ডিবাগ মোডে চলমান না নিয়ে, AdServiceException IllegalStateException কারণ হিসাবে নির্দেশ করে।

একটি রিপোর্টিং সার্ভার সেট আপ করুন

আপনি যখন রিমোট আনতে ওভাররাইডগুলি ব্যবহার করেন, তখন আপনার ডিভাইস বা এমুলেটর রিপোর্টিং ইভেন্টগুলিতে প্রতিক্রিয়া জানাতে আপনার এমন একটি সার্ভার সেট আপ করতে হবে। একটি সাধারণ শেষ পয়েন্ট যা 200 ফেরত দেয় তা পরীক্ষার জন্য যথেষ্ট। গিটহাব রেপোতে ওপেনাপি পরিষেবা সংজ্ঞা অন্তর্ভুক্ত রয়েছে যা সমর্থিত মক বা মাইক্রোসার্ভেসিস প্ল্যাটফর্মে স্থাপন করা যেতে পারে। আরও তথ্যের জন্য, প্রকল্পটি দেখুন।

ওপেনাপি সংজ্ঞাগুলি সন্ধান করার সময়, রিপোর্টিং-সার্ভার.জসন সন্ধান করুন। এই ফাইলটিতে একটি সাধারণ শেষ পয়েন্ট রয়েছে যা এইচটিটিপি প্রতিক্রিয়া কোড উপস্থাপন করে 200 ফেরত দেয়। এই শেষ পয়েন্টটি selectAds() সময় ব্যবহৃত হয় এবং সুরক্ষিত শ্রোতাদের এপিআইয়ের সংকেতগুলি যে ইমপ্রেশন রিপোর্টিং সফলভাবে শেষ হয়েছে।

পরীক্ষা করার কার্যকারিতা

  • পূর্ববর্তী ব্যবহারকারীর ক্রিয়াকলাপের ভিত্তিতে কাস্টম শ্রোতাদের সাথে যোগদান বা চলে যাওয়া এবং সেট আপ করা অনুশীলন করুন।
  • দূরবর্তীভাবে হোস্ট করা জাভাস্ক্রিপ্টের মাধ্যমে ডিভাইস বিজ্ঞাপন নির্বাচনের সূচনাটি অনুশীলন করুন।
  • কাস্টম শ্রোতা সেটিংসের সাথে কোনও অ্যাপের সংযোগ কীভাবে বিজ্ঞাপন নির্বাচনের ফলাফলগুলিকে প্রভাবিত করতে পারে তা পর্যবেক্ষণ করুন।
  • বিজ্ঞাপন নির্বাচনের পরে অনুশীলন ইমপ্রেশন রিপোর্টিং।

সীমাবদ্ধতা

নিম্নলিখিত টেবিলটি সুরক্ষিত শ্রোতাদের এপিআই প্রসেসিংয়ের সীমাবদ্ধতাগুলি তালিকাভুক্ত করে। উপস্থাপিত সীমাগুলি প্রতিক্রিয়ার ভিত্তিতে পরিবর্তনের সাপেক্ষে হতে পারে। অগ্রগতি ক্ষমতাগুলির জন্য, রিলিজ নোটগুলি পড়ুন।

কম্পোনেন্ট সীমা বর্ণনা সীমিত মান
কাস্টম শ্রোতা (সিএ) সিএ প্রতি বিজ্ঞাপনের সর্বাধিক সংখ্যা 100
প্রতি আবেদন প্রতি সিএএসের সর্বাধিক সংখ্যা 1000
সর্বাধিক সংখ্যক অ্যাপ্লিকেশন যা সিএ তৈরি করতে পারে 1000
একটি সিএর সক্রিয়করণের সময় সর্বাধিক বিলম্ব তার তৈরির সময় থেকে 60 দিন
একটি সিএ এর সক্রিয়করণের সময় থেকে সর্বাধিক মেয়াদ শেষ হওয়ার সময় 60 দিন
ডিভাইসে সর্বাধিক সংখ্যা সিএএস 4000
সিএ নামের সর্বাধিক আকার 200 বাইট
দৈনিক আনার সর্বাধিক আকার ইউআরআই 400 বাইট
বিডিং লজিক ইউআরআই এর সর্বাধিক আকার 400 বাইট
বিশ্বস্ত বিডিং ডেটার সর্বাধিক আকার 10 KB
ব্যবহারকারী বিডিং সিগন্যালের সর্বাধিক আকার 10 KB
ক্রেতার প্রতি leaveCustomAudience জন্য সর্বাধিক কল রেট প্রতি সেকেন্ডে 1
ক্রেতার প্রতি joinCustomAudience জন্য সর্বাধিক কল রেট প্রতি সেকেন্ডে 1
সিএ ব্যাকগ্রাউন্ড আনতে টাইমআউট সংযোগ করুন 5 সেকেন্ড
এইচটিটিপি পড়ুন সময়সীমা 30 সেকেন্ড
সর্বোচ্চ মোট ডাউনলোডের আকার 10 KB
একটি আনার পুনরাবৃত্তির সর্বোচ্চ সময়কাল 5 মিনিট
প্রতি চাকরিতে সর্বাধিক সিএএস আপডেট হয়েছে 1000
বিজ্ঞাপন নির্বাচন সর্বাধিক ক্রেতাদের সংখ্যা টিবিডি
ক্রেতা প্রতি সর্বাধিক সিএএস টিবিডি
নিলামে বিজ্ঞাপনের সর্বাধিক সংখ্যা টিবিডি
প্রাথমিক সংযোগ সময়সীমা 5 সেকেন্ড
সংযোগ পড়ার সময়সীমা 5 সেকেন্ড
সামগ্রিক AdSelection সর্বাধিক সম্পাদনের সময় 10 সেকেন্ড
AdSelection সিএ প্রতি বিড করার সর্বাধিক সম্পাদনের সময় 5 সেকেন্ড
AdSelection স্কোর করার সর্বাধিক কার্যকর করার সময় 5 সেকেন্ড
AdSelection ক্রেতার জন্য সর্বোচ্চ মৃত্যুদণ্ডের সময় টিবিডি
বিজ্ঞাপন নির্বাচনের সর্বাধিক আকার/বিক্রেতা/প্রতি ক্রেতা সংকেত টিবিডি
বিক্রেতা/ক্রেতা স্ক্রিপ্টগুলির সর্বাধিক আকার টিবিডি
selectAds জন্য সর্বাধিক কল রেট 1 কিউপিএস
ইমপ্রেশন রিপোর্টিং অধ্যবসায় থেকে বিজ্ঞাপন নির্বাচন অপসারণের আগে সর্বনিম্ন সময় 24 ঘন্টা
স্টোরেজ বিজ্ঞাপন নির্বাচনের সর্বাধিক সংখ্যা টিবিডি
আউটপুট ইউআরএল রিপোর্টিং সর্বাধিক আকার টিবিডি
ইমপ্রেশন রিপোর্টিংয়ের জন্য সর্বাধিক সময় টিবিডি
বিজ্ঞপ্তি কলগুলির জন্য সর্বাধিক সংখ্যা টিবিডি
সংযোগের সময়সীমা শেষ 5 সেকেন্ড
reportImpression জন্য সর্বাধিক সামগ্রিক সম্পাদনের সময় 2 সেকেন্ড
reportImpressions জন্য সর্বাধিক কল রেট 1 কিউপিএস
ইভেন্ট রিপোর্টিং নিলাম প্রতি ক্রেতা প্রতি বীকন সর্বাধিক সংখ্যা 10

নিলাম প্রতি বিক্রেতার প্রতি বীকনগুলির সর্বাধিক সংখ্যা

10

ইভেন্ট কী এর সর্বোচ্চ আকার

40 বাইট

ইভেন্টের ডেটা সর্বাধিক আকার

64KB

বিজ্ঞাপন বিজ্ঞাপন তালিকার সর্বাধিক আকার 10 কেবি প্রাসঙ্গিক জন্য একক সিএতে সমস্ত AdData দ্বারা ভাগ করা
ইউআরএল ইনপুট হিসাবে নেওয়া কোনও ইউআরএল স্ট্রিংয়ের সর্বাধিক দৈর্ঘ্য টিবিডি
জাভাস্ক্রিপ্ট সর্বাধিক কার্যকর করার সময় বিডিং এবং ইমপ্রেশন রিপোর্টিংয়ের জন্য স্কোর করার জন্য 1 সেকেন্ড
সর্বাধিক মেমরি ব্যবহৃত 10 MB

বাগ এবং সমস্যা রিপোর্ট করুন

আপনার প্রতিক্রিয়া অ্যান্ড্রয়েডের গোপনীয়তা স্যান্ডবক্সের একটি গুরুত্বপূর্ণ অংশ! অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের উন্নতির জন্য আপনি যে কোনও সমস্যা বা ধারণাগুলি সম্পর্কে আমাদের ধারণাগুলি সম্পর্কে জানতে দিন।

{ % ভারব্যাটিম %} { % endverbatim %} { % ভারব্যাটিম %} { % endverbatim %},

আপনি অ্যান্ড্রয়েড ডকুমেন্টেশনে গোপনীয়তা স্যান্ডবক্সের মাধ্যমে পড়ার সাথে সাথে, আপনি যে প্রোগ্রামটি নিয়ে কাজ করছেন তা নির্বাচন করতে বিকাশকারী পূর্বরূপ বা বিটা বোতামটি ব্যবহার করুন, কারণ নির্দেশাবলী পৃথক হতে পারে।


অ্যান্ড্রয়েডে সুরক্ষিত শ্রোতা এপিআই (পূর্বে ফ্লেজ নামে পরিচিত) কাস্টম শ্রোতা এপিআই এবং বিজ্ঞাপন নির্বাচন এপিআই অন্তর্ভুক্ত রয়েছে। অ্যাড টেক প্ল্যাটফর্ম এবং বিজ্ঞাপনদাতারা পূর্ববর্তী অ্যাপের ব্যস্ততার উপর ভিত্তি করে কাস্টমাইজড বিজ্ঞাপনগুলি পরিবেশন করতে এই এপিআইগুলি ব্যবহার করতে পারেন যা অ্যাপস জুড়ে শনাক্তকারীদের ভাগ করে নেওয়ার সীমাবদ্ধ করে এবং তৃতীয় পক্ষের সাথে কোনও ব্যবহারকারীর অ্যাপ্লিকেশন ইন্টারঅ্যাকশন সম্পর্কিত তথ্য ভাগ করে নেওয়ার সীমাবদ্ধ করে।

কাস্টম শ্রোতা এপিআই "কাস্টম শ্রোতা" বিমূর্ততার চারপাশে কেন্দ্রিক, যা সাধারণ উদ্দেশ্য সহ ব্যবহারকারীদের একটি দলকে উপস্থাপন করে। একজন বিজ্ঞাপনদাতা কোনও কাস্টম শ্রোতার সাথে ব্যবহারকারীকে নিবন্ধভুক্ত করতে পারেন এবং এর সাথে প্রাসঙ্গিক বিজ্ঞাপনগুলি সংযুক্ত করতে পারেন। এই তথ্যটি স্থানীয়ভাবে সংরক্ষণ করা হয় এবং বিজ্ঞাপনদাতাদের বিড, বিজ্ঞাপন ফিল্টারিং এবং বিজ্ঞাপন রেন্ডারিং অবহিত করতে ব্যবহার করা যেতে পারে।

বিজ্ঞাপন নির্বাচন এপিআই একটি কাঠামো সরবরাহ করে যা একাধিক বিকাশকারীদের কাস্টম দর্শকদের জন্য স্থানীয়ভাবে নিলাম চালাতে দেয়। এটি অর্জনের জন্য, সিস্টেমটি কাস্টম দর্শকদের সাথে সম্পর্কিত প্রাসঙ্গিক বিজ্ঞাপনগুলি বিবেচনা করে এবং বিজ্ঞাপনগুলিতে অতিরিক্ত প্রসেসিং সম্পাদন করে যা একটি বিজ্ঞাপন প্রযুক্তি প্ল্যাটফর্ম ডিভাইসে ফিরে আসে।

বিজ্ঞাপন প্রযুক্তি প্ল্যাটফর্মগুলি ব্যবহারকারীর গোপনীয়তা সংরক্ষণ করে এমন পুনরায় বিপণন বাস্তবায়নের জন্য এই এপিআইগুলিকে সংহত করতে পারে। অ্যাপ্লিকেশন ইনস্টল বিজ্ঞাপন সহ অতিরিক্ত ব্যবহারের ক্ষেত্রে সমর্থন ভবিষ্যতের প্রকাশের জন্য পরিকল্পনা করা হয়েছে। ডিজাইনের প্রস্তাবটিতে অ্যান্ড্রয়েডে সুরক্ষিত শ্রোতা এপিআই সম্পর্কে আরও জানুন।

এই গাইডটি নিম্নলিখিতগুলি করতে অ্যান্ড্রয়েডে সুরক্ষিত শ্রোতাদের এপিআইয়ের সাথে কীভাবে কাজ করবেন তা বর্ণনা করে:

  1. কাস্টম শ্রোতাদের পরিচালনা করুন
  2. একটি ডিভাইসে বিজ্ঞাপন নির্বাচন সেট আপ করুন এবং চালান
  3. বিজ্ঞাপন ছাপ রিপোর্ট

আপনি শুরু করার আগে

আপনি শুরু করার আগে নিম্নলিখিতগুলি সম্পূর্ণ করুন:

  1. অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের জন্য আপনার বিকাশের পরিবেশ সেট আপ করুন
  2. হয় সমর্থিত ডিভাইসে কোনও সিস্টেম চিত্র ইনস্টল করুন বা অ্যান্ড্রয়েডে গোপনীয়তা স্যান্ডবক্সের জন্য সমর্থন অন্তর্ভুক্ত একটি এমুলেটর সেট আপ করুন
  3. একটি টার্মিনালে, নিম্নলিখিত এডিবি কমান্ডের সাথে সুরক্ষিত শ্রোতাদের এপিআই (ডিফল্টরূপে অক্ষম) অ্যাক্সেস সক্ষম করুন

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. একটি টার্মিনালে, নিম্নলিখিত এডিবি কমান্ডগুলির সাথে বীকন রিপোর্টিং সক্ষম করুন।

     adb shell device_config put adservices fledge_beacon_reporting_metrics_enabled true
     adb shell device_config put adservices fledge_register_ad_beacon_enabled true
    
  5. আপনার অ্যাপ্লিকেশনটির ম্যানিফেস্টে একটি ACCESS_ADSERVICES_CUSTOM_AUDIENCE অনুমতি অন্তর্ভুক্ত করুন:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  6. আপনার ম্যানিফেস্টের <application> উপাদানটিতে একটি বিজ্ঞাপন পরিষেবাদি কনফিগারেশন উল্লেখ করুন:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  7. আপনার ম্যানিফেস্টে রেফারেন্সযুক্ত বিজ্ঞাপন পরিষেবাদি এক্সএমএল রিসোর্স উল্লেখ করুন যেমন res/xml/ad_services_config.xmlবিজ্ঞাপন পরিষেবাদির অনুমতি এবং এসডিকে অ্যাক্সেস নিয়ন্ত্রণ সম্পর্কে আরও জানুন

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  8. ডিফল্টরূপে, বিজ্ঞাপন নির্বাচন এপিআই একটি নিলাম বা ইমপ্রেশন রিপোর্টিং স্ক্রিপ্ট বরাদ্দ করতে পারে এমন সর্বাধিক পরিমাণে মেমরির সীমাবদ্ধতা প্রয়োগ করে। মেমরি সীমাবদ্ধতা বৈশিষ্ট্যের জন্য ওয়েবভিউ সংস্করণ 105.0.5195.58 বা তার বেশি প্রয়োজন। প্ল্যাটফর্মটি একটি সংস্করণ চেক প্রয়োগ করে এবং selectAds কল করে এবং reportImpression এপিআইগুলি ব্যর্থ হয় যদি এটি সন্তুষ্ট না হয়। এটি সেট আপ করার জন্য দুটি বিকল্প রয়েছে:

    • বিকল্প 1: এই চেকটি নিষ্ক্রিয় করতে নিম্নলিখিত এডিবি কমান্ডটি চালান:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • বিকল্প 2: গুগল প্লে স্টোর থেকে ওয়েবভিউ বিটা ইনস্টল করুন। এটি অবশ্যই পূর্বে বর্ণিত সংস্করণের চেয়ে সমান বা উচ্চতর হতে হবে।

একটি কাস্টম দর্শকদের সাথে যোগ দিন

একটি কাস্টম শ্রোতা কোনও বিজ্ঞাপনদাতা অ্যাপ্লিকেশন দ্বারা নির্ধারিত হিসাবে সাধারণ উদ্দেশ্য বা আগ্রহের সাথে ব্যবহারকারীদের একটি গ্রুপের প্রতিনিধিত্ব করে। একটি অ্যাপ্লিকেশন বা এসডিকে কোনও নির্দিষ্ট শ্রোতা যেমন কোনও শপিং কার্টে আইটেম রেখে গেছে এমন কেউ নির্দেশ করতে কাস্টম শ্রোতা ব্যবহার করতে পারে। কাস্টম শ্রোতাদের অসাধারণভাবে তৈরি করতে বা যোগ দিতে, নিম্নলিখিতগুলি করুন:

  1. CustomAudienceManager অবজেক্টটি আরম্ভ করুন।
  2. ক্রেতার প্যাকেজ এবং একটি প্রাসঙ্গিক নামের মতো কী পরামিতি নির্দিষ্ট করে একটি CustomAudience অবজেক্ট তৈরি করুন। তারপরে, CustomAudience অবজেক্টের সাথে JoinCustomAudienceRequest অবজেক্টটি আরম্ভ করুন।
  3. JoinCustomAudienceRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টগুলির সাথে অ্যাসিঙ্ক্রোনাস joinCustomAudience() কল করুন।

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a custom audience.
val audience = CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build()

// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build();

// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver);

নিম্নলিখিত পরামিতিগুলির সংমিশ্রণটি কোনও ডিভাইসে প্রতিটি CustomAudience অবজেক্টকে অনন্যভাবে সনাক্ত করে:

  • owner : মালিক অ্যাপের প্যাকেজ নাম। এটি স্পষ্টভাবে কলার অ্যাপের প্যাকেজ নামটিতে সেট করা আছে।
  • buyer : ক্রেতা বিজ্ঞাপন নেটওয়ার্কের জন্য সনাক্তকারী যা এই কাস্টম দর্শকদের জন্য বিজ্ঞাপন পরিচালনা করে।
  • name : কাস্টম দর্শকদের জন্য একটি স্বেচ্ছাসেবী নাম বা সনাক্তকারী।

CustomAudience আলাদা উদাহরণ সহ বারবার joinCustomAudience() কল করা ম্যাচিং owner, buyer এবং name পরামিতিগুলির সাথে বিদ্যমান CustomAudience আপডেট করে। গোপনীয়তা সংরক্ষণে সহায়তা করার জন্য, এপিআইয়ের ফলাফল "সৃষ্টি" এবং "আপডেট" এর মধ্যে পার্থক্য করে না।

অতিরিক্তভাবে, এই প্রয়োজনীয় পরামিতিগুলির সাথে CustomAudience অবশ্যই তৈরি করতে হবে:

CustomAudience অবজেক্টের জন্য al চ্ছিক পরামিতিগুলির মধ্যে অন্তর্ভুক্ত থাকতে পারে:

  • অ্যাক্টিভেশন সময় : একটি কাস্টম শ্রোতা কেবল বিজ্ঞাপন নির্বাচন এবং এর সক্রিয়করণের পরে প্রতিদিনের আপডেটগুলিতে অংশ নিতে পারে। উদাহরণস্বরূপ, কোনও অ্যাপের ল্যাপড ব্যবহারকারীদের জড়িত করার জন্য এটি কার্যকর হতে পারে।
  • মেয়াদোত্তীর্ণ সময় : ভবিষ্যতের সময় যার পরে কাস্টম শ্রোতা ডিভাইস থেকে সরানো হয়।
  • ব্যবহারকারী বিডিং সংকেত : ব্যবহারকারীর পছন্দসই লোকাল হিসাবে ব্যবহারকারী সংকেতযুক্ত একটি জেএসএন স্ট্রিং, যে কোনও ক্রেতার বিডিং লজিক জাভাস্ক্রিপ্ট বিজ্ঞাপন নির্বাচন প্রক্রিয়া চলাকালীন বিড তৈরি করতে গ্রাস করে। এই ফর্ম্যাটটি বিজ্ঞাপন প্রযুক্তি প্ল্যাটফর্মগুলিকে প্ল্যাটফর্মগুলি জুড়ে কোড পুনরায় ব্যবহার করতে সহায়তা করে এবং জাভাস্ক্রিপ্ট ফাংশনগুলিতে খরচ সহজ করে তোলে।
  • বিশ্বস্ত বিডিং ডেটা : একটি এইচটিটিপিএস ইউআরএল এবং বিজ্ঞাপন নির্বাচন প্রক্রিয়া চলাকালীন ব্যবহৃত স্ট্রিংগুলির একটি তালিকা যা একটি বিশ্বস্ত কী/মান পরিষেবা থেকে বিড সংকেত আনতে পারে।
  • বিজ্ঞাপনগুলি : বিজ্ঞাপন নির্বাচনের ক্ষেত্রে অংশ নেওয়া বিজ্ঞাপনগুলির সাথে সম্পর্কিত AdData অবজেক্টগুলির একটি তালিকা। প্রতিটি AdData অবজেক্ট থাকে:
    • রেন্ডার ইউআরএল : একটি এইচটিটিপিএস ইউআরএল যা চূড়ান্ত বিজ্ঞাপনটি রেন্ডার করার জন্য অনুসন্ধান করা হয়।
    • মেটাডেটা : বিজ্ঞাপন নির্বাচন প্রক্রিয়া চলাকালীন ক্রেতা বিডিং লজিক দ্বারা গ্রাস করা তথ্যযুক্ত স্ট্রিং হিসাবে সিরিয়ালযুক্ত একটি জেএসএন অবজেক্ট।
    • বিজ্ঞাপন ফিল্টার : একটি শ্রেণি যাতে বিজ্ঞাপন নির্বাচনের সময় অ্যাপ ইনস্টল বিজ্ঞাপন ফিল্টারিং এবং ফ্রিকোয়েন্সি ক্যাপিংয়ের জন্য সমস্ত প্রয়োজনীয় তথ্য থাকে।

এখানে একটি CustomAudience অবজেক্ট ইনস্ট্যান্টেশনের উদাহরণ:

কোটলিন

// Minimal initialization of a CustomAudience object
val customAudience: CustomAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build()

জাভা

// Minimal initialization of a CustomAudience object
CustomAudience customAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build();

জোয়কস্টোমাডিয়েন্স () ফলাফলগুলি পরিচালনা করুন

অ্যাসিঙ্ক্রোনাস joinCustomAudience() পদ্ধতিটি এপিআই কলটির ফলাফলের সংকেত দিতে OutcomeReceiver অবজেক্টটি ব্যবহার করে।

  • onResult() কলব্যাক কাস্টম শ্রোতাদের সফলভাবে তৈরি বা আপডেট করা হয়েছে তা বোঝায়।
  • onError() কলব্যাক দুটি সম্ভাব্য শর্তকে বোঝায়।
    • যদি JoinCustomAudienceRequest অবৈধ যুক্তি দিয়ে শুরু করা হয় তবে AdServicesException একটি IllegalArgumentException কারণ হিসাবে নির্দেশ করে।
    • অন্যান্য সমস্ত ত্রুটি কারণ হিসাবে একটি IllegalStateException সহ একটি AdServicesException গ্রহণ করে।

joinCustomAudience() :

কোটলিন

var callback: OutcomeReceiver<Void, AdServicesException> =
    object : OutcomeReceiver<Void, AdServicesException> {
    override fun onResult(result: Void) {
        Log.i("CustomAudience", "Completed joinCustomAudience")
    }

    override fun onError(error: AdServicesException) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error)
    }
};

জাভা

OutcomeReceiver callback = new OutcomeReceiver<Void, AdServicesException>() {
    @Override
    public void onResult(@NonNull Void result) {
        Log.i("CustomAudience", "Completed joinCustomAudience");
    }

    @Override
    public void onError(@NonNull AdServicesException error) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error);
    }
};

একটি কাস্টম শ্রোতা ছেড়ে দিন

যদি ব্যবহারকারী আর প্রদত্ত কাস্টম দর্শকদের জন্য ব্যবসায়ের মানদণ্ডটি পূরণ না করে তবে কোনও অ্যাপ্লিকেশন বা এসডিকে ডিভাইস থেকে কাস্টম শ্রোতাদের অপসারণ করতে leaveCustomAudience() কল করতে পারে। এর অনন্য পরামিতিগুলির উপর ভিত্তি করে একটি CustomAudience অপসারণ করতে, নিম্নলিখিতগুলি করুন:

  1. CustomAudienceManager অবজেক্টটি আরম্ভ করুন।
  2. কাস্টম দর্শকদের buyer এবং name সাথে LeaveCustomAudienceRequest সূচনা করুন। এই ইনপুট ক্ষেত্রগুলি সম্পর্কে আরও জানতে, " একটি কাস্টম দর্শকদের সাথে যোগ দিন " পড়ুন।
  3. LeaveCustomAudienceRequest অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টগুলির সাথে অ্যাসিঙ্ক্রোনাস leaveCustomAudience() পদ্ধতিতে কল করুন।

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
    LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build()

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
    new LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build();

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver);

joinCustomAudience() কল করার অনুরূপ, OutcomeReceiver একটি এপিআই কলের সমাপ্তির ইঙ্গিত দেয়। গোপনীয়তা রক্ষায় সহায়তা করতে, একটি ত্রুটি ফলাফল অভ্যন্তরীণ ত্রুটি এবং অবৈধ যুক্তিগুলির মধ্যে পার্থক্য করে না। এপিআই কলটি শেষ হয়ে গেলে, ম্যাচিং কাস্টম শ্রোতাদের সফলভাবে অপসারণ করা হবে কিনা, তখন onResult() কলব্যাকটি ডাকা হয়।

বিজ্ঞাপন নির্বাচন চালান

বিজ্ঞাপনগুলি নির্বাচন করতে সুরক্ষিত শ্রোতাদের এপিআই ব্যবহার করতে, selectAds() পদ্ধতিটি কল করুন:

  1. একটি AdSelectionManager অবজেক্ট আরম্ভ করুন।
  2. একটি AdSelectionConfig অবজেক্ট তৈরি করুন।
  3. AdSelectionConfig অবজেক্ট এবং প্রাসঙ্গিক Executor এবং OutcomeReceiver অবজেক্টগুলির সাথে অ্যাসিঙ্ক্রোনাস selectAds() পদ্ধতিতে কল করুন।

কোটলিন

val adSelectionManager: AdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionConfig
val adSelectionConfig: AdSelectionConfig =
  AdSelectionConfig.Builder().setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(
        contextualAds.getBuyer(), contextualAds
      )
    ).build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
  adSelectionConfig, executor, outcomeReceiver
)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionConfig
AdSelectionConfig adSelectionConfig =
  new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(contextualAds.getBuyer(), contextualAds)
    )
    .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(adSelectionConfig, executor, outcomeReceiver);

selectAds() পদ্ধতিতে একটি AdSelectionConfig ইনপুট প্রয়োজন, যেখানে আপনাকে অবশ্যই নিম্নলিখিত প্রয়োজনীয় পরামিতিগুলি নির্দিষ্ট করতে হবে:

  • বিক্রেতা : বিজ্ঞাপন নির্বাচন শুরু করে বিক্রেতা বিজ্ঞাপন নেটওয়ার্কের জন্য সনাক্তকারী।
  • সিদ্ধান্ত লজিক ইউআরএল : বিক্রেতা বিজ্ঞাপন নেটওয়ার্কের জাভাস্ক্রিপ্ট লজিকটি পাওয়ার জন্য একটি এইচটিটিপিএস ইউআরএল অনুসন্ধান করেছে।
    • Https url : বিক্রেতা বিজ্ঞাপন নেটওয়ার্কের জাভাস্ক্রিপ্ট যুক্তি পেতে অনুসন্ধান করা। প্রয়োজনীয় ফাংশন স্বাক্ষর দেখুন।
    • প্রিপবিল্ট ইউআরআই : এটি ফ্লেজের বিজ্ঞাপন নির্বাচন ফর্ম্যাট অনুসরণ করে। যদি কোনও অসমর্থিত বা ত্রুটিযুক্ত প্রাক -বিল্ড ইউআরআই পাস হয় তবে IllegalArgumentException নিক্ষেপ করা হয়।
  • কাস্টম শ্রোতা ক্রেতারা : ক্রেতা বিজ্ঞাপন নেটওয়ার্কগুলির জন্য সনাক্তকারীদের একটি সম্পূর্ণ তালিকা যা বিক্রেতার দ্বারা বিজ্ঞাপন নির্বাচন প্রক্রিয়াতে অংশ নিতে অনুমতি দেওয়া হয়। এই ক্রেতা সনাক্তকারীরা অংশগ্রহণকারী কাস্টম শ্রোতাদের CustomAudience.getBuyer() এর সাথে মিলে যায়।

নিম্নলিখিত প্যারামিটারগুলি আরও কাস্টমাইজড বিজ্ঞাপন নির্বাচনের জন্য বিকল্পভাবে নির্দিষ্ট করা যেতে পারে:

  • বিজ্ঞাপন নির্বাচন সংকেত : একটি জেএসএন অবজেক্ট, একটি স্ট্রিং হিসাবে সিরিয়ালযুক্ত, ক্রেতা বিডিং লজিক জাভাস্ক্রিপ্ট CustomAudience.getBiddingLogicUrl() থেকে প্রাপ্ত ক্রেতা বিডিং লজিক জাভাস্ক্রিপ্ট দ্বারা গ্রাস করা সংকেতযুক্ত সংকেতযুক্ত।
  • বিক্রেতার সংকেত : একটি জেএসওএন অবজেক্ট, স্ট্রিং হিসাবে সিরিয়ালযুক্ত, বিক্রেতার AdSelectionConfig.getDecisionLogicUrl() থেকে প্রাপ্ত জাভাস্ক্রিপ্ট সিদ্ধান্তের যুক্তি দ্বারা গ্রহণ করা সংকেত রয়েছে।
  • প্রতি ক্রেতা সংকেত : জেএসএন অবজেক্টগুলির একটি মানচিত্র, স্ট্রিং হিসাবে সিরিয়ালযুক্ত, নির্দিষ্ট ক্রেতাদের বিডিং লজিক জাভাস্ক্রিপ্ট দ্বারা CustomAudience.getBiddingLogicUrl() থেকে প্রাপ্ত সংকেতযুক্ত সংকেতযুক্ত।
  • Contextual ads: A collection of ad candidates that are collected directly from buyers during an auction that happens outside of a Protected Audience auction.

Once an ad is selected, the results, bids, and signals are persisted internally for reporting. The OutcomeReceiver.onResult() callback returns an AdSelectionOutcome that contains:

  • A render URL for the winning ad, obtained from AdData.getRenderUrl() .
  • An ad selection ID unique to the device user. This ID is used for reporting the ad impression.

If the ad selection can't be completed successfully due to reasons such as invalid arguments, timeouts, or excessive resource consumption, the OutcomeReceiver.onError() callback provides an AdServicesException with the following behaviors:

  • If the ad selection is initiated with invalid arguments, the AdServicesException indicates an IllegalArgumentException as the cause.
  • All other errors receive an AdServicesException with an IllegalStateException as the cause.

প্রাসঙ্গিক বিজ্ঞাপন

Protected Audience can incorporate contextual ads into a Protected Auction. Contextual ads need to be selected on the ad tech server and returned to the device outside of Protected Audience APIs. Contextual ads can then be included in the auction using the AdSelectionConfig at which point they function the same as on device ads, including eligibility for negative ad filtering. Once the Protected Audience auction has completed, you need to invoke reportImpression() . This calls reportWin() in the winning contextual ad, in the same pattern as impression reporting , to receive the winning ad on a device. Each contextual ad needs a buyer, a bid, a link to reporting logic, a render URL, and ad metadata.

To deploy contextual ads in app, the target app needs to create a ContextualAds object:

কোটলিন

val contextualAds: ContextualAds =
  Builder().setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
    //Pass in your valid app install ads
    .setDecisionLogicUri(mContextualLogicUri)
    .setAdsWithBid(appInstallAd)
    .build()

জাভা

ContextualAds contextualAds = new ContextualAds.Builder()
  .setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
  .setDecisionLogicUri(mContextualLogicUri)
  //Pass in your valid app install ads
  .setAdsWithBid(appInstallAd)
  .build();

The resulting ContextualAds object can then be passed along when creating your AdSelectionConfig :

কোটলিন

// Create a new ad
val noFilterAd: AdData = Builder()
  .setMetadata(JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build()
val noFilterAdWithBid = AdWithBid(noFilterAd, NO_FILTER_BID)
contextualAds.getAdsWithBid().add(noFilterAdWithBid)

জাভা

// Create a new ad
AdData noFilterAd = new AdData.Builder()
  .setMetadata(new JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build();
AdWithBid noFilterAdWithBid = new AdWithBid(noFilterAd, NO_FILTER_BID);
contextualAds.getAdsWithBid().add(noFilterAdWithBid);

App install ad filtering

App install ads filtering helps you to filter installation ads for apps that are already installed on a device.

The first step in this process is to define which advertisers have the ability to filter on the installed package. This needs to happen in the app you want to target with an ad.

কোটলিন

//Create a request for setting the app install advertisers
val adtech = AdTechIdentifier.fromString("your.enrolled.uri")
val adtechSet = setOf(adtech)
val request = SetAppInstallAdvertisersRequest(adtechSet)

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  object : OutcomeReceiver<Any?, Exception?>() {
    fun onResult(@NonNull ignoredResult: Any?) {
      Log.v("[your tag]", "Updated app install advertisers")
    }

    fun onError(@NonNull error: Exception?) {
      Log.e("[your tag]", "Failed to update app install advertisers", error)
    }
  })

জাভা

//Create a request for setting the app install advertisers
AdTechIdentifier adtech = AdTechIdentifier.fromString("your.enrolled.uri");
Set<AdTechIdentifier> adtechSet = Collections.singleton(adtech);
SetAppInstallAdvertisersRequest request = new SetAppInstallAdvertisersRequest(adtechSet);

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  new OutcomeReceiver<Object, Exception>() {
    @Override
    public void onResult(@NonNull Object ignoredResult) {
      Log.v("[your tag]", "Updated app install advertisers");
    }

    @Override
    public void onError(@NonNull Exception error) {
      Log.e("[your tag]", "Failed to update app install advertisers", error);
    }
  });

When the preceding code executes, the advertisers passed in are then able to filter out the installed apps that you specify during their bid generation. If you need to remove an advertiser from having access to this app's install status, run this code again with the advertiser's information removed.

The next step is to set up ad filtering inside the publisher app. The party that serves the ad inside of the publisher app (most likely to be a supply-side SDK) must initialize their AdFilters object with information about which ads related to apps they'd like to filter out:

কোটলিন

// Instantiate AdFilters object with package names.
val filters: AdFilters = Builder().setAppInstallFilters(
    Builder().setPackageNames(setOf("example.target.app")).build()
  ).build()

জাভা

// Instantiate AdFilters object with package names.
AdFilters filters = new AdFilters.Builder()
.setAppInstallFilters(
  new AppInstallFilters.Builder()
  .setPackageNames(Collections.singleton("example.target.app"))
  .build())
.build();

Demand-side publishers may also set an AdFilter for ads that exist inside of their custom audiences.

AdFilters can also be passed in at the point of instantiating a new AdData object:

কোটলিন

// Instantiate an AdData object with the AdFilters created in the
// previous example.
val appInstallAd: AdData =
  Builder().setMetadata("{ ... }") // Valid JSON string
    .setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters).build()

জাভা

// Instantiate an AdData object with the AdFilters created in the
// previous example.
AdData appInstallAd = new AdData.Builder()
.setMetadata("{ ... }") // Valid JSON string
.setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters)
    .build();

Frequency cap filtering

Frequency cap filtering enables ad techs to limit the number of times an ad is shown. Frequency cap filtering reduces ad overexposure and optimizes alternate ad selection for a given ad campaign.

There are two main components of a frequency cap filter: the ad event type, and the ad counter key. The available ad event types that can be used are:

  • Win : A win event indicates that the ad has won an auction. Win events are automatically updated by the Protected Audience API and cannot be called directly by the developer. Win data is only visible to ads within a given custom audience.
  • Impression : Separate from reportImpression , an on-device caller (SSP or MMP) uses updateAdCounterHistogram() to invoke impression events at the point in code they choose. Impression events are visible to all ads belonging to a given DSP, and are not limited to ads in the same custom audience.
  • View : Event is invoked by the on-device caller (SSP or MMP) at a point in code they choose using a call to updateAdCounterHistogram() . View events are visible to all ads belonging to a given DSP and not limited to ads in the same Custom Audience.
  • Click : Event is invoked by the on-device caller (SSP or MMP) at a point in code they choose using a call to updateAdCounterHistogram() . Click events are visible to all ads belonging to a given DSP and not limited to ads in the same Custom Audience.

In the publisher app, an SSP or MMP that has a presence on the device invokes ad events. When updateAdCounterHistogram() is called, the counter of a frequency cap filter is incremented so that future auctions will have up to date information about a user's exposure to a given ad. The ad event types are not forcibly tied to the corresponding user action and are guidelines given to help callers to structure their event system. To increment ad counters at the time of an event, the on-device actor provides the winning ad auction's ad selection ID.

Ad counter keys are arbitrary 32-bit signed integers assigned by a buyer ad tech, and they correspond to a given set of ads as defined by the DSP. Since ad counter keys are limited only to ads that belong to a given DSP, these keys can be selected without overlapping with histograms from another ad tech. Ad counter keys are used to increment DSP-specific identifiers across a DSP's ads or within a given custom audience to filter out ads from future auctions.

Counter keys can be leveraged to prioritize ads that are more likely to be interesting to a given user based on their interactions with other ads from a given buyer ad tech. For example, an ad that has received a high level of engagement from winning ad auctions, views, and clicks, represents an inferred data point. To further illustrate this point: an ad for left handed golf clubs might indicate that the user wouldn't be interested in right handed ones. A frequency cap filter set for a counter key assigned to left-handed ads could filter out ads for right handed clubs.

To use frequency capping in your auction, you must first create KeyedFrequencyCap objects as shown below:

কোটলিন

// Value used when incrementing frequency counter
val adCounterKey = 123

// Frequency cap exceeded after 2 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 2, Duration.ofSeconds(10)
).build()

// Frequency cap exceeded after 1 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 1, Duration.ofSeconds(10)
).build()

জাভা

// Value used when incrementing frequency counter
int adCounterKey = 123;

// Frequency cap exceeded after 2 counts
KeyedFrequencyCap keyedFrequencyCapForImpression =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 2, Duration.ofSeconds(10)
  ).build();

// Frequency Cap exceeded after 1 counts
KeyedFrequencyCap keyedFrequencyCapForClick =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 1, Duration.ofSeconds(10)
  ).build();

Once the KeyedFrequencyCap objects are created, you can pass them into an AdFilters object.

কোটলিন

val filters: AdFilters = Builder()
  .setFrequencyCapFilters(
    Builder()
      .setKeyedFrequencyCapsForImpressionEvents(
        ImmutableObject.of(keyedFrequencyCapForImpression)
      )
      .setKeyedFrequencyCapsForClickEvents(
        ImmutableObject.of(keyedFrequencyCapForClick)
      )
  ).build()

জাভা

AdFilters filters = new AdFilters.Builder()
    .setFrequencyCapFilters(new FrequencyCapFilters.Builder()
        .setKeyedFrequencyCapsForImpressionEvents(
            ImmutableObject.of(keyedFrequencyCapForImpression)
        )
        .setKeyedFrequencyCapsForClickEvents(
            ImmutableObject.of(keyedFrequencyCapForClick)
        )
    ).build();

When the AdFilters object is populated with frequency cap filters, it can be passed along when the custom audience is created:

কোটলিন

// Initialize a custom audience.
val audience: CustomAudience = Builder()
  .setBuyer(buyer)
  .setName(name)
  .setAds(
    listOf(
      Builder()
        .setRenderUri(renderUri)
        .setMetadata(JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()
    )
  ).build()

জাভা

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setAds(Collections.singletonList(new AdData.Builder()
        .setRenderUri(renderUri)
        .setMetadata(new JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()))
    .build();

When frequency cap filters are implemented into a custom audience, the SSP can then invoke the necessary click, view, or impression events.

কোটলিন

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

val request: UpdateAdCounterHistogramRequest = Builder(
  adSelectionId,
  FrequencyCapFilters.AD_EVENT_TYPE_CLICK,  //CLICK, VIEW, or IMPRESSION
  callerAdTech
).build()

জাভা

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

UpdateAdCounterHistogramRequest request =
  new UpdateAdCounterHistogramRequest.Builder(
      adSelectionId,
      FrequencyCapFilters.AD_EVENT_TYPE_CLICK, //CLICK, VIEW, or IMPRESSION
      callerAdTech
).build();

Ads that have hit their pre-set frequency cap filter limits are filtered out of the auction. Filtering happens before the bidding logic is executed for on-device auctions, and as the payload is generating for Bidding & Auction services auctions.This toolkit gives ad techs the flexibility to use the interactions between users and the ads within their custom audiences to focus ad targeting while minimizing ad overexposure.

Contextual ad filtering without network calls

If there is no remarketing demand on the device, you can run ad selection for contextual ads without network calls. With prebuilt URIs and a list of contextual ads with bids, the platform can skip retrieving bidding logic, bidding signals, and scoring signals. The platform uses a prebuilt URI to select the contextual ad with the highest bid.

To improve latency, ad techs can run an ad selection flow that includes only contextual ads with ad filtering functionality without network calls. This is achieved by using prebuilt URIs for scoring signals. Refer to the Supported prebuilt URI use cases and names section for a list of scoreAds implementations.

To run ad selection without network calls:

  1. Set up ad filtering
  2. Create your contextual ads
  3. Create a AdSelectionConfig object with the following:

    1. An empty list of buyers
    2. A prebuilt URI to select the highest bid
    3. প্রাসঙ্গিক বিজ্ঞাপন
    4. An empty URI for the scoring signals. The empty URI is allowed to indicate that you don't want to use the fetching of trusted signals for scoring:
    Uri prebuiltURIScoringUri = Uri.parse("ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=your.registered.uri/reporting");
    // Initialize AdSelectionConfig
    AdSelectionConfig adSelectionConfig =
      new AdSelectionConfig.Builder()
        .setSeller(seller)
        .setDecisionLogicUri(prebuiltURIScoringUri)
        .setCustomAudienceBuyers(Collections.emptyList())
        .setAdSelectionSignals(adSelectionSignals)
        .setSellerSignals(sellerSignals)
        .setPerBuyerSignals(perBuyerSignals)
        .setBuyerContextualAds(buyerContextualAds)
        .setTrustedScoringSignalsUri(Uri.EMPTY)
        .build();
    
  4. Run ad selection:

    adSelectionManager.selectAds(
        adSelectionConfig,
        executor,
        outcomeReceiver);
    

Run your own reporting JavaScript while using prebuilt URIs

Today, the Privacy Sandbox platform only has a basic reporting JavaScript implementation available for prebuilt URIs. If you want to run your own reporting JavaScript while still using prebuilt URIs for a low latency ad selection, you can override the DecisionLogicUri between ad selection and reporting runs.

  1. Run steps to run ad selection for contextual ads using prebuilt URIs
  2. Create a copy of your AdSelectionConfig before running reporting

    adSelectionConfigWithYourReportingJS = adSelectionConfig.cloneToBuilder()
      // Replace <urlToFetchYourReportingJS> with your own URL:
      .setDecisionLogicUri(Uri.parse(<urlToFetchYourReportingJS>))
      .build();
    
  3. Run impression reporting

    // adSelectionId is from the result of the previous selectAds run
    ReportImpressionRequest request = new ReportImpressionRequest(
      adSelectionId,
      adSelectionConfigWithYourReportingJS);
    adSelectionManager.reportImpression(
      request,
      executor,
      outcomeReceiver);
    

Run waterfall mediation

Waterfall mediation requires multiple third party SDKs (3P networks) to be orchestrated by a first party SDK mediation network. Waterfall mediation is done the same way regardless if the auction took place on device or ran on Bidding & Auction services (B&A).

3P networks

3P networks need to provide an adapter that allows the mediation network to invoke the necessary methods for running an auction:

  • Run ad selection
  • Report impressions

Here's an example of a mediation network adapter:

কোটলিন

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

    init {
        adSelectionManager = context.getSystemService(AdSelectionManager::class.java)
    }

    fun selectAds() {...}

    fun reportImpressions() {...}
}

জাভা

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

    public NetworkAdaptor() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void selectAds() {...}

    public void reportImpressions() {...}
}

Each SDK has their own ad selection service managers and clients, and their own selectAds and reportImpressions implementation. SDK providers can refer to the sections on how to run ad selection for on-device auctions or the B&A explainer for B&A auctions. Follow how to report ad impressions (following the single SSP impression reporting for reporting.

Mediation network

Similar to 3P networks, mediation networks need selectAds and reportImpression implementations. Refer to the sections on how to run ad selection and how to report ad impressions for more information.

Mediation networks are responsible for running the mediation chain and placing themselves in the mediation chain. The next section covers how to set up and execute this process.

Retrieve mediation chain and bid floors

The mediation network is responsible for retrieving the first party (1P) contextual ads, mediation chain, and third party networks' bid floors (3P). This can happen in a request to retrieve contextual ads executed by the mediation network. The mediation chain determines how to iterate through the 3P Networks, and the bid floors can be passed to the auction process as adSelectionSignals .

Network placement in the mediation chain

A mediation SDK can place itself in the mediation chain based on their live eCPM of 1P ad bids. In the Protected Audience API, ad bids are opaque. A mediation SDK should use AdSelectionFromOutcomesConfig to be able to compare a given 1P ad's bid to the bid floor of the next 3P network in the chain. If the 1P bid is higher than the bid floor then that means the mediation SDK is placed in front of that 3P network.

Run ad selection

To retrieve a 1P ad candidate, the mediation network can execute an on-device auction following the steps in the run ad selection section. This generates a 1P ad candidate, a bid, and an AdSelectionId that is used in the mediation process.

Create an AdSelectionFromOutcomesConfig

An AdSelectionFromOutcomesConfig allows the mediation network to pass a list of AdSelectionIds (results from previous auctions), ad selection signals, and a URI to fetch JavaScript that selects an ad from multiple candidates. The list of AdSelectionIds along with their bids and the signals are passed to the JavaScript which can return one of the AdSelectionIds if it beats the bid floor, or none if the mediation chain should continued.

Mediation Networks create an AdSelectionFromOutcomesConfig using the 1P AdSelectionId from the previous section, and the bid floor for the 3P Network being considered. A new AdSelectionFromOutcomesConfig should be created for each step in the mediation chain.

কোটলিন

fun  runSelectOutcome(
    adSelectionClient : AdSelectionClient,
    outcome1p : AdSelectionOutcome,
    network3p : NetworkAdapter) : ListenableFuture<AdSelectionOutcome?> {
    val config = AdSelectionFromOutcomesConfig.Builder()
        .setSeller(seller)
        .setAdSelectionIds(listOf(outcome1p))
        .setSelectionSignals({"bid_floor": bid_floor})
        .setSelectionLogicUri(selectionLogicUri)
        .build()
    return adSelectionClient.selectAds(config)
}

জাভা

public ListenableFuture<AdSelectionOutcome> runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) {
    AdSelectionFromOutcomesConfig config = new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .build();

    return adSelectionClient.selectAds(config){}
}

The selectAds() method override for waterfall mediation requires an AdSelectionFromOutcomesConfig input, where you must specify the following required parameters:

  • Seller : Identifier for the seller ad network initiating the ad selection.
  • AdSelectionIds : A singleton list of a previous selectAds() run for a 1P ad.
  • Ad selection signals : A JSON object, serialized as a string, containing signals to be used by buyer bidding logic. In this case, include the bid floor retrieved for the given 3P network.
  • Selection Logic URI : An HTTPS URL queried during ad selection to fetch the mediation network's JavaScript for selecting a winning ad. See the required function signatures in this JavaScript. The JavaScript should return the 3P ad if the bid is higher than the bid floor, or otherwise return null . This allows the mediation SDK to truncate the mediation chain when a winner is found.

With the AdSelectionOutcomesConfig created, call the selectAds() method of the 3P network that is first in the chain.

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
  AdSelectionFromOutcomesConfig.Builder()
    .setSeller(seller)
    .setAdSelectionIds(listof(outcome1p))
    .setSelectionSignals({"bid_floor": bid_floor})
    .setSelectionLogicUri(selectionLogicUri)
    .setAdSelectionIds(outcomeIds)
    .build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
        new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .setAdSelectionIds(outcomeIds)
            .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver);

Orchestrate waterfall mediation

The following is the order of operations for running through the mediation process.

  1. Run 1P ad selection.
  2. Iterate over the mediation chain. For each 3P network, do the following:
    1. Build AdSelectionFromOutcomeConfig including the 1P outcomeId and the 3P SDK's bid floor.
    2. Call selectAds() with the config from the previous step.
    3. If the result is not empty, return the ad.
    4. Call the current SDK network adapter's selectAds() method. If the result is not empty, return the ad.
  3. If no winner is found from the chain, return the 1P ad.

কোটলিন

fun runWaterfallMediation(mediationChain : List<NetworkAdapter>)
  : Pair<AdSelectionOutcome, NetworkAdapter> {
    val outcome1p = runAdSelection()

    var outcome : AdSelectionOutcome
    for(network3p in mediationChain) {
      outcome = runSelectOutcome(outcome1p, network3p)
      if (outcome1p.hasOutcome() && outcome.hasOutcome()) {
          return Pair(outcome, this)
      }

      outcome = network3p.runAdSelection()
      if(outcome.hasOutcome()) {
          return Pair(outcome, network3p)
      }
    }
  return Pair(outcome1p, this)
}

জাভা

class MediationNetwork {
    AdSelectionManager adSelectionManager;

    public MediationNetwork() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void runAdSelection() {...}

    public void reportImpressions() {...}

    public Pair<AdSelectionOutcome, NetworkAdapter> runWaterfallMediation(
            List<NetworkAdapter> mediationChain) {
        AdSelectionOutcome outcome1p = runAdSelection();

        AdSelectionOutcome outcome;
        for(NetworkAdapter network3p: mediationChain) {
            if (outcome1p.hasOutcome() &&
              (outcome = runSelectOutcome(outcome1p, network3p)).hasOutcome()) {
                return new Pair<>(outcome, this);
            }

            if((outcome = network3p.runAdSelection()).hasOutcome()) {
                return new Pair<>(outcome, network3p);
            }
        }
        return new Pair<>(outcome1p, this);
    }

    /* Runs comparison by creating an AdSelectionFromOutcomesConfig */
    public AdSelectionOutcome runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) { ... }
}

Report ad impressions

There are two flows for reporting an ad impression depending on how the auction is run. If you are a single SSP running an auction, follow this section. If you are going to implement waterfall mediation, follow the steps found in the waterfall mediation impression reporting section .

Single SSP impression reporting

After a winning ad has been chosen from the ad selection workflow, you can report the impression back to participating buy-side and sell-side platforms with the AdSelectionManager.reportImpression() method. To report an ad impression:

  1. Initialize an AdSelectionManager object.
  2. Build a ReportImpressionRequest object with the ad selection ID.
  3. Call the asynchronous reportImpression() method with the ReportImpressionRequest object and relevant Executor and OutcomeReceiver objects.

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportImpressionRequest
ReportImpressionRequest reportImpressionRequest =
        new ReportImpressionRequest.Builder()
                .setAdSelectionId(adSelectionId)
                .setAdSelectionConfig(adSelectionConfig)
                .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver);

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize a ReportImpressionRequest
val adSelectionConfig: ReportImpressionRequest =
    ReportImpressionRequest.Builder()
        .setAdSelectionId(adSelectionId)
        .setAdSelectionConfig(adSelectionConfig)
        .build()

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver)

Initialize the ReportImpressionRequest with the following required parameters:

  • Ad selection ID : An ID unique only to a device user that identifies a successful ad selection.
  • Ad selection config : The same configuration used in the selectAds() call identified by the provided ad selection ID.

The asynchronous reportImpression() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback indicates if impression reporting URLs have been created and the request has been scheduled.
  • The onError() callback indicates the following possible conditions:
    • If the call is initialized with an invalid input argument, the AdServicesException indicates an IllegalArgumentException as the cause.
    • All other errors receive an AdServicesException with an IllegalStateException as the cause.

Waterfall mediation impression reporting

A mediation SDK needs to keep track of the winning SDK to trigger their reporting flows. The SDKs participating in a mediation chain should provide a method for the mediator to invoke to trigger their own reporting flow. An SDK participating in a mediated auction can follow the steps above to implement their own reporting.

SSPs can use this 3P SDK code example as a prototype for how to join in mediation flows:

Pair<AdSelectionOutcome, NetworkAdapter> winnerOutcomeAndNetwork =
         mediationSdk.orchestrateMediation(mediationChain);

if (winner.first.hasOutcome()) {
      winner.second.reportImpressions(winner.first.getAdSelectionId());

Impression reporting endpoints

The report impression API issues HTTPS GET requests to endpoints provided by the sell-side platform and the winning buy-side platform:

Buy-side platform endpoint:

  • The API uses the Bidding logic URL specified in the custom audience to fetch the buyer-provided JavaScript that includes logic to return an impression reporting URL.
  • Invoke the reportWin() JavaScript function, which is expected to return the buyer's impression reporting URL.

Sell-side platform endpoint:

  • Use the Decision logic URL specified in the AdSelectionConfig object to fetch the seller's decision logic JavaScript.
  • Invoke the reportResult() JavaScript function, which is expected to return the seller's impression reporting URL.

Bidding & Auction services reporting

An auction executed on Bidding & Auction services will have all the necessary reporting information, including generated URLs for ad interaction reporting , included in the encrypted response from the server-side auction. When the response is decrypted, the appropriate URLs are registered with the platform, so ad and impression reporting follows the same steps listed above.

Best effort Impression reporting

The reportImpression() method is designed to offer a best-effort completion of reporting.

Report Ad Interactions

Protected Audience provides support to report on more granular interactions for a rendered ad. This can include interactions such as view time, clicks, hovers, or any other useful metric that can be collected. The process to receive these reports requires two steps. First, buyers and sellers must register to receive these reports in their reporting JavaScript. Then, the client will need to report these events.

Registering to receive interaction events

Registering for interaction events happens in the buyer's reportWin() and seller's reportResult() JavaScript functions using a JavaScript function provided by the platform: registerAdBeacon . To register to receive an event report, simply call the platform JavaScript Function from your reporting JavaScript. The following snippet is using a buyer's reportWin() , but the same approach applies to reportResult() .

reportWin(
  adSelectionSignals,
  perBuyerSignals,
  signalsForBuyer,
  contextualSignals,
  customAudienceSignals) {
    ...
    // Calculate reportingUri, clickUri, viewUri, and hoverUri

    registerAdBeacon({"click": clickUri, "view": viewUri, "hover": hoverUri});

    return reportingUri;
}

Reporting interaction events

After reporting an impression, clients can report the interactions back to previously registered winning buy-side and sell-side platforms with the AdSelectionManager.reportInteraction() method. To report an ad event:

  1. Initialize an AdSelectionManager object.
  2. Build a ReportInteractionRequest object with the ad selection ID, interaction key, interaction data, and reporting destination.
  3. Call the asynchronous reportInteraction() method with the request object and relevant Executor and OutcomeReceiver objects.
AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportInteractionRequest
ReportInteractionRequest request =
  new ReportInteractionRequest.Builder()
    .setAdSelectionId(adSelectionId)
    .setInteractionKey("view")
    .setInteractionData("{ viewTimeInSeconds : 1 }") // Can be any string
    .setReportingDestinations(
      FLAG_REPORTING_DESTINATION_BUYER | FLAG_REPORTING_DESTINATION_SELLER
    )
    .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportInteraction(
  reportImpressionRequest,
  executor,
  outcomeReceiver);

Initialize the ReportInteractionRequest with the following required parameters:

  • Ad selection ID : An ad selection ID retrieved from a previously returned AdSelectionOutcome .
  • Interaction Key : A string key defined by the client describing the action being reported. This must match the key that was registered by the seller or buyer in the reporting JavaScript functions.
  • Interaction Data : A string containing data to be included with the event report, to be POSTed back to the reporting servers.
  • Reporting Destinations : A bit mask specifying if the events should be reported to the buyer, seller, or both. These flags are provided by the platform and the final destination mask can be created using bitwise operations. To report to one destination, you can use the flag provided by the platform directly. To report to multiple destinations, you can use the bitwise OR ( | ) to combine flag values.

The asynchronous reportInteraction() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback indicates the report interaction call is valid.
  • The onError() callback indicates the following possible conditions:
    • If the call is made when the app is running in the background, an IllegalStateException with a description of the failure is returned.
    • If the client is throttled from calling reportInteraction() , a LimitExceededException is returned.
    • If the package is not enrolled to call the Privacy Preserving APIs, a SecurityException() is returned.
    • If the app reporting interactions is different from the app that called selectAds() , an IllegalStateException is returned.
  • If the user has not consented to enable the Privacy Sandbox APIs, the call will fail silently.

Interaction reporting endpoints

The report interaction API issues HTTPS POST requests to endpoints provided by the sell-side platform and the winning buy-side platform. Protected Audience will match the interaction keys with the URIs declared in reporting JavaScript and issue a POST request to each endpoint for each interaction being reported. The content type of the request is plain text with the body being the Interaction Data.

Best effort Interaction reporting

The reportInteraction() is designed to offer a best-effort completion of reporting through HTTP POST.

Daily background update

When creating a custom audience, your app or SDK can initialize custom audience metadata. Additionally, the platform can update the following pieces of custom audience metadata with a daily background update process.

  • User bidding signals
  • Trusted bidding data
  • AdData list

This process queries against the Daily update URL defined in the custom audience and the URL may return a JSON response.

  • The JSON response may contain any of the supported metadata fields that needs to be updated.
  • Each JSON field is validated independently. The client ignores any malformed fields which results in no updates to that particular field in the response.
  • An empty HTTP response or an empty JSON object " {} " results in no metadata updates.
  • The response message size must be limited to 10 KB.
  • All URIs are required to use HTTPS.
  • trusted_bidding_uri must share the same ETLD+1 as the buyer.

Example: JSON response for background daily update

{
    "user_bidding_signals" : { ... },  // Valid JSON object
    "trusted_bidding_data" : {
        "trusted_bidding_uri" : 'example-dsp1-key-value-service.com',
        "trusted_bidding_keys" : [ 'campaign123', 'campaign456', ... ]
    },
    'ads' : [
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign123.html',
            'metadata' : { ... }  // Valid JSON object
        },
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign456.html',
            'metadata' : { ... }  // Valid JSON object
        },
        ...
    ]
}

JavaScript for ad selection

The ad selection workflow orchestrates the execution of buyer-provided and seller-provided JavaScript.

Buyer-provided JavaScript is fetched from the Bidding logic URL specified in the custom audience. The returned JavaScript should include the following functions:

Seller-provided JavaScript is fetched from the decision logic URL specified in the AdSelectionConfig parameter for the ad selection API. The returned JavaScript should include the following functions:

generateBid()

function generateBid(
  ad,
  auction_signals,
  per_buyer_signals,
  trusted_bidding_signals,
  contextual_signals,
  user_signals,
  custom_audience_bidding_signals) {
  return {'status': 0, 'ad': ad, 'bid': ad.metadata.result };
}

ইনপুট পরামিতি:

  • ad : a JSON object with the format var ad = { 'render_url': url, 'metadata': json_metadata };
  • auction_signals, per_buyer_signals : JSON objects specified in the auction configuration object
  • custom_audience_bidding_signals : JSON object generated by the platform. The format for this JSON object is:

    var custom_audience_signals = {
      "owner":"ca_owner",
      "buyer":"ca_buyer",
      "name":"ca_name",
      "activation_time":"ca_activation_time_epoch_ms",
      "expiration_time":"ca_expiration_time_epoch_ms",
      "user_bidding_signals":"ca_user_bidding_signals"
    }
    

    কোথায়:

    • owner , buyer , and name are string taken from the properties with the same name of the Custom Audience participating to the ad selection
    • activation_time and expiration_time are the time of activation and expiration of the custom audience, expressed as seconds since the Unix epoch
    • ca_user_bidding_signals is a JSON string specified in the userBiddingSignals field of the CustomAudience at creation time
    • trusted_bidding_signals, contextual_signals , and user_signals are JSON objects. They are passed as empty objects and will be filled up in future releases. Their format is not enforced by the platform and is managed by the ad tech.

ফলাফল:

  • ad : is the ad the bid refers to. The script is allowed to return a copy of the ad it received with different metadata. The render_url property of the ad is expected to be unaltered.
  • bid : a float value representing the bid value for this ad
  • status : an integer value that can be:
    • 0 : for a successful execution
    • 1 : (or any non-zero value) in case any of the input signals is invalid. In case a non-zero value is returned by generate-bid the bidding process is invalidated for all the CA ads

scoreAd()

function scoreAd(
  ad,
  bid,
  ad_selection_config,
  seller_signals,
  trusted_scoring_signals,
  contextual_signal,
  user_signal,
  custom_audience_signal) {
    return {'status': 0, 'score': score };
}

ইনপুট পরামিতি:

  • ad : see the generateBid documentation
  • bid : the bid value for the ad
  • ad_selection_config : a JSON object representing the AdSelectionConfig parameter of the selectAds API. বিন্যাস হল:

    var ad_selection_config = {
      'seller': 'seller',
      'decision_logic_url': 'url_of_decision_logic',
      'custom_audience_buyers': ['buyer1', 'buyer2'],
      'auction_signals': auction_signals,
      'per_buyer_signals': per_buyer_signals,
      'contextual_ads': [ad1, ad2]
    }
    
  • seller_signals : JSON objects read from the sellerSignals AdSelectionConfig API parameter

  • trusted_scoring_signal : read from the adSelectionSignals field in the AdSelectionConfig API parameter

  • contextual_signals, user_signals : JSON objects. They are currently passed as empty objects and will be filled up in future releases. Their format is not enforced by the platform and is managed by the ad tech.

  • per_buyer_signals : JSON object read from the perBuyerSignal map in the AdSelectionConfig API parameter using as key the current Custom Audience buyer. Empty if the map doesn't contain any entry for the given buyer.

আউটপুট:

  • score : a float value representing the score value for this ad
  • status : an integer value that can be:
    • 0: for a successful execution
    • 1: in case the customAudienceSignals are invalid
    • 2: in case the AdSelectionConfig is invalid
    • 3: in case any of the other signals is invalid
    • Any non-zero value causes the failure of the process, the value determines the type of exception thrown

selectOutcome()

function selectOutcome(
  outcomes,
  selection_signals) {
    return {'status': 0, 'result': null};
}

ইনপুট পরামিতি:

  • outcomes : a JSON object {"id": id_string, "bid": bid_double}
  • selection_signals : JSON objects specified in the auction configuration object

আউটপুট:

  • status : 0 for success, non-zero for failure
  • result : one of the outcomes passed in or null

reportResult()

function reportResult(ad_selection_config, render_url, bid, contextual_signals) {
   return {
      'status': status,
      'results': {'signals_for_buyer': signals_for_buyer, 'reporting_url': reporting_url }
   };
}

ইনপুট পরামিতি:

  • ad_selection_config : see the documentation of scoreAds
  • render_url : the render URL of the winning ad
  • bid : the bid offered for the winning ad
  • contextual_signals : see the documentation of generateBid

আউটপুট:

  • status: 0 for success and non-zero for failure
  • results : a JSON objects containing:
    • signals_for_buyer : a JSON object that is passed to the reportWin function
    • reporting_url : a URL that is used by the platform to notify the impression to the buyer

reportWin()

function reportWin(
   ad_selection_signals,
   per_buyer_signals,
   signals_for_buyer,
   contextual_signals,
   custom_audience_signals) {
   return {'status': 0, 'results': {'reporting_url': reporting_url } };
}

ইনপুট পরামিতি:

  • ad_selection_signals, per_buyer_signals : see the documentation for scoreAd
  • signals_for_buyer : a JSON object returned by reportResult
  • contextual_signals, custom_audience_signals : see the documentation for generateBid

আউটপুট:

  • status: 0 for success and non-zero for failure
  • results : a JSON object containing:
    • reporting_url : a URL that is used by the platform to notify the impression to the seller

registerAdBeacon()

function registerAdBeacon(
  beacons
)

Input Parameters :

  • beacons : An object containing key-value pairs of interaction keys and reporting URIs. বিন্যাস হল:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key : A string representing the event. This is used by the platform later when reporting event interactions to look up the reporting_uri that should be notified. This key needs to match between what the buyer or seller is registering, and what the seller is reporting.
    • reporting_uri : A URI to receive event reports. This should be specific to the event type being reported. It must accept a POST request to handle any data reported along with the event.

    যেমন:

      let beacons = {
        'click': 'https://reporting.example.com/click_event',
        'view': 'https://reporting.example.com/view_event'
      }
    

Ad Selection prebuilt URIs

Prebuilt URIs give ad techs the ability to appoint JavaScript functions for ad selection decision logic in the AdSelectionConfig and AdSelectionFromOutcomesConfig classes. Prebuilt URIs don't require network calls to download the corresponding JavaScript. Ad techs can use prebuilt URIs without having to set up an enrolled domain to host the JavaScript.

A prebuilt URI is constructed using the following format:

ad-selection-prebuilt:<use-case>/<name>?<required-script-generation-parameters>

The Privacy Sandbox platform provides JavaScript using the information from this URI in the runtime.

An IllegalArgumentException is thrown if:

  • any of the required parameters are not present in the URI
  • there are unrecognized parameters in the URI

Supported prebuilt URI use cases and names

Use case 1: ad-selection

Prebuilt URIs under the ad-selection use case are supported in the selectAds(AdSelectionConfig) flow.

Prebuilt URI name: highest-bid-wins

This prebuilt URI provides a JavaScript that picks the ad with the highest bid after bidding. It also provides a basic reporting function to report the winner's render_uri and bid .

Required parameters

reportingUrl : The base reporting URL that is parameterized with the render_uri and the bid of the winning ad:

<reportingUrl>?render_uri=<renderUriOfWinnigAd>&bid=<bidOfWinningAd>

ব্যবহার

If your base reporting URL is https://www.ssp.com/reporting then the prebuilt URI would be:

`ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=https://www.ssp.com/reporting`

Use case 2: ad-selection-from-outcomes

Prebuilt URIs under the ad-selection-from-outcomes use case support the selectAds(AdSelectionFromOutcomesConfig) workflow.

Prebuilt URI name: waterfall-mediation-truncation

The waterfall-mediation-truncation prebuilt URI provides JavaScript that implements waterfall mediation truncation logic where the JavaScript returns a first-party ad if the bid is higher then or equal to the bid floor , and otherwise returns null .

Required parameters

bidFloor : The key of the bid floor value passed in the getSelectionSignals() that is compared against the mediation SDK's ad.

ব্যবহার

If your ad selection signals look like {"bid_floor": 10} then the resulting prebuilt URI would be:

`ad-selection-prebuilt://ad-selection-from-outcomes/waterfall-mediation-truncation/?bidFloor=bid_floor`

টেস্টিং

To help you get started with the Protected Audience API, we've created sample apps in Kotlin and Java, which can be found on GitHub .

পূর্বশর্ত

The Protected Audience API requires some JavaScript during ad selection and impression reporting. There are two methods of providing this JavaScript in a testing environment:

  • Run a server with the required HTTPS endpoints that returns the JavaScript
  • Override remote fetching by providing the necessary code from a local source

Either approach requires setting up an HTTPS endpoint to handle impression reporting.

HTTPS endpoints

To test ad selection and impression reporting, you need to set up 7 HTTPS endpoints that your test device or emulator can access:

  1. Buyer endpoint that serves the bidding logic JavaScript.
  2. An endpoint that serves the bidding signals.
  3. Seller endpoint that serves the decision logic JavaScript.
  4. An endpoint that serves scoring signals.
  5. Winning buyer impression reporting endpoint.
  6. Seller impression reporting endpoint.
  7. An endpoint to serve the daily updates for a custom audience.

For convenience, the GitHub repo provides basic JavaScript code for testing purposes. It also includes OpenAPI service definitions which can be deployed to a supported mock or microservices platform. For more details, see the project README .

Override remote fetching of JavaScript

This feature is intended to be used for end-to-end testing. To override remote fetching, your app must run in debug mode with developer options enabled.

To enable debug mode for your application, add the following line to the application attribute in your AndroidManifest.xml:

<application
  android:debuggable="true">

For an example of how to use these overrides, please see the the Protected Audience API sample app on GitHub.

You need to add your own custom JavaScript to handle ad selection routines such as bidding, scoring decisions, and reporting. You can find basic JavaScript code examples that handle all required requests in the GitHub repo . The Protected Audience API sample application demonstrates how to read code from that file and prepare it for use as an override.

It is possible to override sell-side and buy-side JavaScript fetching independently, though you need an HTTPS endpoint to serve any JavaScript you aren't providing overrides for. Please see the README for information about how to set up a server that handles these cases.

It is only possible to override JavaScript fetching for custom audiences that are owned by your package.

Override sell-side JavaScript

To set up an override of sell-side JavaScript, do the following as demonstrated in the following code example:

  1. Initialize an AdSelectionManager object.
  2. Get a reference to TestAdSelectionManager from the AdSelectionManager object.
  3. Build an AdSelectionConfig object.
  4. Build an AddAdSelectionOverrideRequest with the AdSelectionConfig object and a String representing the JavaScript you intend to use as an override.
  5. Call the asynchronous overrideAdSelectionConfigRemoteInfo() method with the AddAdSelectionOverrideRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val testAdSelectionManager: TestAdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java).getTestAdSelectionManager()

// Initialize AdSelectionConfig =
val adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build()

// Initialize AddAddSelectionOverrideRequest
val request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build()

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestAdSelectionManager testAdSelectionManager =
  context.getSystemService(AdSelectionManager.class).getTestAdSelectionManager();

// Initialize AdSelectionConfig =
AdSelectionConfig adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build();

// Initialize AddAddSelectionOverrideRequest
AddAdSelectionOverrideRequest request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build();

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver);

See the Run ad selection section for more information about what each of the fields in the AdSelectionConfig represent. The key difference is that the decisionLogicUrl can be set to a placeholder value as it will be ignored.

In order to override the JavaScript used during ad selection, the decisionLogicJs must contain the proper seller-side function signatures . For an example of how to read a JavaScript file as a string, please see the Protected Audience API sample app on GitHub.

The asynchronous overrideAdSelectionConfigRemoteInfo() method uses the OutcomeReceiver object to signal the result of the API call.

The onResult() callback signifies the override was applied successfully. Future calls to selectAds() will use whatever decision and reporting logic you have passed in as the override.

The onError() callback signifies two possible conditions:

  • If the override is attempted with invalid arguments, the AdServiceException indicates an IllegalArgumentException as the cause.
  • If the override is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Reset sell-side overrides

This section assumes that you have overridden the sell-side JavaScript and that you have a reference to the TestAdSelectionManager and AdSelectionConfig used in the previous section.

In order to reset the overrides for all AdSelectionConfigs :

  1. Call the asynchronous resetAllAdSelectionConfigRemoteOverrides() method with the relevant OutcomeReceiver object.

কোটলিন

// Resets overrides for all AdSelectionConfigs
testAadSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
  outComeReceiver)

জাভা

// Resets overrides for all AdSelectionConfigs
testAdSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
    outComeReceiver);

After you reset sell-side overrides, calls to selectAds() use whatever decisionLogicUrl is stored in the AdSelectionConfig to attempt to fetch the required JavaScript.

If the call to resetAllAdSelectionConfigRemoteOverrides() fails, the OutComeReceiver.onError() callback provides an AdServiceException . If the removal of overrides is attempted with an app not running in debug mode with developer options enabled, AdServiceException indicates IllegalStateException as the cause.

Override buy-side JavaScript

  1. Follow the steps to join a custom audience
  2. Build an AddCustomAudienceOverrideRequest with the buyer and name of the custom audience you wish to override, in addition to the bidding logic and data you wish to use as an override
  3. Call the asynchronous overrideCustomAudienceRemoteInfo() method with the AddCustomAudienceOverrideRequest object and relevant Executor and OutcomeReceiver objects

কোটলিন

val testCustomAudienceManager: TestCustomAudienceManager =
  context.getSystemService(CustomAudienceManager::class.java).getTestCustomAudienceManager()

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
val request = AddCustomAudienceOverrideRequest.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setBiddingLogicJs(biddingLogicJS)
    .setTrustedBiddingSignals(trustedBiddingSignals)
    .build()

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestCustomAudienceManager testCustomAudienceManager =
  context.getSystemService(CustomAudienceManager.class).getTestCustomAudienceManager();

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
AddCustomAudienceOverrideRequest request =
    AddCustomAudienceOverrideRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .setBiddingLogicJs(biddingLogicJS)
        .setTrustedBiddingSignals(trustedBiddingSignals)
        .build();

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver);

The values for buyer and name are the same ones used to create the custom audience. Learn more about these fields .

Additionally, you can specify two additional parameters:

  • biddingLogicJs : JavaScript that holds the buyer's logic that is used during ad selection. See the required function signatures in this JavaScript.
  • trustedBiddingSignals : Bidding signals to be used during ad selection. For testing purposes this can be an empty string.

The asynchronous overrideCustomAudienceRemoteInfo() method uses the OutcomeReceiver object to signal the result of the API call.

The onResult() callback signifies the override was applied successfully. Subsequent calls to selectAds() use whatever bidding and reporting logic you have passed in as the override.

The onError() callback signifies two possible conditions.

  • If the override is attempted with invalid arguments, the AdServiceException indicates an IllegalArgumentException as the cause.
  • If the override is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Reset buy-side overrides

This section assumes that you have overridden the buy-side JavaScript and that you have a reference to the TestCustomAudienceManager used in the previous section.

To reset overrides for all custom audiences:

  1. Call the asynchronous resetAllCustomAudienceOverrides() method with relevant Executor and OutcomeReceiver objects.

কোটলিন

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

জাভা

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

After you reset buy-side overrides, subsequent calls to selectAds() use whatever biddingLogicUrl and trustedBiddingData is stored in the CustomAudience to attempt to fetch the required JavaScript.

If the call to resetCustomAudienceRemoteInfoOverride() fails, the OutComeReceiver.onError() callback provides an AdServiceException . If the removal of overrides is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Set Up a Reporting Server

When you use remote fetching overrides, you'll still need to set up a server that your device or emulator can reach to respond to reporting events. A simple endpoint that returns 200 is sufficient for testing. The GitHub repo includes OpenAPI service definitions which can be deployed to a supported mock or microservices platform. For more details, see the project README .

When looking for the OpenAPI definitions, look for the reporting-server.json. This file contains a simple endpoint that returns 200, representing an HTTP response code. This endpoint is used during selectAds() and signals to the Protected Audience API that impression reporting completed successfully.

Functionality to test

  • Exercise joining or leaving and setting up a custom audience based on prior user actions.
  • Exercise the initiation of on-device ad selection through JavaScripts hosted remotely.
  • Observe how an app's association with custom audience settings may affect ad selection outcomes.
  • Exercise impression reporting after ad selection.

সীমাবদ্ধতা

The following table lists limitations for the Protected Audience API processing. The limits presented could be subject to change based on feedback. For in-progress capabilities, read the release notes .

কম্পোনেন্ট সীমা বর্ণনা সীমিত মান
Custom audience (CA) Maximum number of ads per CA 100
Maximum number of CAs per application 1000
Maximum number of apps that can create a CA 1000
Maximum delay in the activation time of a CA from its creation time 60 দিন
Maximum expiration time of a CA from its activation time 60 দিন
Maximum number of CAs on device 4000
Maximum size of CA name 200 bytes
Maximum size of daily fetch URI 400 বাইট
Maximum size of bidding logic URI 400 বাইট
Maximum size of trusted bidding data 10 KB
Maximum size of user bidding signals 10 KB
Maximum call rate for leaveCustomAudience per buyer প্রতি সেকেন্ডে 1
Maximum call rate for joinCustomAudience per buyer প্রতি সেকেন্ডে 1
CA Background Fetch টাইমআউট সংযোগ করুন 5 সেকেন্ড
HTTP read timeout 30 সেকেন্ড
Maximum total download size 10 KB
Max duration of a fetch iteration 5 মিনিট
Maximum number of CAs updated per job 1000
বিজ্ঞাপন নির্বাচন Maximum number of buyers টিবিডি
Maximum number of CAs per buyer টিবিডি
Maximum number of ads in an auction টিবিডি
Initial connection timeout 5 সেকেন্ড
Connection read timeout 5 সেকেন্ড
Maximum execution time of overall AdSelection 10 সেকেন্ড
Maximum execution time of bidding per CA in AdSelection 5 second
Maximum execution time of scoring in AdSelection 5 second
Maximum execution time for per buyer in AdSelection টিবিডি
Maximum size of ad selection/seller/per buyer signals টিবিডি
Maximum size of seller/buyer scripts টিবিডি
Maximum call rate for selectAds 1 QPS
Impression reporting Minimum time before removing ad selection from persistence 24 ঘন্টা
Maximum number of storage ad selections টিবিডি
Maximum size of reporting output URL টিবিডি
Maximum time for impression reporting টিবিডি
Maximum number of retries for notification calls টিবিডি
সংযোগের সময়সীমা শেষ 5 সেকেন্ড
Maximum overall execution time for reportImpression 2 সেকেন্ড
Maximum call rate for reportImpressions 1 QPS
ইভেন্ট রিপোর্টিং Maximum number of beacons per buyer per auction 10

Maximum number of beacons per seller per auction

10

Maximum size of event key

40 বাইট

Maximum size of event data

64KB

বিজ্ঞাপন Maximum size of ad list 10 KB shared by all AdData in a single CA for contextual
ইউআরএল Maximum length of any URL string taken as input টিবিডি
জাভাস্ক্রিপ্ট Maximum execution time 1 second for bidding and scoring for impression reporting
Maximum memory used 10 MB

বাগ এবং সমস্যা রিপোর্ট করুন

Your feedback is a crucial part of the Privacy Sandbox on Android! Let us know of any issues you find or ideas for improving Privacy Sandbox on Android.

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %} ,

As you read through the Privacy Sandbox on Android documentation, use the Developer Preview or Beta button to select the program version that you're working with, as instructions may vary.


The Protected Audience API on Android (formerly known as FLEDGE) includes the Custom Audience API and the Ad Selection API. Ad tech platforms and advertisers can use these APIs to serve customized ads based on previous app engagement that limits the sharing of identifiers across apps and limits sharing a user's app interaction information with third-parties.

The Custom Audience API is centered around the "custom audience" abstraction, which represents a group of users with common intentions. An advertiser can register a user with a custom audience and associate relevant ads with it. This information is stored locally and can be used to inform advertiser bids, ad filtering, and ad rendering.

The Ad Selection API provides a framework that allows multiple developers to run an auction locally for a custom audience. To achieve this, the system considers relevant ads associated with the custom audience and performs additional processing on ads that an ad tech platform returns to the device.

Ad tech platforms can integrate these APIs to implement remarketing that preserves user privacy. Support for additional use cases, including app install ads, are planned for future releases. Learn more about the Protected Audience API on Android in the design proposal .

This guide describes how to work with the Protected Audience API on Android to do the following:

  1. Manage custom audiences
  2. Set up and run ad selection on a device
  3. Report ad impressions

আপনি শুরু করার আগে

Before you get started, complete the following:

  1. Set up your development environment for the Privacy Sandbox on Android.
  2. Either install a system image onto a supported device or set up an emulator that includes support for the Privacy Sandbox on Android.
  3. In a terminal, enable access to the Protected Audience API (disabled by default) with the following adb command.

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. In a terminal, enable beacon reporting with the following adb commands.

     adb shell device_config put adservices fledge_beacon_reporting_metrics_enabled true
     adb shell device_config put adservices fledge_register_ad_beacon_enabled true
    
  5. Include an ACCESS_ADSERVICES_CUSTOM_AUDIENCE permission in your app manifest:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  6. Reference an ad services configuration in the <application> element of your manifest:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  7. Specify the ad services XML resource referenced in your manifest, such as res/xml/ad_services_config.xml . Learn more about ad services permissions and SDK access control .

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  8. By default, the Ad Selection API enforces limits on the maximum amount of memory that an auction or impression reporting script can allocate. The memory limitation feature requires WebView version 105.0.5195.58 or higher. The platform enforces a version check and calls to the selectAds and reportImpression APIs fail if this isn't satisfied. There are two options to set this up:

    • Option 1: Run the following adb command to deactivate this check:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • Option 2: Install WebView Beta from the Google Play store. This must be equal to or higher than the version stated earlier.

Join a custom audience

A custom audience represents a group of users with common intentions or interests as decided by an advertiser app. An app or SDK may use a custom audience to indicate a particular audience, such as someone who has left items in a shopping cart. To create or join a custom audience asynchronously, do the following:

  1. Initialize the CustomAudienceManager object.
  2. Create a CustomAudience object by specifying key parameters such as the buyer's package and a relevant name. Then, initialize the JoinCustomAudienceRequest object with the CustomAudience object.
  3. Call the asynchronous joinCustomAudience() with the JoinCustomAudienceRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a custom audience.
val audience = CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build()

// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build();

// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver);

The combination of the following parameters uniquely identifies each CustomAudience object on a device:

  • owner : Package name of the owner app. This is implicitly set to the package name of the caller app.
  • buyer : Identifier for the buyer ad network which manages ads for this custom audience.
  • name : An arbitrary name or identifier for the custom audience.

Calling joinCustomAudience() repeatedly with a different instance of CustomAudience updates any existing CustomAudience with matching owner, buyer , and name parameters. To help preserve privacy, the result of the API does not distinguish between "creation" and "update."

Additionally, the CustomAudience must be created with these required parameters:

Optional parameters for a CustomAudience object may include:

  • Activation time : A custom audience can only participate in ad selection and daily updates after its activation time. This can be useful to engage lapsed users of an app, for example.
  • Expiration time : A future time after which the custom audience is removed from the device.
  • User bidding signals : A JSON string containing user signals, such as the user's preferred locale, that a buyer's bidding logic JavaScript consumes to generate bids during the ad selection process. This format helps ad tech platforms reuse code across platforms and eases the consumption in JavaScript functions.
  • Trusted bidding data : An HTTPS URL and a list of strings used during the ad selection process that fetch bidding signals from a trusted Key/Value service.
  • Ads : A list of AdData objects corresponding to the ads that participate in ad selection. Each AdData object consists of:
    • Render URL : An HTTPS URL that is queried to render the final ad.
    • Metadata : A JSON object serialized as a string containing information to be consumed by buyer bidding logic during the ad selection process.
    • Ad Filters : A class that contains all necessary information for app install ad filtering and frequency capping during ad selection.

Here's an example of a CustomAudience object instantiation:

কোটলিন

// Minimal initialization of a CustomAudience object
val customAudience: CustomAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build()

জাভা

// Minimal initialization of a CustomAudience object
CustomAudience customAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build();

Handle joinCustomAudience() outcomes

The asynchronous joinCustomAudience() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback signifies the custom audience is successfully created or updated.
  • The onError() callback signifies two possible conditions.

Here's an example of handling the outcome of joinCustomAudience() :

কোটলিন

var callback: OutcomeReceiver<Void, AdServicesException> =
    object : OutcomeReceiver<Void, AdServicesException> {
    override fun onResult(result: Void) {
        Log.i("CustomAudience", "Completed joinCustomAudience")
    }

    override fun onError(error: AdServicesException) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error)
    }
};

জাভা

OutcomeReceiver callback = new OutcomeReceiver<Void, AdServicesException>() {
    @Override
    public void onResult(@NonNull Void result) {
        Log.i("CustomAudience", "Completed joinCustomAudience");
    }

    @Override
    public void onError(@NonNull AdServicesException error) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error);
    }
};

Leave a custom audience

If the user no longer satisfies the business criteria for a given custom audience, an app or SDK can call leaveCustomAudience() to remove the custom audience from the device. To remove a CustomAudience based on its unique parameters, do the following:

  1. Initialize the CustomAudienceManager object.
  2. Initialize the LeaveCustomAudienceRequest with the custom audience's buyer and name . To learn more about these input fields, read " Join a custom audience ."
  3. Call the asynchronous leaveCustomAudience() method with the LeaveCustomAudienceRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
    LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build()

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
    new LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build();

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver);

Similar to calling joinCustomAudience() , the OutcomeReceiver signals the end of an API call. To help protect privacy, an error outcome doesn't distinguish between internal errors and invalid arguments. The onResult() callback is called when the API call has completed, whether or not a matching custom audience is removed successfully.

Run ad selection

To use the Protected Audience API to select ads, call the selectAds() method:

  1. Initialize an AdSelectionManager object.
  2. Build an AdSelectionConfig object.
  3. Call the asynchronous selectAds() method with the AdSelectionConfig object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val adSelectionManager: AdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionConfig
val adSelectionConfig: AdSelectionConfig =
  AdSelectionConfig.Builder().setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(
        contextualAds.getBuyer(), contextualAds
      )
    ).build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
  adSelectionConfig, executor, outcomeReceiver
)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionConfig
AdSelectionConfig adSelectionConfig =
  new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(contextualAds.getBuyer(), contextualAds)
    )
    .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(adSelectionConfig, executor, outcomeReceiver);

The selectAds() method requires an AdSelectionConfig input, where you must specify the following required parameters:

  • Seller : Identifier for the seller ad network initiating the ad selection.
  • Decision logic URL : An HTTPS URL queried to obtain the seller ad network's JavaScript logic.
    • HTTPS URL : queried to obtain the seller ad network's JavaScript logic. See the required function signatures .
    • Prebuilt URI : that follows FLEDGE's ad selection format. IllegalArgumentException is thrown, if an unsupported or malformed prebuilt uri is passed.
  • Custom audience buyers : A full list of identifiers for buyer ad networks that are allowed by the seller to participate in the ad selection process. These buyer identifiers correspond to CustomAudience.getBuyer() of participating custom audiences.

The following parameters can be optionally specified for more customized ad selection:

  • Ad selection signals : A JSON object, serialized as a string, containing signals to be consumed by buyer bidding logic JavaScript fetched from CustomAudience.getBiddingLogicUrl() .
  • Seller signals : A JSON object, serialized as a string, containing signals consumed by the seller's fetched JavaScript decision logic from AdSelectionConfig.getDecisionLogicUrl() .
  • Per buyer signals : A map of JSON objects, serialized as strings, containing signals to be consumed by specific buyers' bidding logic JavaScript fetched from CustomAudience.getBiddingLogicUrl() , which are identified by the buyer fields of participating custom audiences.
  • Contextual ads: A collection of ad candidates that are collected directly from buyers during an auction that happens outside of a Protected Audience auction.

Once an ad is selected, the results, bids, and signals are persisted internally for reporting. The OutcomeReceiver.onResult() callback returns an AdSelectionOutcome that contains:

  • A render URL for the winning ad, obtained from AdData.getRenderUrl() .
  • An ad selection ID unique to the device user. This ID is used for reporting the ad impression.

If the ad selection can't be completed successfully due to reasons such as invalid arguments, timeouts, or excessive resource consumption, the OutcomeReceiver.onError() callback provides an AdServicesException with the following behaviors:

  • If the ad selection is initiated with invalid arguments, the AdServicesException indicates an IllegalArgumentException as the cause.
  • All other errors receive an AdServicesException with an IllegalStateException as the cause.

প্রাসঙ্গিক বিজ্ঞাপন

Protected Audience can incorporate contextual ads into a Protected Auction. Contextual ads need to be selected on the ad tech server and returned to the device outside of Protected Audience APIs. Contextual ads can then be included in the auction using the AdSelectionConfig at which point they function the same as on device ads, including eligibility for negative ad filtering. Once the Protected Audience auction has completed, you need to invoke reportImpression() . This calls reportWin() in the winning contextual ad, in the same pattern as impression reporting , to receive the winning ad on a device. Each contextual ad needs a buyer, a bid, a link to reporting logic, a render URL, and ad metadata.

To deploy contextual ads in app, the target app needs to create a ContextualAds object:

কোটলিন

val contextualAds: ContextualAds =
  Builder().setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
    //Pass in your valid app install ads
    .setDecisionLogicUri(mContextualLogicUri)
    .setAdsWithBid(appInstallAd)
    .build()

জাভা

ContextualAds contextualAds = new ContextualAds.Builder()
  .setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
  .setDecisionLogicUri(mContextualLogicUri)
  //Pass in your valid app install ads
  .setAdsWithBid(appInstallAd)
  .build();

The resulting ContextualAds object can then be passed along when creating your AdSelectionConfig :

কোটলিন

// Create a new ad
val noFilterAd: AdData = Builder()
  .setMetadata(JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build()
val noFilterAdWithBid = AdWithBid(noFilterAd, NO_FILTER_BID)
contextualAds.getAdsWithBid().add(noFilterAdWithBid)

জাভা

// Create a new ad
AdData noFilterAd = new AdData.Builder()
  .setMetadata(new JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build();
AdWithBid noFilterAdWithBid = new AdWithBid(noFilterAd, NO_FILTER_BID);
contextualAds.getAdsWithBid().add(noFilterAdWithBid);

App install ad filtering

App install ads filtering helps you to filter installation ads for apps that are already installed on a device.

The first step in this process is to define which advertisers have the ability to filter on the installed package. This needs to happen in the app you want to target with an ad.

কোটলিন

//Create a request for setting the app install advertisers
val adtech = AdTechIdentifier.fromString("your.enrolled.uri")
val adtechSet = setOf(adtech)
val request = SetAppInstallAdvertisersRequest(adtechSet)

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  object : OutcomeReceiver<Any?, Exception?>() {
    fun onResult(@NonNull ignoredResult: Any?) {
      Log.v("[your tag]", "Updated app install advertisers")
    }

    fun onError(@NonNull error: Exception?) {
      Log.e("[your tag]", "Failed to update app install advertisers", error)
    }
  })

জাভা

//Create a request for setting the app install advertisers
AdTechIdentifier adtech = AdTechIdentifier.fromString("your.enrolled.uri");
Set<AdTechIdentifier> adtechSet = Collections.singleton(adtech);
SetAppInstallAdvertisersRequest request = new SetAppInstallAdvertisersRequest(adtechSet);

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  new OutcomeReceiver<Object, Exception>() {
    @Override
    public void onResult(@NonNull Object ignoredResult) {
      Log.v("[your tag]", "Updated app install advertisers");
    }

    @Override
    public void onError(@NonNull Exception error) {
      Log.e("[your tag]", "Failed to update app install advertisers", error);
    }
  });

When the preceding code executes, the advertisers passed in are then able to filter out the installed apps that you specify during their bid generation. If you need to remove an advertiser from having access to this app's install status, run this code again with the advertiser's information removed.

The next step is to set up ad filtering inside the publisher app. The party that serves the ad inside of the publisher app (most likely to be a supply-side SDK) must initialize their AdFilters object with information about which ads related to apps they'd like to filter out:

কোটলিন

// Instantiate AdFilters object with package names.
val filters: AdFilters = Builder().setAppInstallFilters(
    Builder().setPackageNames(setOf("example.target.app")).build()
  ).build()

জাভা

// Instantiate AdFilters object with package names.
AdFilters filters = new AdFilters.Builder()
.setAppInstallFilters(
  new AppInstallFilters.Builder()
  .setPackageNames(Collections.singleton("example.target.app"))
  .build())
.build();

Demand-side publishers may also set an AdFilter for ads that exist inside of their custom audiences.

AdFilters can also be passed in at the point of instantiating a new AdData object:

কোটলিন

// Instantiate an AdData object with the AdFilters created in the
// previous example.
val appInstallAd: AdData =
  Builder().setMetadata("{ ... }") // Valid JSON string
    .setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters).build()

জাভা

// Instantiate an AdData object with the AdFilters created in the
// previous example.
AdData appInstallAd = new AdData.Builder()
.setMetadata("{ ... }") // Valid JSON string
.setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters)
    .build();

Frequency cap filtering

Frequency cap filtering enables ad techs to limit the number of times an ad is shown. Frequency cap filtering reduces ad overexposure and optimizes alternate ad selection for a given ad campaign.

There are two main components of a frequency cap filter: the ad event type, and the ad counter key. The available ad event types that can be used are:

  • Win : A win event indicates that the ad has won an auction. Win events are automatically updated by the Protected Audience API and cannot be called directly by the developer. Win data is only visible to ads within a given custom audience.
  • Impression : Separate from reportImpression , an on-device caller (SSP or MMP) uses updateAdCounterHistogram() to invoke impression events at the point in code they choose. Impression events are visible to all ads belonging to a given DSP, and are not limited to ads in the same custom audience.
  • View : Event is invoked by the on-device caller (SSP or MMP) at a point in code they choose using a call to updateAdCounterHistogram() . View events are visible to all ads belonging to a given DSP and not limited to ads in the same Custom Audience.
  • Click : Event is invoked by the on-device caller (SSP or MMP) at a point in code they choose using a call to updateAdCounterHistogram() . Click events are visible to all ads belonging to a given DSP and not limited to ads in the same Custom Audience.

In the publisher app, an SSP or MMP that has a presence on the device invokes ad events. When updateAdCounterHistogram() is called, the counter of a frequency cap filter is incremented so that future auctions will have up to date information about a user's exposure to a given ad. The ad event types are not forcibly tied to the corresponding user action and are guidelines given to help callers to structure their event system. To increment ad counters at the time of an event, the on-device actor provides the winning ad auction's ad selection ID.

Ad counter keys are arbitrary 32-bit signed integers assigned by a buyer ad tech, and they correspond to a given set of ads as defined by the DSP. Since ad counter keys are limited only to ads that belong to a given DSP, these keys can be selected without overlapping with histograms from another ad tech. Ad counter keys are used to increment DSP-specific identifiers across a DSP's ads or within a given custom audience to filter out ads from future auctions.

Counter keys can be leveraged to prioritize ads that are more likely to be interesting to a given user based on their interactions with other ads from a given buyer ad tech. For example, an ad that has received a high level of engagement from winning ad auctions, views, and clicks, represents an inferred data point. To further illustrate this point: an ad for left handed golf clubs might indicate that the user wouldn't be interested in right handed ones. A frequency cap filter set for a counter key assigned to left-handed ads could filter out ads for right handed clubs.

To use frequency capping in your auction, you must first create KeyedFrequencyCap objects as shown below:

কোটলিন

// Value used when incrementing frequency counter
val adCounterKey = 123

// Frequency cap exceeded after 2 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 2, Duration.ofSeconds(10)
).build()

// Frequency cap exceeded after 1 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 1, Duration.ofSeconds(10)
).build()

জাভা

// Value used when incrementing frequency counter
int adCounterKey = 123;

// Frequency cap exceeded after 2 counts
KeyedFrequencyCap keyedFrequencyCapForImpression =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 2, Duration.ofSeconds(10)
  ).build();

// Frequency Cap exceeded after 1 counts
KeyedFrequencyCap keyedFrequencyCapForClick =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 1, Duration.ofSeconds(10)
  ).build();

Once the KeyedFrequencyCap objects are created, you can pass them into an AdFilters object.

কোটলিন

val filters: AdFilters = Builder()
  .setFrequencyCapFilters(
    Builder()
      .setKeyedFrequencyCapsForImpressionEvents(
        ImmutableObject.of(keyedFrequencyCapForImpression)
      )
      .setKeyedFrequencyCapsForClickEvents(
        ImmutableObject.of(keyedFrequencyCapForClick)
      )
  ).build()

জাভা

AdFilters filters = new AdFilters.Builder()
    .setFrequencyCapFilters(new FrequencyCapFilters.Builder()
        .setKeyedFrequencyCapsForImpressionEvents(
            ImmutableObject.of(keyedFrequencyCapForImpression)
        )
        .setKeyedFrequencyCapsForClickEvents(
            ImmutableObject.of(keyedFrequencyCapForClick)
        )
    ).build();

When the AdFilters object is populated with frequency cap filters, it can be passed along when the custom audience is created:

কোটলিন

// Initialize a custom audience.
val audience: CustomAudience = Builder()
  .setBuyer(buyer)
  .setName(name)
  .setAds(
    listOf(
      Builder()
        .setRenderUri(renderUri)
        .setMetadata(JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()
    )
  ).build()

জাভা

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setAds(Collections.singletonList(new AdData.Builder()
        .setRenderUri(renderUri)
        .setMetadata(new JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()))
    .build();

When frequency cap filters are implemented into a custom audience, the SSP can then invoke the necessary click, view, or impression events.

কোটলিন

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

val request: UpdateAdCounterHistogramRequest = Builder(
  adSelectionId,
  FrequencyCapFilters.AD_EVENT_TYPE_CLICK,  //CLICK, VIEW, or IMPRESSION
  callerAdTech
).build()

জাভা

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

UpdateAdCounterHistogramRequest request =
  new UpdateAdCounterHistogramRequest.Builder(
      adSelectionId,
      FrequencyCapFilters.AD_EVENT_TYPE_CLICK, //CLICK, VIEW, or IMPRESSION
      callerAdTech
).build();

Ads that have hit their pre-set frequency cap filter limits are filtered out of the auction. Filtering happens before the bidding logic is executed for on-device auctions, and as the payload is generating for Bidding & Auction services auctions.This toolkit gives ad techs the flexibility to use the interactions between users and the ads within their custom audiences to focus ad targeting while minimizing ad overexposure.

Contextual ad filtering without network calls

If there is no remarketing demand on the device, you can run ad selection for contextual ads without network calls. With prebuilt URIs and a list of contextual ads with bids, the platform can skip retrieving bidding logic, bidding signals, and scoring signals. The platform uses a prebuilt URI to select the contextual ad with the highest bid.

To improve latency, ad techs can run an ad selection flow that includes only contextual ads with ad filtering functionality without network calls. This is achieved by using prebuilt URIs for scoring signals. Refer to the Supported prebuilt URI use cases and names section for a list of scoreAds implementations.

To run ad selection without network calls:

  1. Set up ad filtering
  2. Create your contextual ads
  3. Create a AdSelectionConfig object with the following:

    1. An empty list of buyers
    2. A prebuilt URI to select the highest bid
    3. প্রাসঙ্গিক বিজ্ঞাপন
    4. An empty URI for the scoring signals. The empty URI is allowed to indicate that you don't want to use the fetching of trusted signals for scoring:
    Uri prebuiltURIScoringUri = Uri.parse("ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=your.registered.uri/reporting");
    // Initialize AdSelectionConfig
    AdSelectionConfig adSelectionConfig =
      new AdSelectionConfig.Builder()
        .setSeller(seller)
        .setDecisionLogicUri(prebuiltURIScoringUri)
        .setCustomAudienceBuyers(Collections.emptyList())
        .setAdSelectionSignals(adSelectionSignals)
        .setSellerSignals(sellerSignals)
        .setPerBuyerSignals(perBuyerSignals)
        .setBuyerContextualAds(buyerContextualAds)
        .setTrustedScoringSignalsUri(Uri.EMPTY)
        .build();
    
  4. Run ad selection:

    adSelectionManager.selectAds(
        adSelectionConfig,
        executor,
        outcomeReceiver);
    

Run your own reporting JavaScript while using prebuilt URIs

Today, the Privacy Sandbox platform only has a basic reporting JavaScript implementation available for prebuilt URIs. If you want to run your own reporting JavaScript while still using prebuilt URIs for a low latency ad selection, you can override the DecisionLogicUri between ad selection and reporting runs.

  1. Run steps to run ad selection for contextual ads using prebuilt URIs
  2. Create a copy of your AdSelectionConfig before running reporting

    adSelectionConfigWithYourReportingJS = adSelectionConfig.cloneToBuilder()
      // Replace <urlToFetchYourReportingJS> with your own URL:
      .setDecisionLogicUri(Uri.parse(<urlToFetchYourReportingJS>))
      .build();
    
  3. Run impression reporting

    // adSelectionId is from the result of the previous selectAds run
    ReportImpressionRequest request = new ReportImpressionRequest(
      adSelectionId,
      adSelectionConfigWithYourReportingJS);
    adSelectionManager.reportImpression(
      request,
      executor,
      outcomeReceiver);
    

Run waterfall mediation

Waterfall mediation requires multiple third party SDKs (3P networks) to be orchestrated by a first party SDK mediation network. Waterfall mediation is done the same way regardless if the auction took place on device or ran on Bidding & Auction services (B&A).

3P networks

3P networks need to provide an adapter that allows the mediation network to invoke the necessary methods for running an auction:

  • Run ad selection
  • Report impressions

Here's an example of a mediation network adapter:

কোটলিন

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

    init {
        adSelectionManager = context.getSystemService(AdSelectionManager::class.java)
    }

    fun selectAds() {...}

    fun reportImpressions() {...}
}

জাভা

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

    public NetworkAdaptor() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void selectAds() {...}

    public void reportImpressions() {...}
}

Each SDK has their own ad selection service managers and clients, and their own selectAds and reportImpressions implementation. SDK providers can refer to the sections on how to run ad selection for on-device auctions or the B&A explainer for B&A auctions. Follow how to report ad impressions (following the single SSP impression reporting for reporting.

Mediation network

Similar to 3P networks, mediation networks need selectAds and reportImpression implementations. Refer to the sections on how to run ad selection and how to report ad impressions for more information.

Mediation networks are responsible for running the mediation chain and placing themselves in the mediation chain. The next section covers how to set up and execute this process.

Retrieve mediation chain and bid floors

The mediation network is responsible for retrieving the first party (1P) contextual ads, mediation chain, and third party networks' bid floors (3P). This can happen in a request to retrieve contextual ads executed by the mediation network. The mediation chain determines how to iterate through the 3P Networks, and the bid floors can be passed to the auction process as adSelectionSignals .

Network placement in the mediation chain

A mediation SDK can place itself in the mediation chain based on their live eCPM of 1P ad bids. In the Protected Audience API, ad bids are opaque. A mediation SDK should use AdSelectionFromOutcomesConfig to be able to compare a given 1P ad's bid to the bid floor of the next 3P network in the chain. If the 1P bid is higher than the bid floor then that means the mediation SDK is placed in front of that 3P network.

Run ad selection

To retrieve a 1P ad candidate, the mediation network can execute an on-device auction following the steps in the run ad selection section. This generates a 1P ad candidate, a bid, and an AdSelectionId that is used in the mediation process.

Create an AdSelectionFromOutcomesConfig

An AdSelectionFromOutcomesConfig allows the mediation network to pass a list of AdSelectionIds (results from previous auctions), ad selection signals, and a URI to fetch JavaScript that selects an ad from multiple candidates. The list of AdSelectionIds along with their bids and the signals are passed to the JavaScript which can return one of the AdSelectionIds if it beats the bid floor, or none if the mediation chain should continued.

Mediation Networks create an AdSelectionFromOutcomesConfig using the 1P AdSelectionId from the previous section, and the bid floor for the 3P Network being considered. A new AdSelectionFromOutcomesConfig should be created for each step in the mediation chain.

কোটলিন

fun  runSelectOutcome(
    adSelectionClient : AdSelectionClient,
    outcome1p : AdSelectionOutcome,
    network3p : NetworkAdapter) : ListenableFuture<AdSelectionOutcome?> {
    val config = AdSelectionFromOutcomesConfig.Builder()
        .setSeller(seller)
        .setAdSelectionIds(listOf(outcome1p))
        .setSelectionSignals({"bid_floor": bid_floor})
        .setSelectionLogicUri(selectionLogicUri)
        .build()
    return adSelectionClient.selectAds(config)
}

জাভা

public ListenableFuture<AdSelectionOutcome> runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) {
    AdSelectionFromOutcomesConfig config = new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .build();

    return adSelectionClient.selectAds(config){}
}

The selectAds() method override for waterfall mediation requires an AdSelectionFromOutcomesConfig input, where you must specify the following required parameters:

  • Seller : Identifier for the seller ad network initiating the ad selection.
  • AdSelectionIds : A singleton list of a previous selectAds() run for a 1P ad.
  • Ad selection signals : A JSON object, serialized as a string, containing signals to be used by buyer bidding logic. In this case, include the bid floor retrieved for the given 3P network.
  • Selection Logic URI : An HTTPS URL queried during ad selection to fetch the mediation network's JavaScript for selecting a winning ad. See the required function signatures in this JavaScript. The JavaScript should return the 3P ad if the bid is higher than the bid floor, or otherwise return null . This allows the mediation SDK to truncate the mediation chain when a winner is found.

With the AdSelectionOutcomesConfig created, call the selectAds() method of the 3P network that is first in the chain.

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
  AdSelectionFromOutcomesConfig.Builder()
    .setSeller(seller)
    .setAdSelectionIds(listof(outcome1p))
    .setSelectionSignals({"bid_floor": bid_floor})
    .setSelectionLogicUri(selectionLogicUri)
    .setAdSelectionIds(outcomeIds)
    .build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
        new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .setAdSelectionIds(outcomeIds)
            .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver);

Orchestrate waterfall mediation

The following is the order of operations for running through the mediation process.

  1. Run 1P ad selection.
  2. Iterate over the mediation chain. For each 3P network, do the following:
    1. Build AdSelectionFromOutcomeConfig including the 1P outcomeId and the 3P SDK's bid floor.
    2. Call selectAds() with the config from the previous step.
    3. If the result is not empty, return the ad.
    4. Call the current SDK network adapter's selectAds() method. If the result is not empty, return the ad.
  3. If no winner is found from the chain, return the 1P ad.

কোটলিন

fun runWaterfallMediation(mediationChain : List<NetworkAdapter>)
  : Pair<AdSelectionOutcome, NetworkAdapter> {
    val outcome1p = runAdSelection()

    var outcome : AdSelectionOutcome
    for(network3p in mediationChain) {
      outcome = runSelectOutcome(outcome1p, network3p)
      if (outcome1p.hasOutcome() && outcome.hasOutcome()) {
          return Pair(outcome, this)
      }

      outcome = network3p.runAdSelection()
      if(outcome.hasOutcome()) {
          return Pair(outcome, network3p)
      }
    }
  return Pair(outcome1p, this)
}

জাভা

class MediationNetwork {
    AdSelectionManager adSelectionManager;

    public MediationNetwork() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void runAdSelection() {...}

    public void reportImpressions() {...}

    public Pair<AdSelectionOutcome, NetworkAdapter> runWaterfallMediation(
            List<NetworkAdapter> mediationChain) {
        AdSelectionOutcome outcome1p = runAdSelection();

        AdSelectionOutcome outcome;
        for(NetworkAdapter network3p: mediationChain) {
            if (outcome1p.hasOutcome() &&
              (outcome = runSelectOutcome(outcome1p, network3p)).hasOutcome()) {
                return new Pair<>(outcome, this);
            }

            if((outcome = network3p.runAdSelection()).hasOutcome()) {
                return new Pair<>(outcome, network3p);
            }
        }
        return new Pair<>(outcome1p, this);
    }

    /* Runs comparison by creating an AdSelectionFromOutcomesConfig */
    public AdSelectionOutcome runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) { ... }
}

Report ad impressions

There are two flows for reporting an ad impression depending on how the auction is run. If you are a single SSP running an auction, follow this section. If you are going to implement waterfall mediation, follow the steps found in the waterfall mediation impression reporting section .

Single SSP impression reporting

After a winning ad has been chosen from the ad selection workflow, you can report the impression back to participating buy-side and sell-side platforms with the AdSelectionManager.reportImpression() method. To report an ad impression:

  1. Initialize an AdSelectionManager object.
  2. Build a ReportImpressionRequest object with the ad selection ID.
  3. Call the asynchronous reportImpression() method with the ReportImpressionRequest object and relevant Executor and OutcomeReceiver objects.

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportImpressionRequest
ReportImpressionRequest reportImpressionRequest =
        new ReportImpressionRequest.Builder()
                .setAdSelectionId(adSelectionId)
                .setAdSelectionConfig(adSelectionConfig)
                .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver);

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize a ReportImpressionRequest
val adSelectionConfig: ReportImpressionRequest =
    ReportImpressionRequest.Builder()
        .setAdSelectionId(adSelectionId)
        .setAdSelectionConfig(adSelectionConfig)
        .build()

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver)

Initialize the ReportImpressionRequest with the following required parameters:

  • Ad selection ID : An ID unique only to a device user that identifies a successful ad selection.
  • Ad selection config : The same configuration used in the selectAds() call identified by the provided ad selection ID.

The asynchronous reportImpression() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback indicates if impression reporting URLs have been created and the request has been scheduled.
  • The onError() callback indicates the following possible conditions:
    • If the call is initialized with an invalid input argument, the AdServicesException indicates an IllegalArgumentException as the cause.
    • All other errors receive an AdServicesException with an IllegalStateException as the cause.

Waterfall mediation impression reporting

A mediation SDK needs to keep track of the winning SDK to trigger their reporting flows. The SDKs participating in a mediation chain should provide a method for the mediator to invoke to trigger their own reporting flow. An SDK participating in a mediated auction can follow the steps above to implement their own reporting.

SSPs can use this 3P SDK code example as a prototype for how to join in mediation flows:

Pair<AdSelectionOutcome, NetworkAdapter> winnerOutcomeAndNetwork =
         mediationSdk.orchestrateMediation(mediationChain);

if (winner.first.hasOutcome()) {
      winner.second.reportImpressions(winner.first.getAdSelectionId());

Impression reporting endpoints

The report impression API issues HTTPS GET requests to endpoints provided by the sell-side platform and the winning buy-side platform:

Buy-side platform endpoint:

  • The API uses the Bidding logic URL specified in the custom audience to fetch the buyer-provided JavaScript that includes logic to return an impression reporting URL.
  • Invoke the reportWin() JavaScript function, which is expected to return the buyer's impression reporting URL.

Sell-side platform endpoint:

  • Use the Decision logic URL specified in the AdSelectionConfig object to fetch the seller's decision logic JavaScript.
  • Invoke the reportResult() JavaScript function, which is expected to return the seller's impression reporting URL.

Bidding & Auction services reporting

An auction executed on Bidding & Auction services will have all the necessary reporting information, including generated URLs for ad interaction reporting , included in the encrypted response from the server-side auction. When the response is decrypted, the appropriate URLs are registered with the platform, so ad and impression reporting follows the same steps listed above.

Best effort Impression reporting

The reportImpression() method is designed to offer a best-effort completion of reporting.

Report Ad Interactions

Protected Audience provides support to report on more granular interactions for a rendered ad. This can include interactions such as view time, clicks, hovers, or any other useful metric that can be collected. The process to receive these reports requires two steps. First, buyers and sellers must register to receive these reports in their reporting JavaScript. Then, the client will need to report these events.

Registering to receive interaction events

Registering for interaction events happens in the buyer's reportWin() and seller's reportResult() JavaScript functions using a JavaScript function provided by the platform: registerAdBeacon . To register to receive an event report, simply call the platform JavaScript Function from your reporting JavaScript. The following snippet is using a buyer's reportWin() , but the same approach applies to reportResult() .

reportWin(
  adSelectionSignals,
  perBuyerSignals,
  signalsForBuyer,
  contextualSignals,
  customAudienceSignals) {
    ...
    // Calculate reportingUri, clickUri, viewUri, and hoverUri

    registerAdBeacon({"click": clickUri, "view": viewUri, "hover": hoverUri});

    return reportingUri;
}

Reporting interaction events

After reporting an impression, clients can report the interactions back to previously registered winning buy-side and sell-side platforms with the AdSelectionManager.reportInteraction() method. To report an ad event:

  1. Initialize an AdSelectionManager object.
  2. Build a ReportInteractionRequest object with the ad selection ID, interaction key, interaction data, and reporting destination.
  3. Call the asynchronous reportInteraction() method with the request object and relevant Executor and OutcomeReceiver objects.
AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportInteractionRequest
ReportInteractionRequest request =
  new ReportInteractionRequest.Builder()
    .setAdSelectionId(adSelectionId)
    .setInteractionKey("view")
    .setInteractionData("{ viewTimeInSeconds : 1 }") // Can be any string
    .setReportingDestinations(
      FLAG_REPORTING_DESTINATION_BUYER | FLAG_REPORTING_DESTINATION_SELLER
    )
    .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportInteraction(
  reportImpressionRequest,
  executor,
  outcomeReceiver);

Initialize the ReportInteractionRequest with the following required parameters:

  • Ad selection ID : An ad selection ID retrieved from a previously returned AdSelectionOutcome .
  • Interaction Key : A string key defined by the client describing the action being reported. This must match the key that was registered by the seller or buyer in the reporting JavaScript functions.
  • Interaction Data : A string containing data to be included with the event report, to be POSTed back to the reporting servers.
  • Reporting Destinations : A bit mask specifying if the events should be reported to the buyer, seller, or both. These flags are provided by the platform and the final destination mask can be created using bitwise operations. To report to one destination, you can use the flag provided by the platform directly. To report to multiple destinations, you can use the bitwise OR ( | ) to combine flag values.

The asynchronous reportInteraction() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback indicates the report interaction call is valid.
  • The onError() callback indicates the following possible conditions:
    • If the call is made when the app is running in the background, an IllegalStateException with a description of the failure is returned.
    • If the client is throttled from calling reportInteraction() , a LimitExceededException is returned.
    • If the package is not enrolled to call the Privacy Preserving APIs, a SecurityException() is returned.
    • If the app reporting interactions is different from the app that called selectAds() , an IllegalStateException is returned.
  • If the user has not consented to enable the Privacy Sandbox APIs, the call will fail silently.

Interaction reporting endpoints

The report interaction API issues HTTPS POST requests to endpoints provided by the sell-side platform and the winning buy-side platform. Protected Audience will match the interaction keys with the URIs declared in reporting JavaScript and issue a POST request to each endpoint for each interaction being reported. The content type of the request is plain text with the body being the Interaction Data.

Best effort Interaction reporting

The reportInteraction() is designed to offer a best-effort completion of reporting through HTTP POST.

Daily background update

When creating a custom audience, your app or SDK can initialize custom audience metadata. Additionally, the platform can update the following pieces of custom audience metadata with a daily background update process.

  • User bidding signals
  • Trusted bidding data
  • AdData list

This process queries against the Daily update URL defined in the custom audience and the URL may return a JSON response.

  • The JSON response may contain any of the supported metadata fields that needs to be updated.
  • Each JSON field is validated independently. The client ignores any malformed fields which results in no updates to that particular field in the response.
  • An empty HTTP response or an empty JSON object " {} " results in no metadata updates.
  • The response message size must be limited to 10 KB.
  • All URIs are required to use HTTPS.
  • trusted_bidding_uri must share the same ETLD+1 as the buyer.

Example: JSON response for background daily update

{
    "user_bidding_signals" : { ... },  // Valid JSON object
    "trusted_bidding_data" : {
        "trusted_bidding_uri" : 'example-dsp1-key-value-service.com',
        "trusted_bidding_keys" : [ 'campaign123', 'campaign456', ... ]
    },
    'ads' : [
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign123.html',
            'metadata' : { ... }  // Valid JSON object
        },
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign456.html',
            'metadata' : { ... }  // Valid JSON object
        },
        ...
    ]
}

JavaScript for ad selection

The ad selection workflow orchestrates the execution of buyer-provided and seller-provided JavaScript.

Buyer-provided JavaScript is fetched from the Bidding logic URL specified in the custom audience. The returned JavaScript should include the following functions:

Seller-provided JavaScript is fetched from the decision logic URL specified in the AdSelectionConfig parameter for the ad selection API. The returned JavaScript should include the following functions:

generateBid()

function generateBid(
  ad,
  auction_signals,
  per_buyer_signals,
  trusted_bidding_signals,
  contextual_signals,
  user_signals,
  custom_audience_bidding_signals) {
  return {'status': 0, 'ad': ad, 'bid': ad.metadata.result };
}

ইনপুট পরামিতি:

  • ad : a JSON object with the format var ad = { 'render_url': url, 'metadata': json_metadata };
  • auction_signals, per_buyer_signals : JSON objects specified in the auction configuration object
  • custom_audience_bidding_signals : JSON object generated by the platform. The format for this JSON object is:

    var custom_audience_signals = {
      "owner":"ca_owner",
      "buyer":"ca_buyer",
      "name":"ca_name",
      "activation_time":"ca_activation_time_epoch_ms",
      "expiration_time":"ca_expiration_time_epoch_ms",
      "user_bidding_signals":"ca_user_bidding_signals"
    }
    

    কোথায়:

    • owner , buyer , and name are string taken from the properties with the same name of the Custom Audience participating to the ad selection
    • activation_time and expiration_time are the time of activation and expiration of the custom audience, expressed as seconds since the Unix epoch
    • ca_user_bidding_signals is a JSON string specified in the userBiddingSignals field of the CustomAudience at creation time
    • trusted_bidding_signals, contextual_signals , and user_signals are JSON objects. They are passed as empty objects and will be filled up in future releases. Their format is not enforced by the platform and is managed by the ad tech.

ফলাফল:

  • ad : is the ad the bid refers to. The script is allowed to return a copy of the ad it received with different metadata. The render_url property of the ad is expected to be unaltered.
  • bid : a float value representing the bid value for this ad
  • status : an integer value that can be:
    • 0 : for a successful execution
    • 1 : (or any non-zero value) in case any of the input signals is invalid. In case a non-zero value is returned by generate-bid the bidding process is invalidated for all the CA ads

scoreAd()

function scoreAd(
  ad,
  bid,
  ad_selection_config,
  seller_signals,
  trusted_scoring_signals,
  contextual_signal,
  user_signal,
  custom_audience_signal) {
    return {'status': 0, 'score': score };
}

ইনপুট পরামিতি:

  • ad : see the generateBid documentation
  • bid : the bid value for the ad
  • ad_selection_config : a JSON object representing the AdSelectionConfig parameter of the selectAds API. বিন্যাস হল:

    var ad_selection_config = {
      'seller': 'seller',
      'decision_logic_url': 'url_of_decision_logic',
      'custom_audience_buyers': ['buyer1', 'buyer2'],
      'auction_signals': auction_signals,
      'per_buyer_signals': per_buyer_signals,
      'contextual_ads': [ad1, ad2]
    }
    
  • seller_signals : JSON objects read from the sellerSignals AdSelectionConfig API parameter

  • trusted_scoring_signal : read from the adSelectionSignals field in the AdSelectionConfig API parameter

  • contextual_signals, user_signals : JSON objects. They are currently passed as empty objects and will be filled up in future releases. Their format is not enforced by the platform and is managed by the ad tech.

  • per_buyer_signals : JSON object read from the perBuyerSignal map in the AdSelectionConfig API parameter using as key the current Custom Audience buyer. Empty if the map doesn't contain any entry for the given buyer.

আউটপুট:

  • score : a float value representing the score value for this ad
  • status : an integer value that can be:
    • 0: for a successful execution
    • 1: in case the customAudienceSignals are invalid
    • 2: in case the AdSelectionConfig is invalid
    • 3: in case any of the other signals is invalid
    • Any non-zero value causes the failure of the process, the value determines the type of exception thrown

selectOutcome()

function selectOutcome(
  outcomes,
  selection_signals) {
    return {'status': 0, 'result': null};
}

ইনপুট পরামিতি:

  • outcomes : a JSON object {"id": id_string, "bid": bid_double}
  • selection_signals : JSON objects specified in the auction configuration object

আউটপুট:

  • status : 0 for success, non-zero for failure
  • result : one of the outcomes passed in or null

reportResult()

function reportResult(ad_selection_config, render_url, bid, contextual_signals) {
   return {
      'status': status,
      'results': {'signals_for_buyer': signals_for_buyer, 'reporting_url': reporting_url }
   };
}

ইনপুট পরামিতি:

  • ad_selection_config : see the documentation of scoreAds
  • render_url : the render URL of the winning ad
  • bid : the bid offered for the winning ad
  • contextual_signals : see the documentation of generateBid

আউটপুট:

  • status: 0 for success and non-zero for failure
  • results : a JSON objects containing:
    • signals_for_buyer : a JSON object that is passed to the reportWin function
    • reporting_url : a URL that is used by the platform to notify the impression to the buyer

reportWin()

function reportWin(
   ad_selection_signals,
   per_buyer_signals,
   signals_for_buyer,
   contextual_signals,
   custom_audience_signals) {
   return {'status': 0, 'results': {'reporting_url': reporting_url } };
}

ইনপুট পরামিতি:

  • ad_selection_signals, per_buyer_signals : see the documentation for scoreAd
  • signals_for_buyer : a JSON object returned by reportResult
  • contextual_signals, custom_audience_signals : see the documentation for generateBid

আউটপুট:

  • status: 0 for success and non-zero for failure
  • results : a JSON object containing:
    • reporting_url : a URL that is used by the platform to notify the impression to the seller

registerAdBeacon()

function registerAdBeacon(
  beacons
)

Input Parameters :

  • beacons : An object containing key-value pairs of interaction keys and reporting URIs. বিন্যাস হল:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key : A string representing the event. This is used by the platform later when reporting event interactions to look up the reporting_uri that should be notified. This key needs to match between what the buyer or seller is registering, and what the seller is reporting.
    • reporting_uri : A URI to receive event reports. This should be specific to the event type being reported. It must accept a POST request to handle any data reported along with the event.

    যেমন:

      let beacons = {
        'click': 'https://reporting.example.com/click_event',
        'view': 'https://reporting.example.com/view_event'
      }
    

Ad Selection prebuilt URIs

Prebuilt URIs give ad techs the ability to appoint JavaScript functions for ad selection decision logic in the AdSelectionConfig and AdSelectionFromOutcomesConfig classes. Prebuilt URIs don't require network calls to download the corresponding JavaScript. Ad techs can use prebuilt URIs without having to set up an enrolled domain to host the JavaScript.

A prebuilt URI is constructed using the following format:

ad-selection-prebuilt:<use-case>/<name>?<required-script-generation-parameters>

The Privacy Sandbox platform provides JavaScript using the information from this URI in the runtime.

An IllegalArgumentException is thrown if:

  • any of the required parameters are not present in the URI
  • there are unrecognized parameters in the URI

Supported prebuilt URI use cases and names

Use case 1: ad-selection

Prebuilt URIs under the ad-selection use case are supported in the selectAds(AdSelectionConfig) flow.

Prebuilt URI name: highest-bid-wins

This prebuilt URI provides a JavaScript that picks the ad with the highest bid after bidding. It also provides a basic reporting function to report the winner's render_uri and bid .

Required parameters

reportingUrl : The base reporting URL that is parameterized with the render_uri and the bid of the winning ad:

<reportingUrl>?render_uri=<renderUriOfWinnigAd>&bid=<bidOfWinningAd>

ব্যবহার

If your base reporting URL is https://www.ssp.com/reporting then the prebuilt URI would be:

`ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=https://www.ssp.com/reporting`

Use case 2: ad-selection-from-outcomes

Prebuilt URIs under the ad-selection-from-outcomes use case support the selectAds(AdSelectionFromOutcomesConfig) workflow.

Prebuilt URI name: waterfall-mediation-truncation

The waterfall-mediation-truncation prebuilt URI provides JavaScript that implements waterfall mediation truncation logic where the JavaScript returns a first-party ad if the bid is higher then or equal to the bid floor , and otherwise returns null .

Required parameters

bidFloor : The key of the bid floor value passed in the getSelectionSignals() that is compared against the mediation SDK's ad.

ব্যবহার

If your ad selection signals look like {"bid_floor": 10} then the resulting prebuilt URI would be:

`ad-selection-prebuilt://ad-selection-from-outcomes/waterfall-mediation-truncation/?bidFloor=bid_floor`

টেস্টিং

To help you get started with the Protected Audience API, we've created sample apps in Kotlin and Java, which can be found on GitHub .

পূর্বশর্ত

The Protected Audience API requires some JavaScript during ad selection and impression reporting. There are two methods of providing this JavaScript in a testing environment:

  • Run a server with the required HTTPS endpoints that returns the JavaScript
  • Override remote fetching by providing the necessary code from a local source

Either approach requires setting up an HTTPS endpoint to handle impression reporting.

HTTPS endpoints

To test ad selection and impression reporting, you need to set up 7 HTTPS endpoints that your test device or emulator can access:

  1. Buyer endpoint that serves the bidding logic JavaScript.
  2. An endpoint that serves the bidding signals.
  3. Seller endpoint that serves the decision logic JavaScript.
  4. An endpoint that serves scoring signals.
  5. Winning buyer impression reporting endpoint.
  6. Seller impression reporting endpoint.
  7. An endpoint to serve the daily updates for a custom audience.

For convenience, the GitHub repo provides basic JavaScript code for testing purposes. It also includes OpenAPI service definitions which can be deployed to a supported mock or microservices platform. For more details, see the project README .

Override remote fetching of JavaScript

This feature is intended to be used for end-to-end testing. To override remote fetching, your app must run in debug mode with developer options enabled.

To enable debug mode for your application, add the following line to the application attribute in your AndroidManifest.xml:

<application
  android:debuggable="true">

For an example of how to use these overrides, please see the the Protected Audience API sample app on GitHub.

You need to add your own custom JavaScript to handle ad selection routines such as bidding, scoring decisions, and reporting. You can find basic JavaScript code examples that handle all required requests in the GitHub repo . The Protected Audience API sample application demonstrates how to read code from that file and prepare it for use as an override.

It is possible to override sell-side and buy-side JavaScript fetching independently, though you need an HTTPS endpoint to serve any JavaScript you aren't providing overrides for. Please see the README for information about how to set up a server that handles these cases.

It is only possible to override JavaScript fetching for custom audiences that are owned by your package.

Override sell-side JavaScript

To set up an override of sell-side JavaScript, do the following as demonstrated in the following code example:

  1. Initialize an AdSelectionManager object.
  2. Get a reference to TestAdSelectionManager from the AdSelectionManager object.
  3. Build an AdSelectionConfig object.
  4. Build an AddAdSelectionOverrideRequest with the AdSelectionConfig object and a String representing the JavaScript you intend to use as an override.
  5. Call the asynchronous overrideAdSelectionConfigRemoteInfo() method with the AddAdSelectionOverrideRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val testAdSelectionManager: TestAdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java).getTestAdSelectionManager()

// Initialize AdSelectionConfig =
val adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build()

// Initialize AddAddSelectionOverrideRequest
val request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build()

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestAdSelectionManager testAdSelectionManager =
  context.getSystemService(AdSelectionManager.class).getTestAdSelectionManager();

// Initialize AdSelectionConfig =
AdSelectionConfig adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build();

// Initialize AddAddSelectionOverrideRequest
AddAdSelectionOverrideRequest request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build();

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver);

See the Run ad selection section for more information about what each of the fields in the AdSelectionConfig represent. The key difference is that the decisionLogicUrl can be set to a placeholder value as it will be ignored.

In order to override the JavaScript used during ad selection, the decisionLogicJs must contain the proper seller-side function signatures . For an example of how to read a JavaScript file as a string, please see the Protected Audience API sample app on GitHub.

The asynchronous overrideAdSelectionConfigRemoteInfo() method uses the OutcomeReceiver object to signal the result of the API call.

The onResult() callback signifies the override was applied successfully. Future calls to selectAds() will use whatever decision and reporting logic you have passed in as the override.

The onError() callback signifies two possible conditions:

  • If the override is attempted with invalid arguments, the AdServiceException indicates an IllegalArgumentException as the cause.
  • If the override is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Reset sell-side overrides

This section assumes that you have overridden the sell-side JavaScript and that you have a reference to the TestAdSelectionManager and AdSelectionConfig used in the previous section.

In order to reset the overrides for all AdSelectionConfigs :

  1. Call the asynchronous resetAllAdSelectionConfigRemoteOverrides() method with the relevant OutcomeReceiver object.

কোটলিন

// Resets overrides for all AdSelectionConfigs
testAadSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
  outComeReceiver)

জাভা

// Resets overrides for all AdSelectionConfigs
testAdSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
    outComeReceiver);

After you reset sell-side overrides, calls to selectAds() use whatever decisionLogicUrl is stored in the AdSelectionConfig to attempt to fetch the required JavaScript.

If the call to resetAllAdSelectionConfigRemoteOverrides() fails, the OutComeReceiver.onError() callback provides an AdServiceException . If the removal of overrides is attempted with an app not running in debug mode with developer options enabled, AdServiceException indicates IllegalStateException as the cause.

Override buy-side JavaScript

  1. Follow the steps to join a custom audience
  2. Build an AddCustomAudienceOverrideRequest with the buyer and name of the custom audience you wish to override, in addition to the bidding logic and data you wish to use as an override
  3. Call the asynchronous overrideCustomAudienceRemoteInfo() method with the AddCustomAudienceOverrideRequest object and relevant Executor and OutcomeReceiver objects

কোটলিন

val testCustomAudienceManager: TestCustomAudienceManager =
  context.getSystemService(CustomAudienceManager::class.java).getTestCustomAudienceManager()

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
val request = AddCustomAudienceOverrideRequest.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setBiddingLogicJs(biddingLogicJS)
    .setTrustedBiddingSignals(trustedBiddingSignals)
    .build()

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestCustomAudienceManager testCustomAudienceManager =
  context.getSystemService(CustomAudienceManager.class).getTestCustomAudienceManager();

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
AddCustomAudienceOverrideRequest request =
    AddCustomAudienceOverrideRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .setBiddingLogicJs(biddingLogicJS)
        .setTrustedBiddingSignals(trustedBiddingSignals)
        .build();

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver);

The values for buyer and name are the same ones used to create the custom audience. Learn more about these fields .

Additionally, you can specify two additional parameters:

  • biddingLogicJs : JavaScript that holds the buyer's logic that is used during ad selection. See the required function signatures in this JavaScript.
  • trustedBiddingSignals : Bidding signals to be used during ad selection. For testing purposes this can be an empty string.

The asynchronous overrideCustomAudienceRemoteInfo() method uses the OutcomeReceiver object to signal the result of the API call.

The onResult() callback signifies the override was applied successfully. Subsequent calls to selectAds() use whatever bidding and reporting logic you have passed in as the override.

The onError() callback signifies two possible conditions.

  • If the override is attempted with invalid arguments, the AdServiceException indicates an IllegalArgumentException as the cause.
  • If the override is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Reset buy-side overrides

This section assumes that you have overridden the buy-side JavaScript and that you have a reference to the TestCustomAudienceManager used in the previous section.

To reset overrides for all custom audiences:

  1. Call the asynchronous resetAllCustomAudienceOverrides() method with relevant Executor and OutcomeReceiver objects.

কোটলিন

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

জাভা

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

After you reset buy-side overrides, subsequent calls to selectAds() use whatever biddingLogicUrl and trustedBiddingData is stored in the CustomAudience to attempt to fetch the required JavaScript.

If the call to resetCustomAudienceRemoteInfoOverride() fails, the OutComeReceiver.onError() callback provides an AdServiceException . If the removal of overrides is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Set Up a Reporting Server

When you use remote fetching overrides, you'll still need to set up a server that your device or emulator can reach to respond to reporting events. A simple endpoint that returns 200 is sufficient for testing. The GitHub repo includes OpenAPI service definitions which can be deployed to a supported mock or microservices platform. For more details, see the project README .

When looking for the OpenAPI definitions, look for the reporting-server.json. This file contains a simple endpoint that returns 200, representing an HTTP response code. This endpoint is used during selectAds() and signals to the Protected Audience API that impression reporting completed successfully.

Functionality to test

  • Exercise joining or leaving and setting up a custom audience based on prior user actions.
  • Exercise the initiation of on-device ad selection through JavaScripts hosted remotely.
  • Observe how an app's association with custom audience settings may affect ad selection outcomes.
  • Exercise impression reporting after ad selection.

সীমাবদ্ধতা

The following table lists limitations for the Protected Audience API processing. The limits presented could be subject to change based on feedback. For in-progress capabilities, read the release notes .

কম্পোনেন্ট সীমা বর্ণনা সীমিত মান
Custom audience (CA) Maximum number of ads per CA 100
Maximum number of CAs per application 1000
Maximum number of apps that can create a CA 1000
Maximum delay in the activation time of a CA from its creation time 60 দিন
Maximum expiration time of a CA from its activation time 60 দিন
Maximum number of CAs on device 4000
Maximum size of CA name 200 bytes
Maximum size of daily fetch URI 400 বাইট
Maximum size of bidding logic URI 400 বাইট
Maximum size of trusted bidding data 10 KB
Maximum size of user bidding signals 10 KB
Maximum call rate for leaveCustomAudience per buyer প্রতি সেকেন্ডে 1
Maximum call rate for joinCustomAudience per buyer প্রতি সেকেন্ডে 1
CA Background Fetch টাইমআউট সংযোগ করুন 5 সেকেন্ড
HTTP read timeout 30 সেকেন্ড
Maximum total download size 10 KB
Max duration of a fetch iteration 5 মিনিট
Maximum number of CAs updated per job 1000
বিজ্ঞাপন নির্বাচন Maximum number of buyers টিবিডি
Maximum number of CAs per buyer টিবিডি
Maximum number of ads in an auction টিবিডি
Initial connection timeout 5 সেকেন্ড
Connection read timeout 5 সেকেন্ড
Maximum execution time of overall AdSelection 10 সেকেন্ড
Maximum execution time of bidding per CA in AdSelection 5 second
Maximum execution time of scoring in AdSelection 5 second
Maximum execution time for per buyer in AdSelection টিবিডি
Maximum size of ad selection/seller/per buyer signals টিবিডি
Maximum size of seller/buyer scripts টিবিডি
Maximum call rate for selectAds 1 QPS
Impression reporting Minimum time before removing ad selection from persistence 24 ঘন্টা
Maximum number of storage ad selections টিবিডি
Maximum size of reporting output URL টিবিডি
Maximum time for impression reporting টিবিডি
Maximum number of retries for notification calls টিবিডি
সংযোগের সময়সীমা শেষ 5 সেকেন্ড
Maximum overall execution time for reportImpression 2 সেকেন্ড
Maximum call rate for reportImpressions 1 QPS
ইভেন্ট রিপোর্টিং Maximum number of beacons per buyer per auction 10

Maximum number of beacons per seller per auction

10

Maximum size of event key

40 বাইট

Maximum size of event data

64KB

বিজ্ঞাপন Maximum size of ad list 10 KB shared by all AdData in a single CA for contextual
ইউআরএল Maximum length of any URL string taken as input টিবিডি
জাভাস্ক্রিপ্ট Maximum execution time 1 second for bidding and scoring for impression reporting
Maximum memory used 10 MB

বাগ এবং সমস্যা রিপোর্ট করুন

Your feedback is a crucial part of the Privacy Sandbox on Android! Let us know of any issues you find or ideas for improving Privacy Sandbox on Android.

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %} ,

As you read through the Privacy Sandbox on Android documentation, use the Developer Preview or Beta button to select the program version that you're working with, as instructions may vary.


The Protected Audience API on Android (formerly known as FLEDGE) includes the Custom Audience API and the Ad Selection API. Ad tech platforms and advertisers can use these APIs to serve customized ads based on previous app engagement that limits the sharing of identifiers across apps and limits sharing a user's app interaction information with third-parties.

The Custom Audience API is centered around the "custom audience" abstraction, which represents a group of users with common intentions. An advertiser can register a user with a custom audience and associate relevant ads with it. This information is stored locally and can be used to inform advertiser bids, ad filtering, and ad rendering.

The Ad Selection API provides a framework that allows multiple developers to run an auction locally for a custom audience. To achieve this, the system considers relevant ads associated with the custom audience and performs additional processing on ads that an ad tech platform returns to the device.

Ad tech platforms can integrate these APIs to implement remarketing that preserves user privacy. Support for additional use cases, including app install ads, are planned for future releases. Learn more about the Protected Audience API on Android in the design proposal .

This guide describes how to work with the Protected Audience API on Android to do the following:

  1. Manage custom audiences
  2. Set up and run ad selection on a device
  3. Report ad impressions

আপনি শুরু করার আগে

Before you get started, complete the following:

  1. Set up your development environment for the Privacy Sandbox on Android.
  2. Either install a system image onto a supported device or set up an emulator that includes support for the Privacy Sandbox on Android.
  3. In a terminal, enable access to the Protected Audience API (disabled by default) with the following adb command.

      adb shell device_config put adservices ppapi_app_allow_list \"*\"
    
  4. In a terminal, enable beacon reporting with the following adb commands.

     adb shell device_config put adservices fledge_beacon_reporting_metrics_enabled true
     adb shell device_config put adservices fledge_register_ad_beacon_enabled true
    
  5. Include an ACCESS_ADSERVICES_CUSTOM_AUDIENCE permission in your app manifest:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_CUSTOM_AUDIENCE" />
    
  6. Reference an ad services configuration in the <application> element of your manifest:

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
                android:resource="@xml/ad_services_config" />
    
  7. Specify the ad services XML resource referenced in your manifest, such as res/xml/ad_services_config.xml . Learn more about ad services permissions and SDK access control .

      <ad-services-config>
        <custom-audiences allowAllToAccess="true" />
      </ad-services-config>
    
  8. By default, the Ad Selection API enforces limits on the maximum amount of memory that an auction or impression reporting script can allocate. The memory limitation feature requires WebView version 105.0.5195.58 or higher. The platform enforces a version check and calls to the selectAds and reportImpression APIs fail if this isn't satisfied. There are two options to set this up:

    • Option 1: Run the following adb command to deactivate this check:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • Option 2: Install WebView Beta from the Google Play store. This must be equal to or higher than the version stated earlier.

Join a custom audience

A custom audience represents a group of users with common intentions or interests as decided by an advertiser app. An app or SDK may use a custom audience to indicate a particular audience, such as someone who has left items in a shopping cart. To create or join a custom audience asynchronously, do the following:

  1. Initialize the CustomAudienceManager object.
  2. Create a CustomAudience object by specifying key parameters such as the buyer's package and a relevant name. Then, initialize the JoinCustomAudienceRequest object with the CustomAudience object.
  3. Call the asynchronous joinCustomAudience() with the JoinCustomAudienceRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a custom audience.
val audience = CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build()

// Initialize a custom audience request.
val joinCustomAudienceRequest: JoinCustomAudienceRequest =
    JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build()

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    ...
    .build();

// Initialize a custom audience request.
JoinCustomAudienceRequest joinCustomAudienceRequest =
    new JoinCustomAudienceRequest.Builder().setCustomAudience(audience).build();

// Request to join a custom audience.
customAudienceManager.joinCustomAudience(joinCustomAudienceRequest,
    executor,
    outcomeReceiver);

The combination of the following parameters uniquely identifies each CustomAudience object on a device:

  • owner : Package name of the owner app. This is implicitly set to the package name of the caller app.
  • buyer : Identifier for the buyer ad network which manages ads for this custom audience.
  • name : An arbitrary name or identifier for the custom audience.

Calling joinCustomAudience() repeatedly with a different instance of CustomAudience updates any existing CustomAudience with matching owner, buyer , and name parameters. To help preserve privacy, the result of the API does not distinguish between "creation" and "update."

Additionally, the CustomAudience must be created with these required parameters:

Optional parameters for a CustomAudience object may include:

  • Activation time : A custom audience can only participate in ad selection and daily updates after its activation time. This can be useful to engage lapsed users of an app, for example.
  • Expiration time : A future time after which the custom audience is removed from the device.
  • User bidding signals : A JSON string containing user signals, such as the user's preferred locale, that a buyer's bidding logic JavaScript consumes to generate bids during the ad selection process. This format helps ad tech platforms reuse code across platforms and eases the consumption in JavaScript functions.
  • Trusted bidding data : An HTTPS URL and a list of strings used during the ad selection process that fetch bidding signals from a trusted Key/Value service.
  • Ads : A list of AdData objects corresponding to the ads that participate in ad selection. Each AdData object consists of:
    • Render URL : An HTTPS URL that is queried to render the final ad.
    • Metadata : A JSON object serialized as a string containing information to be consumed by buyer bidding logic during the ad selection process.
    • Ad Filters : A class that contains all necessary information for app install ad filtering and frequency capping during ad selection.

Here's an example of a CustomAudience object instantiation:

কোটলিন

// Minimal initialization of a CustomAudience object
val customAudience: CustomAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build()

জাভা

// Minimal initialization of a CustomAudience object
CustomAudience customAudience = CustomAudience.Builder()
    .setBuyer(AdTechIdentifier.fromString("my.buyer.domain.name"))
    .setName("example-custom-audience-name")
    .setDailyUpdateUrl(Uri.parse("https://DAILY_UPDATE_URL"))
    .setBiddingLogicUrl(Uri.parse("https://BIDDING_LOGIC_URL"))
    .build();

Handle joinCustomAudience() outcomes

The asynchronous joinCustomAudience() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback signifies the custom audience is successfully created or updated.
  • The onError() callback signifies two possible conditions.

Here's an example of handling the outcome of joinCustomAudience() :

কোটলিন

var callback: OutcomeReceiver<Void, AdServicesException> =
    object : OutcomeReceiver<Void, AdServicesException> {
    override fun onResult(result: Void) {
        Log.i("CustomAudience", "Completed joinCustomAudience")
    }

    override fun onError(error: AdServicesException) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error)
    }
};

জাভা

OutcomeReceiver callback = new OutcomeReceiver<Void, AdServicesException>() {
    @Override
    public void onResult(@NonNull Void result) {
        Log.i("CustomAudience", "Completed joinCustomAudience");
    }

    @Override
    public void onError(@NonNull AdServicesException error) {
        // Handle error
        Log.e("CustomAudience", "Error executing joinCustomAudience", error);
    }
};

Leave a custom audience

If the user no longer satisfies the business criteria for a given custom audience, an app or SDK can call leaveCustomAudience() to remove the custom audience from the device. To remove a CustomAudience based on its unique parameters, do the following:

  1. Initialize the CustomAudienceManager object.
  2. Initialize the LeaveCustomAudienceRequest with the custom audience's buyer and name . To learn more about these input fields, read " Join a custom audience ."
  3. Call the asynchronous leaveCustomAudience() method with the LeaveCustomAudienceRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val customAudienceManager: CustomAudienceManager =
    context.getSystemService(CustomAudienceManager::class.java)

// Initialize a LeaveCustomAudienceRequest
val leaveCustomAudienceRequest: LeaveCustomAudienceRequest =
    LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build()

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver)

জাভা

CustomAudienceManager customAudienceManager =
    context.getSystemService(CustomAudienceManager.class);

// Initialize a LeaveCustomAudienceRequest
LeaveCustomAudienceRequest leaveCustomAudienceRequest =
    new LeaveCustomAudienceRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .build();

// Request to leave a custom audience
customAudienceManager.leaveCustomAudience(
    leaveCustomAudienceRequest,
    executor,
    outcomeReceiver);

Similar to calling joinCustomAudience() , the OutcomeReceiver signals the end of an API call. To help protect privacy, an error outcome doesn't distinguish between internal errors and invalid arguments. The onResult() callback is called when the API call has completed, whether or not a matching custom audience is removed successfully.

Run ad selection

To use the Protected Audience API to select ads, call the selectAds() method:

  1. Initialize an AdSelectionManager object.
  2. Build an AdSelectionConfig object.
  3. Call the asynchronous selectAds() method with the AdSelectionConfig object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val adSelectionManager: AdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionConfig
val adSelectionConfig: AdSelectionConfig =
  AdSelectionConfig.Builder().setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(
        contextualAds.getBuyer(), contextualAds
      )
    ).build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
  adSelectionConfig, executor, outcomeReceiver
)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionConfig
AdSelectionConfig adSelectionConfig =
  new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .setBuyerContextualAds(
      Collections.singletonMap(contextualAds.getBuyer(), contextualAds)
    )
    .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(adSelectionConfig, executor, outcomeReceiver);

The selectAds() method requires an AdSelectionConfig input, where you must specify the following required parameters:

  • Seller : Identifier for the seller ad network initiating the ad selection.
  • Decision logic URL : An HTTPS URL queried to obtain the seller ad network's JavaScript logic.
    • HTTPS URL : queried to obtain the seller ad network's JavaScript logic. See the required function signatures .
    • Prebuilt URI : that follows FLEDGE's ad selection format. IllegalArgumentException is thrown, if an unsupported or malformed prebuilt uri is passed.
  • Custom audience buyers : A full list of identifiers for buyer ad networks that are allowed by the seller to participate in the ad selection process. These buyer identifiers correspond to CustomAudience.getBuyer() of participating custom audiences.

The following parameters can be optionally specified for more customized ad selection:

  • Ad selection signals : A JSON object, serialized as a string, containing signals to be consumed by buyer bidding logic JavaScript fetched from CustomAudience.getBiddingLogicUrl() .
  • Seller signals : A JSON object, serialized as a string, containing signals consumed by the seller's fetched JavaScript decision logic from AdSelectionConfig.getDecisionLogicUrl() .
  • Per buyer signals : A map of JSON objects, serialized as strings, containing signals to be consumed by specific buyers' bidding logic JavaScript fetched from CustomAudience.getBiddingLogicUrl() , which are identified by the buyer fields of participating custom audiences.
  • Contextual ads: A collection of ad candidates that are collected directly from buyers during an auction that happens outside of a Protected Audience auction.

Once an ad is selected, the results, bids, and signals are persisted internally for reporting. The OutcomeReceiver.onResult() callback returns an AdSelectionOutcome that contains:

  • A render URL for the winning ad, obtained from AdData.getRenderUrl() .
  • An ad selection ID unique to the device user. This ID is used for reporting the ad impression.

If the ad selection can't be completed successfully due to reasons such as invalid arguments, timeouts, or excessive resource consumption, the OutcomeReceiver.onError() callback provides an AdServicesException with the following behaviors:

  • If the ad selection is initiated with invalid arguments, the AdServicesException indicates an IllegalArgumentException as the cause.
  • All other errors receive an AdServicesException with an IllegalStateException as the cause.

প্রাসঙ্গিক বিজ্ঞাপন

Protected Audience can incorporate contextual ads into a Protected Auction. Contextual ads need to be selected on the ad tech server and returned to the device outside of Protected Audience APIs. Contextual ads can then be included in the auction using the AdSelectionConfig at which point they function the same as on device ads, including eligibility for negative ad filtering. Once the Protected Audience auction has completed, you need to invoke reportImpression() . This calls reportWin() in the winning contextual ad, in the same pattern as impression reporting , to receive the winning ad on a device. Each contextual ad needs a buyer, a bid, a link to reporting logic, a render URL, and ad metadata.

To deploy contextual ads in app, the target app needs to create a ContextualAds object:

কোটলিন

val contextualAds: ContextualAds =
  Builder().setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
    //Pass in your valid app install ads
    .setDecisionLogicUri(mContextualLogicUri)
    .setAdsWithBid(appInstallAd)
    .build()

জাভা

ContextualAds contextualAds = new ContextualAds.Builder()
  .setBuyer(AdTechIdentifier.fromString(mBiddingLogicUri.getHost()))
  .setDecisionLogicUri(mContextualLogicUri)
  //Pass in your valid app install ads
  .setAdsWithBid(appInstallAd)
  .build();

The resulting ContextualAds object can then be passed along when creating your AdSelectionConfig :

কোটলিন

// Create a new ad
val noFilterAd: AdData = Builder()
  .setMetadata(JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build()
val noFilterAdWithBid = AdWithBid(noFilterAd, NO_FILTER_BID)
contextualAds.getAdsWithBid().add(noFilterAdWithBid)

জাভা

// Create a new ad
AdData noFilterAd = new AdData.Builder()
  .setMetadata(new JSONObject().toString())
  .setRenderUri(Uri.parse(baseUri + NO_FILTER_RENDER_SUFFIX))
  .build();
AdWithBid noFilterAdWithBid = new AdWithBid(noFilterAd, NO_FILTER_BID);
contextualAds.getAdsWithBid().add(noFilterAdWithBid);

App install ad filtering

App install ads filtering helps you to filter installation ads for apps that are already installed on a device.

The first step in this process is to define which advertisers have the ability to filter on the installed package. This needs to happen in the app you want to target with an ad.

কোটলিন

//Create a request for setting the app install advertisers
val adtech = AdTechIdentifier.fromString("your.enrolled.uri")
val adtechSet = setOf(adtech)
val request = SetAppInstallAdvertisersRequest(adtechSet)

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  object : OutcomeReceiver<Any?, Exception?>() {
    fun onResult(@NonNull ignoredResult: Any?) {
      Log.v("[your tag]", "Updated app install advertisers")
    }

    fun onError(@NonNull error: Exception?) {
      Log.e("[your tag]", "Failed to update app install advertisers", error)
    }
  })

জাভা

//Create a request for setting the app install advertisers
AdTechIdentifier adtech = AdTechIdentifier.fromString("your.enrolled.uri");
Set<AdTechIdentifier> adtechSet = Collections.singleton(adtech);
SetAppInstallAdvertisersRequest request = new SetAppInstallAdvertisersRequest(adtechSet);

//Set the app install advertisers in the ad selection manager
mAdSelectionManager.setAppInstallAdvertisers(
  request,
  mExecutor,
  new OutcomeReceiver<Object, Exception>() {
    @Override
    public void onResult(@NonNull Object ignoredResult) {
      Log.v("[your tag]", "Updated app install advertisers");
    }

    @Override
    public void onError(@NonNull Exception error) {
      Log.e("[your tag]", "Failed to update app install advertisers", error);
    }
  });

When the preceding code executes, the advertisers passed in are then able to filter out the installed apps that you specify during their bid generation. If you need to remove an advertiser from having access to this app's install status, run this code again with the advertiser's information removed.

The next step is to set up ad filtering inside the publisher app. The party that serves the ad inside of the publisher app (most likely to be a supply-side SDK) must initialize their AdFilters object with information about which ads related to apps they'd like to filter out:

কোটলিন

// Instantiate AdFilters object with package names.
val filters: AdFilters = Builder().setAppInstallFilters(
    Builder().setPackageNames(setOf("example.target.app")).build()
  ).build()

জাভা

// Instantiate AdFilters object with package names.
AdFilters filters = new AdFilters.Builder()
.setAppInstallFilters(
  new AppInstallFilters.Builder()
  .setPackageNames(Collections.singleton("example.target.app"))
  .build())
.build();

Demand-side publishers may also set an AdFilter for ads that exist inside of their custom audiences.

AdFilters can also be passed in at the point of instantiating a new AdData object:

কোটলিন

// Instantiate an AdData object with the AdFilters created in the
// previous example.
val appInstallAd: AdData =
  Builder().setMetadata("{ ... }") // Valid JSON string
    .setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters).build()

জাভা

// Instantiate an AdData object with the AdFilters created in the
// previous example.
AdData appInstallAd = new AdData.Builder()
.setMetadata("{ ... }") // Valid JSON string
.setRenderUri(Uri.parse("www.example-dsp1.com/.../campaign123.html"))
    .setAdFilters(filters)
    .build();

Frequency cap filtering

Frequency cap filtering enables ad techs to limit the number of times an ad is shown. Frequency cap filtering reduces ad overexposure and optimizes alternate ad selection for a given ad campaign.

There are two main components of a frequency cap filter: the ad event type, and the ad counter key. The available ad event types that can be used are:

  • Win : A win event indicates that the ad has won an auction. Win events are automatically updated by the Protected Audience API and cannot be called directly by the developer. Win data is only visible to ads within a given custom audience.
  • Impression : Separate from reportImpression , an on-device caller (SSP or MMP) uses updateAdCounterHistogram() to invoke impression events at the point in code they choose. Impression events are visible to all ads belonging to a given DSP, and are not limited to ads in the same custom audience.
  • View : Event is invoked by the on-device caller (SSP or MMP) at a point in code they choose using a call to updateAdCounterHistogram() . View events are visible to all ads belonging to a given DSP and not limited to ads in the same Custom Audience.
  • Click : Event is invoked by the on-device caller (SSP or MMP) at a point in code they choose using a call to updateAdCounterHistogram() . Click events are visible to all ads belonging to a given DSP and not limited to ads in the same Custom Audience.

In the publisher app, an SSP or MMP that has a presence on the device invokes ad events. When updateAdCounterHistogram() is called, the counter of a frequency cap filter is incremented so that future auctions will have up to date information about a user's exposure to a given ad. The ad event types are not forcibly tied to the corresponding user action and are guidelines given to help callers to structure their event system. To increment ad counters at the time of an event, the on-device actor provides the winning ad auction's ad selection ID.

Ad counter keys are arbitrary 32-bit signed integers assigned by a buyer ad tech, and they correspond to a given set of ads as defined by the DSP. Since ad counter keys are limited only to ads that belong to a given DSP, these keys can be selected without overlapping with histograms from another ad tech. Ad counter keys are used to increment DSP-specific identifiers across a DSP's ads or within a given custom audience to filter out ads from future auctions.

Counter keys can be leveraged to prioritize ads that are more likely to be interesting to a given user based on their interactions with other ads from a given buyer ad tech. For example, an ad that has received a high level of engagement from winning ad auctions, views, and clicks, represents an inferred data point. To further illustrate this point: an ad for left handed golf clubs might indicate that the user wouldn't be interested in right handed ones. A frequency cap filter set for a counter key assigned to left-handed ads could filter out ads for right handed clubs.

To use frequency capping in your auction, you must first create KeyedFrequencyCap objects as shown below:

কোটলিন

// Value used when incrementing frequency counter
val adCounterKey = 123

// Frequency cap exceeded after 2 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 2, Duration.ofSeconds(10)
).build()

// Frequency cap exceeded after 1 counts
val keyedFrequencyCapForImpression: KeyedFrequencyCap = Builder(
  adCounterKey, 1, Duration.ofSeconds(10)
).build()

জাভা

// Value used when incrementing frequency counter
int adCounterKey = 123;

// Frequency cap exceeded after 2 counts
KeyedFrequencyCap keyedFrequencyCapForImpression =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 2, Duration.ofSeconds(10)
  ).build();

// Frequency Cap exceeded after 1 counts
KeyedFrequencyCap keyedFrequencyCapForClick =
  new KeyedFrequencyCap.Builder(
    adCounterKey, 1, Duration.ofSeconds(10)
  ).build();

Once the KeyedFrequencyCap objects are created, you can pass them into an AdFilters object.

কোটলিন

val filters: AdFilters = Builder()
  .setFrequencyCapFilters(
    Builder()
      .setKeyedFrequencyCapsForImpressionEvents(
        ImmutableObject.of(keyedFrequencyCapForImpression)
      )
      .setKeyedFrequencyCapsForClickEvents(
        ImmutableObject.of(keyedFrequencyCapForClick)
      )
  ).build()

জাভা

AdFilters filters = new AdFilters.Builder()
    .setFrequencyCapFilters(new FrequencyCapFilters.Builder()
        .setKeyedFrequencyCapsForImpressionEvents(
            ImmutableObject.of(keyedFrequencyCapForImpression)
        )
        .setKeyedFrequencyCapsForClickEvents(
            ImmutableObject.of(keyedFrequencyCapForClick)
        )
    ).build();

When the AdFilters object is populated with frequency cap filters, it can be passed along when the custom audience is created:

কোটলিন

// Initialize a custom audience.
val audience: CustomAudience = Builder()
  .setBuyer(buyer)
  .setName(name)
  .setAds(
    listOf(
      Builder()
        .setRenderUri(renderUri)
        .setMetadata(JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()
    )
  ).build()

জাভা

// Initialize a custom audience.
CustomAudience audience = new CustomAudience.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setAds(Collections.singletonList(new AdData.Builder()
        .setRenderUri(renderUri)
        .setMetadata(new JSONObject().toString())
        .setAdFilters(filters)
        .setAdCounterKeys(adCounterKeys)
        .build()))
    .build();

When frequency cap filters are implemented into a custom audience, the SSP can then invoke the necessary click, view, or impression events.

কোটলিন

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

val request: UpdateAdCounterHistogramRequest = Builder(
  adSelectionId,
  FrequencyCapFilters.AD_EVENT_TYPE_CLICK,  //CLICK, VIEW, or IMPRESSION
  callerAdTech
).build()

জাভা

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

UpdateAdCounterHistogramRequest request =
  new UpdateAdCounterHistogramRequest.Builder(
      adSelectionId,
      FrequencyCapFilters.AD_EVENT_TYPE_CLICK, //CLICK, VIEW, or IMPRESSION
      callerAdTech
).build();

Ads that have hit their pre-set frequency cap filter limits are filtered out of the auction. Filtering happens before the bidding logic is executed for on-device auctions, and as the payload is generating for Bidding & Auction services auctions.This toolkit gives ad techs the flexibility to use the interactions between users and the ads within their custom audiences to focus ad targeting while minimizing ad overexposure.

Contextual ad filtering without network calls

If there is no remarketing demand on the device, you can run ad selection for contextual ads without network calls. With prebuilt URIs and a list of contextual ads with bids, the platform can skip retrieving bidding logic, bidding signals, and scoring signals. The platform uses a prebuilt URI to select the contextual ad with the highest bid.

To improve latency, ad techs can run an ad selection flow that includes only contextual ads with ad filtering functionality without network calls. This is achieved by using prebuilt URIs for scoring signals. Refer to the Supported prebuilt URI use cases and names section for a list of scoreAds implementations.

To run ad selection without network calls:

  1. Set up ad filtering
  2. Create your contextual ads
  3. Create a AdSelectionConfig object with the following:

    1. An empty list of buyers
    2. A prebuilt URI to select the highest bid
    3. প্রাসঙ্গিক বিজ্ঞাপন
    4. An empty URI for the scoring signals. The empty URI is allowed to indicate that you don't want to use the fetching of trusted signals for scoring:
    Uri prebuiltURIScoringUri = Uri.parse("ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=your.registered.uri/reporting");
    // Initialize AdSelectionConfig
    AdSelectionConfig adSelectionConfig =
      new AdSelectionConfig.Builder()
        .setSeller(seller)
        .setDecisionLogicUri(prebuiltURIScoringUri)
        .setCustomAudienceBuyers(Collections.emptyList())
        .setAdSelectionSignals(adSelectionSignals)
        .setSellerSignals(sellerSignals)
        .setPerBuyerSignals(perBuyerSignals)
        .setBuyerContextualAds(buyerContextualAds)
        .setTrustedScoringSignalsUri(Uri.EMPTY)
        .build();
    
  4. Run ad selection:

    adSelectionManager.selectAds(
        adSelectionConfig,
        executor,
        outcomeReceiver);
    

Run your own reporting JavaScript while using prebuilt URIs

Today, the Privacy Sandbox platform only has a basic reporting JavaScript implementation available for prebuilt URIs. If you want to run your own reporting JavaScript while still using prebuilt URIs for a low latency ad selection, you can override the DecisionLogicUri between ad selection and reporting runs.

  1. Run steps to run ad selection for contextual ads using prebuilt URIs
  2. Create a copy of your AdSelectionConfig before running reporting

    adSelectionConfigWithYourReportingJS = adSelectionConfig.cloneToBuilder()
      // Replace <urlToFetchYourReportingJS> with your own URL:
      .setDecisionLogicUri(Uri.parse(<urlToFetchYourReportingJS>))
      .build();
    
  3. Run impression reporting

    // adSelectionId is from the result of the previous selectAds run
    ReportImpressionRequest request = new ReportImpressionRequest(
      adSelectionId,
      adSelectionConfigWithYourReportingJS);
    adSelectionManager.reportImpression(
      request,
      executor,
      outcomeReceiver);
    

Run waterfall mediation

Waterfall mediation requires multiple third party SDKs (3P networks) to be orchestrated by a first party SDK mediation network. Waterfall mediation is done the same way regardless if the auction took place on device or ran on Bidding & Auction services (B&A).

3P networks

3P networks need to provide an adapter that allows the mediation network to invoke the necessary methods for running an auction:

  • Run ad selection
  • Report impressions

Here's an example of a mediation network adapter:

কোটলিন

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

    init {
        adSelectionManager = context.getSystemService(AdSelectionManager::class.java)
    }

    fun selectAds() {...}

    fun reportImpressions() {...}
}

জাভা

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

    public NetworkAdaptor() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void selectAds() {...}

    public void reportImpressions() {...}
}

Each SDK has their own ad selection service managers and clients, and their own selectAds and reportImpressions implementation. SDK providers can refer to the sections on how to run ad selection for on-device auctions or the B&A explainer for B&A auctions. Follow how to report ad impressions (following the single SSP impression reporting for reporting.

Mediation network

Similar to 3P networks, mediation networks need selectAds and reportImpression implementations. Refer to the sections on how to run ad selection and how to report ad impressions for more information.

Mediation networks are responsible for running the mediation chain and placing themselves in the mediation chain. The next section covers how to set up and execute this process.

Retrieve mediation chain and bid floors

The mediation network is responsible for retrieving the first party (1P) contextual ads, mediation chain, and third party networks' bid floors (3P). This can happen in a request to retrieve contextual ads executed by the mediation network. The mediation chain determines how to iterate through the 3P Networks, and the bid floors can be passed to the auction process as adSelectionSignals .

Network placement in the mediation chain

A mediation SDK can place itself in the mediation chain based on their live eCPM of 1P ad bids. In the Protected Audience API, ad bids are opaque. A mediation SDK should use AdSelectionFromOutcomesConfig to be able to compare a given 1P ad's bid to the bid floor of the next 3P network in the chain. If the 1P bid is higher than the bid floor then that means the mediation SDK is placed in front of that 3P network.

Run ad selection

To retrieve a 1P ad candidate, the mediation network can execute an on-device auction following the steps in the run ad selection section. This generates a 1P ad candidate, a bid, and an AdSelectionId that is used in the mediation process.

Create an AdSelectionFromOutcomesConfig

An AdSelectionFromOutcomesConfig allows the mediation network to pass a list of AdSelectionIds (results from previous auctions), ad selection signals, and a URI to fetch JavaScript that selects an ad from multiple candidates. The list of AdSelectionIds along with their bids and the signals are passed to the JavaScript which can return one of the AdSelectionIds if it beats the bid floor, or none if the mediation chain should continued.

Mediation Networks create an AdSelectionFromOutcomesConfig using the 1P AdSelectionId from the previous section, and the bid floor for the 3P Network being considered. A new AdSelectionFromOutcomesConfig should be created for each step in the mediation chain.

কোটলিন

fun  runSelectOutcome(
    adSelectionClient : AdSelectionClient,
    outcome1p : AdSelectionOutcome,
    network3p : NetworkAdapter) : ListenableFuture<AdSelectionOutcome?> {
    val config = AdSelectionFromOutcomesConfig.Builder()
        .setSeller(seller)
        .setAdSelectionIds(listOf(outcome1p))
        .setSelectionSignals({"bid_floor": bid_floor})
        .setSelectionLogicUri(selectionLogicUri)
        .build()
    return adSelectionClient.selectAds(config)
}

জাভা

public ListenableFuture<AdSelectionOutcome> runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) {
    AdSelectionFromOutcomesConfig config = new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .build();

    return adSelectionClient.selectAds(config){}
}

The selectAds() method override for waterfall mediation requires an AdSelectionFromOutcomesConfig input, where you must specify the following required parameters:

  • Seller : Identifier for the seller ad network initiating the ad selection.
  • AdSelectionIds : A singleton list of a previous selectAds() run for a 1P ad.
  • Ad selection signals : A JSON object, serialized as a string, containing signals to be used by buyer bidding logic. In this case, include the bid floor retrieved for the given 3P network.
  • Selection Logic URI : An HTTPS URL queried during ad selection to fetch the mediation network's JavaScript for selecting a winning ad. See the required function signatures in this JavaScript. The JavaScript should return the 3P ad if the bid is higher than the bid floor, or otherwise return null . This allows the mediation SDK to truncate the mediation chain when a winner is found.

With the AdSelectionOutcomesConfig created, call the selectAds() method of the 3P network that is first in the chain.

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
  AdSelectionFromOutcomesConfig.Builder()
    .setSeller(seller)
    .setAdSelectionIds(listof(outcome1p))
    .setSelectionSignals({"bid_floor": bid_floor})
    .setSelectionLogicUri(selectionLogicUri)
    .setAdSelectionIds(outcomeIds)
    .build()

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver)

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize AdSelectionFromOutcomesConfig
AdSelectionFromOutcomesConfig adSelectionFromOutcomesConfig =
        new AdSelectionFromOutcomesConfig.Builder()
            .setSeller(seller)
            .setAdSelectionIds(Collection.singletonList(outcome1p))
            .setSelectionSignals({"bid_floor": bid_floor})
            .setSelectionLogicUri(selectionLogicUri)
            .setAdSelectionIds(outcomeIds)
            .build();

// Run ad selection with AdSelectionConfig
adSelectionManager.selectAds(
    adSelectionFromOutcomesConfig,
    executor,
    outcomeReceiver);

Orchestrate waterfall mediation

The following is the order of operations for running through the mediation process.

  1. Run 1P ad selection.
  2. Iterate over the mediation chain. For each 3P network, do the following:
    1. Build AdSelectionFromOutcomeConfig including the 1P outcomeId and the 3P SDK's bid floor.
    2. Call selectAds() with the config from the previous step.
    3. If the result is not empty, return the ad.
    4. Call the current SDK network adapter's selectAds() method. If the result is not empty, return the ad.
  3. If no winner is found from the chain, return the 1P ad.

কোটলিন

fun runWaterfallMediation(mediationChain : List<NetworkAdapter>)
  : Pair<AdSelectionOutcome, NetworkAdapter> {
    val outcome1p = runAdSelection()

    var outcome : AdSelectionOutcome
    for(network3p in mediationChain) {
      outcome = runSelectOutcome(outcome1p, network3p)
      if (outcome1p.hasOutcome() && outcome.hasOutcome()) {
          return Pair(outcome, this)
      }

      outcome = network3p.runAdSelection()
      if(outcome.hasOutcome()) {
          return Pair(outcome, network3p)
      }
    }
  return Pair(outcome1p, this)
}

জাভা

class MediationNetwork {
    AdSelectionManager adSelectionManager;

    public MediationNetwork() {
        AdSelectionManager adSelectionManager =
            context.getSystemService(AdSelectionManager.class);
    }

    public void runAdSelection() {...}

    public void reportImpressions() {...}

    public Pair<AdSelectionOutcome, NetworkAdapter> runWaterfallMediation(
            List<NetworkAdapter> mediationChain) {
        AdSelectionOutcome outcome1p = runAdSelection();

        AdSelectionOutcome outcome;
        for(NetworkAdapter network3p: mediationChain) {
            if (outcome1p.hasOutcome() &&
              (outcome = runSelectOutcome(outcome1p, network3p)).hasOutcome()) {
                return new Pair<>(outcome, this);
            }

            if((outcome = network3p.runAdSelection()).hasOutcome()) {
                return new Pair<>(outcome, network3p);
            }
        }
        return new Pair<>(outcome1p, this);
    }

    /* Runs comparison by creating an AdSelectionFromOutcomesConfig */
    public AdSelectionOutcome runSelectOutcome(AdSelectionOutcome outcome1p,
                                              NetworkAdapter network3p) { ... }
}

Report ad impressions

There are two flows for reporting an ad impression depending on how the auction is run. If you are a single SSP running an auction, follow this section. If you are going to implement waterfall mediation, follow the steps found in the waterfall mediation impression reporting section .

Single SSP impression reporting

After a winning ad has been chosen from the ad selection workflow, you can report the impression back to participating buy-side and sell-side platforms with the AdSelectionManager.reportImpression() method. To report an ad impression:

  1. Initialize an AdSelectionManager object.
  2. Build a ReportImpressionRequest object with the ad selection ID.
  3. Call the asynchronous reportImpression() method with the ReportImpressionRequest object and relevant Executor and OutcomeReceiver objects.

জাভা

AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportImpressionRequest
ReportImpressionRequest reportImpressionRequest =
        new ReportImpressionRequest.Builder()
                .setAdSelectionId(adSelectionId)
                .setAdSelectionConfig(adSelectionConfig)
                .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver);

কোটলিন

val adSelectionManager = context.getSystemService(AdSelectionManager::class.java)

// Initialize a ReportImpressionRequest
val adSelectionConfig: ReportImpressionRequest =
    ReportImpressionRequest.Builder()
        .setAdSelectionId(adSelectionId)
        .setAdSelectionConfig(adSelectionConfig)
        .build()

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportImpression(
    reportImpressionRequest,
    executor,
    outcomeReceiver)

Initialize the ReportImpressionRequest with the following required parameters:

  • Ad selection ID : An ID unique only to a device user that identifies a successful ad selection.
  • Ad selection config : The same configuration used in the selectAds() call identified by the provided ad selection ID.

The asynchronous reportImpression() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback indicates if impression reporting URLs have been created and the request has been scheduled.
  • The onError() callback indicates the following possible conditions:
    • If the call is initialized with an invalid input argument, the AdServicesException indicates an IllegalArgumentException as the cause.
    • All other errors receive an AdServicesException with an IllegalStateException as the cause.

Waterfall mediation impression reporting

A mediation SDK needs to keep track of the winning SDK to trigger their reporting flows. The SDKs participating in a mediation chain should provide a method for the mediator to invoke to trigger their own reporting flow. An SDK participating in a mediated auction can follow the steps above to implement their own reporting.

SSPs can use this 3P SDK code example as a prototype for how to join in mediation flows:

Pair<AdSelectionOutcome, NetworkAdapter> winnerOutcomeAndNetwork =
         mediationSdk.orchestrateMediation(mediationChain);

if (winner.first.hasOutcome()) {
      winner.second.reportImpressions(winner.first.getAdSelectionId());

Impression reporting endpoints

The report impression API issues HTTPS GET requests to endpoints provided by the sell-side platform and the winning buy-side platform:

Buy-side platform endpoint:

  • The API uses the Bidding logic URL specified in the custom audience to fetch the buyer-provided JavaScript that includes logic to return an impression reporting URL.
  • Invoke the reportWin() JavaScript function, which is expected to return the buyer's impression reporting URL.

Sell-side platform endpoint:

  • Use the Decision logic URL specified in the AdSelectionConfig object to fetch the seller's decision logic JavaScript.
  • Invoke the reportResult() JavaScript function, which is expected to return the seller's impression reporting URL.

Bidding & Auction services reporting

An auction executed on Bidding & Auction services will have all the necessary reporting information, including generated URLs for ad interaction reporting , included in the encrypted response from the server-side auction. When the response is decrypted, the appropriate URLs are registered with the platform, so ad and impression reporting follows the same steps listed above.

Best effort Impression reporting

The reportImpression() method is designed to offer a best-effort completion of reporting.

Report Ad Interactions

Protected Audience provides support to report on more granular interactions for a rendered ad. This can include interactions such as view time, clicks, hovers, or any other useful metric that can be collected. The process to receive these reports requires two steps. First, buyers and sellers must register to receive these reports in their reporting JavaScript. Then, the client will need to report these events.

Registering to receive interaction events

Registering for interaction events happens in the buyer's reportWin() and seller's reportResult() JavaScript functions using a JavaScript function provided by the platform: registerAdBeacon . To register to receive an event report, simply call the platform JavaScript Function from your reporting JavaScript. The following snippet is using a buyer's reportWin() , but the same approach applies to reportResult() .

reportWin(
  adSelectionSignals,
  perBuyerSignals,
  signalsForBuyer,
  contextualSignals,
  customAudienceSignals) {
    ...
    // Calculate reportingUri, clickUri, viewUri, and hoverUri

    registerAdBeacon({"click": clickUri, "view": viewUri, "hover": hoverUri});

    return reportingUri;
}

Reporting interaction events

After reporting an impression, clients can report the interactions back to previously registered winning buy-side and sell-side platforms with the AdSelectionManager.reportInteraction() method. To report an ad event:

  1. Initialize an AdSelectionManager object.
  2. Build a ReportInteractionRequest object with the ad selection ID, interaction key, interaction data, and reporting destination.
  3. Call the asynchronous reportInteraction() method with the request object and relevant Executor and OutcomeReceiver objects.
AdSelectionManager adSelectionManager =
    context.getSystemService(AdSelectionManager.class);

// Initialize a ReportInteractionRequest
ReportInteractionRequest request =
  new ReportInteractionRequest.Builder()
    .setAdSelectionId(adSelectionId)
    .setInteractionKey("view")
    .setInteractionData("{ viewTimeInSeconds : 1 }") // Can be any string
    .setReportingDestinations(
      FLAG_REPORTING_DESTINATION_BUYER | FLAG_REPORTING_DESTINATION_SELLER
    )
    .build();

// Request to report the impression with the ReportImpressionRequest
adSelectionManager.reportInteraction(
  reportImpressionRequest,
  executor,
  outcomeReceiver);

Initialize the ReportInteractionRequest with the following required parameters:

  • Ad selection ID : An ad selection ID retrieved from a previously returned AdSelectionOutcome .
  • Interaction Key : A string key defined by the client describing the action being reported. This must match the key that was registered by the seller or buyer in the reporting JavaScript functions.
  • Interaction Data : A string containing data to be included with the event report, to be POSTed back to the reporting servers.
  • Reporting Destinations : A bit mask specifying if the events should be reported to the buyer, seller, or both. These flags are provided by the platform and the final destination mask can be created using bitwise operations. To report to one destination, you can use the flag provided by the platform directly. To report to multiple destinations, you can use the bitwise OR ( | ) to combine flag values.

The asynchronous reportInteraction() method uses the OutcomeReceiver object to signal the result of the API call.

  • The onResult() callback indicates the report interaction call is valid.
  • The onError() callback indicates the following possible conditions:
    • If the call is made when the app is running in the background, an IllegalStateException with a description of the failure is returned.
    • If the client is throttled from calling reportInteraction() , a LimitExceededException is returned.
    • If the package is not enrolled to call the Privacy Preserving APIs, a SecurityException() is returned.
    • If the app reporting interactions is different from the app that called selectAds() , an IllegalStateException is returned.
  • If the user has not consented to enable the Privacy Sandbox APIs, the call will fail silently.

Interaction reporting endpoints

The report interaction API issues HTTPS POST requests to endpoints provided by the sell-side platform and the winning buy-side platform. Protected Audience will match the interaction keys with the URIs declared in reporting JavaScript and issue a POST request to each endpoint for each interaction being reported. The content type of the request is plain text with the body being the Interaction Data.

Best effort Interaction reporting

The reportInteraction() is designed to offer a best-effort completion of reporting through HTTP POST.

Daily background update

When creating a custom audience, your app or SDK can initialize custom audience metadata. Additionally, the platform can update the following pieces of custom audience metadata with a daily background update process.

  • User bidding signals
  • Trusted bidding data
  • AdData list

This process queries against the Daily update URL defined in the custom audience and the URL may return a JSON response.

  • The JSON response may contain any of the supported metadata fields that needs to be updated.
  • Each JSON field is validated independently. The client ignores any malformed fields which results in no updates to that particular field in the response.
  • An empty HTTP response or an empty JSON object " {} " results in no metadata updates.
  • The response message size must be limited to 10 KB.
  • All URIs are required to use HTTPS.
  • trusted_bidding_uri must share the same ETLD+1 as the buyer.

Example: JSON response for background daily update

{
    "user_bidding_signals" : { ... },  // Valid JSON object
    "trusted_bidding_data" : {
        "trusted_bidding_uri" : 'example-dsp1-key-value-service.com',
        "trusted_bidding_keys" : [ 'campaign123', 'campaign456', ... ]
    },
    'ads' : [
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign123.html',
            'metadata' : { ... }  // Valid JSON object
        },
        {
            "render_uri" : 'www.example-dsp1.com/.../campaign456.html',
            'metadata' : { ... }  // Valid JSON object
        },
        ...
    ]
}

JavaScript for ad selection

The ad selection workflow orchestrates the execution of buyer-provided and seller-provided JavaScript.

Buyer-provided JavaScript is fetched from the Bidding logic URL specified in the custom audience. The returned JavaScript should include the following functions:

Seller-provided JavaScript is fetched from the decision logic URL specified in the AdSelectionConfig parameter for the ad selection API. The returned JavaScript should include the following functions:

generateBid()

function generateBid(
  ad,
  auction_signals,
  per_buyer_signals,
  trusted_bidding_signals,
  contextual_signals,
  user_signals,
  custom_audience_bidding_signals) {
  return {'status': 0, 'ad': ad, 'bid': ad.metadata.result };
}

ইনপুট পরামিতি:

  • ad : a JSON object with the format var ad = { 'render_url': url, 'metadata': json_metadata };
  • auction_signals, per_buyer_signals : JSON objects specified in the auction configuration object
  • custom_audience_bidding_signals : JSON object generated by the platform. The format for this JSON object is:

    var custom_audience_signals = {
      "owner":"ca_owner",
      "buyer":"ca_buyer",
      "name":"ca_name",
      "activation_time":"ca_activation_time_epoch_ms",
      "expiration_time":"ca_expiration_time_epoch_ms",
      "user_bidding_signals":"ca_user_bidding_signals"
    }
    

    কোথায়:

    • owner , buyer , and name are string taken from the properties with the same name of the Custom Audience participating to the ad selection
    • activation_time and expiration_time are the time of activation and expiration of the custom audience, expressed as seconds since the Unix epoch
    • ca_user_bidding_signals is a JSON string specified in the userBiddingSignals field of the CustomAudience at creation time
    • trusted_bidding_signals, contextual_signals , and user_signals are JSON objects. They are passed as empty objects and will be filled up in future releases. Their format is not enforced by the platform and is managed by the ad tech.

ফলাফল:

  • ad : is the ad the bid refers to. The script is allowed to return a copy of the ad it received with different metadata. The render_url property of the ad is expected to be unaltered.
  • bid : a float value representing the bid value for this ad
  • status : an integer value that can be:
    • 0 : for a successful execution
    • 1 : (or any non-zero value) in case any of the input signals is invalid. In case a non-zero value is returned by generate-bid the bidding process is invalidated for all the CA ads

scoreAd()

function scoreAd(
  ad,
  bid,
  ad_selection_config,
  seller_signals,
  trusted_scoring_signals,
  contextual_signal,
  user_signal,
  custom_audience_signal) {
    return {'status': 0, 'score': score };
}

ইনপুট পরামিতি:

  • ad : see the generateBid documentation
  • bid : the bid value for the ad
  • ad_selection_config : a JSON object representing the AdSelectionConfig parameter of the selectAds API. বিন্যাস হল:

    var ad_selection_config = {
      'seller': 'seller',
      'decision_logic_url': 'url_of_decision_logic',
      'custom_audience_buyers': ['buyer1', 'buyer2'],
      'auction_signals': auction_signals,
      'per_buyer_signals': per_buyer_signals,
      'contextual_ads': [ad1, ad2]
    }
    
  • seller_signals : JSON objects read from the sellerSignals AdSelectionConfig API parameter

  • trusted_scoring_signal : read from the adSelectionSignals field in the AdSelectionConfig API parameter

  • contextual_signals, user_signals : JSON objects. They are currently passed as empty objects and will be filled up in future releases. Their format is not enforced by the platform and is managed by the ad tech.

  • per_buyer_signals : JSON object read from the perBuyerSignal map in the AdSelectionConfig API parameter using as key the current Custom Audience buyer. Empty if the map doesn't contain any entry for the given buyer.

আউটপুট:

  • score : a float value representing the score value for this ad
  • status : an integer value that can be:
    • 0: for a successful execution
    • 1: in case the customAudienceSignals are invalid
    • 2: in case the AdSelectionConfig is invalid
    • 3: in case any of the other signals is invalid
    • Any non-zero value causes the failure of the process, the value determines the type of exception thrown

selectOutcome()

function selectOutcome(
  outcomes,
  selection_signals) {
    return {'status': 0, 'result': null};
}

ইনপুট পরামিতি:

  • outcomes : a JSON object {"id": id_string, "bid": bid_double}
  • selection_signals : JSON objects specified in the auction configuration object

আউটপুট:

  • status : 0 for success, non-zero for failure
  • result : one of the outcomes passed in or null

reportResult()

function reportResult(ad_selection_config, render_url, bid, contextual_signals) {
   return {
      'status': status,
      'results': {'signals_for_buyer': signals_for_buyer, 'reporting_url': reporting_url }
   };
}

ইনপুট পরামিতি:

  • ad_selection_config : see the documentation of scoreAds
  • render_url : the render URL of the winning ad
  • bid : the bid offered for the winning ad
  • contextual_signals : see the documentation of generateBid

আউটপুট:

  • status: 0 for success and non-zero for failure
  • results : a JSON objects containing:
    • signals_for_buyer : a JSON object that is passed to the reportWin function
    • reporting_url : a URL that is used by the platform to notify the impression to the buyer

reportWin()

function reportWin(
   ad_selection_signals,
   per_buyer_signals,
   signals_for_buyer,
   contextual_signals,
   custom_audience_signals) {
   return {'status': 0, 'results': {'reporting_url': reporting_url } };
}

ইনপুট পরামিতি:

  • ad_selection_signals, per_buyer_signals : see the documentation for scoreAd
  • signals_for_buyer : a JSON object returned by reportResult
  • contextual_signals, custom_audience_signals : see the documentation for generateBid

আউটপুট:

  • status: 0 for success and non-zero for failure
  • results : a JSON object containing:
    • reporting_url : a URL that is used by the platform to notify the impression to the seller

registerAdBeacon()

function registerAdBeacon(
  beacons
)

Input Parameters :

  • beacons : An object containing key-value pairs of interaction keys and reporting URIs. বিন্যাস হল:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key : A string representing the event. This is used by the platform later when reporting event interactions to look up the reporting_uri that should be notified. This key needs to match between what the buyer or seller is registering, and what the seller is reporting.
    • reporting_uri : A URI to receive event reports. This should be specific to the event type being reported. It must accept a POST request to handle any data reported along with the event.

    যেমন:

      let beacons = {
        'click': 'https://reporting.example.com/click_event',
        'view': 'https://reporting.example.com/view_event'
      }
    

Ad Selection prebuilt URIs

Prebuilt URIs give ad techs the ability to appoint JavaScript functions for ad selection decision logic in the AdSelectionConfig and AdSelectionFromOutcomesConfig classes. Prebuilt URIs don't require network calls to download the corresponding JavaScript. Ad techs can use prebuilt URIs without having to set up an enrolled domain to host the JavaScript.

A prebuilt URI is constructed using the following format:

ad-selection-prebuilt:<use-case>/<name>?<required-script-generation-parameters>

The Privacy Sandbox platform provides JavaScript using the information from this URI in the runtime.

An IllegalArgumentException is thrown if:

  • any of the required parameters are not present in the URI
  • there are unrecognized parameters in the URI

Supported prebuilt URI use cases and names

Use case 1: ad-selection

Prebuilt URIs under the ad-selection use case are supported in the selectAds(AdSelectionConfig) flow.

Prebuilt URI name: highest-bid-wins

This prebuilt URI provides a JavaScript that picks the ad with the highest bid after bidding. It also provides a basic reporting function to report the winner's render_uri and bid .

Required parameters

reportingUrl : The base reporting URL that is parameterized with the render_uri and the bid of the winning ad:

<reportingUrl>?render_uri=<renderUriOfWinnigAd>&bid=<bidOfWinningAd>

ব্যবহার

If your base reporting URL is https://www.ssp.com/reporting then the prebuilt URI would be:

`ad-selection-prebuilt://ad-selection/highest-bid-wins/?reportingUrl=https://www.ssp.com/reporting`

Use case 2: ad-selection-from-outcomes

Prebuilt URIs under the ad-selection-from-outcomes use case support the selectAds(AdSelectionFromOutcomesConfig) workflow.

Prebuilt URI name: waterfall-mediation-truncation

The waterfall-mediation-truncation prebuilt URI provides JavaScript that implements waterfall mediation truncation logic where the JavaScript returns a first-party ad if the bid is higher then or equal to the bid floor , and otherwise returns null .

Required parameters

bidFloor : The key of the bid floor value passed in the getSelectionSignals() that is compared against the mediation SDK's ad.

ব্যবহার

If your ad selection signals look like {"bid_floor": 10} then the resulting prebuilt URI would be:

`ad-selection-prebuilt://ad-selection-from-outcomes/waterfall-mediation-truncation/?bidFloor=bid_floor`

টেস্টিং

To help you get started with the Protected Audience API, we've created sample apps in Kotlin and Java, which can be found on GitHub .

পূর্বশর্ত

The Protected Audience API requires some JavaScript during ad selection and impression reporting. There are two methods of providing this JavaScript in a testing environment:

  • Run a server with the required HTTPS endpoints that returns the JavaScript
  • Override remote fetching by providing the necessary code from a local source

Either approach requires setting up an HTTPS endpoint to handle impression reporting.

HTTPS endpoints

To test ad selection and impression reporting, you need to set up 7 HTTPS endpoints that your test device or emulator can access:

  1. Buyer endpoint that serves the bidding logic JavaScript.
  2. An endpoint that serves the bidding signals.
  3. Seller endpoint that serves the decision logic JavaScript.
  4. An endpoint that serves scoring signals.
  5. Winning buyer impression reporting endpoint.
  6. Seller impression reporting endpoint.
  7. An endpoint to serve the daily updates for a custom audience.

For convenience, the GitHub repo provides basic JavaScript code for testing purposes. It also includes OpenAPI service definitions which can be deployed to a supported mock or microservices platform. For more details, see the project README .

Override remote fetching of JavaScript

This feature is intended to be used for end-to-end testing. To override remote fetching, your app must run in debug mode with developer options enabled.

To enable debug mode for your application, add the following line to the application attribute in your AndroidManifest.xml:

<application
  android:debuggable="true">

For an example of how to use these overrides, please see the the Protected Audience API sample app on GitHub.

You need to add your own custom JavaScript to handle ad selection routines such as bidding, scoring decisions, and reporting. You can find basic JavaScript code examples that handle all required requests in the GitHub repo . The Protected Audience API sample application demonstrates how to read code from that file and prepare it for use as an override.

It is possible to override sell-side and buy-side JavaScript fetching independently, though you need an HTTPS endpoint to serve any JavaScript you aren't providing overrides for. Please see the README for information about how to set up a server that handles these cases.

It is only possible to override JavaScript fetching for custom audiences that are owned by your package.

Override sell-side JavaScript

To set up an override of sell-side JavaScript, do the following as demonstrated in the following code example:

  1. Initialize an AdSelectionManager object.
  2. Get a reference to TestAdSelectionManager from the AdSelectionManager object.
  3. Build an AdSelectionConfig object.
  4. Build an AddAdSelectionOverrideRequest with the AdSelectionConfig object and a String representing the JavaScript you intend to use as an override.
  5. Call the asynchronous overrideAdSelectionConfigRemoteInfo() method with the AddAdSelectionOverrideRequest object and relevant Executor and OutcomeReceiver objects.

কোটলিন

val testAdSelectionManager: TestAdSelectionManager =
  context.getSystemService(AdSelectionManager::class.java).getTestAdSelectionManager()

// Initialize AdSelectionConfig =
val adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build()

// Initialize AddAddSelectionOverrideRequest
val request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build()

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestAdSelectionManager testAdSelectionManager =
  context.getSystemService(AdSelectionManager.class).getTestAdSelectionManager();

// Initialize AdSelectionConfig =
AdSelectionConfig adSelectionConfig = new AdSelectionConfig.Builder()
    .setSeller(seller)
    .setDecisionLogicUrl(decisionLogicUrl)
    .setCustomAudienceBuyers(customAudienceBuyers)
    .setAdSelectionSignals(adSelectionSignals)
    .setSellerSignals(sellerSignals)
    .setPerBuyerSignals(perBuyerSignals)
    .build();

// Initialize AddAddSelectionOverrideRequest
AddAdSelectionOverrideRequest request = AddAdSelectionOverrideRequest.Builder()
    .setAdSelectionConfig(adSelectionConfig)
    .setDecisionLogicJs(decisionLogicJS)
    .build();

// Run the call to override the JavaScript for the given AdSelectionConfig
// Note that this only takes effect in apps marked as debuggable
testAdSelectionManager.overrideAdSelectionConfigRemoteInfo(
    request,
    executor,
    outComeReceiver);

See the Run ad selection section for more information about what each of the fields in the AdSelectionConfig represent. The key difference is that the decisionLogicUrl can be set to a placeholder value as it will be ignored.

In order to override the JavaScript used during ad selection, the decisionLogicJs must contain the proper seller-side function signatures . For an example of how to read a JavaScript file as a string, please see the Protected Audience API sample app on GitHub.

The asynchronous overrideAdSelectionConfigRemoteInfo() method uses the OutcomeReceiver object to signal the result of the API call.

The onResult() callback signifies the override was applied successfully. Future calls to selectAds() will use whatever decision and reporting logic you have passed in as the override.

The onError() callback signifies two possible conditions:

  • If the override is attempted with invalid arguments, the AdServiceException indicates an IllegalArgumentException as the cause.
  • If the override is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Reset sell-side overrides

This section assumes that you have overridden the sell-side JavaScript and that you have a reference to the TestAdSelectionManager and AdSelectionConfig used in the previous section.

In order to reset the overrides for all AdSelectionConfigs :

  1. Call the asynchronous resetAllAdSelectionConfigRemoteOverrides() method with the relevant OutcomeReceiver object.

কোটলিন

// Resets overrides for all AdSelectionConfigs
testAadSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
  outComeReceiver)

জাভা

// Resets overrides for all AdSelectionConfigs
testAdSelectionManager.resetAllAdSelectionConfigRemoteOverrides(
    outComeReceiver);

After you reset sell-side overrides, calls to selectAds() use whatever decisionLogicUrl is stored in the AdSelectionConfig to attempt to fetch the required JavaScript.

If the call to resetAllAdSelectionConfigRemoteOverrides() fails, the OutComeReceiver.onError() callback provides an AdServiceException . If the removal of overrides is attempted with an app not running in debug mode with developer options enabled, AdServiceException indicates IllegalStateException as the cause.

Override buy-side JavaScript

  1. Follow the steps to join a custom audience
  2. Build an AddCustomAudienceOverrideRequest with the buyer and name of the custom audience you wish to override, in addition to the bidding logic and data you wish to use as an override
  3. Call the asynchronous overrideCustomAudienceRemoteInfo() method with the AddCustomAudienceOverrideRequest object and relevant Executor and OutcomeReceiver objects

কোটলিন

val testCustomAudienceManager: TestCustomAudienceManager =
  context.getSystemService(CustomAudienceManager::class.java).getTestCustomAudienceManager()

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
val request = AddCustomAudienceOverrideRequest.Builder()
    .setBuyer(buyer)
    .setName(name)
    .setBiddingLogicJs(biddingLogicJS)
    .setTrustedBiddingSignals(trustedBiddingSignals)
    .build()

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver)

জাভা

TestCustomAudienceManager testCustomAudienceManager =
  context.getSystemService(CustomAudienceManager.class).getTestCustomAudienceManager();

// Join custom audience

// Build the AddCustomAudienceOverrideRequest
AddCustomAudienceOverrideRequest request =
    AddCustomAudienceOverrideRequest.Builder()
        .setBuyer(buyer)
        .setName(name)
        .setBiddingLogicJs(biddingLogicJS)
        .setTrustedBiddingSignals(trustedBiddingSignals)
        .build();

// Run the call to override JavaScript for the given custom audience
testCustomAudienceManager.overrideCustomAudienceRemoteInfo(
    request,
    executor,
    outComeReceiver);

The values for buyer and name are the same ones used to create the custom audience. Learn more about these fields .

Additionally, you can specify two additional parameters:

  • biddingLogicJs : JavaScript that holds the buyer's logic that is used during ad selection. See the required function signatures in this JavaScript.
  • trustedBiddingSignals : Bidding signals to be used during ad selection. For testing purposes this can be an empty string.

The asynchronous overrideCustomAudienceRemoteInfo() method uses the OutcomeReceiver object to signal the result of the API call.

The onResult() callback signifies the override was applied successfully. Subsequent calls to selectAds() use whatever bidding and reporting logic you have passed in as the override.

The onError() callback signifies two possible conditions.

  • If the override is attempted with invalid arguments, the AdServiceException indicates an IllegalArgumentException as the cause.
  • If the override is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Reset buy-side overrides

This section assumes that you have overridden the buy-side JavaScript and that you have a reference to the TestCustomAudienceManager used in the previous section.

To reset overrides for all custom audiences:

  1. Call the asynchronous resetAllCustomAudienceOverrides() method with relevant Executor and OutcomeReceiver objects.

কোটলিন

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

জাভা

// Resets overrides for all custom audiences
testCustomAudienceManager.resetCustomAudienceRemoteInfoOverride(
    executor,
    outComeReceiver)

After you reset buy-side overrides, subsequent calls to selectAds() use whatever biddingLogicUrl and trustedBiddingData is stored in the CustomAudience to attempt to fetch the required JavaScript.

If the call to resetCustomAudienceRemoteInfoOverride() fails, the OutComeReceiver.onError() callback provides an AdServiceException . If the removal of overrides is attempted with an app not running in debug mode with developer options enabled, the AdServiceException indicates IllegalStateException as the cause.

Set Up a Reporting Server

When you use remote fetching overrides, you'll still need to set up a server that your device or emulator can reach to respond to reporting events. A simple endpoint that returns 200 is sufficient for testing. The GitHub repo includes OpenAPI service definitions which can be deployed to a supported mock or microservices platform. For more details, see the project README .

When looking for the OpenAPI definitions, look for the reporting-server.json. This file contains a simple endpoint that returns 200, representing an HTTP response code. This endpoint is used during selectAds() and signals to the Protected Audience API that impression reporting completed successfully.

Functionality to test

  • Exercise joining or leaving and setting up a custom audience based on prior user actions.
  • Exercise the initiation of on-device ad selection through JavaScripts hosted remotely.
  • Observe how an app's association with custom audience settings may affect ad selection outcomes.
  • Exercise impression reporting after ad selection.

সীমাবদ্ধতা

The following table lists limitations for the Protected Audience API processing. The limits presented could be subject to change based on feedback. For in-progress capabilities, read the release notes .

কম্পোনেন্ট সীমা বর্ণনা সীমিত মান
Custom audience (CA) Maximum number of ads per CA 100
Maximum number of CAs per application 1000
Maximum number of apps that can create a CA 1000
Maximum delay in the activation time of a CA from its creation time 60 দিন
Maximum expiration time of a CA from its activation time 60 দিন
Maximum number of CAs on device 4000
Maximum size of CA name 200 bytes
Maximum size of daily fetch URI 400 বাইট
Maximum size of bidding logic URI 400 বাইট
Maximum size of trusted bidding data 10 KB
Maximum size of user bidding signals 10 KB
Maximum call rate for leaveCustomAudience per buyer প্রতি সেকেন্ডে 1
Maximum call rate for joinCustomAudience per buyer প্রতি সেকেন্ডে 1
CA Background Fetch টাইমআউট সংযোগ করুন 5 সেকেন্ড
HTTP read timeout 30 সেকেন্ড
Maximum total download size 10 KB
Max duration of a fetch iteration 5 মিনিট
Maximum number of CAs updated per job 1000
বিজ্ঞাপন নির্বাচন Maximum number of buyers টিবিডি
Maximum number of CAs per buyer টিবিডি
Maximum number of ads in an auction টিবিডি
Initial connection timeout 5 সেকেন্ড
Connection read timeout 5 সেকেন্ড
Maximum execution time of overall AdSelection 10 সেকেন্ড
Maximum execution time of bidding per CA in AdSelection 5 second
Maximum execution time of scoring in AdSelection 5 second
Maximum execution time for per buyer in AdSelection টিবিডি
Maximum size of ad selection/seller/per buyer signals টিবিডি
Maximum size of seller/buyer scripts টিবিডি
Maximum call rate for selectAds 1 QPS
Impression reporting Minimum time before removing ad selection from persistence 24 ঘন্টা
Maximum number of storage ad selections টিবিডি
Maximum size of reporting output URL টিবিডি
Maximum time for impression reporting টিবিডি
Maximum number of retries for notification calls টিবিডি
সংযোগের সময়সীমা শেষ 5 সেকেন্ড
Maximum overall execution time for reportImpression 2 সেকেন্ড
Maximum call rate for reportImpressions 1 QPS
ইভেন্ট রিপোর্টিং Maximum number of beacons per buyer per auction 10

Maximum number of beacons per seller per auction

10

Maximum size of event key

40 বাইট

Maximum size of event data

64KB

বিজ্ঞাপন Maximum size of ad list 10 KB shared by all AdData in a single CA for contextual
ইউআরএল Maximum length of any URL string taken as input টিবিডি
জাভাস্ক্রিপ্ট Maximum execution time 1 second for bidding and scoring for impression reporting
Maximum memory used 10 MB

বাগ এবং সমস্যা রিপোর্ট করুন

Your feedback is a crucial part of the Privacy Sandbox on Android! Let us know of any issues you find or ideas for improving Privacy Sandbox on Android.

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}