masayuki-0319 / scrap

0 stars 0 forks source link

[Report] Web アプリケーションにおけるリワード広告について #10

Closed masayuki-0319 closed 3 years ago

masayuki-0319 commented 3 years ago

Abstract and TableContents

  1. リワード広告とは
    • どのような広告?
    • 実例
    • 収益の発生タイミングは?
  2. 実装前に考えること
  3. 必要な実装

References

公式

その他

masayuki-0319 commented 3 years ago

リワード広告とは

どのような広告?

広告配信側は、ユーザに対する 報酬 を決める。 ユーザは、報酬 を取得したい場合、動画広告を閲覧する。 ユーザは、動画広告の閲覧終了後、報酬 を得られる。 https://admob.google.com/intl/ja/home/resources/rewarded-ads-playbook/

実例

Web アプリケーション

masayuki-0319 commented 3 years ago

📝 リワード広告配信の参考コード

Web アプリケーション

https://withonline.jp/comic/rikka-memorandom/Xrzol

// withonline のコード

function(window){
  var debug = (function(msg){
    if (true) { console.log(msg) }
  });
  var modalHtml = function() {/*
    <div class="reward_modal_bg">
      <div class="reward_modal_contents">
        <div class="reward_modal_message">CMを見るとマンガが読めます。<br/>音量に注意して Continue を押してね。</div>
        <button class="reward_modal_btn">CMを見てマンガを読む</button>
      </div>
    </div>
  */};
  var loadingStart = (function(){
    $('body').append('<div id="loading_modal"><div class="loader">Loading...</div></div>');
  });
  var loadingStop = (function(){
    $("#loading_modal").remove();
  });
  var renderModal = function(){
    var htmlObject = document.createElement('div');
    htmlObject.innerHTML = modalHtml.toString().match(/(?:\/\*(?:[\s\S]*?)\*\/)/).pop().replace(/^\/\*/, "").replace(/\*\/$/, "");
    return htmlObject.querySelector('.reward_modal_bg');
  };
  var urlParser = function(url){
      // fallback to location object if no arg has been provided
      url = url === undefined ? window.location.href : url

      // parse url | source: https://news.ycombinator.com/item?id=12172180
      var A = document.createElement('a')
      A.href = url // "https://www.domain.io:8080/path?pa=1&ram=2#fragment"

      // extract query params as map
      var queryParams = {};
      if (A.search.length > 0) {
          A.search.split('?')[1].split('&').map(function(queryParam){
              var p = queryParam.split('=');
              queryParams[p[0]] = p[1];
          });
      }
      // [alternative] extract query params as array
      // const queryParams = A.search.length > 0 ? A.search.split('?')[1].split('&').map(queryParam => [key, value] = queryParam.split('=')) : []

      return {
          url: A.href, // "https://www.domain.io:8080/path?pa=1&ram=2#fragment"
          origin: A.origin, // "https://www.domain.io:8080"
          protocol: A.protocol, // "https"
          host: A.host, // "www.domain.io:8080"
          hostname: A.hostname, // "www.domain.io"
          port: A.port, // "8080"
          pathname: A.pathname, // "/path"
          hash: A.hash, // "#fragment"
          query_params: queryParams // {"pa" => "1", "ram" => "2"}  // to get the number of query params, use property 'size'
          // query_params: queryParams  // [["pa", "1"], ["ram", "2"]]  // to get the number of query params, use property 'length'
      }
  };
  var assignRewardEvent = function(){
    try {
      var current_href = urlParser();
      if (current_href.hash == '#anker_comic') {
        loadingStart();
      }

      googletag = window.googletag || {cmd: []};
      googletag.cmd.push(function(){
        var rewardedSlot = googletag.defineOutOfPageSlot(
          '/134974094/withonline/WO_PC_reward',
          googletag.enums.OutOfPageFormat.REWARDED
        ).addService(googletag.pubads());
        googletag.pubads().addEventListener('rewardedSlotReady', function(evt) {
          var targets = document.getElementsByClassName('js-reward');
          for (let i = 0; i < targets.length; i++) {
            var target = targets[i];
            target.querySelector('.slider-container').appendChild(renderModal());
            target.querySelector('.reward_modal_btn').addEventListener('click', function localFunc(e) {
              e.preventDefault();
              evt.makeRewardedVisible();
              self.removeEventListener('click', localFunc);
            });
          }
          loadingStop();
          if (current_href.hash == '#anker_comic') {
            $('html,body').animate({ scrollTop: $("#anker_comic").offset().top }, 'slow');
          }
          // 削除する場合.
          // googletag.destroySlots([rewardedSlot]);
         });
         googletag.pubads().addEventListener('rewardedSlotGranted', function(evt) {
          // alert('報酬が提供されました。' + JSON.stringify(evt.payload));
          var targets = document.getElementsByClassName('js-reward');
          for (let i = 0; i < targets.length; i++) {
            var target = targets[i];
            target.querySelector('.reward_modal_bg').remove();
          }
         });
         googletag.pubads().addEventListener('rewardedSlotClosed', function(evt) {
          //googletag.destroySlots([rewardedSlot]);
          var targets = document.getElementsByClassName('js-reward');
          for (let i = 0; i < targets.length; i++) {
            var target = targets[i];
            if (target.querySelector('.reward_modal_bg')) {
              target.querySelector('.reward_modal_message').innerHTML = "CMがキャンセルされました。<br>ページを再読み込みして、CMを見ると<br/>マンガが読めます。";
              target.querySelector('.reward_modal_btn').textContent = "ぺージ再読み込み"
              target.querySelector('.reward_modal_btn').addEventListener('click', function(e) {
                location.reload();
              }); 
            } else {
              target.querySelector('.slider').slick.refresh();
            }
          }
           //googletag.pubads().refresh([rewardedSlot]);
         });
        googletag.display(rewardedSlot);
        googletag.pubads().refresh([rewardedSlot]);
      });

    } catch(e) {
      console.log("------- Error:gallery_reward -------");
      console.log(e.message);
      console.log(e.stack);
    } finally {
      setTimeout(loadingStop, 5000);
    }
  }
  var callOnDOMContentLoaded = (function(callback){
    if (document.readyState === 'loading') {
      window.addEventListener('DOMContentLoaded', callback);
    } else {
      callback();
    }
  });

  callOnDOMContentLoaded(assignRewardEvent);
})(window);
masayuki-0319 commented 3 years ago

実装前に考えること

ユーザに動画広告を最後まで視聴させた後、何を報酬として提供するか が必要となる。

ソシャゲなら、 無料ジェム とか。 Web メディアなら、この先は有料会員のみ みたいなのを突破 OK にするとか。

masayuki-0319 commented 3 years ago

必要な実装 ( Web アプリケーション )

Google の方が詳しい。 ウェブ向けリワード広告を設定、入稿する(ベータ版) - Google アド マネージャー ヘルプ REWARDED WEB - Native Ads

最低限で必要な実装は、以下3つのイベントに対する Callback 関数を設定すること。