Google Tag Manger から Google Analytics にカスタムイベントを送る方法

＊
**Google Analytics** → 以下、**GA** と略します
**Google Tag Manger** → 以下、**GTM** と略します

# 前提

- GAをセットアップ済み
- GTMをセットアップ済み
- GAとGTMの連携をセットアップ済み（GAタグをGTMによって配信している）

# 概要

GTMの [`dataLayer`](https://developers.google.com/tag-manager/reference) というAPIを使って、GAにカスタムイベントを送信する方法を説明します。

＊参考: [`dataLayer` についてのGoogle公式ガイド（英語）](https://developers.google.com/tag-manager/devguide)

カスタムイベント実装のベースはGAの [イベントトラッキング](https://developers.google.com/analytics/devguides/collection/analyticsjs/events) と呼ばれている仕組みです。
この仕組みをGTMの `dataLayer` で実装するようにします。

## `ga` 関数の場合

GAのイベントトラッキングを行う場合、通常は以下のような [`ga`](https://developers.google.com/analytics/devguides/collection/analyticsjs/command-queue-reference) 関数を使うと思いますが、

```js
ga('send', 'event', [eventCategory], [eventAction], [eventLabel], [eventValue], [fieldsObject]);
```

GTMは **非同期に** GAのタグを配信するので、`ga` 関数を使う場所すべてで `ga` 関数がが定義されているかチェックする必要があります。
（このチェックがないと、`ReferenceError: ga is not defined` といったエラーが発生する可能性があります）

```js
if ('ga' in window) {
  ga('send', 'event', 'sample category', 'sample action' /* ... */);
}
```

**＊2017-04-17 修正（@1987yama3 ご指摘ありがとうございました :bow: ）**
~~また、上記のようなコードが実行された後にGAタグが配信される可能性もあるため（配信が非同期なため）、イベントがGAに送信されないケースも出てきます。~~
また、GTMのデフォルト設定だと `ga('create')` 関数に指定される[トラッカー名](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#name)がランダムな値に設定されるために特定できず、イベントが送信されません。

```js
// GTMにより発行される
ga('create', 'UA-XXXXX-Y', { name: 'gtm1454402957304' });

// `trackeName` が指定されていないため、イベントが送信されない
ga('send', 'event', 'sample category', 'sample action');

// 正しくはこうしなければならないが `gtm1454402957304` は特定できない
ga('gtm1454402957304.send', 'event', 'sample category', 'sample action');
```

- [`ga('create')` 関数リファレンス](https://developers.google.com/analytics/devguides/collection/analyticsjs/command-queue-reference#create)
- [`ga('send')` 関数リファレンス](https://developers.google.com/analytics/devguides/collection/analyticsjs/command-queue-reference#send)

## `dataLayer` の場合

```js
dataLayer.push({
  event: 'analytics',
  eventCategory: 'sample category',
  eventAction: 'sample action'
  /* ... */
});
```

`dataLayer` の初期化コード（GTMのセットアップコード）は `<head>` タグの開始直後に置くことが推奨されているので、普通は `window.dataLayer` が定義済みであると考えてよく、 `if ('dataLayer' in window) { ... }` といった存在チェックのコードが不要になります。

＊参考: [Google公式のGTMクイックガイド](https://developers.google.com/tag-manager/quickstart)

```html
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXX');</script>
<!-- End Google Tag Manager -->
```

（関数冒頭の `w[l]=w[l]||[];` というコードは、`window['dataLayer'] = window['dataLayer'] || [];` と同等です）

また、`dataLayer` にイベントデータを `push` さえしておけば、非同期な実行タイミングのことは考慮せずに、GTMの方でよしなにイベントデータを処理してくれます。

# GTMダッシュボードでの設定

とはいえ、これまではお手軽に `ga` 関数を実行すればよかったのですが、GTM経由でイベント送信する方法では、GTMダッシュボードでの設定が必要になります。
１つレイヤーが増えてしまうので、`ga` 関数を使う方法よりは理解が難しくなります。このあたりはデメリットですね :sweat: 

**＊2017-04-17 追記**
GAタグ設定画面で「詳細設定＞高度な設定＞トラッカー名を設定する」チェックをONにして、トラッカー名」を空欄すると、これまで通り `ga` 関数が使えるようになりオススメです。

<img width="531" alt="スクリーンショット 2017-04-17 18.22.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/d8a0313d-2ea7-c153-ff23-df96e9b79a03.png">

```js
// `trackeName` を指定しなくてもイベントを送信できる
ga('send', 'event', 'sample category', 'sample action');
```

## 変数の設定

:point_down: のGTMダッシュボードのスクリーンショットを見てください。

<img width="765" alt="スクリーンショット 2017-04-14 0.09.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/ee552663-578b-4b89-27b0-a32b483e76e3.png">

この中で重要なのは、以下の変数です。

- 組み込み変数
    - `Event`: `dataLayer.push()` に渡す `event` フィールドを指す。
- ユーザー定義変数
    - `ANALYTICS_TRACKING_ID`: `UA-XXXXX-Y` 形式のGAトラッキングID。定数にしておくことで、複数のタグから参照しやすくなります。
    - GAイベントフィールド。`ga` 関数に設定するデータと同じです。
        - `eventCategory`
        - `eventAction`
        - `eventLabel`
        - `eventValue`

<img width="747" alt="スクリーンショット 2017-04-14 0.17.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/3b3884ac-a2f3-4dbc-97cb-e62f34b7acdb.png">

（[GA公式ドキュメント](https://developers.google.com/analytics/devguides/collection/analyticsjs/events)のスクリーンショット）

## トリガーの設定

次に、トリガーを設定します。トリガーとは、タグを配信させるための条件のことです。
イベント名は何でもいいのですが、ここでは `analytics` と設定することにします。

<img width="990" alt="スクリーンショット 2017-04-14 0.21.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/d6f581e0-2bef-17c0-8402-72a52216560f.png">

先ほどの組み込み変数 `Event` に `analytics` が設定されることをトリガー条件とします。実際のコードでは、以下のようになります。

```js
dataLayer.push({ event: 'analytics' });
```

## タグの設定

最後に、タグを設定します。タグタイプに「ユニバーサル アナリティクス」を選び、 :point_down: のスクリーンショットのように設定していきます。

<img width="914" alt="スクリーンショット 2017-04-14 0.26.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/0cfd4f8a-fba8-20d1-d96d-9a6fd4154881.png">

### 非インタラクションヒット

ここで注意しておきたいのは、「非インタラクションヒット」です。
[GA公式ガイド](https://developers.google.com/analytics/devguides/collection/analyticsjs/events#non-interaction_events)にある `nonInteraction` のことです。

例）

```js
ga('send', 'event', 'Videos', 'play', 'Fall Campaign', {
  nonInteraction: true
});
```

「非インタラクション」を**真（`true`）**に設定**していない**イベントをGAに送信した場合、そのセッションは**直帰**とカウント**されません** （[GA公式ヘルプ](https://support.google.com/analytics/answer/1033068#NonInteractionEvents)）。
「非インタラクションが偽（`false`）」、つまり、ユーザーのインタラクションがあると見なされて、ユーザーがそのページで何もせずに直帰した場合でも、直帰と見なされなくなります。

これは**デフォルト**の動作です（`nonInteraction: false`）。

カスタムイベントをログのように使う場合（ページに来たセッションすべてでイベントを送信するなど）、デフォルトのままだと直帰率が急激に低下します。
用途にもよりますが、**「非インタラクション」は注意深く設定するようにしてください！**
（私はまさに全ページでログ用途にイベントを送信していたため、直帰率が急激に低下して困りました :sob:）

参考:
- [イベントについて - アナリティクス ヘルプ](https://support.google.com/analytics/answer/1033068)
- [直帰率 - アナリティクス ヘルプ](https://support.google.com/analytics/answer/1009409)
- [離脱率と直帰率の違い - アナリティクス ヘルプ](https://support.google.com/analytics/answer/2525491)

## 動作確認

設定が完了したら、プレビュー機能を使って、タグが想定通りに配信されているか、`dataLayer` にきちんとデータがプッシュされているか、などを必ず確認しましょう。

<img width="436" alt="スクリーンショット 2017-04-14 0.46.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/a2e1ba93-7772-49e1-40dd-fee4c3e32247.png">

<img width="1000" alt="スクリーンショット 2017-04-14 0.47.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/e9ba8bb5-0b04-f5be-2ec6-c1aa442b5009.png">

<img width="1131" alt="スクリーンショット 2017-04-14 0.48.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/104952/ce78a44c-f4c8-42d2-2bd5-375304235ab1.png">

もちろん、実際に `dataLayer.push()` を実行するコードが必要です。
このコードはGTMで配信しても、アプリケーションのソースコードに埋め込んでも、どちらでも構いません。

例）

```js
dataLayer.push({
  event: 'analytics',
  eventCategory: 'フォームトラッキング',
  eventAction: 'click',
  eventLabel: '性別',
  eventValue: 0
});
```

GTMのプレビュー画面で `dataLayer` にプッシュされていることが確認できたら、GAのダッシュボードの

リアルタイム ＞ イベント ＞ イベント（直前の 30 分間）

で実際にイベントが送信されているか確認してみましょう。
うまくいっていれば、`dataLayer` にプッシュされて数秒後に、GAダッシュボードに反映されるはずです。

# まとめ

GTMに関しては日本語の情報が少ないので、正しい情報を探すのにかなり苦労しました。また、ダッシュボードのUIも数年前と比べてかなり変わっているので、ググった情報を参考にしても情報が古かったりして余計に混乱します。

GTM経由にすると、レイヤーが１つ増えるので理解が難しくなりますが、タグの非同期配信・高速配信などメリットもありますので、もっと使う人が増えて日本語の情報が増えるといいなと思います。
（GoogleがGTMの日本語公式リファレンスを出してくれると、もっとありがたいのですが… :sweat_smile: ）

GTMの設定やUIはかなり頻繁に変わっている印象なので、最終的には公式ドキュメントを確認するのが一番確実かと思います :smile: 
（この記事の情報も数ヶ月ですぐに陳腐化するかもしれませんので）

# 参考情報

- GAのデバッグに便利: Chrome拡張 [Google Analytics Debugger](https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna)