Phát triển bộ chuyển đổi đặt giá thầu

Hướng dẫn này dành cho các mạng quảng cáo đang tìm cách xây dựng một bộ chuyển đổi đặt giá thầu để tham gia đặt giá thầu theo thời gian thực (RTB) trong tính năng dàn xếp của Google. Nếu bạn là nhà xuất bản, hãy xem hướng dẫn dàn xếp dành cho nhà xuất bản.

Bộ chuyển đổi đặt giá thầu là phần phía máy khách của hoạt động tích hợp. Bộ chuyển đổi cho phép SDK mạng quảng cáo giao tiếp với SDK quảng cáo trên thiết bị di động của Google để tải quảng cáo do bên đặt giá thầu phân phát.

Để tính năng đặt giá thầu hoạt động chính xác, bộ chuyển đổi của bạn cần phải xử lý việc khởi chạy, thu thập tín hiệu, tải quảng cáo và chuyển tiếp các sự kiện trong vòng đời quảng cáo. Trong hướng dẫn này, chúng tôi sẽ giới thiệu cách triển khai bộ chuyển đổi để xử lý các thao tác này.

Quy trình làm việc của bộ chuyển đổi đặt giá thầu

Khởi chạy

Dưới đây là luồng chi tiết về toàn bộ vòng đời yêu cầu-phản hồi-hiển thị của bộ chuyển đổi:

Bộ chuyển đổi chịu trách nhiệm thực hiện các phần sau trong quy trình làm việc:

  • Bước 4-7: Khởi chạy bộ chuyển đổi và gọi lại SDK quảng cáo trên thiết bị di động của Google sau khi quy trình khởi chạy hoàn tất.

  • Bước 10-13: Thu thập tín hiệu từ SDK mạng quảng cáo sẽ được gửi đến bên đặt giá thầu để tham gia vào yêu cầu RTB và chuyển tiếp các tín hiệu đó đến SDK quảng cáo trên thiết bị di động của Google.

  • Bước 18-21: Nếu bên đặt giá thầu trả về giá thầu giành chiến thắng, hãy tải quảng cáo theo nội dung phản hồi từ bên đặt giá thầu của bạn. Sau khi tải, hãy thông báo cho SDK quảng cáo trên thiết bị di động của Google rằng quảng cáo đã được tải.

  • Bước 23 trở lên: Trong khi quảng cáo đang hiển thị, hãy thông báo cho SDK quảng cáo trên thiết bị di động của Google về các sự kiện lượt nhấp và lượt hiển thị, cũng như các sự kiện quảng cáo khác xảy ra trong vòng đời hiển thị của quảng cáo.

Triển khai bộ chuyển đổi đặt giá thầu

Để tạo một bộ chuyển đổi đặt giá thầu cho SDK quảng cáo trên thiết bị di động của Google, bạn phải mở rộng lớp trừu tượng RtbAdapter. Các phần sau giải thích từng phương thức trừu tượng trong RtbAdapter.

getSDKVersionInfo()

Tại đây, bạn nên trả về phiên bản của SDK. Phiên bản này được chuyển cho người đặt giá thầu như một phần của yêu cầu OpenRTB.

Phương thức này yêu cầu bạn trả về một VersionInfo. Ví dụ bên dưới cho thấy cách bạn có thể chuyển đổi phiên bản chuỗi của SDK thành 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()

Tại đây, bạn nên trả về phiên bản của bộ chuyển đổi. Phiên bản này được chuyển cho người đặt giá thầu như một phần của yêu cầu OpenRTB.

Bộ chuyển đổi nguồn mở và được tạo phiên bản của Google sử dụng lược đồ phiên bản bộ chuyển đổi 4 chữ số, nhưng VersionInfo chỉ cho phép 3 chữ số. Để giải quyết vấn đề này, bạn nên kết hợp 2 chữ số cuối vào phiên bản bản vá, như minh hoạ dưới đây.

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

Thời gian chờ: 30 giây

Phương thức initialize() là phương thức đầu tiên được gọi trong bộ chuyển đổi của bạn. Phương thức này chỉ được gọi một lần cho mỗi phiên hoạt động. Phương thức này cung cấp cho bạn danh sách đối tượng MediationConfiguration đại diện cho danh sách đầy đủ các vị trí trong ứng dụng đã được định cấu hình cho mạng quảng cáo này; Bạn có thể lặp lại danh sách này để phân tích cú pháp thông tin xác thực cho từng vị trí và chuyển dữ liệu có liên quan đến SDK để khởi chạy.

Sau khi SDK được khởi tạo và sẵn sàng nhận yêu cầu quảng cáo, hãy gọi phương thức onInitializationSucceeded() của InitializationCompleteCallback. Lệnh gọi lại này được chuyển tiếp đến các nhà xuất bản ứng dụng để họ biết rằng họ có thể bắt đầu tải quảng cáo.

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

Thời gian chờ: 1 giây

Mỗi lần nhà xuất bản yêu cầu quảng cáo, một bản sao RtbAdapter mới sẽ được tạo và phương thức collectSignals() sẽ được gọi. Phiên bản RtbAdapter này sẽ được sử dụng trong suốt vòng đời yêu cầu quảng cáo, phản hồi và hiển thị cho quảng cáo đó. Phương thức collectSignals() cho phép bộ chuyển đổi của bạn cung cấp các tín hiệu từ thiết bị sẽ được gửi đến người đặt giá thầu trong yêu cầu OpenRTB.

collectSignals() được gọi trên luồng trong nền. SDK quảng cáo trên thiết bị di động của Google yêu cầu đồng thời các tín hiệu từ tất cả các bộ chuyển đổi tham gia vào hoạt động đặt giá thầu. Hãy tôn trọng và giới hạn số lệnh gọi đến luồng giao diện người dùng trong thời gian này. Mọi công việc khó khăn mà bộ chuyển đổi hoặc SDK cần thực hiện để thu thập tín hiệu đều phải được thực hiện trong phương thức initialize() và lưu vào bộ nhớ đệm.

Sau khi các tín hiệu đã sẵn sàng, hãy gọi lệnh gọi lại onSuccess() bằng các tín hiệu đã mã hoá.

Dưới đây là ví dụ về cách triển khai:

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

Nếu bộ chuyển đổi không thu thập được các tín hiệu, hãy gọi signalCallbacks.onFailure() kèm theo chuỗi giải thích lỗi đã xảy ra.

Triển khai các phương thức tải quảng cáo

Thời gian chờ: 10 giây

Nếu bên đặt giá thầu trả về giá thầu thắng cuộc, SDK quảng cáo trên thiết bị di động của Google sẽ gọi bộ chuyển đổi của bạn để tải quảng cáo chiến thắng, chuyển cho bạn mọi dữ liệu mà bên đặt giá thầu đã trả về mà SDK cần để tải quảng cáo đó.

Phương thức tải chính xác được gọi sẽ phụ thuộc vào định dạng quảng cáo trong yêu cầu này đối với:

Định dạng quảng cáo Phương thức tải
Biểu ngữ loadBannerAd()
Quảng cáo xen kẽ loadInterstitialAd()
Được thưởng loadRewardedAd()

Hãy triển khai các phương thức này cho các định dạng quảng cáo mà bộ chuyển đổi của bạn hỗ trợ.

Phương thức tải được gọi trên luồng giao diện người dùng, trên cùng một bản sao của bộ chuyển đổi mà bạn đã cung cấp tín hiệu. Phương thức này cung cấp cho bạn các thông số sau:

  • MediationAdConfiguration, chứa các thông số mà SDK cần để tải quảng cáo cho giá thầu thắng cuộc, chẳng hạn như nội dung phản hồi giá thầu và mọi thông tin đăng nhập mà nhà xuất bản đã định cấu hình trong giao diện người dùng AdMob.

  • Đối tượng MediationAdLoadCallback được dùng để thông báo cho SDK quảng cáo trên thiết bị di động của Google khi tải thành công hay không thành công.

Sau khi SDK tải quảng cáo, hãy gọi mediationAdLoadCallback.onSuccess(). Trong trường hợp tải quảng cáo không thành công, hãy gọi mediationAdLoadCallback.onFailure() kèm theo chuỗi giải thích lỗi đã xảy ra.

Phương thức mediationAdLoadCallback.onSuccess() yêu cầu bạn truyền vào một đối tượng sẽ xác nhận cho một trong các giao diện "Quảng cáo" do SDK quảng cáo trên thiết bị di động của Google xác định. Những giao diện quảng cáo này yêu cầu bạn cung cấp một số thông tin về quảng cáo.

MediationAdConfiguration cũng có một phương thức getWatermark() để trả về một chuỗi mã hoá base64 biểu thị một ảnh PNG. Ảnh này phải được xếp kề trong một lớp phủ trong suốt trên quảng cáo của bạn. Hãy liên hệ với Google để được hướng dẫn thêm về cách hiển thị hình mờ. Công cụ này chứa siêu dữ liệu về quảng cáo đang hiển thị, được các nhà xuất bản dùng để xác định nguồn của quảng cáo hiển thị.

Đối với quảng cáo biểu ngữ, bạn sẽ được yêu cầu cung cấp chế độ xem biểu ngữ. Đối với quảng cáo xen kẽ và quảng cáo có tặng thưởng, bạn sẽ được yêu cầu triển khai một phương thức show() để hiển thị quảng cáo vào thời điểm sau đó. Cách tốt nhất là bạn nên tạo lớp sẽ tải quảng cáo cũng như chịu trách nhiệm triển khai các phương thức quảng cáo này.

Sau đây là ví dụ về cách triển khai loadBannerAd(). Lưu ý rằng quá trình triển khai bộ chuyển đổi sẽ khác vì bộ chuyển đổi của bạn tích hợp với một SDK khác.

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

Chuyển tiếp các sự kiện trong vòng đời hiển thị quảng cáo

Trách nhiệm cuối cùng của bộ chuyển đổi là thông báo cho SDK quảng cáo trên thiết bị di động của Google về mọi sự kiện trong vòng đời hiển thị quảng cáo để các sự kiện đó có thể được chuyển tiếp đến nhà xuất bản. Nhà xuất bản muốn các lệnh gọi lại này vào những thời điểm cụ thể bất kể mạng quảng cáo nào phân phát quảng cáo. Vì vậy, điều quan trọng là phải gọi càng nhiều lệnh gọi lại này càng tốt và vào đúng thời điểm để SDK Quảng cáo trên thiết bị di động của Google có thể chuyển tiếp chúng đến nhà xuất bản.

Bộ chuyển đổi sẽ gọi các sự kiện sau đây (khi phù hợp):

Phổ biến với mọi định dạng
Phương thức Thời điểm gọi
reportAdClicked() Đã có người nhấp vào quảng cáo.
reportAdImpression() Quảng cáo đã hiển thị.
onAdOpened() Quảng cáo đã hiển thị chế độ xem toàn màn hình.
onAdClosed() Chế độ xem toàn màn hình của quảng cáo đã đóng.
onAdLeftApplication() Quảng cáo khiến người dùng rời khỏi ứng dụng.
Quảng cáo có tặng thưởng
onRewarded() Người dùng nhận được phần thưởng.
Lệnh gọi lại video (quảng cáo gốc và quảng cáo có tặng thưởng)
onVideoStarted() Video của quảng cáo đã bắt đầu.
onVideoCompleted() Video của quảng cáo đã kết thúc.

Bộ chuyển đổi sẽ nhận lại đối tượng MediationAdLoadCallback<MediationAdT, MediationAdCallbackT> khi gọi mediationAdLoadCallback.onSuccess(). Dự kiến bộ chuyển đổi sẽ giữ lại đối tượng này và sử dụng đối tượng để gọi các sự kiện trình bày xảy ra trên quảng cáo của bạn.

Thông thường, hầu hết các sự kiện này đều do SDK của mạng quảng cáo thúc đẩy. Vai trò của bộ chuyển đổi chỉ đơn giản là liên kết các lệnh gọi lại từ SDK mạng quảng cáo với SDK quảng cáo trên thiết bị di động của Google.

Ví dụ sau minh hoạ cách bạn sẽ chuyển tiếp lệnh gọi lại từ trình nghe quảng cáo của SDK đến SDK quảng cáo trên thiết bị di động của Google:

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

Thành phần bắt buộc để theo dõi lượt hiển thị quảng cáo gốc

SDK quảng cáo trên thiết bị di động của Google ghi lại một lượt hiển thị cho quảng cáo gốc khi 1 px của quảng cáo hiển thị. Nếu SDK mạng quảng cáo của bạn yêu cầu hiển thị những tài sản cụ thể để hiển thị lượt hiển thị hợp lệ, thì bên đặt giá thầu có thể cho biết những tài sản gốc bắt buộc này trong giá thầu phản hồi. Sau đó, SDK quảng cáo trên thiết bị di động của Google sẽ xác thực rằng những thành phần gốc bắt buộc đã xuất hiện trước khi ghi lại một lượt hiển thị.

Xem tài liệu về tài sản gốc bắt buộc để biết thêm thông tin về cách chỉ định các tài sản bổ sung bắt buộc trong phản hồi giá thầu.

Hiển thị lỗi quảng cáo

Đối với các định dạng toàn màn hình, chẳng hạn như quảng cáo xen kẽ và quảng cáo có tặng thưởng, khi gọi lại tải thành công, bạn sẽ triển khai MediationInterstitialAd hoặc MediationRewardedAd để SDK quảng cáo trên thiết bị di động của Google có thể yêu cầu bộ chuyển đổi hiển thị quảng cáo.

SDK quảng cáo trên thiết bị di động của Google dự kiến rằng nếu một bộ chuyển đổi đã tải quảng cáo thành công, thì quảng cáo đó sẽ sẵn sàng hiển thị khi nhà xuất bản yêu cầu hiển thị. Điều này có nghĩa là mỗi lệnh gọi hiển thị sẽ dẫn đến một lượt hiển thị.

Tuy nhiên, có thể có những trường hợp mà bạn không thể hiển thị quảng cáo. Nếu bạn không thể hiển thị quảng cáo, hãy gọi lệnh gọi lại onAdFailedToShow() để huỷ lượt hiển thị.

Bảng bên dưới cho biết cách lệnh gọi lại bản trình bày ảnh hưởng đến việc ghi lại lượt hiển thị cho các định dạng quảng cáo toàn màn hình:

Lệnh gọi lại Kết quả
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
Không có lựa chọn nào ở trên trong vài giây Impression recorded

1 Đối với lượt hiển thị không thành công, mạng quảng cáo của bạn không bị tính phí cho lượt hiển thị, nhưng sẽ ảnh hưởng đến mức điều chỉnh tỷ lệ sự kiện có thể lập hoá đơn. Xem tín hiệu yêu cầu giá thầu để biết thêm thông tin.

Ví dụ mô phỏng sau đây minh hoạ vòng đời tải/hiển thị mà trong đó lệnh gọi hiển thị quảng cáo có thể dẫn đến lỗi.

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