td-js-sdk(Treasure Data)をGTM経由で配信した時に得たTips

この記事は GMOペパボ [Advent Calendar 2018](https://qiita.com/advent-calendar/2018/pepabo) 10日目 の記事です。
**突然ですが皆さん、プロダクトの行動ログって収集してますか??**
ちょっと前に、`Treasure Data`で行動ログをに収集する!!!1ために、プロダクトに[`td-js-sdk`](https://github.com/treasure-data/td-js-sdk)を導入することを経験しました。
実際に行動ログを取り始めると、プロダクトにあるどのページにアクセスしているのかを、`Treasure Data`のダッシュボード上でSQLを叩くとわかるのがとても面白い!!!っと思いました。
今回はその時に得た主に`GTM(Google Tag Manager)`周りのTipsを書いていこうと思います。
え!?`Treasure Data`って聞くとなんか難しそう!?そんなこと全然無いですよ!!簡単に設定できちゃいます!!!
`Treasure Data`のDEMO版のリクエストは[こちらのURL](https://www.treasuredata.com/custom-demo/)からリクエストすれば使えるようです。
(自分のプライベートのgmail入れたら、バリデーションエラーになったので会社のメールアドレスとかじゃないと作れないっぽいのかな...)
DB作成方法については、色々なやり方があるようですが、[公式ドキュメント](https://support.treasuredata.com/hc/en-us)(一部日本語対応してます)や[こちらの記事](https://qiita.com/akito1986/items/550393f1bf8ae674742a)が参考になるかと思います。

## `td-js-sdk`をGTM経由で配信する
### コンテナを作成する
`td-js-sdk`を導入するに当たり[公式リポジトリ](https://github.com/treasure-data/td-js-sdk#script-snippet)にある`Script snippet`をプロダクトの共通のページ(Railsでいうと`views/layouts/application.html.erb`的な共通ページ)に埋め込むのですが、直接埋め込んでしまうと管理が煩雑になってしまいます。
そのためGTMを使って配信することで一元管理され何か値が変わった場合、GTMのダッシュボードから変更できるようになります。(直接埋め込んだ場合、プルリクエストをして変更することになるかと思います...)
さっそく、GTMにアクセスしましょう。
GTMを初めて利用する際はアクセスすると、以下のようなコンテナ作成ページが表示されると思います。(Dockerのコンテナとは意味が違う)
アカウント名と国を入力し、コンテナ名にプロダクト名を入れましょう。
最後にコンテナの使用場所(今回は`ウェブ`)を選択して`作成`を押せばダッシュボードへアクセスできるようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/514f63a3-e560-0ddd-ee84-5ff095090094.png)

### td-js-sdkのタグを作成する
画面にある`タグ`をクリックし赤い`新規`ボタンを押すと以下のような画面になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/1a7923be-5f5c-7137-96ac-7f073e88fc7f.png)

タグの名前は何でも良いです。(今回は`td-js-sdk`とします)
タグの設定は`カスタムHTML`を選択し、HTMLのところに[公式リポジトリ](https://github.com/treasure-data/td-js-sdk#script-snippet)にある`script-snippet`を貼り付けます。
`foo`のところに、`Treasure Dataのデータベース名`を、`writeKey`にTreasure Dataのダッシュボードで発行する書き込み専用の`APIキー`を入れます。
![screencapture-tagmanager-google-2018-12-10-06_25_06.png](https://qiita-image-store.s3.amazonaws.com/0/131669/a3610e5c-f2ec-aa65-2daf-fa6481fab4eb.png)

```html
<script type="text/javascript">
!function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["blockEvents","unblockEvents","setSignedMode","setAnonymousMode","resetUUID","addRecord","fetchGlobalID","set","trackEvent","trackPageview","trackClicks","ready"],n=0;n<s.length;n++){var c=s[n];e[t].prototype[c]=r(c)}var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=("https:"===document.location.protocol?"https:":"http:")+"//cdn.treasuredata.com/sdk/2.1/td.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)}}("Treasure",this);
  
var foo = new Treasure({
  database: 'Treasure Dataのデータベース名',
  writeKey: '発行したAPIキー'
});  
</script>
```

トリガーには`All Pages`を選択します。

### GTMをプロダクトに埋め込む
GTMのダッシュボードにあるコンテナID(`ワークスペースでの変更数`の左横あたりにある)をクリックすると`Google タグマネージャをインストール`というモーダルウィンドウが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/26a83e44-7b92-7d54-ae3b-839ffa5ddde2.png)

`このコードは、次のようにページの <head> 内のなるべく上のほうに貼り付けてください。`という方のスクリプトをコピーし、プロダクトの共通のページ(先程言っていたRailsでいう`views/layouts/application.html.erb`的な共通ページ)の`<head>`タグ直下に貼り付けてください、`<script>`を外して、GTM用のjsファイルを作成し、それを`<head>`に読み込ませるのもアリだと思います。

### どうやって確認するの?
GTMの配信方法はダッシュボードにある`公開`ボタンを押せば公開できます。けど、確認せずに公開って怖いですよね。大丈夫です。GTMには`プレビュー`という機能があります。
ダッシュボードにある`プレビュー`を押してみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/a9d83ac7-db0f-0f69-3179-17da8c579f65.png)
すると以下のようなものが表示されます。
この状態からタグ(トリガー、変数)に変更があれば更新ボタンを押す必要があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/bcb9f78f-8a49-9f16-ab0c-48352d570206.png)
それでは、自分のプロダクトのローカル環境にアクセスしてみましょう(どのページでも良いです。staging環境にデプロイして確認でも大丈夫です。)
すると以下のようなデバッグモードがぴょこっと表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/230a53f5-c70c-822e-c749-e7dfd16be151.png)
すると`Summary`の欄に設定したタグが表示されます。ここで`Fired`(発火)と表示されていれば成功です。
(どーでも良いですが疲れた時にここの表示の字面が`failed`に見えて失敗したんじゃないかとよく勘違いしていました...)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/b63b8047-82ec-df70-8942-f1aa26539948.png)

これで`td-js-sdk`をGTM経由で配信することができました。
いやいやいやいやいやいや、行動ログまだ送れるようにしてないでしょ!?
そうですね。ここからは行動ログを送るタグを作成します。

## 行動ログを送るタグを作成
**事前にTreasure Data側のDBに`行動ログを収集するテーブル`(下記画像でいうところの`action-log`)を作成しておいてください**
さてここからが本番です。と言っても簡単ですが...
`td-js-sdk`を作成したときのようにタグを新規で作成し、カスタムHTMLを選択し、以下のスクリプトを入れます。
タグの名前は今回は`action-log`という名前にします。

```html
<script>  
  td.setAnonymousMode();
  td.set('行動ログを収集するテーブル名');
  td.trackPageview('行動ログを収集するテーブル名');
</script>
```
`詳細設定`をクリックし、`タグの順位付け`を選択し、`〜が発効する前にタグを配信`の設定タグを`td-sdk-js`を選択します。
あとは、トリガーを`All Pages`に選択して保存しましょう。

![screencapture-tagmanager-google-2018-12-10-07_04_53.png](https://qiita-image-store.s3.amazonaws.com/0/131669/1c07920a-77a1-2353-abc6-27b105453221.png)

### setAnonymousModeについて(ココ重要)
`setAnonymousMode`というのはバージョン2.0 から追加された `Do Not Track` 機能というものでユーザのデータ主体の同意状況によって取得するデータを選択できるオプション機能です。
今回はIPアドレス`td_ip`・`td_client_id`・`td_global_id`が匿名化される`setAnonymousMode`で設定しております。
もし、プロダクトによってIPアドレスも知りたい場合は`setSignMode`を選択し、以下のようにスクリプトを変更することになります。

```html

<script>
  td.setSignedMode();
  td.set('$global', 'td_global_id', 'td_global_id');
  td.set('行動ログを収集するテーブル名');
  td.trackPageview('行動ログを収集するテーブル名', td.fetchGlobalID);
</script>
```
**ただし、特にIPアドレスは昨今話題になっているGDPR（EU一般データ保護規則）に関わってくる話になるため、自社のプロダクトの責任者や法務担当の方に確認・相談をしてから`setSignMode`への設定変更を検討するのが良いかと思います。**
`Do Not Track` 機能の詳細は公式ブログを、td-js-sdkのGDPR対応についてはサポートページを御覧ください。(一度ご一読することを勧めます)
>JavaScript SDKのオプトアウト機能とHive/Presto UDF “TD_IP_TO_COUNTRY_CODE”
https://www.treasuredata.co.jp/blog_jp/do-not-track-td-ip-to-country-code/

>GDPR対応のJavascript SDKとモバイルSDK のご案内
https://support.treasuredata.com/hc/ja/articles/360001496727-GDPR%E5%AF%BE%E5%BF%9C%E3%81%AEJavascript-SDK%E3%81%A8%E3%83%A2%E3%83%90%E3%82%A4%E3%83%ABSDK-%E3%81%AE%E3%81%94%E6%A1%88%E5%86%85

さて、この状態でGTMをプレビューモードにし(既にプレビューモードの場合は`更新`をクリック)、ローカル環境にアクセスしてみましょう。
すると先ほと作成した`行動ログを送るタグ`(今回で言うところの`action-log`)が`Fired`になっているかと思います。
確認したら、`Treasure Data`のダッシュボードにアクセスし、該当のDBのテーブルにアクセスしてみましょう。
少し時間が経ったらかもですが、レコードが追加されているはずです。

## リリース方法
さて、プレビューモードでの確認ができたら、最後にリリースをします。
リリースは以下2つになります。

1. GTMコンテナのリリース
1. [GTMをプロダクトに埋め込む](https://qiita.com/bake0937/items/f170f01a81ae2702bf8c#gtm%E3%82%92%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E3%81%AB%E5%9F%8B%E3%82%81%E8%BE%BC%E3%82%80)をプルリクエストしてリリース

`1.`は普通にプルリクエスト作成してリリースする作業なので、`2.`について説明します。

### GTMコンテナのリリース
こちらも特に難しくなく、GTMダッシュボードにある`公開`をクリックします
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/901f27df-d6d5-c2ac-62cd-c8e400b90e12.png)
すると以下のような画面が表示されます。
バージョン名とバージョンの説明には今回追加したタグのついての説明を入れます。
どんな風に説明を入れるかは人それぞれだとは思いますが私は、普段のプルリクエスト時に入れる説明文を意識して入れております。
![screencapture-tagmanager-google-2018-12-10-07_44_25.png](https://qiita-image-store.s3.amazonaws.com/0/131669/75074bbd-84ed-8dde-96ba-0d7540f0e3fe.png)
最後に公開をクリックすれば公開されます。
その後に`2.`をリリースすればOKです。

## Appendix
### 環境別に行動ログを収集する
おそらく、皆さんのプロダクトには`devlopment`、`staging`、`production`と環境が別にあるかと思います。
トレジャーデータ側のDBも環境別にある場合(今回、Treasure Data側に`devlopment-my-product`、`staging-my-product`、`production-my-product`というDBを作っていると仮定します。の場合)はどうしたら良いでしょうか?
これは、実はGTMの`変数`を使うだけで解決します。
ダッシュボードで変数メニューをクリックし、**ユーザ定義変数の方の変数**のボタンを押します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131669/fcc50910-6e97-17f4-f802-3c5c14d26ec7.png)
すると以下のように表示され、変数のタイプを`カスタム JavaScript`を選択します。
名前は`environment`とします。
![screencapture-tagmanager-google-2018-12-10-08_12_27.png](https://qiita-image-store.s3.amazonaws.com/0/131669/3ea832b4-06ce-ca12-e39b-20fb201b806f.png)
`カスタム JavaScript`には以下を入れます。

```javascript
function () {
  switch(document.domain){
    case 'プロダクトのproductionのURL': return 'Treasure Dataのproductionのデータベース名'
    case 'プロダクトのstagingのURL': return 'Treasure Dataのstagingのデータベース名'
  }
  return 'Treasure Dataのdevlopmentのデータベース名'
}
```
この後、保存すればOKです。

### 作成した変数を使う
[td-js-sdkのタグを作成する](https://qiita.com/bake0937/items/f170f01a81ae2702bf8c#td-js-sdk%E3%81%AE%E3%82%BF%E3%82%B0%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)で作成したタグを以下のように変更し、作成した変数を使うようにします。

```diff
<script type="text/javascript">
!function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["blockEvents","unblockEvents","setSignedMode","setAnonymousMode","resetUUID","addRecord","fetchGlobalID","set","trackEvent","trackPageview","trackClicks","ready"],n=0;n<s.length;n++){var c=s[n];e[t].prototype[c]=r(c)}var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=("https:"===document.location.protocol?"https:":"http:")+"//cdn.treasuredata.com/sdk/2.1/td.min.js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)}}("Treasure",this);
  
var foo = new Treasure({
--  database: 'Treasure Dataのデータベース名',
++  database: '{{environment}}',
  writeKey: '発行したAPIキー'
});  
</script>
```

この後、プレビューモードでの確認をしましょう!
OKの場合はまた、GTMコンテナのリリースをすればプロダクトに反映されます。

## さいごに
これで、GTM経由で`Treasure Data`を使って行動ログを収集できるようになりました!! :tada::tada:
行動ログを取ることで、ユーザはどのページに興味があるのか、どんなことを実現したいのかという仮設やそれに繋がる施策が生まれるかと思います。
プロダクトの規模に関わらず、グロースするためには行動ログは大事な財産の一つになるかと思います。
この記事を通して少しでも参考になって「お!ウチでも行動ログ収集してみるか!!」ってなったら幸いです。
これからもどんどん仕組みを作っていくぞ!!!!!!1111