פיתוח מתאמי בידינג

המדריך הזה מיועד לרשתות פרסום שרוצות ליצור מתאם בידינג כדי להשתתף בבידינג בזמן אמת (RTB) במסגרת תהליך בחירת הרשת (Mediation) של Google. בעלי תוכן דיגיטלי יכולים לעיין בהוראות בנושא תהליך בחירת הרשת לבעלי תוכן דיגיטלי.

מתאם בידינג הוא החלק של השילוב בצד הלקוח. המתאם מאפשר ל-SDK של רשת המודעות לתקשר עם Google Mobile Ads SDK כדי לטעון מודעות שמוצגות על ידי הבידינג.

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

תהליך העבודה של מתאם בידינג

אתחול

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

המתאם אחראי על החלקים הבאים בתהליך העבודה:

  • שלבים 4-7: מפעילים את המתאם ומפעילים מחדש את Google Mobile Ads SDK בסיום ההפעלה.

  • שלבים 10-13: אוספים אותות מה-SDK של רשת המודעות כדי לשלוח למגיש הצעות המחיר כדי שישתתף בבקשת RTB, ומעבירים אותם ל-Google Mobile Ads SDK.

  • שלבים 18-21: אם הבידינג מחזיר את הצעת המחיר הזוכה, צריך לטעון את המודעה בהתאם לתגובה מהבידינג. אחרי הטעינה, מדווחים ל-Google Mobile Ads SDK שהמודעה נטענה.

  • שלב 23 ואילך: בזמן שהמודעה מוצגת, מדווחים ל-Google Mobile Ads SDK על אירועי חשיפות ולחיצות, וגם על אירועי המודעות האחרים שמתרחשים במהלך מחזור החיים של הצגת המודעה.

הטמעת מתאם הבידינג

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

getSDKVersionInfo()

כאן צריך להחזיר את גרסת ה-SDK. הגרסה הזו מועברת למגיש הצעות המחיר כחלק מהבקשה של OpenRTB.

בשיטה הזו צריך להחזיר VersionInfo. בדוגמה הבאה מוסבר איך ממירים את גרסת המחרוזת של ה-SDK ל-VersionInfo.

@Override
public VersionInfo getSDKVersionInfo() {
  // Get your SDK's version as a string. E.g. "1.2.3"
  // String versionString = YourSdk.getVersion();
  String splits[] = versionString.split("\\.");
  if (splits.length >= 3) {
      int major = Integer.parseInt(splits[0]);
      int minor = Integer.parseInt(splits[1]);
      int micro = Integer.parseInt(splits[2]);
      return new VersionInfo(major, minor, micro);
   }

   String logMessage = String.format("Unexpected SDK version format: %s." +
           "Returning 0.0.0 for SDK version.", sdkVersion);
   Log.w(TAG, logMessage);
   return new VersionInfo(0, 0, 0);
}

getVersionInfo()

כאן צריך להחזיר את גרסת המתאם. הגרסה הזו מועברת למגיש הצעות המחיר כחלק מהבקשה של OpenRTB.

במתאמים של Google עם קוד מקור פתוח וגרסאות נעשה שימוש בסכימה של 4 ספרות לגרסאות של מתאמים, אבל בשדה VersionInfo אפשר להזין רק 3 ספרות. כדי לעקוף את הבעיה הזו, מומלץ לשלב את שתי הספרות האחרונות בגרסה עם התיקון, כפי שמתואר בהמשך.

@Override
public VersionInfo getVersionInfo() {
  // Get your adapters's version as a string. E.g. "1.2.3.0"
  String versionString = BuildConfig.VERSION_NAME;
  String splits[] = versionString.split("\\.");
  if (splits.length >= 4) {
      int major = Integer.parseInt(splits[0]);
      int minor = Integer.parseInt(splits[1]);
      int micro = Integer.parseInt(splits[2]) * 100 + Integer.parseInt(splits[3]);
      return new VersionInfo(major, minor, micro);
    }

    String logMessage = String.format("Unexpected adapter version format: %s." +
                "Returning 0.0.0 for adapter version.", versionString);
    Log.w(TAG, logMessage);
    return new VersionInfo(0, 0, 0);
}

initialize()‎

זמן קצוב לתפוגה: 30 שניות

השיטה initialize() היא השיטה הראשונה שנקראת ב-adapter. הוא נקרא רק פעם אחת בכל סשן. השיטה הזו מספקת רשימה של אובייקטים מסוג MediationConfiguration שמייצגים את הרשימה המלאה של מיקומי המודעות באפליקציה הזו שמוגדרים לרשת המודעות. אפשר לעבור ברשימה הזו כדי לנתח את פרטי הכניסה של כל מיקום מודעה ולהעביר את הנתונים הרלוונטיים ל-SDK לצורך אתחול.

אחרי שה-SDK מופעל ומוכון לקבל בקשות להצגת מודעות, מפעילים את השיטה onInitializationSucceeded() של InitializationCompleteCallback. הקריאה החוזרת מועברת לבעלי האפליקציות כדי שהם ידעו שהם יכולים להתחיל לטעון מודעות.

@Override
public void initialize(Context context,
    InitializationCompleteCallback initializationCompleteCallback,
    List<MediationConfiguration> mediationConfigurations) {
  // Initialize your ad network's SDK.
  ...

  // Invoke the InitializationCompleteCallback once initialization completes.
  initializationCompleteCallback.onInitializationSucceeded();
}

collectSignals()

זמן קצוב לתפוגה: שנייה אחת

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

collectSignals() נקראת בשרשור ברקע. Google Mobile Ads SDK מבקש אותות בו-זמנית מכל המתאמים שמשתתפים בבידינג. חשוב להקפיד על התנהגות מכבדת ולהגביל את הקריאות לשרשור של ממשק המשתמש במהלך התקופה הזו. כל עבודה כבדה שהמתאם או ה-SDK צריכים לבצע כדי לאסוף אותות צריכה להתבצע בשיטה initialize() ולהישמר במטמון.

כשהאותות מוכנים, צריך לבצע קריאה חוזרת (callback) ל-onSuccess() עם האותות המקודדים.

דוגמה להטמעה:

@Override
public void collectSignals(RtbSignalData rtbSignalData,
                           SignalCallbacks signalCallbacks) {
  String signals = YourSdk.getSignals();
  signalCallbacks.onSuccess(signals);
}

אם המתאם לא מצליח לאסוף אותות, צריך לקרוא לפונקציה signalCallbacks.onFailure() עם מחרוזת שמסבירה את השגיאה שהתרחשה.

הטמעת שיטות טעינה של מודעות

זמן קצוב לתפוגה: 10 שניות

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

שיטת הטעינה המדויקת שתופעל תלויה בפורמט המודעה שלגביו נשלחה הבקשה:

פורמט מודעה שיטת הטעינה
מודעת באנר loadBannerAd()
מעברון loadInterstitialAd()
ההטבה הופעלה loadRewardedAd()

מטמיעים את השיטות האלה עבור פורמטים של מודעות שהמתאם תומך בהם.

שיטת הטעינה נקראת בשרשור של ממשק המשתמש, באותה מופע של המתאם שממנו סיפקתם אותות. השיטה הזו מספקת את הפרמטרים הבאים:

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

  • אובייקט MediationAdLoadCallback שמשמש להודעה ל-Google Mobile Ads SDK כשהטעינה מסתיימת בהצלחה או כשהיא נכשלת.

אחרי שה-SDK טוען את המודעה, צריך לבצע קריאה ל-mediationAdLoadCallback.onSuccess(). אם טעינה של מודעה נכשלת, צריך לבצע קריאה ל-mediationAdLoadCallback.onFailure() עם מחרוזת שמסבירה את השגיאה שהתרחשה.

כדי להשתמש בשיטה mediationAdLoadCallback.onSuccess(), צריך להעביר אובייקט שתואם לאחד מממשקי ה-Ad שמוגדרים על ידי Google Mobile Ads SDK. בממשקי המודעות האלה תתבקשו לספק מידע על המודעה.

ל-MediationAdConfiguration יש גם שיטה getWatermark() שמחזירה מחרוזת בקידוד base64 שמייצגת קובץ PNG. התמונה הזו צריכה להיות מוגדרת כתמונה מרובעת בשכבת-על שקופה במודעות. אפשר לפנות אל Google לקבלת הנחיות נוספות לגבי עיבוד סימן המים. הוא מכיל מטא-נתונים על המודעה שמוצגת, שבעזרתם בעלי התוכן הדיגיטלי יכולים לקבוע את מקור המודעות שמוצגות.

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

בהמשך מופיעה דוגמה להטמעה של loadBannerAd(). חשוב לזכור שההטמעה של המתאם תהיה שונה, כי המתאם משתלב עם SDK אחר.

public final class SampleRtbAdapter extends RtbAdapter {
  ...

  @Override
  public void loadBannerAd(
      MediationBannerAdConfiguration adConfiguration,
      MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> callback) {

      SampleBannerRenderer bannerRenderer =
          new SampleBannerRenderer(adConfiguration, callback);
      bannerRenderer.render();
    }
}

// Renders a banner ad, and forwards callbacks to the Google Mobile Ads SDK.
public class SampleBannerRenderer implements MediationBannerAd {
  private MediationBannerAdConfiguration adConfiguration;
  private final MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> adLoadCallback;
  private AdView adView;
  private MediationBannerAdCallback callback;

  public SampleRtbBannerRenderer(
      MediationBannerAdConfiguration adConfiguration,
      MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> adLoadCallback) {
    this.adConfiguration = adConfiguration;
    this.adLoadCallback = adLoadCallback;
  }

  public void render() {
    adView = new AdView(adConfiguration.getContext());
    adView.setAdSize(adConfiguration.getAdSize());
    // serverParameters are the parameters entered in the AdMob UI for your network.
    adView.setAdUnitId(adConfiguration.getServerParameters().getString("adUnitId"));

    // Map the callbacks from your SDK to Google's SDK.
    adView.setAdListener(new AdListener() {
      // See the next step for more information on callback mapping.
      // ...
    });

    // Get the bid response and watermark from the ad configuration and
    // pass the relevant information to your SDK.
    String ad = adConfiguration.getBidResponse();
    String watermark = adConfiguration.getWatermark();
    Bundle extras = new Bundle();
    extras.putString("bid", ad);
    extras.putString("watermark", watermark);
    AdRequest request = new AdRequest.Builder()
        .addNetworkExtrasBundle(AdMobAdapter.class, extras)
        .build();
    adView.loadAd(request);
  }

  // MediationBannerAd implementation

  @NonNull
  @Override
  public View getView() {
    return adView;
  }
}

העברה של אירועים במחזור החיים של הצגת מודעות

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

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

משותף לכל הפורמטים
שיטה מתי כדאי להתקשר
reportAdClicked() בוצעה לחיצה על המודעה.
reportAdImpression() המודעה הניבה חשיפה.
onAdOpened() המודעה הוצגה בתצוגת מסך מלא.
onAdClosed() תצוגת המסך המלא של המודעה נסגרה.
onAdLeftApplication() המודעה גרמה למשתמש לצאת מהאפליקציה.
מודעות מתגמלות
onRewarded() המשתמש מקבל פרס.
מודעות וידאו עם קריאה חוזרת (מודעות וידאו מתגמלות ומודעות וידאו מותאמות)
onVideoStarted() הסרטון של המודעה התחיל.
onVideoCompleted() הסרטון של המודעה הושלם.

מתבצעת קריאה ל-mediationAdLoadCallback.onSuccess() ומקבלים אובייקט MediationAdLoadCallback<MediationAdT, MediationAdCallbackT>. מתאמים אמורים לשמור את האובייקט הזה ולהשתמש בו כדי להפעיל אירועי הצגה שמתרחשים במודעה.

בדרך כלל, רוב האירועים האלה מופעלים על ידי ה-SDK של רשת המודעות. התפקיד של המתאם הוא פשוט למפות את קריאות החזרה (callbacks) מ-SDK של רשת המודעות ל-Google Mobile Ads SDK.

בדוגמה הבאה מוסבר איך מעבירים קריאות חוזרות (callbacks) מהמאזין למודעות של ה-SDK ל-Google Mobile Ads SDK:

adView.setAdListener(new AdListener() {
    public void onAdLoaded() {
        callback = adLoadCallback.onSuccess(SampleBannerRenderer.this);
    }

    public void onAdImpression() {
        if (callback != null) {
            callback.reportAdImpression();
        }
    }

    public void onAdFailedToLoad(LoadAdError adError) {
        adLoadCallback.onFailure("Error: " + adError.toString());
    }

    public void onAdClosed() {
        if (callback != null) {
            callback.onAdClosed();
        }
    }

    public void onAdOpened() {
        if (callback != null) {
            callback.onAdOpened();
            callback.reportAdClicked();
        }
    }

    public void onAdLeftApplication() {
        if (callback != null) {
            callback.onAdLeftApplication();
        }
    }
});

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

מערכת Google Mobile Ads SDK מתעדת חשיפה של מודעה מותאמת כשרואים 1px של המודעה. אם ערכת ה-SDK של רשת המודעות דורשת להציג נכסים ספציפיים כדי ליצור חשיפה תקפה, הבידינג יכול לציין את הנכסים הנתמכים האלה בתגובה להצעת המחיר. לאחר מכן, ערכת Google Mobile Ads SDK מאמתת שהנכסים המותאמים הנדרשים מוצגים לפני תיעוד החשיפה.

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

הצגת שגיאות במודעות

בפורמטים של מסך מלא, כמו מודעות מעברון ומודעות מתגמלות, צריך לספק הטמעה של MediationInterstitialAd או של MediationRewardedAd בקריאה החוזרת (callback) של הטעינה לאחר הצלחה, כדי ש-Google Mobile Ads SDK תוכל לבקש מהמתאם להציג את המודעה.

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

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

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

התקשרות חזרה תוצאה
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
אף אחת מהאפשרויות האלה למשך כמה שניות Impression recorded

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

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

final class SampleRtbAdapter extends RtbAdapter implements MediationRewardedAd {

 private MediationRewardedAdCallback callback;
 private RewardedAd rewardedAd;

 ...

  @Override
  public void loadRewardedAd(
      MediationRewardedAdConfiguration adConfiguration,
      final MediationAdLoadCallback<MediationRewardedAd, MediationRewardedAdCallback> loadCallback) {

    // Load an ad. This mock example uses Google's SDK, but in practice
    // your adapter will load the ad using your ad network's SDK.
    RewardedAd.load(adConfiguration.getContext(),
        "ca-app-pub-3940256099942544/5224354917",
        new AdRequest.Builder().build(),
        new RewardedAdLoadCallback() {
          @Override
          public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
            // When the ad loads, invoke the load success callback.
            callback = loadCallback.onSuccess(SampleRtbAdapter.this);
          }
        });
  }

  @Override
  public void showAd(Context context) {
    // In this mock example, your ad network requires an activity context, but
    // didn't receive one, making you unable to show the ad.
    if (!(context instanceof Activity)) {
      AdError error = new AdError(1, "Context must be an activity",
          "com.google.ads.mediation.sample");
      callback.onAdFailedToShow(error);
    }

    // This example shows Google SDK's callbacks, but it's likely your SDK
    // has similar presentation callbacks.
    rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
      @Override
      public void onAdShowedFullScreenContent() {
        // Your ad network SDK successfully showed the ad. Call onAdOpened().
        callback.onAdOpened();
      }

      @Override
      public void onAdFailedToShowFullScreenContent(AdError adError) {
        // Your ad network SDK failed to show the ad, invoke onAdFailedToShow.
        // In practice, you will map your SDK's error to an AdError.
        AdError error = new AdError(adError.getCode(), adError.getMessage(),
            adError.getDomain());
        callback.onAdFailedToShow(adError);
      }
    });


    rewardedAd.show((Activity) context, ...);
  }
}