Google Ad Manager のSafeFrameを利用してみる

# はじめに
GoogleAdManager等のアドサーバは、通常iframeで広告のクリエイティブを配信している。
通常のセキュリティだとiframeの中身(srcで実際に表示されている側)がiframeを操作する事はできない。
つまりインフィード広告のように、ブラウザサイズに合わせるよう表示領域を可変、拡大する場合に問題となる。

このような問題をセキュアに解決するために、IABが提唱したのがSafeFrameという規格でGoogleAdManagerにも採用されている。
GoogleAdManagerからSafeFrameを利用するにあたり覚書のため利用方法を下記にまとめた。

[参考]

* [IAB](https://www.iab.com/) 
* [SafeFrame](http://safeframes.net/)
* [DFP SafeFrame PreviewTool](http://publisherconsole.appspot.com/safeframe/creative-preview.html)

# SafeFrameとは
媒体（GoogleAdManager）と広告コンテンツの間で安全な方法で通信を行える規格。
SafeFrame APIを使用し媒体側の安全性を保ちつつ、SafeFrameが提供する範囲内で広告コンテンツは媒体の情報を取得したり表示を拡大する事ができる。
SafeFrameが提供できる機能は、媒体側の設定で利用できるものが制限されている。

# GoogleAdManagerで利用できるSafeFrameの機能
GoogleAdManagerで利用できる機能を下記に記載する。

* $sf.ext.register :  SafeFrameを実行する関数
* $sf.ext.supports：サポートしているSafeFrameの機能を返す関数
* $sf.ext.geom：メディア、クリエイティブ等の位置や幅等の情報
* $sf.ext.expand：広告拡張処理関数（プッシュモードとオーバーレイ モードの両方の展開に対応）
* $sf.ext.status：実行後のステータスを表示する関数
* $sf.ext.inViewPercentage：ビューアブル計測用関数

下記は利用が出来ない。

* $sf.ext.cookie：cookieへのアクセスは禁止
* $sf.ext.meta：meta情報の取得はできない（一部機能を除く）

# 実装サンプル
SafeFrameの機能は、GoogleAdManagerでSafeFrameモードがサポートされているクリエイティブから登録が可能。
サードパーティー、HTML5形式などが対象となる。
下記にクリエイティブに登録する内容例を記載する。
ex.) width:350 height:200 の表示枠をwidth:400 height:320 へ拡張する例。

```html:third_party_creative

<style>html,body {height:100%;background:#FFBF00;}</style>
<button onclick='expandAd();'>Expand</button>
<button onclick='collapseAd();'>Collapse</button>
<div id="feedback">hogehoge</div>

<script>
const extern = window.extern || $sf.ext;
const sfAPI = extern;
const expandedWidth = 400, expandedHeight = 320;
 
/**
 * ステータス確認用
 */
function status_update(status, data)
{
    if(status == "expanded"){
    } else if (status == "geom-update") {
        // update viewability
    }
}

/**
* 広告拡張のためSafeFrameAPI実行
*/
function expandAd() {
    const g, ex, obj;
    if ($sf.ext) {
        try {
            // サンプルでは利用していないが、下記の関数を使うことで広告コンテンツ幅や呼び出し元のページの情報を取得できる
            // g = $sf.ext.geom();
            // ex = g && g.exp;
            obj = {};
            obj.l = 0;
            obj.r = expandedWidth;
            obj.t = 0;
            obj.b = expandedHeight;
            obj.push = true; // 広告拡張モード（このサンプルはプッシュモード）
            // 広告を拡張する
            $sf.ext.expand(obj);
        } catch (e) {
        }
    } else {
    }
} 

function collapseAd(){
    $sf.ext.collapse();
}

if (extern) {
    try {
        extern.register(350, 200, status_update);
    } catch (e) {
    }
}

</script>
```
GoogleAdManagerで利用できる機能では広告拡張にオーバーレイモード（コンテンツ上書き）とプッシュモード（コンテンツ拡張）をサポートしていると記載していたが、初期値でプッシュモードが利用できないのでメディア側ではGPTタグで下記の設定値を該当のAdUnitに対し定義する必要がある。

```html:gpt_safeframe_pushmode_config
<script async='async' src='https://www.googletagservices.com/tag/js/gpt.js'></script>
<script>
    const googletag = googletag || {};
    googletag.cmd = googletag.cmd || [];
</script>

<script>
    // allowPushExpansionをtrueにし、該当のadunitにsetSafeFrameConfigで渡すことによりプッシュモードが利用可能となる。
    const safeFrameConfig = {
        allowPushExpansion: true
    };
    googletag.cmd.push(function() {
        googletag.defineSlot('[network code]', [1, 1], '[枠ID]').setSafeFrameConfig(safeFrameConfig).addService(googletag.pubads());
        googletag.pubads().enableSingleRequest();
        googletag.enableServices();
    });
</script>
```

# 参考

* [SafeFrame AD TestPage](http://safeframes.net/examples/creative_test.html)