PythonでMeasurement Protocolを使う

皆さんこんにちは。@best_not_bestです。

GoogleアナリティクスのMeasurement Protocolを使用することで、HTTPリクエストで生データを Googleアナリティクスサーバに直接送信することが出来ます。
これにより、オンラインとオフラインでの行動を結び付け、Googleアナリティクス上で分析することが可能になります。

## Measurement Protocolについて

### 公式ドキュメント

https://developers.google.com/analytics/devguides/collection/protocol/

### データインポートとの違い

Googleアナリティクスには[データインポート](https://support.google.com/analytics/answer/3191589)という似たような機能がありますが、違いは（ざっくりと）以下になります。

|  | Measurement Protocol | データインポート |
|:-----:|:-----|:-----|
| **データの送信方法** | HTTPリクエスト | 主にファイルアップロード |
| **送信対象のユーザ** | Googleアナリティクス内に存在しないユーザ（新規ユーザ）のデータ送信も可能 | Googleアナリティクス内に存在するユーザ（既存ユーザ）のみ |
| **反映時間** | ほぼリアルタイム | 24時間程度かかることもある |
| **Pythonでの使用例を記した公式ドキュメント** | なし | あり（[Management API](https://developers.google.com/analytics/devguides/config/mgmt/v3/data-import)） |

## 利用例

### Googleアナリティクス無償版

[カスタムディメンション](https://support.google.com/analytics/answer/2709828)で会員IDを取得。システムデータと結合させた後、Measurement Protocolでデータ送信。
Googleアナリティクスに送信したデータは広告配信等にも利用可能です。

<img width="694" alt="スクリーンショット 2019-12-08 22.47.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17452/0a305791-4681-6aaa-91fa-b4450e7a3fcd.png">

### Googleアナリティクス有償版 + Google Cloud Platform

Googleアナリティクスデータの[BigQuery Export](https://support.google.com/analytics/answer/3437618)が使えますので、BigQuery上でシステムデータと結合させた後、DataflowやCloud ComposerからMeasurement Protocolでデータを送信するのが良いと思います。

<img width="802" alt="スクリーンショット 2019-12-08 22.47.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17452/46512a71-e5cb-640f-1411-ce25d8a00070.png">

前置きが長くなりましたが、以下からMeasurement Protocolの使用例となります。

## 環境

### マシン/OS

```shell-session
$ cat /etc/os-release

PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
```

### Python

* Python: 3.5.3
    * urllib3: 1.24

## プログラム

```py3:mp.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""send Google Analytics data using MeasurementProtocol."""

import sys
import urllib.parse
import urllib.request
from urllib.request import urlopen

if __name__ == '__main__':
    mp_url = 'https://www.google-analytics.com/collect'
    tid = 'UA-XXXXX-X'
    ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:71.0) Gecko/20100101 Firefox/71.0'
    t = 'event'
    ec = 'sample_event_category'
    ea = 'sample_event_action'
    el = 'sample_event_labe'
    v = '1'
    ni = 1

    # url params
    url_params = [
        {
            'v': v,
            'tid': tid,
            'ua': ua,
            't': t,
            'ec': ec,
            'ea': ea,
            'el': el,
            'ni': '1',
            'cid': '11111.11111',
        },
        {
            'v': v,
            'tid': tid,
            'ua': ua,
            't': t,
            'ec': ec,
            'ea': ea,
            'el': el,
            'ni': '1',
            'cid': '22222.22222',
        },
        {
            'v': v,
            'tid': tid,
            'ua': ua,
            't': t,
            'ec': ec,
            'ea': ea,
            'el': el,
            'ni': '1',
            'cid': '33333.33333',
        },
    ]

    try:
        for url_param in url_params:
            # url encode
            data = urllib.parse.urlencode(url_param).encode('utf-8')
            request = urllib.request.Request(mp_url, data)
            response = urlopen(request)
    except Exception as e:
        print(e)
        sys.exit(1)

    sys.exit(0)
```

`tid`には送信先のGoogleアナリティクスのトラッキングIDを、`ua`には適当なユーザエージェントを指定ください。
`url_params`がAPIのパラメータとなります。`cid`にはGoogleアナリティクスのクライアントIDをそれぞれ設定ください。
使用できるパラメータは以下を参照ください。
https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters

### 実行方法

```shell-session
$ python mp.py
```

### 実行結果

Googleアナリティクスのリアルタイムイベントを見ると、設定したイベントがトラッキングされていることが確認できます。

<img width="968" alt="スクリーンショット 2019-12-09 0.41.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17452/2c5842c7-887a-c4e8-3f27-732a5f79ff77.png">


## その他どうでも良い話

Macのpyenvをアップデートしたらopensslが上手く動作しなくなったので、クラウド環境で実行しています・・・。
（Pythonのバージョンが3.5なのはそれが理由です。）
直すのめんどそう・・・。