การพัฒนาอะแดปเตอร์การเสนอราคา

คู่มือนี้มีไว้สําหรับเครือข่ายโฆษณาที่ต้องการสร้างอะแดปเตอร์การเสนอราคาเพื่อเข้าร่วมการเสนอราคาแบบเรียลไทม์ (RTB) ภายในสื่อกลางของ Google หากคุณเป็นผู้เผยแพร่โฆษณา โปรดดูวิธีการสื่อกลางของผู้เผยแพร่โฆษณา

อะแดปเตอร์การเสนอราคาเป็นส่วนฝั่งไคลเอ็นต์ของการผสานรวม อะแดปเตอร์ช่วยให้ SDK เครือข่ายโฆษณาสื่อสารกับ SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google เพื่อโหลดโฆษณาที่ผู้เสนอราคาแสดงได้

เพื่อให้การเสนอราคาทํางานได้อย่างถูกต้อง ตัวแปลงจะต้องจัดการการเริ่มต้น การรวบรวมสัญญาณ โหลดโฆษณา และการถ่ายทอดเหตุการณ์ในวงจรโฆษณา ในคู่มือนี้ เราจะอธิบายวิธีติดตั้งใช้งานอะแดปเตอร์เพื่อจัดการการดำเนินการเหล่านี้

เวิร์กโฟลว์ของอะแดปเตอร์การเสนอราคา

การเริ่มต้น

ขั้นตอนโดยละเอียดของวงจรการตอบสนองของคำขอทั้งหมดที่แสดงผลของอะแดปเตอร์แสดงอยู่ด้านล่าง

อะแดปเตอร์มีหน้าที่รับผิดชอบในส่วนต่อไปนี้ของเวิร์กโฟลว์

  • ขั้นตอนที่ 4-7: เริ่มต้นอะแดปเตอร์และเรียกใช้ SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google อีกครั้งเมื่อเริ่มต้นเสร็จแล้ว

  • ขั้นตอนที่ 10-13: รวบรวมสัญญาณจาก SDK ของเครือข่ายโฆษณาเพื่อส่งไปยังผู้เสนอราคาเพื่อเข้าร่วมในคําขอ RTB และส่งต่อไปยัง SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google

  • ขั้นตอนที่ 18-21: หากผู้เสนอราคาส่งคืนราคาเสนอที่ชนะ ให้โหลดโฆษณาตามคําตอบจากผู้เสนอราคา เมื่อโหลดแล้ว ให้แจ้ง SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google ว่าโหลดโฆษณาแล้ว

  • ขั้นตอนที่ 23 ขึ้นไป: ขณะที่โฆษณาแสดงอยู่ ให้แจ้ง SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google เกี่ยวกับเหตุการณ์การแสดงผลและการคลิก รวมถึงเหตุการณ์อื่นๆ ของโฆษณาที่เกิดขึ้นในวงจรการแสดงโฆษณา

การใช้อะแดปเตอร์การเสนอราคา

หากต้องการสร้างอะแดปเตอร์การเสนอราคาสําหรับ Google Mobile Ads SDK คุณต้องขยายRtbAdapterคลาส Abstract ส่วนต่อไปนี้อธิบายเมธอดนามธรรมแต่ละรายการใน RtbAdapter

getSDKVersionInfo()

ในส่วนนี้ คุณควรส่งคืนเวอร์ชันของ SDK ระบบจะส่งเวอร์ชันนี้ไปยังผู้เสนอราคาโดยเป็นส่วนหนึ่งของคําขอ OpenRTB

วิธีนี้กำหนดให้คุณส่งคืน VersionInfo ตัวอย่างด้านล่างแสดงวิธีแปลงเวอร์ชันสตริงของ SDK เป็น 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()

ในส่วนนี้ คุณควรระบุเวอร์ชันของอะแดปเตอร์ ระบบจะส่งเวอร์ชันนี้ไปยังผู้เสนอราคาโดยเป็นส่วนหนึ่งของคําขอ OpenRTB

อะแดปเตอร์แบบโอเพนซอร์สและเวอร์ชันของ Google ใช้รูปแบบเวอร์ชันอะแดปเตอร์ 4 หลัก แต่ VersionInfo อนุญาตให้ใช้เพียง 3 หลัก วิธีแก้ปัญหาชั่วคราวคือให้รวมตัวเลข 2 หลักสุดท้ายไว้ในเวอร์ชันแพตช์ ดังที่แสดงด้านล่าง

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

ระยะหมดเวลา: 30 วินาที

เมธอด initialize() เป็นเมธอดแรกที่เรียกใช้ในอะแดปเตอร์ ระบบจะเรียกใช้เพียงครั้งเดียวต่อเซสชัน เมธอดนี้จะแสดงรายการออบเจ็กต์ MediationConfiguration ที่แสดงรายการตําแหน่งทั้งหมดในแอปนี้ซึ่งกําหนดค่าไว้สําหรับเครือข่ายโฆษณาของคุณ คุณสามารถวนดูรายการนี้เพื่อแยกวิเคราะห์ข้อมูลเข้าสู่ระบบสําหรับตําแหน่งแต่ละรายการ และส่งข้อมูลที่เกี่ยวข้องไปยัง SDK เพื่อนําไปเริ่มต้นใช้งาน

เมื่อเริ่มต้น SDK และพร้อมรับคําขอโฆษณาแล้ว ให้เรียกใช้เมธอด onInitializationSucceeded() ของ InitializationCompleteCallback ระบบจะส่งต่อการเรียกกลับนี้ไปยังผู้เผยแพร่โฆษณาเพื่อให้ทราบว่าสามารถเริ่มโหลดโฆษณาได้

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

ระยะหมดเวลา: 1 วินาที

ทุกครั้งที่ผู้เผยแพร่โฆษณาขอโฆษณา ระบบจะสร้างอินสแตนซ์ใหม่ของ RtbAdapter และเรียกใช้เมธอด collectSignals() ระบบจะใช้อินสแตนซ์ของ RtbAdapter นี้ตลอดอายุวงจรคำขอโฆษณา การตอบกลับ และการเรนเดอร์โฆษณานั้น เมธอด collectSignals() ช่วยให้อะแดปเตอร์ส่งสัญญาณจากอุปกรณ์ไปยังผู้เสนอราคาในคำขอ OpenRTB ได้

collectSignals() เรียกในเธรดเบื้องหลัง SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google จะขอสัญญาณจากอะแดปเตอร์ทั้งหมดที่เข้าร่วมการเสนอราคาพร้อมกัน โปรดเคารพและจำกัดการเรียกใช้ชุดข้อความ UI ในช่วงเวลานี้ งานหนักที่อะแดปเตอร์หรือ SDK ต้องทำเพื่อรวบรวมสัญญาณควรทำในเมธอด initialize() และแคชไว้

เมื่อสัญญาณพร้อมแล้ว ให้โทรกลับหา onSuccess() พร้อมสัญญาณที่เข้ารหัส

ตัวอย่างการใช้งาน

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

หากอะแดปเตอร์รวบรวมสัญญาณไม่ได้ ให้เรียกใช้ signalCallbacks.onFailure() พร้อมสตริงที่อธิบายข้อผิดพลาดที่เกิดขึ้น

ใช้วิธีการโหลดโฆษณา

ระยะหมดเวลา: 10 วินาที

หากผู้เสนอราคาแสดงราคาเสนอที่ชนะ Google Mobile Ads SDK จะเรียกใช้อะแดปเตอร์เพื่อโหลดโฆษณาที่ชนะ โดยส่งข้อมูลที่ผู้เสนอราคาแสดงซึ่ง SDK ของคุณต้องใช้เพื่อโหลดโฆษณานั้น

วิธีการโหลดที่เรียกใช้จะขึ้นอยู่กับรูปแบบโฆษณาของคําขอนี้

รูปแบบโฆษณา วิธีโหลด
แบนเนอร์ loadBannerAd()
โฆษณาคั่นระหว่างหน้า loadInterstitialAd()
ได้รับรางวัลแล้ว loadRewardedAd()

ใช้วิธีการเหล่านี้กับรูปแบบโฆษณาที่อะแดปเตอร์รองรับ

ระบบจะเรียกใช้เมธอด load ในเธรด UI ในอินสแตนซ์เดียวกันของอะแดปเตอร์ที่คุณให้สัญญาณ วิธีนี้จะมีพารามิเตอร์ต่อไปนี้

  • MediationAdConfiguration ซึ่งมีพารามิเตอร์ที่ SDK ของคุณต้องใช้เพื่อโหลดโฆษณาสําหรับราคาเสนอที่ชนะ เช่น การเสนอราคาตอบและข้อมูลเข้าสู่ระบบที่ผู้เผยแพร่โฆษณากําหนดค่าไว้ใน UI ของ AdMob

  • MediationAdLoadCallbackออบเจ็กต์ที่ใช้เพื่อแจ้งให้ Google Mobile Ads SDK ทราบเมื่อการโหลดสําเร็จหรือไม่สําเร็จ

เมื่อ SDK โหลดโฆษณาแล้ว ให้เรียก mediationAdLoadCallback.onSuccess() ในกรณีที่การโหลดโฆษณาไม่สําเร็จ ให้เรียกใช้ mediationAdLoadCallback.onFailure() พร้อมสตริงที่อธิบายข้อผิดพลาดที่เกิดขึ้น

เมธอด mediationAdLoadCallback.onSuccess() กำหนดให้คุณส่งออบเจ็กต์ที่สอดคล้องกับอินเทอร์เฟซ "โฆษณา" รายการใดรายการหนึ่งที่กำหนดโดย SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google อินเทอร์เฟซโฆษณาเหล่านี้จะขอให้คุณระบุข้อมูลบางอย่างเกี่ยวกับโฆษณา

MediationAdConfiguration ยังมีเมธอด getWatermark() ในการแสดงผลสตริงที่เข้ารหัส Base64 ซึ่งแสดงรูปภาพ PNG ด้วย รูปภาพนี้ควรวางเป็นไทล์แบบวางซ้อนโปร่งใสในโฆษณา โปรดติดต่อ Google เพื่อขอคำแนะนำเพิ่มเติมเกี่ยวกับวิธีแสดงผลลายน้ำ ซึ่งประกอบด้วยข้อมูลเมตาเกี่ยวกับโฆษณาที่แสดงเพื่อให้ผู้เผยแพร่โฆษณาใช้ระบุแหล่งที่มาของโฆษณาที่แสดง

สําหรับแบนเนอร์ ระบบจะขอให้คุณระบุมุมมองแบนเนอร์ สําหรับโฆษณาคั่นระหว่างหน้าและโฆษณาที่มีการให้รางวัล ระบบจะขอให้คุณใช้วิธีการ show() เพื่อแสดงโฆษณาในภายหลัง แนวทางปฏิบัติแนะนำคือให้คลาสที่โหลดโฆษณารับผิดชอบในการติดตั้งใช้งานวิธีการโฆษณาเหล่านี้ด้วย

ต่อไปนี้เป็นตัวอย่างการใช้งาน loadBannerAd() โปรดทราบว่าการใช้งานอะแดปเตอร์จะมีลักษณะแตกต่างออกไป เนื่องจากอะแดปเตอร์ผสานรวมกับ 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;
  }
}

ส่งต่อเหตุการณ์ในวงจรของการแสดงโฆษณา

ความรับผิดชอบสุดท้ายของอะแดปเตอร์คือการแจ้งให้ Google Mobile Ads SDK ทราบถึงเหตุการณ์ในวงจรการแสดงผล เพื่อให้ส่งต่อไปยังผู้เผยแพร่โฆษณาได้ ผู้เผยแพร่โฆษณาคาดหวังว่าจะได้รับคอลแบ็กเหล่านี้ในเวลาที่เจาะจง ไม่ว่าเครือข่ายโฆษณาใดจะแสดงโฆษณาก็ตาม ดังนั้นจึงควรเรียกใช้คอลแบ็กเหล่านี้ให้มากที่สุดเท่าที่จะเป็นไปได้และในเวลาที่เหมาะสม เพื่อให้ Google Mobile Ads SDK ส่งต่อคอลแบ็กเหล่านี้ไปยังผู้เผยแพร่โฆษณาได้

อะแดปเตอร์ควรเรียกใช้เหตุการณ์ต่อไปนี้ (หากมี)

เหมือนกันสำหรับทุกรูปแบบ
วิธีการ กรณีที่ควรโทร
reportAdClicked() มีการคลิกโฆษณา
reportAdImpression() โฆษณาแสดงผล
onAdOpened() โฆษณาแสดงในโหมดเต็มหน้าจอ
onAdClosed() ปิดมุมมองแบบเต็มหน้าจอของโฆษณาแล้ว
onAdLeftApplication() โฆษณาทําให้ผู้ใช้ออกจากแอปพลิเคชัน
โฆษณาที่มีการให้รางวัล
onRewarded() ผู้ใช้ได้รับรางวัล
การติดต่อกลับทางวิดีโอ (โฆษณาที่มีการให้รางวัลและโฆษณาเนทีฟ)
onVideoStarted() วิดีโอของโฆษณาเริ่มเล่น
onVideoCompleted() วิดีโอของโฆษณาเสร็จสมบูรณ์แล้ว

อะแดปเตอร์จะได้รับMediationAdLoadCallback<MediationAdT, MediationAdCallbackT> ออบเจ็กต์กลับเมื่อเรียกใช้ mediationAdLoadCallback.onSuccess() คาดว่าอะแดปเตอร์จะเก็บออบเจ็กต์นี้ไว้และใช้เพื่อเรียกเหตุการณ์การแสดงผลที่เกิดขึ้นในโฆษณา

โดยปกติแล้ว เหตุการณ์เหล่านี้ส่วนใหญ่จะมาจาก SDK ของเครือข่ายโฆษณา บทบาทของอะแดปเตอร์คือจับคู่การเรียกกลับจาก SDK เครือข่ายโฆษณากับ SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google

ตัวอย่างต่อไปนี้แสดงวิธีส่งต่อการเรียกกลับจากโปรแกรมฟังโฆษณาของ SDK ไปยัง 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();
        }
    }
});

ชิ้นงานที่จําเป็นสําหรับการติดตามการแสดงโฆษณาเนทีฟ

Google Mobile Ads SDK จะบันทึกการแสดงผลของโฆษณาเนทีฟเมื่อโฆษณาแสดง 1 พิกเซล หาก SDK เครือข่ายโฆษณากำหนดให้ต้องแสดงชิ้นงานหนึ่งๆ เพื่อแสดงผลลัพธ์ที่ถูกต้อง ผู้เสนอราคาสามารถระบุชิ้นงานเนทีฟที่จำเป็นเหล่านี้ในการตอบกลับราคาเสนอ จากนั้น Google Mobile Ads SDK จะตรวจสอบว่าชิ้นงานเนทีฟที่จําเป็นแสดงก่อนบันทึกการแสดงผล

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีระบุชิ้นงานที่จําเป็นเพิ่มเติมในการเสนอราคาได้จากเอกสารประกอบเกี่ยวกับชิ้นงานที่จําเป็นสําหรับโฆษณาเนทีฟ

แสดงข้อผิดพลาดเกี่ยวกับโฆษณา

สําหรับรูปแบบแบบเต็มหน้าจอ เช่น โฆษณาคั่นระหว่างหน้าและโฆษณาที่มีการให้รางวัล คุณจะระบุการใช้งาน MediationInterstitialAd หรือ MediationRewardedAd ในคอลแบ็กการโหลดที่ประสบความสําเร็จ เพื่อให้ SDK โฆษณาในอุปกรณ์เคลื่อนที่ของ Google ขอให้อะแดปเตอร์แสดงโฆษณาได้

Google Mobile Ads SDK คาดหวังว่าหากอะแดปเตอร์โหลดโฆษณาสําเร็จ โฆษณาจะพร้อมแสดงเมื่อผู้เผยแพร่โฆษณาขอให้แสดง ซึ่งหมายความว่าการเรียกใช้การแสดงผลทุกครั้งควรส่งผลให้มีการแสดงผล

อย่างไรก็ตาม อาจมีบางกรณีที่คุณแสดงโฆษณาไม่ได้ หากแสดงโฆษณาไม่ได้ ให้เรียกใช้การเรียกกลับ onAdFailedToShow() เพื่อยกเลิกการแสดงผล

ตารางด้านล่างแสดงวิธีที่การเรียกกลับของการแสดงผลส่งผลต่อการบันทึกการแสดงผลสําหรับโฆษณาแบบเต็มหน้าจอ

การติดต่อกลับ ผลลัพธ์
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
ไม่ตรงกับข้อใดเลยเป็นเวลาหลายวินาที Impression recorded

1 สําหรับการแสดงผลที่ไม่สําเร็จ ระบบจะไม่เรียกเก็บเงินจากเครือข่ายโฆษณาสําหรับการแสดงผลนั้น แต่การแสดงผลดังกล่าวจะส่งผลต่อการปรับอัตราเหตุการณ์ที่เรียกเก็บเงินได้ ดูข้อมูลเพิ่มเติมที่สัญญาณคําขอราคาเสนอ

ตัวอย่างจำลองต่อไปนี้แสดงวงจรการโหลด/แสดงโฆษณาที่การเรียก adshow อาจส่งผลให้เกิดความล้มเหลว

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