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ính năng đặ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 về 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 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ý 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ói trên.

Quy trình hoạt động của bộ chuyển đổi đặt giá thầu

Khởi chạy

Dưới đây là quy trình 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 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 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 người đặt giá thầu 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ừ người đặ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ở đi: 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ụ 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 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 hai chữ số cuối vào phiên bản bản vá, như hiển thị 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

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 1 lần/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ể xử lý từng mục trong danh sách này để phân tích cú pháp thông tin đăng nhập cho từng vị trí và chuyển dữ liệu có liên quan đến SDK để khởi tạo.

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 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 thời gian hoạt động của 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 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 nặng 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 thể thu thập 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 người đặt giá thầu của bạn 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 để tải quảng cáo thắng cuộc, chuyển cho bạn mọi dữ liệu mà người đặt giá thầu đã trả về và SDK cần để tải quảng cáo đó.

Phương thức tải chính xác được gọi sẽ tuỳ 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()

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 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 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ị vân nước. 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 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 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 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 của hoạt động 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 tới 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 có phân phát quảng cáo hay không. Do đó, điều quan trọng là các lệnh gọi lại này được gọi nhiều nhất có thể 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 lệnh gọi đế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ị một lần.
onAdOpened() Quảng cáo đã hiển thị chế độ xem toàn màn hình.
onAdClosed() Đã đóng chế độ xem toàn màn hình của quảng cáo.
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> sau 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 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 của Google trên thiết bị di động 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ị 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ể chỉ định các thành phần gốc bắt buộc này trong phản hồi giá thầu. Sau đó, SDK quảng cáo của Google trên thiết bị di động sẽ 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 lượt hiển thị.

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

SDK quảng cáo của Google trên thiết bị di động dự kiến rằng nếu một bộ chuyển đổi tải thành công một quảng cáo, 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 sẽ dẫn đến một lượt hiển thị.

Tuy nhiên, có thể có một số 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 lệnh gọi lại onAdFailedToShow() để huỷ lượt hiển thị.

Bảng dưới đây 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:

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

1 Đối với các lượt hiển thị không thành công, mạng quảng cáo của bạn sẽ không bị tính phí cho lượt hiển thị đó, nhưng điều này sẽ ảnh hưởng đến mức điều chỉnh tỷ lệ sự kiện có thể lập hoá đơn. Hãy xem phần 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, ...);
  }
}