Desarrollo del adaptador de licitación

Esta guía está dirigida a las redes de publicidad que pretenden crear un adaptador de ofertas para participar en la licitación en tiempo real (RTB) dentro de la mediación de Google. Si eres publicador, consulta las instrucciones sobre mediación para publicadores.

Un adaptador de licitación es la parte de la integración del lado del cliente. El adaptador permite que el SDK de tu red de publicidad se comunique con el SDK de anuncios de Google para dispositivos móviles para cargar los anuncios que publica tu ofertante.

Para que la licitación funcione correctamente, tu adaptador deberá controlar la inicialización, la recopilación de indicadores, la carga de anuncios y la retransmisión de eventos del ciclo de vida de los anuncios. En esta guía, te explicaremos cómo se debe implementar tu adaptador para controlar estas operaciones.

Flujo de trabajo de un adaptador de licitación

Inicialización

A continuación, se muestra un flujo detallado del ciclo de vida completo de solicitud, respuesta y renderización de un adaptador:

El adaptador es responsable de las siguientes partes del flujo de trabajo:

  • Pasos 4 a 7: Inicializa tu adaptador y llama de vuelta al SDK de anuncios de Google para dispositivos móviles una vez que se complete la inicialización.

  • Pasos 10 a 13: Recopila indicadores del SDK de tu red de publicidad para enviarlos a tu ofertante de modo que pueda participar en una solicitud de RTB, y reenvíalos al SDK de anuncios de Google para dispositivos móviles.

  • Pasos 18 a 21: Si tu ofertante devuelve la oferta ganadora, carga el anuncio según la respuesta de tu ofertante. Una vez cargado, notifica al SDK de anuncios de Google para dispositivos móviles que se cargó el anuncio.

  • Paso 23 y posteriores: Mientras se muestra tu anuncio, notifica al SDK de anuncios de Google para dispositivos móviles los eventos de impresiones y clics, así como los demás eventos de anuncios que se produzcan durante el ciclo de vida de presentación de tu anuncio.

Implementa el adaptador de licitación

Para crear un adaptador de licitación para el SDK de anuncios de Google para dispositivos móviles, debes extender la clase abstracta RtbAdapter. En las siguientes secciones, se explica cada método abstracto en RtbAdapter.

getSDKVersionInfo()

Aquí debes devolver la versión de tu SDK. Esta versión se pasa a tu ofertante como parte de la solicitud de OpenRTB.

Este método requiere que devuelvas un objeto VersionInfo. En el siguiente ejemplo, se muestra cómo puedes convertir la versión de cadena de tu SDK en un 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()

Aquí debes devolver la versión de tu adaptador. Esta versión se pasa a tu ofertante como parte de la solicitud de OpenRTB.

Los adaptadores de código abierto y de control de versiones de Google usan un esquema de versión de adaptador de 4 dígitos, pero el VersionInfo solo permite 3 dígitos. Para solucionar este problema, se recomienda combinar los dos últimos dígitos en la versión del parche, como se muestra a continuación.

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

Tiempo de espera: 30 segundos

El método initialize() es el primer método que se llama en tu adaptador. Se llama solo una vez por sesión. Este método te proporciona una lista de objetos MediationConfiguration que representan la lista completa de posiciones en esta app que están configuradas para tu red de publicidad. Puedes iterar esta lista para analizar las credenciales de cada posición y pasar los datos pertinentes a tu SDK para la inicialización.

Una vez que el SDK esté inicializado y listo para recibir solicitudes de anuncios, invoca el método onInitializationSucceeded() de InitializationCompleteCallback. Esta devolución de llamada se reenvía a los publicadores de apps para que sepan que pueden comenzar a cargar anuncios.

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

Tiempo de espera: 1 segundo

Cada vez que el publicador solicita un anuncio, se crea una instancia nueva de tu RtbAdapter y se llama al método collectSignals(). Esta instancia de RtbAdapter se usará durante todo el ciclo de vida de solicitud, respuesta y renderización del anuncio. El método collectSignals() permite que tu adaptador proporcione indicadores del dispositivo para que se envíen a tu ofertante en una solicitud de OpenRTB.

Se llama a collectSignals() en un subproceso en segundo plano. El SDK de anuncios de Google para dispositivos móviles solicita simultáneamente indicadores a todos los adaptadores que participan en la licitación. Intenta limitar al máximo las llamadas al subproceso de IU durante este tiempo. Cualquier trabajo pesado que deba realizar tu adaptador o SDK para recopilar indicadores debe hacerse en el método initialize() y almacenarse en caché.

Una vez que tengas listos tus indicadores, llama a la devolución de llamada onSuccess() con tus indicadores codificados.

A continuación, se incluye un ejemplo de implementación:

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

Si tu adaptador no puede recopilar indicadores, llama a signalCallbacks.onFailure() con una cadena que explique el error que ocurrió.

Implementa métodos de carga de anuncios

Tiempo de espera: 10 segundos

Si tu ofertante devuelve la oferta ganadora, el SDK de anuncios de Google para dispositivos móviles llamará a tu adaptador para cargar el anuncio ganador y te pasará los datos que haya devuelto tu ofertante y que tu SDK necesite para cargar ese anuncio.

El método de carga exacto que se llama depende del formato del anuncio para el que se realiza esta solicitud:

Formato del anuncio Método de carga
Banner loadBannerAd()
Intersticial loadInterstitialAd()
Recompensado loadRewardedAd()

Implementa estos métodos para los formatos de anuncios que admite tu adaptador.

Se llama al método de carga en el subproceso de IU, en la misma instancia del adaptador desde la que proporcionaste indicadores. Este método te proporciona los siguientes parámetros:

  • Un objeto MediationAdConfiguration, que contiene los parámetros que necesita tu SDK para cargar el anuncio de la oferta ganadora, como la respuesta de oferta y las credenciales que configuró el publicador en la IU de AdMob.

  • Es un objeto MediationAdLoadCallback que se usa para notificar al SDK de anuncios de Google para dispositivos móviles cuando la carga se realiza correctamente o falla.

Una vez que el SDK cargue el anuncio, llama a mediationAdLoadCallback.onSuccess(). En caso de que falle la carga del anuncio del evento, llama a mediationAdLoadCallback.onFailure() con una cadena que explique el error que se produjo.

El método mediationAdLoadCallback.onSuccess() requiere que pases un objeto que confirme una de las interfaces "Ad" definidas por el SDK de anuncios de Google para dispositivos móviles. Estas interfaces de anuncios te solicitan que proporciones información sobre el anuncio.

MediationAdConfiguration también tiene un método getWatermark() para devolver una cadena codificada en base64 que representa una imagen PNG. Esta imagen debe aparecer como mosaico en una superposición transparente en tus anuncios. Comunícate con Google para obtener orientación adicional sobre cómo renderizar la marca de agua. Contiene metadatos sobre el anuncio que se muestra para que los publicadores determinen la fuente de los anuncios publicados.

En el caso de los banners, se te pedirá que proporciones la vista del banner. En el caso de los anuncios intersticiales y recompensados, se te pedirá que implementes un método show() para mostrar el anuncio en un momento posterior. Como práctica recomendada, te sugerimos que la clase que carga los anuncios también sea responsable de implementar estos métodos de anuncios.

A continuación, se incluye una implementación de muestra de loadBannerAd(). Ten en cuenta que la implementación de tu adaptador se verá diferente, ya que tu adaptador se integra en un SDK diferente.

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

Retransmite eventos de ciclo de vida de la presentación de anuncios

La responsabilidad final del adaptador es notificar al SDK de anuncios de Google para dispositivos móviles sobre cualquier evento de ciclo de vida de la presentación, de modo que se pueda reenviar al publicador. El publicador espera estas devoluciones de llamada en momentos específicos, sin importar qué red de publicidad publique el anuncio, por lo que es importante que se invoquen tantas devoluciones de llamada como sea posible y que esto se haga en el momento adecuado para que el SDK de anuncios de Google para dispositivos móviles pueda reenviarlas al publicador.

Los adaptadores deben invocar los siguientes eventos cuando corresponda:

Común a todos los formatos
Método Cuándo llamar
reportAdClicked() Se hizo clic en el anuncio.
reportAdImpression() El anuncio renderizó una impresión.
onAdOpened() El anuncio presentó una vista de pantalla completa.
onAdClosed() Se cerró la vista de pantalla completa del anuncio.
onAdLeftApplication() El anuncio hizo que el usuario abandonara la aplicación.
Anuncios recompensados
onRewarded() Se le otorga una recompensa al usuario.
Devoluciones de llamada de video (anuncios recompensados y nativos)
onVideoStarted() Se inició el video del anuncio.
onVideoCompleted() Se completó el video del anuncio.

El adaptador recibe un objeto MediationAdLoadCallback<MediationAdT, MediationAdCallbackT> cuando llama a mediationAdLoadCallback.onSuccess(). Se espera que los adaptadores conserven este objeto y lo usen para invocar eventos de presentación que ocurren en tu anuncio.

Por lo general, la mayoría de estos eventos se generan a través del SDK de tu red de publicidad. El rol del adaptador es simplemente asignar las devoluciones de llamada de tu SDK de red de publicidad al SDK de anuncios de Google para dispositivos móviles.

En el siguiente ejemplo, se muestra cómo reenviar devoluciones de llamada desde el objeto de escucha de anuncios de tu SDK al SDK de anuncios de Google para dispositivos móviles:

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

Recursos obligatorios para el seguimiento de impresiones de anuncios nativos

El SDK de anuncios de Google para dispositivos móviles registra una impresión para un anuncio nativo cuando se ve 1 px del anuncio. Si el SDK de tu red de publicidad requiere que se muestren recursos específicos para renderizar una impresión válida, tu ofertante puede indicar estos recursos nativos requeridos en la respuesta de oferta. Luego, el SDK de anuncios de Google para dispositivos móviles valida que los recursos nativos obligatorios se muestren antes de registrar una impresión.

Consulta la documentación sobre los recursos nativos obligatorios para obtener más información sobre cómo especificar recursos obligatorios adicionales en la respuesta de oferta.

Mostrar errores de anuncios

En el caso de los formatos de pantalla completa, como los anuncios intersticiales y recompensados, en la devolución de llamada de carga exitosa, deberás proporcionar una implementación de MediationInterstitialAd o MediationRewardedAd para que el SDK de anuncios de Google para dispositivos móviles pueda solicitarle a tu adaptador que muestre el anuncio.

Si un adaptador cargó un anuncio correctamente, el SDK de anuncios de Google para dispositivos móviles espera que el anuncio esté listo para mostrarse cuando el publicador lo solicite. Esto significa que cada llamada de visualización debe generar una impresión.

Sin embargo, es posible que haya casos extremos en los que no puedas mostrar un anuncio. Si no puedes mostrar el anuncio, llama a la devolución de llamada onAdFailedToShow() para cancelar la impresión.

En la siguiente tabla, se muestra cómo las devoluciones de llamada de presentación afectan el registro de impresiones para los formatos de anuncios de pantalla completa:

Devolución de llamada Resultado
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
Ninguna de las opciones anteriores durante varios segundos Impression recorded

1 Cuando existen impresiones fallidas, no se le cobran a tu red de publicidad, pero sí afectan el ajuste de la tasa de evento facturable. Consulta la sección sobre indicadores de solicitudes de oferta para obtener más información.

En el siguiente ejemplo simulado, se muestra un ciclo de vida de carga o visualización en el que una llamada de visualización del anuncio puede generar un error.

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