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 tạo 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 của bạn giao tiếp với Google Mobile Ads SDK để tải quảng cáo do người đặ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ý hoạt động khởi tạo, 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ẽ hướng dẫn bạn cách triển khai bộ chuyển đổi để xử lý các hoạt động này.

Quy trình hoạt động 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 cho các phần dưới đây 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 Google Mobile Ads SDK sau khi quá trình khởi tạo hoàn tất.

  • Bước 10-13: Thu thập những tín hiệu từ SDK mạng quảng cáo sẽ được gửi đến người đặ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 của bạn trả về giá thầu thắng cuộc, 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 Google Mobile Ads SDK rằng quảng cáo đã được tải.

  • Bước 23 về sau: Trong khi quảng cáo đang hiển thị, hãy thông báo cho SDK Quảng cáo của Google trên thiết bị di động về các sự kiện lượt hiển thị và sự kiện nhấp chuột, cũng như các sự kiện quảng cáo khác xảy ra trong vòng đời trình bày 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 Google Mobile Ads SDK, bạn phải mở rộng lớp trừu tượng RtbAdapter. Các phần sau đây 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 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ụ dưới đây 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 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ó phiên bản của Google sử dụng một lược đồ phiên bản bộ chuyển đổi gồm 4 chữ số, nhưng VersionInfo chỉ cho phép 3 chữ số. Để khắc phục vấn đề này, bạn nên kết hợp hai chữ số cuối cùng thành phiên bản bản vá, như minh hoạ bên dưới.

@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. Phương thức này chỉ được gọi một lần cho mỗi phiên. Phương thức này cung cấp cho bạn danh sách các đối tượng MediationConfiguration biểu thị danh sách đầy đủ các vị trí trong ứng dụng này được định cấu hình cho mạng quảng cáo của bạn; Bạn có thể lặp lại qua danh sách này để phân tích cú pháp thông tin đăng nhập cho từng vị trí và truyền dữ liệu có liên quan đến SDK để khởi động.

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 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 khi nhà xuất bản yêu cầu một quảng cáo, một thực thể mới của RtbAdapter sẽ được tạo và phương thức collectSignals() sẽ được gọi. Bản sao RtbAdapter này sẽ được dùng trong suốt thời gian diễn ra vòng đời yêu cầu quảng cáo, phản hồi và hiển thị quảng cáo 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 chuỗi nền. Google Mobile Ads SDK đồng thời yêu cầu tín hiệu từ tất cả các bộ chuyển đổi tham gia đặt giá thầu. Hãy tuân thủ 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 nặng nhọc 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à được 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ã hóa.

Dưới đây là một 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 tín hiệu, hãy gọi signalCallbacks.onFailure() bằng một 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 của bạn trả về giá thầu thắng cuộc, Google Mobile Ads SDK sẽ gọi bộ chuyển đổi của bạn để tải quảng cáo thắng cuộc, truyền cho bạn mọi dữ liệu mà bên đặt giá thầu đã trả về (dữ liệu mà SDK cần để tải quảng cáo đó).

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

Đị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()

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 tham số sau:

  • MediationAdConfiguration, chứa các tham số mà SDK cần để tải quảng cáo cho giá thầu thắng cuộc, chẳng hạn như giá thầu phản hồi 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 dùng để thông báo cho Google Mobile Ads SDK khi quá trình tải thành công hoặc 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() bằng một chuỗi giải thích lỗi đã xảy ra.

Phương thức mediationAdLoadCallback.onSuccess() yêu cầu bạn chuyể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. Các 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 getWatermark() phương thức để trả về một chuỗi mã hóa base64 đại diện cho 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ờ. Vân nước 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 phương thức show() để hiển thị quảng cáo vào một 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 về việc triển khai các phương thức quảng cáo này.

Sau đây là một mẫu triển khai loadBannerAd(). Xin lưu ý rằng cách triển khai của 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 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 Google Mobile Ads SDK về mọi sự kiện trong vòng đời bản trình bày để các sự kiện đó có thể được chuyển tiếp đến nhà xuất bản. Nhà xuất bản mong đợi 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à bạn 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 để Google Mobile Ads SDK có thể chuyển tiếp các lệnh gọi lại đó đến nhà xuất bản.

Bộ chuyển đổi nên gọi các sự kiện sau đây khi có thể áp dụng:

Dành cho tất cả các định dạng
Phương thức Thời điểm gọi
reportAdClicked() Quảng cáo đã được nhấp.
reportAdImpression() Quảng cáo đã tạo ra một lượt hiển thị.
onAdOpened() Quảng cáo đã hiển thị lượt xem toàn màn hình.
onAdClosed() Lượt 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 được cấp phần thưởng.
Lệnh gọi lại video (quảng cáo có tặng thưởng và quảng cáo gốc)
onVideoStarted() Video của quảng cáo đã bắt đầu.
onVideoCompleted() Video của quảng cáo đã hoàn tất.

Bộ chuyển đổi nhận lại một MediationAdLoadCallback<MediationAdT, MediationAdCallbackT> đối tượng khi gọi mediationAdLoadCallback.onSuccess(). Bộ chuyển đổi dự kiến sẽ giữ lại đối tượng này và sử dụng đối tượng này để gọi các sự kiện hiển thị 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 Google Mobile Ads SDK.

Ví dụ sau minh hoạ cách bạn chuyển tiếp lệnh gọi lại từ trình nghe quảng cáo của SDK đến 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();
        }
    }
});

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

Google Mobile Ads SDK 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 yêu cầu hiển thị các thành phần cụ thể để hiển thị một lượt hiển thị hợp lệ, thì bên đặt giá thầu có thể cho biết các thành phần gốc bắt buộc này trong giá thầu phản hồi. Google Mobile Ads SDK sau đó xác thực rằng các thành phần gốc bắt buộc của bạn được hiển thị trước khi ghi lại một lần hiển thị.

Hãy xem tài liệu về các thành phần gốc bắt buộc để biết thêm thông tin về cách chỉ định các thành phần bắt buộc bổ sung 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, trong lệnh gọi lại tải thành công bạn sẽ cung cấp một cách triển khai MediationInterstitialAd hoặc MediationRewardedAd để Google Mobile Ads SDK có thể yêu cầu bộ chuyển đổi của bạn hiển thị quảng cáo.

Google Mobile Ads SDK mong đợi 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ị đều phải dẫn đến một lần hiển thị.

Tuy nhiên, có thể có những trường hợp đặc biệt 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 onAdFailedToShow() lệnh gọi lại để huỷ lần hiển thị.

Bảng dưới đây cho biết cách các lệnh gọi lại hiển thị ả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:

Số nhận cuộc gọi lại Kết quả
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
Không có mục nào ở trên trong vài giây Impression recorded

1 Đối với các lần 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ần hiển thị đó, nhưng điều này ảnh hưởng đến việc điều chỉnh tỷ lệ sự kiện có thể tính phí. 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ị 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, ...);
  }
}