Google Analyticsでユーザー単位でデータを分析するテクニック


#概要

Google Analyticsは非常に高度なくせに無料と素晴らしい。
しかし、個々のユーザーの動きを知りたいケースになると、途端に使い物にならない。
今回は自動付与されているclientIdを使って、簡単にユーザー単位でデータを見るまでの軌跡をまとめておく。

本記事はgtag.jsでclientIdを取得する苦労話だが、前身のanalytics.jsでは公式ドキュメントに取得方法があるので簡単に送信可能。
https://developers.google.com/analytics/devguides/collection/analyticsjs/accessing-trackers?hl=ja#getting_data_stored_on_a_tracker


#読者対象

- Google Analyticsを何となく扱えるレベルを有する方。
- ログイン状態にかかわらずユーザー単位で簡単に調査したい。
- Adsense狩りにあって困っている方。


#どうしてユーザー単位で見る必要があるの？

私の運営しているサイトはクリック報酬型のAdsenseを導入しています。
クリックされると報酬が発生するため、不正なクリックには厳しい罰則が科されます。
そして、その責任はサイト運営者が負わなくてはなりません。
先日私もAdsense狩りにあいまして、不正なクリックを監視して、不正なクリックをするユーザーを報告する必要性を感じました。
今回はその途中の段階である、個々のユーザーを識別するまでをスピンオフして切り出しました。

今回Analyticsが生成している個人を特定できないclientIdを使用しますが、個人を特定できるデータをAnalyticsに投げると規約違反なので注意しましょう。

https://support.google.com/analytics/answer/2795983

>Analyticsをご利用のすべてのお客様に遵守が求められるAnalytics利用規約は、個人情報（PII）（氏名、社会保障番号、メールアドレスなどのデータ）や、特定のデバイスを恒久的に識別できるようなデータ（携帯電話固有の端末識別子で、リセットできないものなど）を、Analyticsに送信する行為を禁じています。このようなデータを使用した場合、お客様のAnalytics アカウントは強制停止され、ご使用のデータはすべて破棄されることがあります。

#Special thanks

今回はこの記事なくして到達できませんでした。
素晴らしい記事をありがとうございました:relaxed:
https://sem-technology.info/en/google-analytics/gtag-clientid

>```javascript
>gtag('js', new Date());
>gtag('config', 'UA-xxxxxxxx-y', {
>  'custom_map': {
>    'dimension1': 'clientId'
>  }
>});
```

きっかけはStack Overflow等です。こちらもありがとうございました。
https://stackoverflow.com/questions/48368486/getting-client-id-with-gtag-js/48380241
https://www.simoahava.com/analytics/add-clientid-to-custom-dimension-gtag-js/
http://stony.me/google-analytics-explained-adding-client-id-to-a-custom-diimension-in-gtag-js/


#軌跡

##まずはどうやってユーザーを識別するか検討する

Google Analyticsでどのような形でユーザーを扱うかを検討しないといけない。
思い浮かぶのは以下の識別子。

1. ユーザーID
2. IPアドレス
3. クライアントID

まず、通常ログインしてくれるユーザーならユーザーIDで識別すればOK。
デバイス間も問題なく認識可能。これで終了。
User-ID 機能について
https://support.google.com/analytics/answer/3123662?hl=ja&ref_topic=3123660

しかし招かざる客がログインする確率は極めて低いため、私の目的ではこの方法は使えない。

次にIPアドレスによる識別。
IPアドレスは情報開示請求も想定すれば取得しておいたほうがいいが、変わりやすく共有されるものであるため識別には使えない。

最後はユーザーエクスプローラーで使用されているクライアントID。
Cookieにユニークキーを生成して保存しているらしい。
似たようなもので、Firebaseでは匿名認証をサポートしており、これも同様にユニークキーを生成してIndexedDBに保存している。
AnalyticsのクライアントIDが使用できれば、ダイレクトにユーザーエクスプローラーで検索できるので、クライアントIDを採用することに決定。


##調査過程で有益だったものを貼っておく

冒頭でのSpecialThanksのコードの通り、非常に簡単にクライアントIDをカスタムディメンションとして送信できる。
結論としてはもう出ているが、調査過程で有益だったものを残しておく。

User-ID 機能を使用するメリット
https://support.google.com/analytics/answer/3123663?hl=ja
User-ID使用するとユーザーを正確に把握できる。Firebaseの匿名認証使えばこれでもいいかもとおもったが…

User-ID のリファレンス
https://support.google.com/analytics/answer/6205850

>User-ID 機能には現在、次のような制限があります。
>
>User-ID 機能が有効なクロスデバイス レポートで指定可能な期間は最大 90 日です。
>管理画面でも API でも、レポートのディメンションとして User-ID の値を使うことはできません。

ディメンションで使用できないんじゃ意味がない。User-IDはつかえない…と思ったがこれカスタムディメンションならいけそうな気がする…ログインを前提としているサイトならこっちでよさそう。

次に思いついたのがBigQueryで扱えないかという案。
BigQuery Export のスキーマ
https://support.google.com/analytics/answer/3437719?hl=ja
Analytics360ならBigQueryにExportできる。
スキーマにclientIdとadsenseBackfillDfpClicksがあるからデータ取れると思った。
しかしAnalytics360の料金を調査すると、130万とかポルナレフ状態だったので無理:joy:

次に最近Firebase向けのAnalyticsがWebに対応した。
Firebaseの方ならBigQueryに出力できるから調査。
Firebase向けAnalyticsのBigQuery Export のスキーマ
https://support.google.com/firebase/answer/7029846?hl=ja&ref_topic=7029512
しかしスキーマを見るとWebのものとは異なるから、Adsenseのクリック抽出には使用できなそうだ。

クライアントIDを送信して問題ないことを確認しておいた。
Google の契約およびポリシーにおける個人情報の扱いを理解する
https://support.google.com/analytics/answer/7686480

>Google が個人情報として解釈しない例として、次のようなものがあります。
>
>仮名化された Cookie ID
>仮名化された広告 ID
>IP アドレス
>その他の仮名化されたエンドユーザー識別情報

Googleとしては、それ単体で個人の特定、個人への接触、個人の所在地の特定を可能にするものが個人情報と解釈している模様。


##メインディッシュ

```html:index.html

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=%REACT_APP_GOOGLE_AN_CLIENT%"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      function gtagPageview(pathname){gtag('config', '%REACT_APP_GOOGLE_AN_CLIENT%', {'page_path': pathname,'custom_map': {'dimension1':'clientId'}});}
      gtag('js', new Date());
    </script>

```

サイトはReactで構築しているのでSPA故、ページ切り替えごとにgtagPageview()をコールしている。
ここで```custom_map```を使ってdimension1にclientIdを設定している。
内部で持っているclientIdをdimension1にコピーする形なんだろうなと想像できる。
clientIdはanaylitics.jsのフィールド名だが、gtag.jsのclient_idでも問題はない。
https://developers.google.com/analytics/devguides/collection/gtagjs/migration?hl=ja#client_id_and_user_id

カスタムディメンションに関することは公式ドキュメントを参照のこと。
gtag.js を使用したカスタム ディメンションとカスタム指標
https://developers.google.com/analytics/devguides/collection/gtagjs/custom-dims-mets?hl=ja


クライアントIDをディメンションにして分類した例。
カスタムレポートを使用すれば、プライマリーディメンションにクライアントIDを使用し、完全にユーザー主体の分析が可能になる。
![クライアントごとに表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310578/37b25c47-524f-a39f-9996-93329bd015f3.png)


#まとめ

公式にはない方法ながら、賢者の素晴らしい投稿により、gtag.jsでも簡単にユーザー単位の調査が可能になりました:grinning:
個人情報保護が厳しくなる影響か、難しくなってくるのかもしれませんが、サイトの防衛には必要なことなので難しくしてもらいたくないところです。
ユーザー単位の分析ならこれで終了ですが、サイト防衛の場合にはこれにIPも必要になると思います。
IPについてはAnalyticsは開放していないでしょうから、別途用意してあげないといけないはずです。


#掲載場所がなかったその他の参照ドキュメント

gtag.jsの仕様がドキュメントに全然載っていないと思って探したらあった:sweat_smile:

gtag.js デベロッパー ガイド
https://developers.google.com/gtagjs?hl=ja
gtag.js API リファレンス
https://developers.google.com/gtagjs/reference/api?hl=ja#config

IPアドレスを取得可能か？
https://support.google.com/google-ads/thread/1449169?hl=en