入札アダプターの開発

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

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

入札を正しく動作させるには、アダプタで、初期化、シグナルの収集、広告の読み込み、広告ライフサイクル イベントのリレーを処理する必要があります。このガイドでは、アダプタを実装してこれらの処理を処理する方法を説明します。

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

初期化

アダプタのリクエスト、レスポンス、レンダリングのライフサイクル全体の詳細なフローを以下に示します。

アダプタは、ワークフローの次の部分を担当します。

  • ステップ 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 管理画面で設定した認証情報など)が含まれます。

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

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

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

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 では、インプレッションを記録する前に、必要なネイティブ アセットが表示されているかどうかの検証が行われます。

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

広告エラーを表示

インタースティシャル広告やリワード広告などのフルスクリーン フォーマットの場合、成功の読み込みコールバックで、 MediationInterstitialAdMediationRewardedAd の実装を渡して、Google Mobile Ads SDK がアダプタに広告を表示するよう要求できるようにします。

Google Mobile Ads SDK は、アダプタが広告を正常に読み込んだ後、パブリッシャーが広告表示をリクエストしたときに、表示の準備が整っていることを想定しています。つまり、すべての show 呼び出しが 1 回のインプレッションとなります。

場合によっては、広告を表示できないことがあります。広告が表示されない場合は、 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, ...);
  }
}