Разработка адаптера для назначения ставок

Это руководство предназначено для рекламных сетей, которые хотят создать адаптер назначения ставок, чтобы участвовать в назначении ставок в реальном времени (RTB) в рамках медиации Google. Если вы издатель, ознакомьтесь с инструкциями по медиации для издателей.

Адаптер назначения ставок – это клиентская часть интеграции. Адаптер позволяет SDK вашей рекламной сети взаимодействовать с Google Mobile Ads SDK (Legacy), чтобы загружать объявления, которые показывает ваша система назначения ставок.

Чтобы назначение ставок работало правильно, адаптер должен обрабатывать инициализацию, сбор сигналов, загрузку объявлений и передачу событий жизненного цикла объявлений. В этом руководстве мы расскажем, как реализовать адаптер для обработки этих операций.

Как работает адаптер назначения ставок

Инициализация

Ниже приведена подробная схема жизненного цикла адаптера, включающего запрос, ответ и отрисовку.

Адаптер отвечает за следующие этапы рабочего процесса:

  • Шаги 4–7. Инициализируйте адаптер и вызовите Google Mobile Ads SDK (Legacy) после завершения инициализации.

  • Шаги 10–13. Сбор сигналов из SDK рекламной сети, которые будут отправлены покупателю для участия в запросе RTB, и их передача в Google Mobile Ads SDK.

  • Шаги 18–21. Если ваша система назначения ставок возвращает выигрышную ставку, загрузите объявление в соответствии с ответом от этой системы. После загрузки сообщите Google Mobile Ads SDK (Legacy), что объявление загружено.

  • Шаг 23 и последующие. Пока объявление показывается, уведомляйте Google Mobile Ads SDK о показах и кликах, а также о других событиях, связанных с объявлением, которые происходят в течение его жизненного цикла.

Как реализовать адаптер назначения ставок

Чтобы создать адаптер назначения ставок для Google Mobile Ads SDK (Legacy), необходимо расширить абстрактный класс 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 с открытым исходным кодом и версиями используется четырехзначная схема версий, но VersionInfo поддерживает только три цифры. Чтобы обойти это ограничение, рекомендуем объединить последние две цифры в версию исправления, как показано ниже.

@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() вызывается в адаптере первым. Он вызывается только один раз за сеанс. Этот метод предоставляет список объектов 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()

Время ожидания: 1 секунда.

Каждый раз, когда издатель запрашивает объявление, создается новый экземпляр RtbAdapter и вызывается метод collectSignals(). Этот экземпляр RtbAdapter будет использоваться на протяжении всего жизненного цикла запроса объявления, ответа и отрисовки для этого объявления. Метод collectSignals() позволяет адаптеру передавать сигналы с устройства в систему назначения ставок в запросе OpenRTB.

collectSignals() вызывается в фоновом потоке. Google Mobile Ads SDK (Legacy) одновременно запрашивает сигналы у всех адаптеров, участвующих в назначении ставок. Будьте вежливы и ограничьте вызовы потока 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 (Legacy) вызывает ваш адаптер для загрузки выигрышного объявления, передавая вам все данные, возвращенные вашей системой назначения ставок, которые необходимы вашему SDK для загрузки этого объявления.

Выбор метода зависит от формата объявления, для которого предназначен запрос:

Формат объявления Метод загрузки
Баннер loadBannerAd()
Межстраничное объявление loadInterstitialAd()
Бонус предоставлен loadRewardedAd()

Реализуйте эти методы для форматов объявлений, которые поддерживает ваш адаптер.

Метод load вызывается в потоке UI в том же экземпляре адаптера, из которого вы предоставили сигналы. Этот метод предоставляет следующие параметры:

  • MediationAdConfiguration, содержащий параметры, необходимые SDK для загрузки объявления, выигравшего аукцион, например ответ на запрос ставки и учетные данные, настроенные издателем в интерфейсе AdMob.

  • Объект MediationAdLoadCallback, который используется для уведомления Google Mobile Ads SDK (Legacy) об успешной или неуспешной загрузке.

После того как 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 Google Mobile Ads SDK (Legacy).
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 (Legacy) о любых событиях жизненного цикла показа, чтобы их можно было пересылать издателю. Издатель ожидает эти обратные вызовы в определенное время независимо от того, какая рекламная сеть показывает объявление. Поэтому важно, чтобы как можно больше таких вызовов выполнялось в нужное время, чтобы Google Mobile Ads SDK (Legacy) мог перенаправлять их издателю.

Адаптеры должны вызывать следующие события, когда это применимо:

Общие для всех форматов
Метод Когда звонить
reportAdClicked() Пользователь нажал на объявление.
reportAdImpression() Объявление было показано.
onAdOpened() Объявление показывалось в полноэкранном режиме.
onAdClosed() Полноэкранный режим объявления закрыт.
onAdLeftApplication() Объявление заставило пользователя выйти из приложения.
Объявления с вознаграждением
onRewarded() Пользователь получает вознаграждение.
Обратные вызовы для видео (объявления с вознаграждением и нативные объявления)
onVideoStarted() Начало воспроизведения видеообъявления.
onVideoCompleted() Видеообъявление было показано до конца.

При вызове mediationAdLoadCallback.onSuccess() адаптер получает объект MediationAdLoadCallback<MediationAdT, MediationAdCallbackT>. Адаптеры должны хранить этот объект и использовать его для вызова событий показа, которые происходят в вашем объявлении.

Обычно большинство таких событий вызывается SDK рекламной сети. Роль адаптера заключается в том, чтобы сопоставить обратные вызовы из SDK рекламной сети с Google Mobile Ads SDK (Legacy).

В примере ниже показано, как перенаправлять обратные вызовы из прослушивателя объявлений SDK в Google Mobile Ads SDK (Legacy).

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 (Legacy) регистрирует показ нативного объявления, когда виден хотя бы один его пиксель. Если для корректного показа объявления SDK рекламной сети требует наличия определенных объектов, система назначения ставок может указать их в ответе на запрос ставки. Google Mobile Ads SDK (Legacy) проверяет, показываются ли обязательные объекты нативных объявлений, прежде чем регистрировать показ.

Подробную информацию о том, как указать дополнительные обязательные объекты в ответе на запрос ставки, можно найти в документации по обязательным объектам нативных объявлений.

Показать ошибки в объявлениях

Для полноэкранных форматов, таких как межстраничные объявления и объявления с вознаграждением, в обратном вызове успешной загрузки необходимо предоставить реализацию MediationInterstitialAd или MediationRewardedAd, чтобы Google Mobile Ads SDK (Legacy) мог запросить у адаптера показ объявления.

Google Mobile Ads SDK (Legacy) ожидает, что если адаптер успешно загрузил объявление, то оно готово к показу, когда издатель запрашивает его показ. Это означает, что каждый вызов 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, ...);
  }
}