Développement d'un adaptateur d'enchères

Ce guide s'adresse aux réseaux publicitaires qui souhaitent créer un adaptateur d'enchères afin de participer aux enchères en temps réel (RTB, Real Time Bidding) dans la médiation Google. Si vous êtes éditeur, consultez les instructions sur la médiation pour les éditeurs.

Un adaptateur d'enchères correspond à la partie côté client de l'intégration. L'adaptateur permet à votre SDK de réseau publicitaire de communiquer avec le SDK Google Mobile Ads pour charger les annonces diffusées par votre enchérisseur.

Pour que les enchères fonctionnent correctement, votre adaptateur doit gérer l'initialisation, la collecte des signaux, le chargement des annonces et la transmission des événements du cycle de vie des annonces. Dans ce guide, nous vous expliquerons comment implémenter votre adaptateur pour gérer ces opérations.

Workflow d'un adaptateur d'enchères

Initialisation

Vous trouverez ci-dessous un flux détaillé de l'ensemble du cycle de vie de rendu de requête-réponse d'un adaptateur:

L'adaptateur est responsable des parties suivantes du workflow:

  • Étapes 4 à 7: Initialisez votre adaptateur et appelez le SDK Google Mobile Ads une fois l'initialisation terminée.

  • Étapes 10 à 13: collectez les signaux du SDK de votre réseau publicitaire à envoyer à votre enchérisseur pour participer à une demande RTB, puis transmettez-les au SDK Google Mobile Ads.

  • Étapes 18 à 21: si votre système d'enchères renvoie l'enchère gagnante, chargez l'annonce en fonction de la réponse de votre système d'enchères. Une fois l'annonce chargée, informez le SDK Google Mobile Ads qu'elle a été chargée.

  • Étape 23 et suivantes: lorsque votre annonce s'affiche, informez le SDK Google Mobile Ads des événements d'impression et de clic, ainsi que des autres événements d'annonce qui se produisent pendant le cycle de présentation de votre annonce.

Implémenter l'adaptateur d'enchères

Pour créer un adaptateur d'enchères pour le SDK Google Mobile Ads, vous devez étendre la classe abstraite RtbAdapter. Les sections suivantes décrivent chacune des méthodes abstraites de RtbAdapter.

getSDKVersionInfo()

Vous devez ici renvoyer la version de votre SDK. Cette version est transmise à votre enchérisseur dans la requête OpenRTB.

Cette méthode vous oblige à renvoyer un VersionInfo. L'exemple ci-dessous montre comment convertir la version de chaîne de votre SDK en 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()

Vous devez ici renvoyer la version de votre adaptateur. Cette version est transmise à votre enchérisseur dans la requête OpenRTB.

Les adaptateurs Open Source et versionnés de Google utilisent un schéma de version de l'adaptateur à quatre chiffres, mais VersionInfo n'en accepte que trois. Pour contourner ce problème, nous vous recommandons de combiner les deux derniers chiffres dans la version du correctif, comme indiqué ci-dessous.

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

Délai avant expiration: 30 secondes

La méthode initialize() est la première méthode appelée dans votre adaptateur. Il n'est appelé qu'une seule fois par session. Cette méthode vous fournit une liste d'objets MediationConfiguration qui représentent la liste complète des emplacements de cette application configurés pour votre réseau publicitaire. Vous pouvez parcourir cette liste pour analyser les identifiants de chaque emplacement et transmettre les données pertinentes à votre SDK pour l'initialisation.

Une fois que votre SDK est initialisé et prêt à recevoir des demandes d'annonces, appelez la méthode onInitializationSucceeded() de InitializationCompleteCallback. Ce rappel est transmis aux éditeurs d'applications afin qu'ils sachent qu'ils peuvent commencer à charger des annonces.

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

Délai avant expiration: 1 seconde

Chaque fois que l'éditeur demande une annonce, une nouvelle instance de votre RtbAdapter est créée et la méthode collectSignals() est appelée. Cette instance de RtbAdapter sera utilisée pendant toute la durée du cycle de vie de la demande d'annonce, de la réponse et du rendu de cette annonce. La méthode collectSignals() permet à votre adaptateur de fournir des signaux de l'appareil à envoyer à votre enchérisseur dans une requête OpenRTB.

collectSignals() est appelé sur un thread d'arrière-plan. Le SDK Google Mobile Ads demande simultanément des signaux à tous les adaptateurs participant aux enchères. Veuillez faire preuve de respect et limiter les appels au thread UI pendant cette période. Toute tâche lourde que votre adaptateur ou votre SDK doit effectuer pour collecter des signaux doit être effectuée dans la méthode initialize() et mise en cache.

Une fois vos signaux prêts, appelez le rappel onSuccess() avec vos signaux encodés.

Voici un exemple d'implémentation:

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

Si votre adaptateur ne parvient pas à collecter des signaux, appelez signalCallbacks.onFailure() avec une chaîne expliquant l'erreur qui s'est produite.

Implémenter des méthodes de chargement d'annonces

Délai avant expiration: 10 secondes

Si votre enchérisseur renvoie l'enchère gagnante, le SDK Google Mobile Ads appelle votre adaptateur pour charger l'annonce gagnante, en vous transmettant toutes les données que votre enchérisseur a renvoyées et dont votre SDK a besoin pour charger cette annonce.

La méthode de chargement exacte appelée dépend du format d'annonce auquel cette requête est destinée:

Format d'annonce Méthode de chargement
Bannière loadBannerAd()
Interstitiel loadInterstitialAd()
Avec récompense loadRewardedAd()

Implémentez ces méthodes pour les formats d'annonces compatibles avec votre adaptateur.

La méthode de chargement est appelée sur le thread d'UI, sur la même instance de l'adaptateur à partir duquel vous avez fourni des signaux. Cette méthode vous fournit les paramètres suivants:

  • Un MediationAdConfiguration, qui contient les paramètres dont votre SDK a besoin pour charger l'annonce de l'enchère gagnante, tels que la réponse à l'enchère et les identifiants que l'éditeur a configurés dans l'UI AdMob.

  • Objet MediationAdLoadCallback utilisé pour informer le SDK Google Mobile Ads lorsque le chargement aboutit ou échoue.

Une fois que votre SDK a chargé l'annonce, appelez mediationAdLoadCallback.onSuccess(). En cas d'échec du chargement de l'annonce, appelez mediationAdLoadCallback.onFailure() avec une chaîne expliquant l'erreur qui s'est produite.

La méthode mediationAdLoadCallback.onSuccess() nécessite que vous transmettiez un objet conforme à l'une des interfaces "Annonce" définies par le SDK Google Mobile Ads. Ces interfaces publicitaires vous demandent de fournir des informations sur l'annonce.

MediationAdConfiguration dispose également d'une méthode getWatermark() pour renvoyer une chaîne encodée en base64 représentant une image PNG. Cette image doit être affichée en mosaïque dans une superposition transparente sur vos annonces. Contactez Google pour obtenir des conseils supplémentaires sur l'affichage du filigrane. Il contient des métadonnées sur l'annonce diffusée, que les éditeurs peuvent utiliser pour déterminer la source des annonces diffusées.

Pour les bannières, vous devrez fournir la vue de la bannière. Pour les annonces interstitielles et les annonces avec récompense, vous devrez implémenter une méthode show() pour diffuser l'annonce ultérieurement. Nous vous recommandons de faire en sorte que la classe chargée de charger les annonces soit également responsable de l'implémentation de ces méthodes d'annonces.

Voici un exemple d'implémentation de loadBannerAd(). N'oubliez pas que l'implémentation de votre adaptateur sera différente, car il s'intègre à un autre 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;
  }
}

Événements de cycle de vie de la présentation de l'annonce relayée

La responsabilité finale de l'adaptateur est d'informer le SDK Google Mobile Ads de tous les événements de cycle de vie de la présentation afin qu'ils puissent être transférés à l'éditeur. L'éditeur s'attend à ces rappels à des moments spécifiques, quel que soit le réseau publicitaire qui diffuse l'annonce. Il est donc important que le plus grand nombre possible de ces rappels soit appelé au bon moment, afin que le SDK Google Mobile Ads puisse les transmettre à l'éditeur.

Les adaptateurs doivent appeler les événements suivants, le cas échéant:

Commun à tous les formats
Méthode Quand appeler
reportAdClicked() L'utilisateur a cliqué sur l'annonce.
reportAdImpression() L'annonce a généré une impression.
onAdOpened() L'annonce était présentée en plein écran.
onAdClosed() La vue plein écran de l'annonce a été fermée.
onAdLeftApplication() L'annonce a poussé l'utilisateur à quitter l'application.
Annonces avec récompense
onRewarded() L'utilisateur reçoit une récompense.
Rappels vidéo (annonces avec récompense et annonces natives)
onVideoStarted() La vidéo de l'annonce a commencé.
onVideoCompleted() La vidéo de l'annonce est terminée.

L'adaptateur reçoit un objet MediationAdLoadCallback<MediationAdT, MediationAdCallbackT> lors de l'appel de mediationAdLoadCallback.onSuccess(). Les adaptateurs doivent conserver cet objet et l'utiliser pour appeler les événements de présentation qui se produisent sur votre annonce.

En règle générale, la plupart de ces événements sont générés par le SDK de votre réseau publicitaire. Le rôle de l'adaptateur est simplement de mapper les rappels du SDK de votre réseau publicitaire sur le SDK Google Mobile Ads.

L'exemple suivant montre comment transférer les rappels de l'écouteur d'annonces de votre SDK vers le SDK Google Mobile Ads:

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

Éléments requis pour le suivi des impressions des annonces natives

Le SDK Google Mobile Ads enregistre une impression pour une annonce native lorsqu'un pixel de l'annonce est visible. Si le SDK de votre réseau publicitaire nécessite l'affichage de composants spécifiques pour générer une impression valide, votre enchérisseur peut indiquer ces composants natifs obligatoires dans la réponse aux enchères. Le SDK Google Mobile Ads vérifie ensuite que vos composants natifs requis sont affichés avant d'enregistrer une impression.

Pour en savoir plus sur la spécification d'éléments obligatoires supplémentaires dans la réponse d'enchère, consultez la documentation sur les composants obligatoires natifs.

Afficher les erreurs d'annonce

Pour les formats plein écran, tels que les annonces interstitielles et avec récompense, dans le rappel de chargement de succès, vous devez fournir une implémentation de MediationInterstitialAd ou de MediationRewardedAd afin que le SDK Google Mobile Ads puisse demander à votre adaptateur d'afficher l'annonce.

Le SDK Google Mobile Ads s'attend à ce qu'une annonce soit prête à être diffusée lorsque l'éditeur demande à la diffuser si un adaptateur a réussi à en charger une. Cela signifie que chaque appel de diffusion doit générer une impression.

Toutefois, il peut arriver que vous ne puissiez pas diffuser d'annonce. Si vous ne pouvez pas diffuser l'annonce, appelez le rappel onAdFailedToShow() pour annuler l'impression.

Le tableau ci-dessous montre comment les rappels de présentation affectent l'enregistrement des impressions pour les formats d'annonces en plein écran:

Rappel Résultat
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
Aucune de ces propositions pendant plusieurs secondes Impression recorded

1 Pour les impressions non réussies, votre réseau publicitaire n'est pas facturé, mais cela a un impact sur l'ajustement du tarif des événements facturables. Pour en savoir plus, consultez la section Signaux de requête d'enchère.

L'exemple fictif suivant illustre un cycle de vie de chargement/diffusion où un appel de diffusion d'annonce peut entraîner un échec.

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