入札アダプタの開発

このガイドは、Google メディエーション内でリアルタイム ビッダー(RTB)に参加するため入札アダプタの構築が必要な広告ネットワークを対象としています。パブリッシャーの方は、パブリッシャー様向けメディエーションの手順をご覧ください。

入札アダプタは、統合のクライアント側の部分です。アダプタを使用すると、広告ネットワーク SDK が Google Mobile Ads SDK と通信し、ビッダーが配信する広告を読み込むことができます。

入札が正しく機能するには、アダプタによって初期化、シグナルの収集、広告の読み込み、広告ライフサイクル イベントの中継が処理される必要があります。このガイドでは、これらの処理を実行できるようにアダプタを実装する方法について説明します。

入札アダプタのワークフロー

初期化

アダプタの request-response-rendering ライフサイクル全体の詳細なフローを以下に示します。

ワークフローの以下の部分はアダプタ側で行います。

  • ステップ 4 ~ 7: アダプタを初期化し、初期化が完了したら Google Mobile Ads SDK をコールバックします。

  • ステップ 10 ~ 13: RTB リクエストに参加するために、広告ネットワーク SDK からシグナルを収集してビッダーに送信し、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 桁の数字しか使用できません。この問題に対処するには、以下に示すように、最後の 2 桁をパッチ バージョンに組み込むことをおすすめします。

@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() メソッドは、アダプタで呼び出される最初のメソッドで、セッションごとに 1 回だけ呼び出されます。このメソッドでは、広告ネットワーク用に設定されているこのアプリ内のプレースメントの完全なリストを表す MediationConfiguration オブジェクトのリストが提供されます。このリストをループして、各プレースメントの認証情報を解析し、関連するデータを SDK に渡して初期化することができます。

SDK が初期化され、広告リクエストを受信する準備が整ったら、InitializationCompleteCallbackonInitializationSucceeded() メソッドを呼び出します。このコールバックはアプリのパブリッシャーに転送され、広告の読み込みを開始する準備が整ったことを通知します。

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

タイムアウト: 1 秒

パブリッシャーが広告をリクエストするたびに、RtbAdapter の新しいインスタンスが作成され、collectSignals() メソッドが呼び出されます。その広告のライフサイクルの期間中(広告リクエスト、レスポンス、レンダリング)、RtbAdapter のインスタンスが使用されます。collectSignals() メソッドにより、アダプタは、OpenRTB リクエストでビッダーに送信されるデバイスからのシグナルを提供できるようになります。

collectSignals() はバックグラウンド スレッドで呼び出されます。Google Mobile Ads SDK は、入札に参加しているすべてのアダプタからのシグナルを同時にリクエストします。この点を考慮して、この間は UI スレッドへの呼び出しを制限してください。シグナルを収集するためにアダプタまたは SDK が必要とする負荷の大きな作業は initialize() メソッドで実行し、キャッシュするとよいでしょう。

シグナルが準備できたら、エンコードされたシグナルで 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()

アダプタでサポートされている広告フォーマットにこれらのメソッドを実装します。

読み込みメソッドは、シグナルを提供したアダプタの同じインスタンス上の UI スレッドに呼び出されます。このメソッドは、次のパラメータを提供します。

  • MediationAdConfiguration。これには、SDK が落札価格で落札された広告を読み込むために必要なパラメータ(入札レスポンスや、パブリッシャーが AdMob 管理画面で設定した認証情報など)が含まれています。

  • MediationAdLoadCallback オブジェクト。読み込みの成否を Google Mobile Ads SDK に通知するために使用されます。

SDK が広告を読み込んだら、mediationAdLoadCallback.onSuccess() を呼び出します。広告の読み込みが失敗した場合は、発生したエラーを説明する文字列を含む mediationAdLoadCallback.onFailure() を呼び出します。

mediationAdLoadCallback.onSuccess() メソッドでは、Google Mobile Ads SDK によって定義された「広告」インターフェースのひとつに確認するオブジェクトを渡す必要があります。これらの広告インターフェースでは、広告に関する情報を入力するよう求められます。

MediationAdConfiguration には、PNG 画像を表す base64 でエンコードされた文字列を返す getWatermark() メソッドもあります。この画像は透明なオーバーレイで広告にタイル表示されます。透かしのレンダリング方法に関してさらにガイドが必要な場合は、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 によって行われます。アダプタの役割は、単に広告ネットワーク SDK のコールバックを Google Mobile Ads SDK にマッピングすることです。

次の例は、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 は、広告の 1 ピクセルが表示されると、ネイティブ広告のインプレッションを記録します。広告ネットワーク SDK で有効なインプレッションをレンダリングするために特定のアセットを表示する必要がある場合、ビッダーはこれらの必須ネイティブ アセットを入札レスポンスで指定できます。その後、Google Mobile Ads SDK は、インプレッションを記録する前に、必要なネイティブ アセットが表示されていることを確認します。

入札レスポンスで追加の必須アセットを指定する方法について詳しくは、ネイティブの必須アセットに関するドキュメントをご覧ください。

広告エラーを表示する

インタースティシャル広告やリワード広告などの全画面フォーマットの場合、読み込み成功コールバックで MediationInterstitialAd または MediationRewardedAd の実装を指定します。これにより、Google Mobile Ads SDK がアダプタに広告の表示をリクエストできるようになります。

Google Mobile Ads SDK では、アダプタが広告を正常に読み込んだ場合、パブリッシャーが広告の表示をリクエストしたときに広告を表示できる状態になっていることを想定しています。つまり、すべての show 呼び出しでインプレッションが発生する必要があります。

ただし、広告を表示できない特殊なケースもあります。広告を表示できない場合は、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, ...);
  }
}