Prebid.jsとGoogleタグでHeaderBiddingライフ

はじめに

TechDiv BeyondXサービスチームの石鍋です。
Prebid.jsでHeaderBiddingを実現させたい人向けの記事を作成してみました。

Header Biddingって?

言葉の通り、HTMLタグの「head」タグに各SSPの「Bidding(入札)」をすることで、
広告サーバー(PrebidなのでGoogle Ad Manager)にリクエストを送信する前に各SSPに入札させ、もっとも高単価な広告とGAMの広告を競わせ、単価が高い方の広告を配信する仕組みのことです。

Prebid.jsって?

先に説明したHeader Biddingを実現させるために開発されているWeb向けの機能豊富なヘッダー入札プラットフォームのオープンソースです。
本記事はPrebid.jsのバージョンは2.xx系をターゲットとしています。

簡単な概略図

HeaderBidding実現に向けた前提条件

Prebid.jsでのHeaderBiddingの前提条件としては、たった一つ。
・Googleタグを使用して広告配信しているWEBページであること

Prebid.jsを使用してシンプルなページを作成

本ブログでは詳細は省き、おおまかな流れのみ記載します。
詳細はこちらを参照ください: Prebid.jsの本家サイト

  1. prebid.jsの入手。ソースをダウンロードして自前でビルドすることも可能ですが、WEBから簡単にビルドされたprebid.jsを入手することが可能。
    Customize and Download Prebid.js
  2. WEBページのhaedタグ内にPrebid.jsに必要な定義を記載。
    Getting Started for Developers
  3. GAMでkey-value、およびラインアイテムの作成。
    Send all bids to the ad server

いざ、配信確認! ・・・の前に確認方法

上記1~3まで問題なくできていれば、Prebid.jsを使用してHeader Bidding完了!となるのですが、
初めて挑戦した方などの場合、「え、うまくいっているの?」と不安になるかと思います。
確認方法はいくつかありますが、今回はChromeブラウザ限定となり、ちょっとひと手間かかりますが、わかりやすい確認方法をお伝えしたいと思います。
他の確認方法を知りたい方はこちらをクリック

①「F12」で開発ツールを開き、「Sources」クリック⇒下記の赤枠の矢印をクリック

② 「>>」クリック⇒「Snippets」をクリック

③ 「+New snippet」クリック

④以下の内容を貼り付ける
snippet名は任意で構いませんが、今後ほかのsnippetが増えたときにわかるような名前にしておくことをおすすめします。

(function() {
  function forEach(responses, cb) {
    Object.keys(responses).forEach(function(adUnitCode) {
      var response = responses[adUnitCode];
      response.bids.forEach(function(bid) {
        cb(adUnitCode, bid);
      });
    });
  }
  var winners = pbjs.getAllWinningBids();
  var output = [];
  forEach(pbjs.getBidResponses(), function(code, bid) {
    output.push({
      bid: bid,
      adunit: code,
      adId: bid.adId,
      bidder: bid.bidder,
      time: bid.timeToRespond,
      cpm: bid.cpm,
      msg: bid.statusMessage,
      rendered: !!winners.find(function(winner) {
        return winner.adId==bid.adId;
      })
    });
  });
  forEach(pbjs.getNoBids && pbjs.getNoBids() || {}, function(code, bid) {
    output.push({
      msg: "no bid",
      adunit: code,
      adId: bid.bidId,
      bidder: bid.bidder
    });
  });
  if (output.length) {
    if (console.table) {
      console.table(output);
    } else {
      for (var j = 0; j < output.length; j++) {
        console.log(output[j]);
      }
    }
  } else {
    console.warn('NO prebid responses');
  }
})();

⑤ Prebid.jsを導入しているWEBページで 作成したsnippetを右クリック⇒「Run」で実行

⑥開発ツールの「Console」に各SSPの買付情報やレスポンス時間、および表示されたかどうかがわかりやすく表示されていれば、疎通確認完了!

【項目説明】
index 項番
bid prebidのbidオブジェクト
adunit adunitを特定するためのユニークID。head / bodyに設置するGoogleタグのあれです。
bidder bidder名。詳しくはhttp://prebid.org/dev-docs/bidders.htmlを参照
time リクエストからレスポンスまでの経過時間
cpm 買付金額
msg Bid available:有効な買付あり
no bid:NoBid or 通信タイムアウト
rendered true:オークション勝利、かつ広告表示
false:上記以外

Prebid.jsとGoogleタグの関係について知る

Prebid.jsxGoogleタグについてもう少し深堀したいと思います。

Prebid.jsのサンプルソースの一部抜粋。
(★)記載箇所を後程ピックアップして説明します。

// ======== DO NOT EDIT BELOW THIS LINE =========== //
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function() {
    googletag.pubads().disableInitialLoad();  // ★1
});

var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];

pbjs.que.push(function() {
    pbjs.addAdUnits(adUnits);
    pbjs.requestBids({
        bidsBackHandler: initAdserver,
        timeout: PREBID_TIMEOUT
    });
});

function initAdserver() {
    if (pbjs.initAdserverSet) return;
    pbjs.initAdserverSet = true;
    googletag.cmd.push(function() {
        pbjs.setTargetingForGPTAsync && pbjs.setTargetingForGPTAsync();
        googletag.pubads().refresh();        // ★2
    });
}

// in case PBJS doesn't load
setTimeout(function() {
    initAdserver();
}, FAILSAFE_TIMEOUT);

googletag.cmd.push(function() {
    googletag.defineSlot('/19968336/header-bid-tag-1', sizes, 'div-1').addService(googletag.pubads());
    googletag.pubads().enableSingleRequest();     // ★3
    googletag.enableServices();                   // ★4
});

【覚えておいてほしいgoogleタグ API】
1 googletag.pubads().disableInitialLoad() google広告リクエストを停止させるメソッド
2 googletag.pubads().enableSingleRequest() google広告リクエストをひとまとめにする。通常であれば1アドスロットごとにgoogleへのリクエストが発生することになります。主にパフォーマンス向上(リクエストをひとまとめにできるため)を目的としています。
3 googletag.enableServices() ページ上で定義されているすべてのアドスロットのGPTサービスを有効にします。
4 googletag.pubads().refresh() ページ上の特定のスロットまたはすべてのスロットの新しい広告を取得するメソッド。通常HeaderBiddingのオークション開始時にgoogletag.pubads().disableInitialLoad()でgoogleへのリクエストを抑止しているため、このメソッドを呼び出して広告リクエストを発生させる必要があります。

詳細は下記のGoogleタグAPIをご確認ください。
参照:GPT Reference


HeaderBiddingで難しい(ハマる) ポイント としては、上記のGoogleタグのメソッドの呼び出し順序が非常に重要となる点です!

Googletagの呼び出し順序を考えてみる

WEBページ上での HeaderBiddingのステップは大きく分けると以下の3ステップになります。
 ① Google広告リクエストを一時停止
 ② prebid.jsでオークション実施
 ③ オークション結果をGoogleリクエストに設定し、Google広告リクエスト再開

上記3ステップと照らし合わせることでgoogletagの呼び出し順序が明確になります。
①google広告リクエストを一時停止 googletag.pubads().disableInitialLoad()
②prebid.jsでオークション実施 googletagの操作不要
③prebid.jsのオークション結果をgoogleに設定し、googleの広告リクエスト再開 googletag.pubads().refresh()

少し乱暴な表現かもしれないんですが、「googletag.pubads().disableInitialLoad()」をとりあえず初めに宣言していることが重要となります。
 WEBページアクセス
 ↓ googletag.defineSlot(….). addService(googletag.pubads()) ;
 ↓ googletag.pubads().disableInitialLoad();
 ↓ googletag.pubads().enableSingleRequest();
 ↓ googletag.enableServices();
 ↓ オークション
 ↓ googletag.pubads().refresh();
 広告表示

まとめ

最後までご覧いただきありがとうございました。
Prebid.jsでHeaderBiddingを実現させたいけど、なんかうまくいかない!という人向けに記事を作ってみました。prebidについては触りだけとなりますが、Googleタグの使い方については参考になれば幸いです。
Header Biddingは敷居が高いように見えますが、一つ一つ噛み砕くと思ったよりシンプルなものです。
ただ複数のHeader Biddingを組み合わせて~、となると難しいと思うので、まずはシンプルなHeader Biddingから始めることをおすすめします。
良いHeader Biddingライフを!!