מדריך למפתחים בנושא Protected Audience API

כשקוראים את התיעוד של ארגז החול לפרטיות ב-Android, משתמשים בלחצן תצוגה מקדימה למפתחים או בטא כדי לבחור את גרסת התוכנית שאיתה עובדים, כי ההוראות עשויות להשתנות.


Protected Audience API ב-Android (לשעבר FLEDGE) כולל את Custom Audience API ואת Ad Selection API. פלטפורמות של פרסום דיגיטלי ומפרסמים יכולים להשתמש בממשקי ה-API האלה כדי להציג מודעות מותאמות אישית על סמך אינטראקציות קודמות באפליקציה, מה שמגביל את השיתוף של המזהים בין האפליקציות ומגביר את השיתוף של פרטי האינטראקציה של המשתמשים עם צדדים שלישיים.

Custom Audience API מתמקד בהפשטה של 'קהל בהתאמה אישית', שמייצג קבוצה של משתמשים עם כוונות משותפות. מפרסם יכול לרשום משתמש בקהל בהתאמה אישית ולשייך אליו מודעות רלוונטיות. המידע הזה מאוחסן באופן מקומי ואפשר להשתמש בו כדי לעדכן את הצעות המחיר של המפרסמים, את סינון המודעות ואת הצגת המודעות.

Ad Selection API מספק מסגרת שמאפשרת למפתחים מרובים להפעיל מכרז מקומי לקהל מותאם אישית. כדי לעשות זאת, המערכת מביאה בחשבון מודעות רלוונטיות שמשויכות לקהל המותאם אישית, ומבצעת עיבוד נוסף של מודעות שפלטפורמת טכנולוגיית הפרסום מחזירה למכשיר.

פלטפורמות טכנולוגיית הפרסום יכולות לשלב את ממשקי ה-API האלה כדי להטמיע רימרקטינג שמגן על פרטיות המשתמשים. בגרסאות עתידיות אנחנו מתכננים להוסיף תמיכה בתרחישים נוספים, כולל מודעות להתקנת אפליקציה. מידע נוסף על Protected Audience API ב-Android זמין בהצעת העיצוב.

במדריך הזה מוסבר איך להשתמש ב-Protected Audience API ב-Android כדי לבצע את הפעולות הבאות:

  1. ניהול קהלים בהתאמה אישית
  2. הגדרה והפעלה של בחירת מודעות במכשיר
  3. דיווח על חשיפות של מודעות

לפני שמתחילים

לפני שמתחילים, צריך לבצע את הפעולות הבאות:

  1. מגדירים את סביבת הפיתוח לארגז החול לפרטיות ב-Android.
  2. מתקינים תמונת מערכת במכשיר נתמך או מגדירים אמולטור שכולל תמיכה בארגז החול לפרטיות ב-Android.
  3. בטרמינל, מפעילים את הגישה ל-Protected Audience API (מושבת כברירת מחדל) באמצעות פקודת adb הבאה.

      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. ברירת המחדל של Ad Selection API היא לאכוף מגבלות על נפח הזיכרון המקסימלי שסקריפט של דיווח על מכרזים או חשיפות יכול להקצות. לתכונת מגבלת הזיכרון נדרשת WebView גרסה 105.0.5195.58 ואילך. הפלטפורמה אוכפת בדיקת גרסה, וקריאות לממשקי ה-API selectAds ו-reportImpression נכשלות אם התנאי הזה לא מתקיים. יש שתי שיטות להגדיר:

    • אפשרות 1: מריצים את פקודת adb הבאה כדי להשבית את הבדיקה:

      adb device_config put fledge_js_isolate_enforce_max_heap_size false
      
    • אפשרות 2: מתקינים את WebView Beta מחנות Google Play. הערך הזה צריך להיות שווה לגרסה שצוינה קודם או גבוה ממנה.

הצטרפות לקהל בהתאמה אישית

קהל בהתאמה אישית מייצג קבוצה של משתמשים עם כוונות או תחומי עניין משותפים, כפי שהחליטה אפליקציית המפרסם. אפליקציה או ערכת SDK עשויות להשתמש בקהל בהתאמה אישית כדי לציין קהל מסוים, למשל משתמש שהשאיר פריטים בעגלת קניות. כדי ליצור קהל בהתאמה אישית או להצטרף אליו באופן אסינכרוני, מבצעים את הפעולות הבאות:

  1. מאתחלים את האובייקט CustomAudienceManager.
  2. כדי ליצור אובייקט CustomAudience, מציינים פרמטרים מרכזיים כמו החבילה של הקונה ושם רלוונטי. לאחר מכן, מאתחלים את האובייקט JoinCustomAudienceRequest עם האובייקט CustomAudience.
  3. קוראים לפונקציה joinCustomAudience() האסינכרונית עם האובייקט JoinCustomAudienceRequest והאובייקטים הרלוונטיים Executor ו-OutcomeReceiver.

Kotlin

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)

Java

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: שם או מזהה שרירותיים של הקהל בהתאמה אישית.

קריאה חוזרת של joinCustomAudience() באמצעות מופע אחר של CustomAudience מעדכנת את כל הפרמטרים הקיימים של CustomAudience עם פרמטרים תואמים owner, buyer ו-name. כדי לשמור על הפרטיות, התוצאה של ה-API לא מבחינה בין 'creation' ל-'update'.

בנוסף, צריך ליצור את CustomAudience עם הפרמטרים הנדרשים הבאים:

  • כתובת URL לעדכון יומי: כתובת URL מסוג HTTPS שמתבצעת אליה שאילתה מדי יום ברקע כדי לעדכן את אותות הבידינג של משתמשים בקהל מותאם אישית, את נתוני הבידינג המהימנים ולעבד כתובות URL ומטא-נתונים של מודעות.
  • כתובת URL של לוגיקת בידינג: כתובת URL מסוג HTTPS נשלחת שאילתה במהלך בחירת המודעה כדי לאחזר את לוגיקת הבידינג ב-JavaScript של הקונה. חתימות הפונקציות הנדרשות מפורטות בקוד ה-JavaScript הזה.
  • Ad Render IDs: מזהה שרירותי שהוגדר על ידי טכנולוגיית הפרסום של הקונה. זהו אופטימיזציה ליצירת עומס התועלת (payload) ל-B&A.

הפרמטרים האופציונליים לאובייקט CustomAudience יכולים לכלול:

  • מועד ההפעלה: קהל בהתאמה אישית יכול להשתתף בבחירת מודעות ובעדכונים יומיים רק לאחר מועד ההפעלה שלו. לדוגמה, אפשר להשתמש באפשרות הזו כדי לעורר עניין בקרב משתמשים שהפסיקו להשתמש באפליקציה.
  • מועד תפוגה: מועד עתידי שבו הקהל המותאם אישית יוסר מהמכשיר.
  • אותות לבידינג של משתמשים: מחרוזת JSON שמכילה אותות של המשתמשים, כמו הלוקאל המועדף על המשתמש, ש-JavaScript של הקונה משתמש בלוגיקת הבידינג של הקונה כדי ליצור הצעות מחיר בתהליך בחירת המודעה. הפורמט הזה עוזר לפלטפורמות של טכנולוגיות פרסום לעשות שימוש חוזר בקוד בפלטפורמות שונות, ומקל על השימוש בפונקציות JavaScript.
  • נתוני בידינג מהימנים: כתובת URL מסוג HTTPS ורשימת מחרוזות שנעשה בהן שימוש בתהליך בחירת המודעות, שמאחזרות אותות בידינג משירות מהימן של מפתח/ערך.
  • Ads: רשימה של אובייקטים מסוג AdData שתואמים למודעות שמשתתפות בבחירת המודעות. כל אובייקט AdData מורכב מ:
    • כתובת URL לעיבוד: כתובת URL מסוג HTTPS שמופיעה בשאילתה לצורך עיבוד המודעה הסופית.
    • מטא-נתונים: אובייקט JSON שעבר סריאליזציה למחרוזת שמכילה את המידע שמתאים ללוגיקת הבידינג של הקונים בתהליך בחירת המודעה.
    • מסנני מודעות: סיווג שמכיל את כל המידע הנדרש לסינון מודעות להתקנת אפליקציות ולהגדרת מכסות תדירות במהלך בחירת המודעות.

דוגמה ליצירת אובייקט CustomAudience:

Kotlin

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

Java

// 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() משתמשת באובייקט OutcomeReceiver כדי לסמן את התוצאה של קריאת ה-API.

  • הקריאה החוזרת onResult() מציינת שהקהל בהתאמה אישית נוצר או עודכן בהצלחה.
  • קריאת החזרה (callback) של onError() מציינת שני תנאים אפשריים.

דוגמה לטיפול בתוצאה של joinCustomAudience():

Kotlin

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

Java

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. הפעלת LeaveCustomAudienceRequest עם הערכים buyer ו-name של הקהל בהתאמה אישית. מידע נוסף על שדות הקלט האלה זמין במאמר הצטרפות לקהל מותאם אישית.
  3. קוראים ל-method האסינכרוני leaveCustomAudience() עם האובייקט LeaveCustomAudienceRequest והאובייקטים הרלוונטיים Executor ו-OutcomeReceiver.

Kotlin

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)

Java

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. כדי להגן על הפרטיות, תוצאת השגיאה לא מבחינה בין שגיאות פנימיות לארגומנטים לא חוקיים. הקריאה החוזרת (callback) של onResult() מתבצעת בסיום הקריאה ל-API, גם אם הוסר בהצלחה קהל מותאם אישית תואם וגם אם לא.

הרצת הבחירה של המודעות

כדי להשתמש ב-Protected Audience API לבחירת מודעות, צריך לקרוא ל-method‏ selectAds():

  1. מאתחלים אובייקט AdSelectionManager.
  2. בונים אובייקט AdSelectionConfig.
  3. קוראים ל-method האסינכרוני selectAds() עם האובייקט AdSelectionConfig והאובייקטים הרלוונטיים Executor ו-OutcomeReceiver.

Kotlin

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
)

Java

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, שבו צריך לציין את הפרמטרים הנדרשים הבאים:

  • Seller: מזהה של רשת המודעות של המוכר שמפעילה את בחירת המודעה.
  • כתובת URL של לוגיקה של החלטה: כתובת URL מסוג HTTPS שמופיעה בשאילתה כדי לקבל את הלוגיקה של JavaScript של רשת המודעות של המוכר.
    • כתובת URL מסוג HTTPS: נשלחת שאילתה כדי לקבל את הלוגיקה של JavaScript של רשת המודעות של המוכר. חתימות הפונקציות הנדרשות
    • URI שנוצר מראש: שתואם לפורמט הבחירה של מודעות ב-FLEDGE. IllegalArgumentException יזרק אם יועבר URI מוגדר מראש או לא נתמך או בצורה שגויה.
  • קונים של קהלים בהתאמה אישית: רשימה מלאה של מזהים של רשתות המודעות של קונים שמורשים על ידי בית העסק להשתתף בתהליך בחירת המודעות. מזהי הקונים האלה תואמים ל-CustomAudience.getBuyer() מהקהלים בהתאמה אישית שמשתתפים.

אפשר לציין את הפרמטרים הבאים כדי להתאים אישית את בחירת המודעות:

  • אותות לבחירת מודעות: אובייקט JSON שעבר סריאליזציה למחרוזת, ומכיל אותות לצריכה על ידי ה-JavaScript של לוגיקת הבידינג של הקונים, שאוחזר מ-CustomAudience.getBiddingLogicUrl().
  • אותות של מוכרים: אובייקט JSON שעבר סריאליזציה למחרוזת, ומכיל אותות שמנוצלים על ידי לוגיקת ההחלטות של JavaScript של המוכר שאוחזרה מ-AdSelectionConfig.getDecisionLogicUrl().
  • לפי אותות של קונים: מפה של אובייקטי JSON, שעבר סריאליזציה למחרוזות, שמכילה אותות לשימוש בלוגיקה של בידינג ב-JavaScript של קונים ספציפיים, שאוחזרו מ-CustomAudience.getBiddingLogicUrl(). האותות מזוהים לפי השדות של הקונים בקהלים המותאמים אישית שמשתתפים.
  • מודעות לפי הקשר: אוסף של שילובים אפשריים להצגת מודעות, שנאספים ישירות מהקונים במהלך מכרז שמתקיים מחוץ למכרז של Protected Audience API.

אחרי שבוחרים מודעה, התוצאות, הצעות המחיר והאותות נשמרים באופן פנימי לצורך דיווח. פונקציית הקריאה החוזרת OutcomeReceiver.onResult() מחזירה AdSelectionOutcome שמכיל את הפרטים הבאים:

  • כתובת URL לעיבוד של המודעה הזוכה, שהתקבלה מהכתובת AdData.getRenderUrl().
  • מזהה ייחודי של בחירת מודעות למשתמש במכשיר. המזהה הזה משמש לדיווח על החשיפה של המודעה.

אם לא ניתן להשלים את בחירת המודעה מסיבות כמו ארגומנטים לא חוקיים, תפוגות זמן או צריכת משאבים מוגזמת, פונקציית ה-call back של OutcomeReceiver.onError() מספקת AdServicesException עם ההתנהגויות הבאות:

  • אם בחירת המודעה מופעלת עם ארגומנטים לא חוקיים, הערך IllegalArgumentException יופיע ב-AdServicesException כגורם.
  • כל שאר השגיאות מקבלות AdServicesException עם IllegalStateException כהסיבה.

מודעות לפי הקשר

Protected Audience יכול לשלב מודעות לפי הקשר במכרז מוגן. צריך לבחור מודעות לפי הקשר בשרת טכנולוגיית הפרסום ולהחזיר אותן למכשיר מחוץ לממשקי ה-API של Protected Audience API. לאחר מכן אפשר לכלול מודעות לפי הקשר במכרז באמצעות AdSelectionConfig. בשלב הזה הן פועלות באותו אופן כמו מודעות במכשיר, כולל הכשירות לסינון מודעות שליליות. בסיום המכרז של הקהל המוגן, צריך להפעיל את reportImpression(). הפעולה הזו מפעילה reportWin() במודעה ההקשרית הזוכה, באותו דפוס כמו דיווח על חשיפות, כדי לקבל את המודעה המנצחת במכשיר. כל מודעה לפי הקשר צריכה קונה, הצעת מחיר, קישור ללוגיקת הדיווח, כתובת URL לעיבוד (render) ומטא-נתונים של מודעה.

כדי לפרוס מודעות לפי הקשר באפליקציה, אפליקציית היעד צריכה ליצור אובייקט ContextualAds:

Kotlin

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

Java

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

לאחר מכן אפשר להעביר את אובייקט ContextualAds שמתקבל כשיוצרים את ה-AdSelectionConfig:

Kotlin

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

Java

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

סינון מודעות להתקנת אפליקציות

סינון של מודעות להתקנת אפליקציה עוזר לכם לסנן מודעות להתקנת אפליקציות שכבר מותקנות במכשיר.

השלב הראשון בתהליך הזה הוא להגדיר לאילו מפרסמים תהיה אפשרות לסנן לפי החבילה המותקנת. זה צריך להתרחש באפליקציה שאליה רוצים לטרגט מודעה.

Kotlin

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

Java

//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 עם מידע לגבי המודעות שקשורות לאפליקציות שהם רוצים לסנן:

Kotlin

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

Java

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

בעלי תוכן דיגיטלי בצד הביקוש יכולים גם להגדיר AdFilter למודעות שנמצאות בתוך הקהלים בהתאמה אישית שלהם.

אפשר גם להעביר את AdFilters בנקודה שבה יוצרים אובייקט AdData חדש:

Kotlin

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

Java

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

סינון של מכסת תדירות

סינון לפי מכסת תדירות מאפשר לטכנאי הפרסום להגביל את מספר הפעמים שהמודעה תוצג. סינון לפי מכסת תדירות מפחית את חשיפת המודעות ומבצע אופטימיזציה של בחירת המודעות החלופיות בקמפיין מודעות נתון.

במסנן של מכסת התדירות יש שני רכיבים עיקריים: סוג האירוע של המודעה והמפתח של מונה המודעות. אלה הסוגים הזמינים של אירועי מודעות:

  • זכייה: אירוע זכייה מציין שהמודעה זכתה במכרז. אירועי Win מתעדכנים באופן אוטומטי על ידי Protected Audience API, והמפתח לא יכול להפעיל אותם ישירות. נתוני הזכייה מוצגים רק למודעות בתוך קהל מותאם אישית מסוים.
  • חשיפת מודעה: בנפרד מ-reportImpression, מבצע קריאה במכשיר (SSP או MMP) משתמש ב-updateAdCounterHistogram() כדי להפעיל אירועי חשיפת מודעות בנקודה בקוד שבחר. אירועי חשיפות גלויים לכל המודעות ששייכות ל-DSP נתון, והם לא מוגבלים למודעות באותו קהל מותאם אישית.
  • View: מבצע הקריאה במכשיר (SSP או MMP) מפעיל את האירוע בנקודה בקוד שהוא בוחר באמצעות קריאה ל-updateAdCounterHistogram(). אירועי צפייה גלויים לכל המודעות ששייכות ל-DSP נתון, ולא רק למודעות באותו קהל מותאם אישית.
  • קליק: האירוע מופעל על ידי מבצע הקריאה במכשיר (SSP או MMP) בנקודה בקוד שבחר באמצעות קריאה ל-updateAdCounterHistogram(). אירועי קליקים גלויים לכל המודעות ששייכות ל-DSP נתון, ולא רק למודעות באותו קהל מותאם אישית.

באפליקציה של בעל האפליקציה, מערכת SSP או MMP שנמצאת במכשיר מפעילה אירועי מודעות. כשקוראים לפונקציה updateAdCounterHistogram(), המונה של מסנן של מכסת התדירות גדל כך שבמכרזים עתידיים יהיה מידע עדכני על החשיפה של המשתמש למודעה מסוימת. סוגי האירועים של המודעות לא מקושרים בכוח לפעולת המשתמש המתאימה, והם מוצגים כהנחיות כדי לעזור למתקשרים לבנות את מערכת האירועים שלהם. כדי להגדיל את מספר הספירות של המודעות בזמן האירוע, הגורם במכשיר מספק את המזהה של בחירת המודעות שזכתה במכרז.

מפתחות של ספירת מודעות הם מספרים שלמים בסימן של 32 ביט שהוקצו על ידי טכנולוגיית הפרסום של הקונה, והם תואמים לקבוצה נתונה של מודעות כפי שהוגדרה על ידי ה-DSP. מכיוון שמפתחות של מודעות נספרות מוגבלים רק למודעות ששייכות ל-DSP נתון, אפשר לבחור את המפתחות האלה בלי חפיפה לתרשים התרשימים של טכנולוגיית פרסום אחרת. מפתחות של מודעות נספרות משמשים להגדלת מזהי DSP ספציפיים במודעות של DSP או בתוך קהל מותאם אישית נתון, כדי לסנן מודעות ממעשי מכרז עתידיים.

אפשר להשתמש במפתחות מונים כדי לתת עדיפות למודעות שיש סיכוי גבוה יותר שהן יעניינו משתמש נתון, על סמך האינטראקציות שלו עם מודעות אחרות מטכנולוגיית פרסום של קונה נתון. לדוגמה, מודעה שקיבלה רמת התעניינות גבוהה במכרזים על מודעות, צפיות וקליקים, מייצגת נקודה של נתונים משוערים. כדי להמחיש את הנקודה הזו: מודעה למקלות גולף ליד שמאל עשויה להצביע על כך שהמשתמש לא יהיה מעוניין במקלות ליד ימין. מסנן של מכסת תדירות שמוגדר למפתח מונה שהוקצה למודעות בצד שמאל יכול לסנן מודעות של מועדונים ימניים.

כדי להשתמש במכסת תדירות במכרז, קודם צריך ליצור אובייקטים מסוג KeyedFrequencyCap כפי שמוצג כאן:

Kotlin

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

Java

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

Kotlin

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

Java

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

כשהאובייקט AdFilters מאוכלס במסננים של מכסת תדירות, אפשר להעביר אותו בזמן יצירת הקהל בהתאמה אישית:

Kotlin

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

Java

// 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 יכולה להפעיל את אירועי הקליק, הצפייה או החשיפות הנדרשים.

Kotlin

val callerAdTech: AdTechIdentifier = mAdSelectionConfig.getSeller()

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

Java

AdTechIdentifier callerAdTech = mAdSelectionConfig.getSeller();

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

מודעות שחורגות ממגבלות הסינון של מכסת התדירות המוגדרת מראש מסוננות מהמכרז. הסינון מתבצע לפני שהלוגיקה של הבידינג מתבצעת במכרזים במכשיר, ותוך כדי יצירת עומס הנתונים במכרזים של שירותי בידינג ומכרזים. ערכת הכלים הזו מעניקה לטכנאי הפרסום גמישות להשתמש באינטראקציות בין המשתמשים לבין המודעות בתוך הקהלים המותאמים אישית שלהם, כדי למקד את הטירגוט של המודעות תוך צמצום של חשיפת יתר למודעות.

סינון מודעות לפי הקשר ללא קריאות לרשת

אם אין ביקוש לרימרקטינג במכשיר, תוכלו לבחור מודעות לפי הקשר ללא שיחות רשת. כשמשתמשים במזהי URI שנוצרו מראש וברשימה של מודעות לפי הקשר עם הצעות מחיר, הפלטפורמה יכולה לדלג על אחזור הלוגיקה של הבידינג, אותות הבידינג ואותות הדירוג. הפלטפורמה משתמשת ב-URI שנוצר מראש כדי לבחור את המודעה לפי הקשר עם הצעת המחיר הגבוהה ביותר.

כדי לשפר את זמן האחזור, טכנאי הפרסום יכולים להריץ תהליך בחירת מודעות שכולל רק מודעות לפי הקשר עם פונקציונליות של סינון מודעות, ללא קריאות לרשת. אפשר לעשות זאת באמצעות שימוש במזהי URI מוכנים מראש למתן ציונים. בקטע 'שמות ותרחישי לדוגמה של URI מובנה נתמכים' מפורטת רשימה של הטמעות של 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);
    

הרצת JavaScript לדיווח משלכם תוך שימוש במזהי URI מוכנים מראש

כיום, בפלטפורמת ארגז החול לפרטיות יש רק הטמעה בסיסית של JavaScript לדיווח, שזמינה למזהי URI מוכנים מראש. אם אתם רוצים להריץ קוד JavaScript משלכם לדיווח ועדיין להשתמש בכתובות URI מוכנות מראש לצורך בחירת מודעות עם זמן אחזור קצר, תוכלו לשנות את הערך של DecisionLogicUri בין ההפעלות של בחירת המודעות לבין ההפעלות של הדיווח.

  1. מבצעים את השלבים להפעלת בחירת מודעות למודעות לפי הקשר באמצעות כתובות URI שנוצרו מראש
  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);
    

הפעלת רשימת רשתות בתהליך בחירת הרשת

כדי להשתמש בתהליך בחירת הרשת מסוג Waterfall, צריך כמה ערכות SDK של צד שלישי (רשתות צד שלישי) שיושקו על ידי רשת תהליך בחירת הרשת (Mediation) של SDK מצד ראשון. תהליך בחירת הרשת ב-Waterfall מתבצע באותו אופן, בין שהמכרז התקיים במכשיר ובין שהוא הופעל בשירותי בידינג ומכרזים (B&A).

רשתות צד שלישי

רשתות צד שלישי צריכות לספק מתאם שמאפשר לרשת בחירת הרשת להפעיל את השיטות הנדרשות להפעלת מכרז:

  • הפעלת בחירת מודעות
  • דיווח על חשיפות

דוגמה למתאם רשתות לבחירת רשת:

Kotlin

class NetworkAdaptor {
    private val adSelectionManager : AdSelectionManager

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

    fun selectAds() {...}

    fun reportImpressions() {...}
}

Java

class NetworkAdaptor {
    AdSelectionManager adSelectionManager;

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

    public void selectAds() {...}

    public void reportImpressions() {...}
}

לכל SDK יש מנהלים ולקוחות משלו של שירות בחירת המודעות, והטמעה משלו של selectAds ו-reportImpressions. ספקי SDK יכולים לעיין בקטעים על הפעלת בחירת מודעות במכרזים במכשיר או בהסבר על מכרזים של B&A. פועלים לפי ההוראות לדיווח על חשיפות של מודעות (בהתאם לדיווח על חשיפות ב-SSP יחיד).

רשת בתהליך בחירת הרשת (Mediation)

בדומה לרשתות צד שלישי, רשתות לבחירת רשת צריכות הטמעות של selectAds ושל reportImpression. מידע נוסף זמין בקטעים בנושא הפעלת בחירת מודעות ובנושא דיווח על חשיפות של מודעות.

רשתות בתהליך בחירת הרשת אחראיות להפעלת השרשרת לבחירת רשת ולמיקום שלהם בשרשרת לבחירת רשת. בקטע הבא מוסבר איך מגדירים ומפעילים את התהליך הזה.

אחזור של שרשרת תהליך בחירת הרשת וערכי סף תחתון להצעות מחיר

הרשת בתהליך בחירת הרשת אחראית לאחזור המודעות לפי הקשר, שרשרת לבחירת רשת וערכי הסף להצעות מחיר של רשתות צד שלישי (צד ג') מצב כזה יכול לקרות בבקשה לאחזור מודעות לפי הקשר שהופעלו על ידי הרשת שבה נערך תהליך בחירת הרשת. שרשרת בחירת הרשת קובעת איך לעבור על רשתות הצד השלישי, וניתן להעביר את סכומי מינימום הצעות המחיר לתהליך המכרז כ-adSelectionSignals.

מיקום מודעה ברשת בשרשרת לבחירת רשת

ערכת SDK של תהליך בחירת הרשת יכולה למקם את עצמה בשרשרת לבחירת רשת על סמך העלות בפועל לאלף חשיפות (eCPM) בזמן אמת של הצעות מחיר מאינטראקציה ישירה (First-Party). ב-Protected Audience API, הצעות המחיר למודעות הן אטומות. ערכת ה-SDK של תהליך בחירת הרשת (Mediation) צריכה להשתמש ב-AdSelectionFromOutcomesConfig כדי להשוות בין הצעת המחיר של מודעה מאינטראקציה ישירה לבין הסף המינימלי להצעות המחיר של הרשת הבאה ברשת של צד שלישי. אם הצעת המחיר מאינטראקציה ישירה גבוהה מהסף התחתון להצעת המחיר, המשמעות היא שה-SDK של תהליך בחירת הרשת (Mediation) ממוקם לפני הרשת של הצד השלישי.

הרצת הבחירה של המודעות

כדי לאחזר אפשרות להצגת מודעות מאינטראקציה ישירה, הרשת בתהליך בחירת הרשת יכולה להפעיל מכרז במכשיר לפי השלבים המפורטים בקטע הפעלת בחירת מודעות. הפעולה הזו יוצרת מודעת 1P מועמדת, הצעת מחיר ו-AdSelectionId שמשמש בתהליך בחירת הרשת.

יצירת AdSelectionFromOutcomesConfig

ה-AdSelectionFromOutcomesConfig מאפשר לרשת בחירת הרשתות להעביר רשימה של AdSelectionIds (תוצאות ממעשי מכרז קודמים), אותות לבחירת מודעות ומזהה URI לאחזור JavaScript שבוחר מודעה מבין כמה מועמדות. רשימת AdSelectionIds יחד עם הצעות המחיר שלהן והאותות מועברים ל-JavaScript, שיכול להחזיר אחד מה-AdSelectionIds אם הוא יעבור את סף הצעת המחיר, או אף אחד אם שרשרת בחירת הרשת תמשיך לפעול.

רשתות בחירת הרשת יוצרות את הערך AdSelectionFromOutcomesConfig באמצעות הערך AdSelectionId של הצד ה-1 מהקטע הקודם, ואת סכום מינימום הצעת המחיר של רשת הצד השלישי שנלקחת בחשבון. צריך ליצור AdSelectionFromOutcomesConfig חדש לכל שלב בשרשרת בחירת הרשת.

Kotlin

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

Java

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

כדי לשנות את ה-method selectAds() ברשימת הרשתות בתהליך בחירת הרשת צריך להזין קלט AdSelectionFromOutcomesConfig, שבו צריך לציין את הפרמטרים הנדרשים הבאים:

  • בית עסק: המזהה של רשת המודעות של בית העסק שממנה מתחיל בחירת המודעה.
  • AdSelectionIds: רשימה יחידה של נתונים מסוג selectAds() להפעלת מודעה מאינטראקציה ישירה.
  • אותות לבחירת מודעות: אובייקט JSON שעבר סריאליזציה למחרוזת, ומכיל את האותות לשימוש הלוגיקה של הבידינג של הקונים. במקרה כזה, כוללים את הסף התחתון להצעת המחיר שאוחזרה לרשת הצד השלישי הנתונה.
  • Selection Logic URI: כתובת URL מסוג HTTPS שמופיעה בשאילתה במהלך בחירת המודעה כדי לאחזר את ה-JavaScript של רשת בחירת הרשתות לצורך בחירת המודעה הזוכה. כאן מפורטות חתימות הפונקציות הנדרשות ב-JavaScript. קוד ה-JavaScript אמור להחזיר את מודעת הצד השלישי אם הצעת המחיר גבוהה מהסף התחתון להצעת המחיר, או אם היא מחזירה את הערך null באופן אחר. כך ה-SDK של תהליך בחירת הרשת יכול לקצר את שרשרת תהליך בחירת הרשת כשנמצאת רשת מנצחת.

אחרי שיצרתם את AdSelectionOutcomesConfig, קוראים ל-method selectAds() של הרשת מצד שלישי הראשונה בשרשרת.

Kotlin

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)

Java

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. מריצים את הבחירה של מודעות מצד ראשון.
  2. הצגת איטרציה לאורך השרשרת לבחירת רשת. בכל רשת של צד שלישי, מבצעים את הפעולות הבאות:
    1. גרסה AdSelectionFromOutcomeConfig, כולל outcomeId של הצד הראשון וסכום מינימום להצעת המחיר של ה-SDK של הצד השלישי.
    2. קוראים לפונקציה selectAds() עם ההגדרות מהשלב הקודם.
    3. אם לא מופיעה תוצאה ריקה, מחזירים את המודעה.
    4. קוראים לשיטה selectAds() של מתאם הרשת הנוכחי של ה-SDK. אם התוצאה לא ריקה, מחזירים את המודעה.
  3. אם לא נמצא מנצח ברשת, מחזירים את המודעה מאינטראקציה ישירה.

Kotlin

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

Java

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 שמפעילים מכרז יחיד, עליכם לפעול לפי ההוראות שבקטע הזה. אם אתם מתכוונים להטמיע את רשימת הרשתות בתהליך בחירת הרשת, בצעו את השלבים המפורטים בקטע דיווח על חשיפות של תהליך בחירת הרשת ב-Waterfall.

דיווח על חשיפות ב-SSP יחיד

אחרי שבוחרים מודעה מנצחת בתהליך הבחירה של המודעות, אפשר לדווח על החשיפות חזרה לפלטפורמות בצד הקונה ובצד המוכר שמשתתפות בתוכנית באמצעות השיטה AdSelectionManager.reportImpression(). כך מדווחים על חשיפה של מודעה:

  1. מאתחלים אובייקט AdSelectionManager.
  2. יוצרים אובייקט ReportImpressionRequest עם מזהה בחירת המודעה.
  3. קוראים ל-method reportImpression() האסינכרוני עם האובייקט ReportImpressionRequest והאובייקטים הרלוונטיים Executor ו-OutcomeReceiver.

Java

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

Kotlin

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 עם הפרמטרים הנדרשים הבאים:

  • מזהה בחירת מודעה: מזהה ייחודי למשתמש במכשיר שמזהה בחירת מודעה מוצלחת.
  • Ad selection config: אותה הגדרה ששימשה בקריאה ל-selectAds() שמזוהה לפי מזהה בחירת המודעות שצוין.

השיטה האסינכרונית reportImpression() משתמשת באובייקט OutcomeReceiver כדי לסמן את התוצאה של קריאת ה-API.

  • הקריאה החוזרת (callback) של onResult() מציינת אם נוצרו כתובות URL לדיווח על חשיפות והבקשה תוזמנה.
  • בקריאה החוזרת onError() מצוינים התנאים האפשריים הבאים:
    • אם הקריאה מופעלת עם ארגומנט קלט לא תקין, הערך של AdServicesException יהיה IllegalArgumentException.
    • כל שאר השגיאות מקבלות AdServicesException עם IllegalStateException כהסיבה.

דיווח על חשיפות בתהליך בחירת הרשת (Mediation) ב-Waterfall

ערכת ה-SDK לבחירת הרשת צריכה לעקוב אחרי ערכת ה-SDK הזוכה כדי להפעיל את תהליכי הדיווח שלה. ערכות ה-SDK שמשתתפות בשרשרת לבחירת רשת צריכות לספק שיטה שבה המגשר יכול להפעיל את תהליך הדיווח שלו. כדי להטמיע דיווח משלכם ב-SDK שמשתתף במכרזים שמנוהלים על ידי צד שלישי, תוכלו לפעול לפי השלבים שלמעלה.

ספקי SSP יכולים להשתמש בדוגמה הזו של קוד ה-SDK של צד שלישי כאב-טיפוס כדי להצטרף לתהליכי בחירת הרשת:

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

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

נקודות קצה לדיווח על חשיפות

ה-Reporting API של הדוח מנפיק בקשות HTTPS GET לנקודות קצה (endpoint) שהפלטפורמה בצד המוכר והפלטפורמה הזוכה בצד הקונה:

נקודת הקצה (endpoint) של הפלטפורמה בצד הקונה:

  • ה-API משתמש בכתובת ה-URL של לוגיקת הבידינג שצוינה בקהל המותאם אישית כדי לאחזר את ה-JavaScript שסופק על ידי הקונה, שכולל לוגיקה להחזרת כתובת URL לדיווח על חשיפות.
  • מפעילים את פונקציית ה-JavaScript‏ reportWin(), שאמורה להחזיר את כתובת ה-URL של הדיווח על החשיפות של הקונה.

נקודת הקצה (endpoint) של הפלטפורמה בצד המוכר:

  • משתמשים בכתובת ה-URL של לוגיקה של החלטה שצוינה באובייקט AdSelectionConfig כדי לאחזר את ה-JavaScript של לוגיקה של החלטה של המוכר.
  • מפעילים את פונקציית ה-JavaScript reportResult(), שאמורה להחזיר את כתובת ה-URL לדיווח על חשיפות של אתר המכירה.

דיווח על שירותי בידינג ומכרזים

מכרז שמופעל בשירותי בידינג ומכרזים יכלול את כל פרטי הדיווח הנדרשים, כולל כתובות URL שנוצרו לדיווח על אינטראקציות עם מודעות, שכלולות בתגובה המוצפנת מהמכרז בצד השרת. כשהתגובה מפענחת, כתובות ה-URL המתאימות נרשמות בפלטפורמה, כך שדיווח על מודעות וחשיפות מתבצע לפי אותם השלבים שמפורטים למעלה.

הדיווח על חשיפות במאמץ הטוב ביותר

השיטה reportImpression() נועדה לספק את הדיווח הטוב ביותר האפשרי.

דיווח על אינטראקציות עם מודעות

התכונה 'קהל מוגן' מספקת תמיכה בדיווח על אינטראקציות מפורטות יותר עם מודעה שמוצגת. האינטראקציות האלה יכולות לכלול אירועים כמו משך הצפייה, קליקים, מעברים עם העכבר מעל המודעות או כל מדד שימושי אחר שאפשר לאסוף. התהליך של קבלת הדוחות האלה כולל שני שלבים. קודם כול, הקונים והמוכרים חייבים להירשם כדי לקבל את הדוחות האלה ב-JavaScript לדיווח. לאחר מכן, הלקוח יצטרך לדווח על האירועים האלה.

הרשמה לקבלת אירועי אינטראקציה

ההרשמה לאירועי אינטראקציה מתבצעת בפונקציות ה-JavaScript reportWin() של הקונה ובפונקציות JavaScript של reportResult() באמצעות פונקציית JavaScript שמסופקת על ידי הפלטפורמה: registerAdBeacon. כדי להירשם לקבלת דוח אירועים, צריך פשוט לקרוא לפונקציית ה-JavaScript של הפלטפורמה מ-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. קוראים לשיטה reportInteraction() האסינכרונית עם האובייקט request ואת האובייקטים הרלוונטיים Executor ו-OutcomeReceiver.
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 שהוחזר בעבר.
  • מפתח אינטראקציה: מפתח מחרוזת שהלקוח מגדיר ומתאר את הפעולה שעליה מדווחים. המפתח הזה צריך להיות זהה למפתח שרשום על ידי המוכר או הקונה בפונקציות ה-JavaScript לדיווח.
  • נתוני אינטראקציה: מחרוזת שמכילה נתונים שייכללו בדוח האירועים, ויש להעביר אותם ב-POST חזרה לשרתי הדיווח.
  • יעדי דיווח: מסכה קטנה שמציינת אם האירועים צריכים לדווח לקונה, למפיץ או לשניהם. הדגלים האלה מסופקים על ידי הפלטפורמה, וניתן ליצור את מסכת היעד הסופית באמצעות פעולות בייט-בייט. כדי לדווח ליעד אחד, אפשר להשתמש בדגל שסופק ישירות על ידי הפלטפורמה. כדי לדווח לכמה יעדים, אפשר להשתמש ב-OR בייטבי (|) כדי לשלב בין ערכי הדגלים.

השיטה האסינכרונית reportInteraction() משתמשת באובייקט OutcomeReceiver כדי לאותת את התוצאה של הקריאה ל-API.

  • קריאת החזרה (callback) של onResult() מציינת שהקריאה לדיווח על אינטראקציה תקינה.
  • בקריאה החוזרת onError() מצוינים התנאים האפשריים הבאים:
    • אם הקריאה מתבצעת כשהאפליקציה פועלת ברקע, מוחזר IllegalStateException עם תיאור של הכישלון.
    • אם יש ויסות נתונים (throttle) של הלקוח מביצוע הקריאה ל-reportInteraction(), מוחזר LimitExceededException.
    • אם החבילה לא רשומה לקריאה לממשקי ה-API לשמירה על הפרטיות, מוחזר הערך SecurityException().
    • אם האפליקציה שמדווחת על אינטראקציות שונה מהאפליקציה שקראה ל-selectAds(), המערכת מחזירה את הערך IllegalStateException.
  • אם המשתמש לא הביע הסכמה להפעלת ממשקי ה-API של ארגז החול לפרטיות, הקריאה תיכשל ללא הודעה.

נקודות קצה לדיווח על אינטראקציות

ה-API של האינטראקציה בדוח מנפיק בקשות HTTPS POST לנקודות קצה (endpoint) של הפלטפורמה בצד המוכר והפלטפורמה המנצחת בצד הקונה. Protected Audience API יתאים בין מפתחות האינטראקציה למזהי ה-URI שהוצהרו ב-JavaScript לדיווח, וישלחו בקשת POST לכל נקודת קצה (endpoint) עבור כל אינטראקציה שמדווחת. סוג התוכן של הבקשה הוא טקסט פשוט, והגוף הוא נתוני האינטראקציה.

הדוח על האינטראקציות (המאמץ הטוב ביותר)

המטרה של reportInteraction() היא להשלים את הדיווח באמצעות HTTP POST.

עדכון יומי ברקע

כשיוצרים קהל בהתאמה אישית, האפליקציה או ה-SDK יכולים להפעיל מטא-נתונים של קהל בהתאמה אישית. בנוסף, הפלטפורמה יכולה לעדכן את החלקים הבאים של מטא-נתונים מותאמים אישית של קהלים באמצעות תהליך עדכון ברקע שמתבצע מדי יום.

  • אותות לבידינג של משתמשים
  • נתוני בידינג מהימנים
  • רשימה אחת (AdData)

התהליך הזה שולח שאילתות לכתובת ה-URL לעדכון יומי שמוגדרת בקהל המותאם אישית, וייתכן שכתובת ה-URL תחזיר תגובה בפורמט JSON.

  • תגובת ה-JSON עשויה להכיל כל אחד משדות המטא-נתונים הנתמכים שצריך לעדכן.
  • כל שדה JSON מאומת בנפרד. הלקוח מתעלם משדות בפורמט שגוי, וכתוצאה מכך לא מתבצעים עדכונים בשדה הספציפי הזה בתגובה.
  • תגובת HTTP ריקה או אובייקט JSON ריק '{}' לא מובילה לעדכונים של מטא-נתונים.
  • גודל הודעת התגובה חייב להיות מוגבל ל-10KB.
  • חובה להשתמש ב-HTTPS בכל מזהי ה-URI.
  • trusted_bidding_uri חייב לשתף את אותו ETLD+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
        },
        ...
    ]
}

JavaScript לבחירת מודעות

תהליך העבודה של בחירת המודעות מרכז את הביצוע של קוד JavaScript שסופק על ידי הקונה ועל ידי המוכר.

ה-JavaScript שסופק על ידי הקונה מאוחזר מכתובת ה-URL של לוגיקת הבידינג שצוינה בקהל המותאם אישית. קוד ה-JavaScript שמוחזר צריך לכלול את הפונקציות הבאות:

קוד JavaScript שסופק על ידי בית העסק מאוחזר מתוך כתובת ה-URL של לוגיקת ההחלטות שצוינה בפרמטר AdSelectionConfig עבור ה-API לבחירת מודעות. קוד ה-JavaScript שמוחזר צריך לכלול את הפונקציות הבאות:

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: אובייקט JSON בפורמט var ad = { 'render_url': url, 'metadata': json_metadata };
  • auction_signals, per_buyer_signals: אובייקטים מסוג JSON שצוינו באובייקט ההגדרה של המכרז
  • custom_audience_bidding_signals: אובייקט JSON שנוצר על ידי הפלטפורמה. הפורמט של אובייקט ה-JSON הזה הוא:

    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 היא מחרוזת JSON שצוינה בשדה userBiddingSignals של CustomAudience בזמן היצירה
    • trusted_bidding_signals, contextual_signals ו-user_signals הם אובייקטים של JSON. הם מועברים כאובייקטים ריקים ויתמלאו בגרסאות עתידיות. הפורמט שלהם לא נאכף על ידי הפלטפורמה, והוא מנוהל על ידי טכנולוגיית הפרסום.

תוצאה:

  • ad: זו המודעה שהצעת המחיר מתייחסת אליה. הסקריפט רשאי להחזיר עותק של המודעה שהוא קיבל עם מטא-נתונים שונים. לא צפויים שינויים במאפיין render_url של המודעה.
  • bid: ערך של float שמייצג את ערך הצעת המחיר של המודעה הזו
  • status: ערך של מספר שלם שיכול להיות:
    • 0: להרצה מוצלחת
    • 1: (או כל ערך שאינו אפס) אם אחד מאותות הקלט לא תקין. אם ערך שאינו אפס מוחזר כתוצאה מתהליך היצירה של הצעת מחיר, תהליך הבידינג יבוטל בכל מודעות ה-CA

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: יש לעיין במסמכי התיעוד בנושא generateBid
  • bid: ערך הצעת המחיר של המודעה
  • ad_selection_config: אובייקט JSON שמייצג את הפרמטר AdSelectionConfig של ה-API selectAds. הפורמט הוא:

    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 של ה-API AdSelectionConfig

  • trusted_scoring_signal: קריאה מהשדה adSelectionSignals בפרמטר AdSelectionConfig של ה-API

  • contextual_signals, user_signals: אובייקטים בפורמט JSON. הם מועברים כרגע כאובייקטים ריקים ויתמלאו בגרסאות עתידיות. הפלטפורמה לא אוכפת את הפורמט שלהם, והוא מנוהל על ידי חברת טכנולוגיית הפרסום.

  • per_buyer_signals: אובייקט JSON שנקרא מהמפה perBuyerSignal בפרמטר AdSelectionConfig של ה-API, תוך שימוש כמפתח בקונה הנוכחי של הקהל בהתאמה אישית. הערך יהיה ריק אם המפה לא מכילה רשומה של הקונה הנתון.

פלט:

  • score: ערך מספר ממשי (float) שמייצג את ערך הציון של המודעה הזו
  • status: ערך שלם שיכול להיות:
    • 0: להרצה מוצלחת
    • 1: למקרה שהערכים customAudienceSignals לא תקינים
    • 2: למקרה שהשדה AdSelectionConfig לא תקין
    • 3: אם אחד מהאותות האחרים לא תקף
    • כל ערך שאינו אפס גורם לכישלון התהליך, והערך קובע את סוג החריגה שתופעל

selectOutcome()‎

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

פרמטרים של קלט:

  • outcomes: אובייקט JSON {"id": id_string, "bid": bid_double}
  • selection_signals: אובייקטי JSON שצוינו באובייקט התצורה של המכרז

פלט:

  • status: 0 להצלחה, לא אפס לכישלון
  • result: אחת מהתוצאות שהועברו או 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: אפשר לעיין במסמכי התיעוד של scoreAds
  • render_url: כתובת ה-URL של ה-render של המודעה הזוכה
  • bid: הצעת המחיר שהוצעה למודעה שזכתה במכרז
  • contextual_signals: עיינו במסמכי התיעוד של generateBid

פלט:

  • status: 0 להצלחה ומספר שאינו אפס לכישלון
  • results: אובייקט JSON שמכיל:
    • signals_for_buyer: אובייקט JSON שמוענק לפונקציה reportWin
    • reporting_url: כתובת URL שבה הפלטפורמה משתמשת כדי להודיע על החשיפות לקונה

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: אפשר לעיין במסמכי התיעוד של scoreAd
  • signals_for_buyer: אובייקט JSON שהוחזר על ידי reportResult
  • contextual_signals, custom_audience_signals: אפשר לעיין במסמכי התיעוד עבור generateBid

פלט:

  • status: 0 להצלחה ומספר שאינו אפס לכישלון
  • results: אובייקט JSON שמכיל:
    • reporting_url: כתובת URL שבה הפלטפורמה משתמשת כדי להודיע למוכרים על החשיפות

registerAdBeacon()

function registerAdBeacon(
  beacons
)

פרמטרים של קלט:

  • beacons: אובייקט שמכיל צמדי מפתח/ערך של מפתחות אינטראקציה ומזהי URI לדיווח. הפורמט הוא:

    let beacons = {
      'interaction_key': 'reporting_uri',
      'interaction_key': 'reporting_uri',
      ...
    }
    
    • interaction_key: מחרוזת שמייצגת את האירוע. הפלטפורמה תשתמש בנתונים האלה בהמשך כדי לדווח על אינטראקציות עם אירועים כדי לחפש את ה-reporting_uri שצריך לקבל התראה. המפתח הזה צריך להתאים למה שהקונה או המוכר רושמים ולמה שהמוכר מדווח.
    • reporting_uri: URI לקבלת דוחות אירועים. הוא צריך להיות ספציפי לסוג האירוע המדווח. הוא צריך לקבל בקשת POST כדי לטפל בכל הנתונים שדווחו יחד עם האירוע.

    לדוגמה:

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

מזהי URI מוכנים מראש לבחירת מודעות

כתובות URI מוכנות מראש מאפשרות לטכנאי הפרסום להקצות פונקציות JavaScript ללוגיקה של קבלת ההחלטות לגבי בחירת מודעות בכיתות AdSelectionConfig ו-AdSelectionFromOutcomesConfig. מזהי URI מובנים לא צריכים קריאות רשת כדי להוריד את קוד ה-JavaScript התואם. טכנולוגיות הפרסום יכולות להשתמש במזהי URI שנוצרו מראש, בלי שתצטרכו להגדיר דומיין רשום לאירוח ה-JavaScript.

ה-URI שנוצר מראש נבנה בפורמט הבא:

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

הפלטפורמה של ארגז החול לפרטיות מספקת JavaScript באמצעות המידע מה-URI הזה בזמן הריצה.

IllegalArgumentException מושלכת אם:

  • אחד מהפרמטרים הנדרשים לא נמצא ב-URI
  • יש פרמטרים לא מזוהים ב-URI

תרחישים לדוגמה ושמות נתמכים של URI מוכן מראש

תרחיש לדוגמה 1: בחירת מודעות

בתרחישים לדוגמה ad-selection ו-selectAds(AdSelectionConfig) יש תמיכה במזהי URI שנוצרו מראש.

שם URI שנוצר מראש: highest-bid-wins

ה-URI המובנה הזה מספק קוד JavaScript שבוחר את המודעה עם הצעת המחיר הגבוהה ביותר אחרי הבידינג. הוא גם מספק פונקציית דיווח בסיסית לדיווח על הערכים של render_uri ו-bid של המנצח.

פרמטרים נדרשים

reportingUrl: כתובת ה-URL הבסיסית לדיווח, שהפרמטרים שלה הם render_uri ו-bid של המודעה הזוכה:

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

שימוש

אם כתובת ה-URL לדיווח הבסיסי היא https://www.ssp.com/reporting, ה-URI המוגדר מראש יהיה:

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

תרחיש לדוגמה 2: ad-selection-from-outcomes

מזהי URI שנוצרו מראש במסגרת תרחיש לדוגמה ad-selection-from-outcomes תומכים בתהליך העבודה selectAds(AdSelectionFromOutcomesConfig).

שם ה-URI המוגדר מראש: waterfall-mediation-truncation

ה-URI המובנה waterfall-mediation-truncation מספק JavaScript, שמטמיע לוגיקה של סיום תהליך בחירת הרשת ב-Waterfall שבו ה-JavaScript מחזיר מודעה מאינטראקציה ישירה אם הערך של bid גבוה מהערך bid floor או שווה לו, ובמקרה אחר הוא מחזיר מודעה null.

פרמטרים נדרשים

bidFloor: המפתח של ערך סכום המינימום להצעת המחיר שהוענק ב-getSelectionSignals(), והוא מושווה למודעה של ה-SDK לבחירת רשת.

שימוש

אם האותות לבחירת מודעות נראים כמו {"bid_floor": 10}, ה-URI שנוצר מראש שתתקבל יהיה:

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

בדיקה

כדי לעזור לכם להתחיל להשתמש ב-Protected Audience API, יצרנו אפליקציות לדוגמה ב-Kotlin וב-Java. אפשר למצוא אותן ב-GitHub.

דרישות מוקדמות

Protected Audience API מצריך JavaScript בזמן בחירת המודעות והדיווח על החשיפות. יש שתי שיטות לספק את ה-JavaScript בסביבת הבדיקה:

  • מריצים שרת עם נקודות הקצה (endpoints) הנדרשות של HTTPS שמחזירות את ה-JavaScript.
  • ביטול אחזור מרחוק על ידי אספקת הקוד הדרוש ממקור מקומי

בכל אחת מהגישות צריך להגדיר נקודת קצה (endpoint) מסוג HTTPS כדי לטפל בדיווח על חשיפות.

נקודות קצה ב-HTTPS

כדי לבדוק את בחירת המודעות ואת הדיווח על החשיפות, צריך להגדיר 7 נקודות קצה מסוג HTTPS שמכשיר הבדיקה או האמולטור שלכם יכולים לגשת אליהן:

  1. נקודת הקצה של הקונה שמציגה את ה-JavaScript של לוגיקת הבידינג.
  2. נקודת קצה (endpoint) שמשתמשת באותות לבידינג.
  3. נקודת הקצה של בית העסק שמציגה את ה-JavaScript של לוגיקת ההחלטות.
  4. נקודת קצה שמציגה אותות למתן ציונים.
  5. נקודת קצה לדיווח על חשיפות של קונה זוכה.
  6. נקודת קצה לדיווח על חשיפות של בית העסק.
  7. נקודת קצה להצגת העדכונים היומיים לקהל בהתאמה אישית.

למען הנוחות, במאגר GitHub יש קוד JavaScript בסיסי למטרות בדיקה. הוא כולל גם הגדרות של שירות OpenAPI שאפשר לפרוס בפלטפורמה נתמכת של הדמיה או מיקרו-שירותים. פרטים נוספים זמינים בקובץ README של הפרויקט.

שינוי אוטומטי של אחזור מרחוק של JavaScript

התכונה הזו מיועדת לשימוש בבדיקת 'קצה-לקצה'. כדי לשנות את הגדרת האחזור מרחוק, האפליקציה צריכה לפעול במצב ניפוי באגים עם אפשרויות למפתחים מופעלות.

כדי להפעיל את מצב ניפוי הבאגים באפליקציה, מוסיפים את השורה הבאה למאפיין application בקובץ AndroidManifest.xml:

<application
  android:debuggable="true">

דוגמה לאופן השימוש בשינויים האלה מופיעה באפליקציה לדוגמה של Protected Audience API ב-GitHub.

עליכם להוסיף JavaScript מותאם אישית משלכם כדי לטפל בשגרה של בחירת מודעות, כמו בידינג, החלטות בנושא ניקוד ודיווח. במאגר GitHub תוכלו למצוא דוגמאות לקוד JavaScript בסיסי שמטפל בכל הבקשות הנדרשות. באפליקציית הדוגמה של Protected Audience API מוסבר איך לקרוא קוד מהקובץ הזה ולהכין אותו לשימוש כביטול.

ניתן לעקוף באופן עצמאי את אחזור JavaScript בצד המוכר ובצד הקונה, אבל נדרשת נקודת קצה (endpoint) מסוג HTTPS כדי להציג כל קוד JavaScript שלא מספקים עבורו שינויים. ב-README מוסבר איך להגדיר שרת שמטפל במקרים האלה.

אפשר לבטל אחזור של JavaScript רק לקהלים בהתאמה אישית שבבעלות החבילה שלכם.

שינוי JavaScript בצד המוכר

כדי להגדיר שינוי של JavaScript בצד המכירה, מבצעים את הפעולות הבאות, כפי שמתואר בדוגמת הקוד הבאה:

  1. מאתחלים אובייקט AdSelectionManager.
  2. מקבלים הפניה ל-TestAdSelectionManager מהאובייקט AdSelectionManager.
  3. בונים אובייקט AdSelectionConfig.
  4. יוצרים AddAdSelectionOverrideRequest עם האובייקט AdSelectionConfig ו-String שמייצג את ה-JavaScript שבו מתכוונים להשתמש בתור שינוי מברירת המחדל.
  5. קוראים ל-method overrideAdSelectionConfigRemoteInfo() האסינכרוני עם האובייקט AddAdSelectionOverrideRequest והאובייקטים הרלוונטיים Executor ו-OutcomeReceiver.

Kotlin

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)

Java

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. ההבדל העיקרי הוא שאפשר להגדיר את ה-decisionLogicUrl לערך placeholder כי המערכת תתעלם ממנו.

כדי לשנות את קוד ה-JavaScript שמשמש לבחירת המודעה, השדה decisionLogicJs חייב להכיל את חתימות הפונקציה המתאימות בצד המוכר. דוגמה לקריאת קובץ JavaScript כמחרוזת מופיעה באפליקציה לדוגמה של Protected Audience API ב-GitHub.

השיטה האסינכרונית overrideAdSelectionConfigRemoteInfo() משתמשת באובייקט OutcomeReceiver כדי לסמן את התוצאה של קריאת ה-API.

קריאת החזרה (callback) של onResult() מציינת שהשינוי הוגדר בהצלחה. בקריאות עתידיות ל-selectAds(), המערכת תשתמש בלוגיקה של ההחלטה והדיווח שהעברתם כעקיפה.

קריאת החזרה (call back) של onError() מציינת שני תנאים אפשריים:

  • אם תנסו לבטל את ההגדרה באמצעות ארגומנטים לא חוקיים, הערך AdServiceException יציין ש-IllegalArgumentException הוא הסיבה לכך.
  • אם ניסיתם לבטל את ההגדרה המקורית באפליקציה שלא פועלת במצב ניפוי באגים עם אפשרויות הפיתוח מופעלות, הערך IllegalStateException יופיע ב-AdServiceException כסימן לכך שזו הסיבה.

איפוס השינויים מברירת המחדל בצד המוכר

הקטע הזה נניח שהחלפתם את קוד ה-JavaScript בצד המוכר, ושיש לכם הפניה ל-TestAdSelectionManager ול-AdSelectionConfig שבהם השתמשתם בקטע הקודם.

כדי לאפס את ההחרגות לכל AdSelectionConfigs:

  1. קוראים ל-method האסינכרוני resetAllAdSelectionConfigRemoteOverrides() עם האובייקט OutcomeReceiver הרלוונטי.

Kotlin

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

Java

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

אחרי שמאפסים את השינויים בצד המוכר, הקריאות ל-selectAds() ישתמשו באותו decisionLogicUrl שמאוחסן ב-AdSelectionConfig כדי לנסות לאחזר את ה-JavaScript הנדרש.

אם הקריאה ל-resetAllAdSelectionConfigRemoteOverrides() נכשלת, הקריאה החוזרת של OutComeReceiver.onError() מספקת AdServiceException. אם מנסים להסיר את ההחרגות כשהאפליקציה לא פועלת במצב ניפוי באגים עם אפשרויות הפיתוח מופעלות, הערך IllegalStateException יופיע ב-AdServiceException כסימן לכך שזו הסיבה.

ביטול JavaScript בצד הקונה

  1. פועלים לפי השלבים להצטרפות לקהל בהתאמה אישית
  2. יוצרים AddCustomAudienceOverrideRequest עם הקונה והשם של הקהל המותאם אישית שרוצים לשנות, בנוסף ללוגיקה של הבידינג ולנתונים שרוצים להשתמש בהם כשינוי מברירת המחדל.
  3. קוראים לשיטה overrideCustomAudienceRemoteInfo() האסינכרונית עם האובייקט AddCustomAudienceOverrideRequest והאובייקטים הרלוונטיים Executor ו-OutcomeReceiver

Kotlin

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)

Java

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

הערכים של buyer ו-name הם אותם ערכים ששימשו ליצירת הקהל המותאם אישית. מידע נוסף על השדות האלה

בנוסף, אפשר לציין שני פרמטרים נוספים:

  • biddingLogicJs: JavaScript שמכיל את הלוגיקה של הקונה שמשמש במהלך בחירת המודעה. אתם יכולים לראות מהן חתימות הפונקציות הנדרשות ב-JavaScript הזה.
  • trustedBiddingSignals: האותות לבידינג לשימוש במהלך בחירת המודעות. למטרות בדיקה, אפשר להשתמש במחרוזת ריקה.

השיטה האסינכרונית overrideCustomAudienceRemoteInfo() משתמשת באובייקט OutcomeReceiver כדי לאותת את התוצאה של הקריאה ל-API.

הקריאה החוזרת onResult() מציינת שהביטול הוחל בהצלחה. בקריאות הבאות ל-selectAds() ייעשה שימוש בלוגיקת הבידינג והדיווח שהעברתם בתור השינוי מברירת המחדל.

הקריאה החוזרת (callback) של onError() מציינת שני תנאים אפשריים.

  • אם מנסים לשנות את השינוי עם ארגומנטים לא חוקיים, הסיבה AdServiceException היא IllegalArgumentException.
  • אם מנסים לבטל את השינוי ואפליקציה שלא פועלת במצב ניפוי באגים והאפשרויות למפתחים מופעלות, הערך AdServiceException מציין שהסיבה היא IllegalStateException.

איפוס שינויים מצד הקונה

בקטע הזה נניח שהחרגתם את JavaScript בצד הקונה ושיש לכם הפניה ל-TestCustomAudienceManager שנעשה בו שימוש בקטע הקודם.

כדי לאפס את ההחרגות לכל הקהלים בהתאמה אישית:

  1. מפעילים את השיטה resetAllCustomAudienceOverrides() האסינכרונית עם האובייקטים Executor ו-OutcomeReceiver הרלוונטיים.

Kotlin

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

Java

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

לאחר איפוס השינויים בצד הקונה, הקריאות הבאות ל-selectAds() ישתמשו באותו biddingLogicUrl ו-trustedBiddingData שמאוחסנים ב-CustomAudience כדי לנסות לאחזר את קוד ה-JavaScript הנדרש.

אם הקריאה ל-resetCustomAudienceRemoteInfoOverride() נכשלת, הקריאה החוזרת (call back) של OutComeReceiver.onError() תחזיר AdServiceException. אם מנסים להסיר את ההחרגות כשהאפליקציה לא פועלת במצב ניפוי באגים עם אפשרויות הפיתוח מופעלות, הערך IllegalStateException יופיע ב-AdServiceException כסימן לכך שזו הסיבה.

הגדרת שרת דיווח

כשמשתמשים בשינוי מברירת המחדל של אחזור מרחוק, עדיין צריך להגדיר שרת שהמכשיר או האמולטור יכולים להגיע אליו כדי להגיב לאירועי דיווח. כדי לבדוק את הנתונים, אפשר להשתמש בנקודת קצה פשוטה שמחזירה 200. המאגר ב-GitHub כולל הגדרות של שירותי OpenAPI שאפשר לפרוס בפלטפורמת מודל או בפלטפורמת מיקרו-שירותים נתמכת. פרטים נוספים זמינים בקובץ README של הפרויקט.

כשמחפשים את הגדרות OpenAPI, מחפשים את הקובץ reporting-server.json. הקובץ הזה מכיל נקודת קצה פשוטה שמחזירה את 200, שמייצג קוד תשובת HTTP. נקודת הקצה (endpoint) הזו משמשת במהלך selectAds() ומסמנת ל-Protected Audience API שהדיווח על החשיפות הושלם בהצלחה.

פונקציונליות לבדיקה

  • תרגול של הצטרפות או עזיבה והגדרה של קהל בהתאמה אישית על סמך פעולות קודמות של משתמשים.
  • איך מפעילים את בחירת המודעות במכשיר באמצעות קוד JavaScript שמתארח מרחוק.
  • בודקים איך השיוך של אפליקציה להגדרות של קהלים מותאמים אישית יכול להשפיע על תוצאות בחירת המודעות.
  • להפעיל דיווח על חשיפות אחרי בחירת המודעה.

מגבלות

בטבלה הבאה מפורטות המגבלות על העיבוד של Protected Audience API. המגבלות המוצגות עשויות להשתנות בהתאם למשוב. בנתוני הגרסה תוכלו לקרוא על יכולות שנמצאות בתהליך פיתוח.

רכיב תיאור המגבלה ערך מגבלה
קהל בהתאמה אישית (CA) מספר מודעות מקסימלי לכל CA 100
המספר המקסימלי של רשויות אישורים לכל אפליקציה 1000
המספר המקסימלי של אפליקציות שיכולות ליצור רשות אישורים 1000
העיכוב המקסימלי בזמן ההפעלה של רשות אישורים ממועד היצירה שלה 60 ימים
מועד התפוגה המקסימלי של רשות אישורים ממועד ההפעלה שלה 60 ימים
המספר המקסימלי של רשויות אישורים במכשיר 4000
הגודל המקסימלי של שם הרשות 200 בייטים
הגודל המקסימלי של URI לאחזור יומי 400 בייטים
הגודל המקסימלי של URI של לוגיקה לבידינג 400 בייטים
הגודל המקסימלי של נתוני בידינג מהימנים 10 KB
הגודל המקסימלי של האותות לבידינג המשתמשים 10 KB
שיעור שיחות מקסימלי עבור leaveCustomAudience לכל קונה 1 לשנייה
שיעור שיחות מקסימלי ב-joinCustomAudience לכל קונה 1 לשנייה
אחזור רקע של קליפורניה פג הזמן הקצוב של החיבור ‫5 שניות
זמן קצוב לתפוגה של קריאת HTTP ‫30 שניות
גודל הורדה כולל מקסימלי 10 KB
משך הזמן המקסימלי של מחזור אחזור 5 דקות
המספר המקסימלי של רשויות אישורים שעודכנו לכל משימה 1000
בחירת מודעות מספר הקונים המקסימלי טרם נקבע
המספר המקסימלי של רשויות אישורים לכל קונה טרם נקבע
המספר המקסימלי של מודעות במכרז טרם נקבע
זמן קצוב לתפוגה של חיבור ראשוני ‫5 שניות
הזמן הקצוב לקריאת החיבור פג ‫5 שניות
זמן ביצוע מקסימלי של AdSelection ‫10 שניות
זמן ביצוע מקסימלי של בידינג לכל CA ב-AdSelection 5 שניות
זמן ביצוע מקסימלי של ניקוד ב-AdSelection 5 שניות
משך ההפעלה המקסימלי לכל קונה ב-AdSelection טרם נקבע
הגודל המקסימלי של אותות בחירת המודעה/אתר המכירה/לכל קונה טרם נקבע
הגודל המקסימלי של סקריפטים של מוכרים/קונים טרם נקבע
קצב שיחות מקסימלי ב-selectAds QPS אחד
דיווח על חשיפות משך הזמן המינימלי לפני הסרת בחירת המודעות מהתגובה לזיהוי 24 שעות
המספר המקסימלי של מודעות האחסון שייבחרו טרם נקבע
הגודל המקסימלי של כתובת URL לפלט הדיווח טרם נקבע
משך זמן מקסימלי לדיווח על חשיפות טרם נקבע
מספר הניסיונות החוזרים המקסימלי לשיחות התראה טרם נקבע
תם פרק הזמן שהוקצב להתחברות ‫5 שניות
משך ההפעלה הכולל המקסימלי של reportImpression 2 שניות
קצב שיחות מקסימלי ב-reportImpressions 1 QPS
דיווח על אירועים המספר המקסימלי של סמנים לכל קונה בכל מכרז 10

המספר המקסימלי של סמנים לכל מוכר בכל מכרז

10

הגודל המקסימלי של מפתח האירוע

40 בייטים

הגודל המקסימלי של נתוני האירוע

64KB

מודעות גודל מקסימלי של רשימת מודעות 10KB ששותפים על ידי כל AdData ב-CA יחיד לצורך מודעות לפי הקשר
URLs האורך המקסימלי של מחרוזת כתובת URL שנלקחת כקלט טרם נקבע
JavaScript משך ההפעלה המקסימלי שנייה אחת לבידינג ולניקוד לצורך דיווח על חשיפות
השימוש המקסימלי בזיכרון ‎10 MB

דיווח על באגים ובעיות

המשוב שלכם הוא חלק חיוני בארגז החול לפרטיות ב-Android. נשמח לקבל ממך דיווח על בעיות שמצאת או רעיונות לשיפור ארגז החול לפרטיות ב-Android.