AngularJS で Google Universal Analytics のeコマース機能を使用する


仕事で AngularJS を使った決済システム（？！）に遭遇し、Google Analytics（ga）の設定で問題が発生したので、その対処方法を調べたメモです。

## 問題の概要

AngularJS の ngView を使用してページを遷移した場合、ga の pageview イベントが発生しません。

### Chrome の Google Analytics Debugger 拡張機能での出力例

![1. toppage.png](https://qiita-image-store.s3.amazonaws.com/0/54471/a6b564fb-20e3-9ec6-6d55-624d6a05d486.png "1. toppage.png")


![2. testpage.png](https://qiita-image-store.s3.amazonaws.com/0/54471/9687bbe8-f7cd-9b6e-f66c-62e5a75944c2.png "2. testpage.png")

### 対処方法

AnglarJS のページ切り替えイベント（$routeChangeSuccess など）が発生した際、`ga("send", "pageView", [url])` を実行すればよいのですが自力で設定するのは面倒です。

勝手に設定を行ってくれるモジュールがいくつか公開されているので、これを使用します。


## モジュールの比較

[Angular Modules](http://ngmodules.org/) に登録されている、ga 用モジュールを比較しました。（似通ったモジュール名が多いので github 上の名前をそのまま記載しています）

※2014年11月19日 時点の情報です。

|名前|最終更新日|評価|備考|
|:--|:-:|:-:|:--|
|[luisfarzati/angulartics](https://github.com/luisfarzati/angulartics)|2014/11/09|△|非対応|
|[segmentio/analytics.js](https://github.com/segmentio/analytics.js)|2014/11/13|△|[Segment.io](http://segment.io) のアカウントが必要|
|[revolunet/angular-google-analytics](https://github.com/revolunet/angular-google-analytics)|2014/11/11|○|対応|
|[mgonto/angularytics](https://github.com/mgonto/angularytics)|2014/06/08|×|非対応|
|[isamuelson/angularjs-googleanalytics](https://github.com/isamuelson/angularjs-googleanalytics)|2013/04/28|×|非対応|
|[doodeec/dc-angular-analytics](https://github.com/doodeec/dc-angular-analytics)|2014/01/22|×|非対応|
|[panrafal/angular-ga](https://github.com/panrafal/angular-ga)|2014/11/15|×|低機能過ぎる|

[luisfarzati/angulartics](https://github.com/luisfarzati/angulartics) は Google Tag Manager（GTM）に対応しているので、上手く dataLayer を設定できれば GTM 経由でeコマース機能を利用できる可能性があります。（未確認）

- dataLeyer については [GTM のヘルプ](https://support.google.com/tagmanager/answer/3002596?hl=ja) を参照
- [luisfarzati/angulartics](https://github.com/luisfarzati/angulartics) で GTM を設定する方法は次の記事を参照
	- [新時代に備える！AngularJSにリマーケティングタグを実装する方法](http://developers.linecorp.com/blog/ja/?p=3360) - LINE Engineers' Blog


自力で調べるのは面倒なので、一通りの機能がそろっており使いやすそうな [revolunet/angular-google-analytics](https://github.com/revolunet/angular-google-analytics) を使用します。


## モジュールのインストール

通常通り bower でインストールします。

`$ bower install angular-google-analytics`

インストールしたら module を追加します。

```js:app.js
angular.module('test-analytics', ['ngRoute', 'angular-google-analytics'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {	// ルーティングの設定
	$locationProvider.html5Mode(true);	// URL を hash（#）無しに設定

	$routeProvider	// 適当に設定するよー
	.when('/', { templateUrl: '/views/index.html' })
	.when('/test1', { templateUrl: '/views/test1.html' })
	.when('/test2', { templateUrl: '/views/test2.html' })
	.otherwise({ redirectTo: '/' })
}])
.controller('AppController', [function AppController() {}])
.config(function(AnalyticsProvider) {	// ここから Analytics の設定
	// トラッキング ID
	AnalyticsProvider.setAccount('UA-XXXXXXXX-X');
	
	// cookieDomain の設定（localhost でテストする場合は none、本番時は auto を指定）
	AnalyticsProvider.setCookieConfig('none');
	
	// pageview トラッキングを有効化
	AnalyticsProvider.trackPages(true);
	
	// Universal Analytics を使用（省略すると legacy になる）
	AnalyticsProvider.useAnalytics(true);
	
	// 最初の pageview イベントを送信しない（後述）
	AnalyticsProvider.ignoreFirstPageLoad(true);
})
.run(function(Analytics) {
	// Analytics を初期化した直後（最初の pageview イベント送信前）に1回だけ、
	// 何らかのイベントを送信したい場合はここへ記述（なければ空 {} でOK）
	// ※ .run(...) を記載しないと Analytics が初期化されないので、空でも良いので
	// 必ず記載する
});

```

以上でページを遷移した際にも pageview イベントが発生するようになります。

![3. module.png](https://qiita-image-store.s3.amazonaws.com/0/54471/ecc4544a-2f5e-68c6-eb25-c835dc698caa.png "3. module.png")

### ignoreFirstPageLoad について

View を次のような構成にしている場合、pageview イベントが 2 回発生します。

![4. template.png](https://qiita-image-store.s3.amazonaws.com/0/54471/f5851201-6a89-15f1-51b7-1940c8d74fb1.png "4. template.png")

0. /index.html へのアクセス
	- ga("send', "pageview", "/") が発生
0. 挿入する /views/index.html へのアクセス
	- ga("send", "pageview", { "page": "/", "title": [ページのタイトル] }) が発生

![5. dobule.png](https://qiita-image-store.s3.amazonaws.com/0/54471/4746a52e-74e1-76be-f5d0-1370a2b87642.png "5. dobule.png")

この場合、ignoreFirstPageLoad を true に指定することで、1回目の不要なイベントを抑制できます。

## eコマースの実装

.config 内の設定に useECommerce を追加します。

```js:app.js
.config(function(AnalyticsProvider) {
	...省略...
	// useECommerce(ecommerce, enhancedEcommerce)
	// - ecommerce: eコマースの有効、無効
	// - enhancedEcommerce: 拡張eコマースの有効、無効
	AnalyticsProvider.useECommerce(true,false);
})
```

次にコントローラーへ、以下を追加します。

```js:app.js
// AnalyticsProvider を追加
.config(['$routeProvider', '$locationProvider', 'AnalyticsProvider', function ($routeProvider, $locationProvider, AnalyticsProvider) {
	$locationProvider.html5Mode(true);  // URL を hash（#）無しに設定

	$routeProvider
	...省略...
	.when('/thankyou', {
		templateUrl: '/views/thankyou.html',
		controller: function(Analytics) {
			// トランザクションの設定
			// 実際に設定する値は $scope などから引っ張ってくること
			Analytics.addTrans(
				'111',		// 注文 ID
				'へろへろ店',	// アフィリエイト/店舗名
				'1280',		// 合計金額
				'80',		// 税金
				'200',		// 送料
				'杉並区',	// 市区町村
				'東京都',	// 都道府県
				'日本',		// 国
				'JPY'		// 通貨
			);
			
			Analytics.addItem(	// 商品の設定
				'111',		// 注文 ID
				'X-XXX',	// SKU
				'商品A',		// 商品名
				'日用品',	// カテゴリー
				'1000',		// 単価
				'1'		// 数量
			);
			
			Analytics.trackTrans();	// eコマースイベントの送信
		}
	})
	...省略...
}])
```

以上でeコマース関連のデータが送信できます。

![6. Finish.png](https://qiita-image-store.s3.amazonaws.com/0/54471/0f11ff22-8e75-0815-4618-543d19d62a86.png "6. Finish.png")