google-api-php-clientを使ってGoogle Analyticsのデータを取得する

# はじめに
Webアクセス解析ツールとして Google Analytics（以下GA）を利用しています。
自社のデータはGAから、競合他社はVALUESから、というスキームが多いのですが
それぞれ別々にデータを取得してBIツールで繋ぎ合わせる、というやり方ではなく
1つのWebサービス上でシームレスに繋ぎ合わさったサービスの開発に取り組んでいます。

データ検証として、google-api-php-clientを使ってGAデータの取得までを試したため
作成したラッパーとともに記載します。

# GAデータを取得するまで
1.サービスアカウントキーの取得
2.Google Analytics APIの有効化
3.Google API Client Libraries（PHP）のインストール
4.GA側の設定
5.GAデータの取得
※ Googleアカウントは既にある前提
※ 1～3は特に順番はありません（どれを先にやってもよいです）
※ 1,3は既に他で実施済みであれば不要

## 1.サービスアカウントキーの取得
※既に取得済みであればこの項は不要です。

Google Developer Console または Google Cloud Platform の
APIとサービス ＞ 認証情報
から認証情報（サービスアカウントキー）を作成します。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/0063ebe1-0713-2997-6c3e-9570d5510c0c.png)
※サービスアカウント名を入力すると、サービスアカウントIDが自動で振られます。
※サービスアカウントIDをメモしておきます（後で使います）
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/a561c516-6ea2-abff-f430-a460862dfe74.png)

※作成したJSONファイルを保存します（後で使います）

## 2.Google Analytics APIの有効化
Google Developer Console または Google Cloud Platform の
APIとサービス ＞ ライブラリ
からGoogle Analytics APIを有効化します。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/10accd56-999e-d1a2-6df8-9e3a74a9188e.png)

※ Google Analytics APIは一番下の その他 の中にあります。
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/eb7504ac-c827-ee96-25b8-cb8a8c8709e1.png)
※上図は既にAPIを有効にした後ですが、前であれば「有効にする」ボタンが表示されているはずです。
※ まだプロジェクトがない場合は、併せてプロジェクトも作成しておきましょう。

## 3.Google API Client Libraries（PHP）のインストール
※既にインストール済みであればこの項は不要です

google-api-php-clientのGitHubはこちら
[google-api-php-client](https://github.com/googleapis/google-api-php-client)
`Composer`またはソースコードを直接ダウンロードします。

## 4.GA側の設定
作成したサービスアカウントIDをGA側に設定します。

目的のビューに対してユーザー（1.で取得したサービスアカウントID）を追加します。
![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/0ff3783d-0823-4e98-f0d9-f2a0925c70ef.png)
![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/50dbe512-3cb3-7bd9-c4ea-6c42a255ee03.png)
※メールアドレスにサービスアカウントIDを設定します。
![図7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/61611414-349d-9aa6-6cec-810a35ca30cd.png)
※権限は「表示と分析」のみで大丈夫です。

![図8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270785/cd71c09f-0460-bdea-15be-40ff1bdce300.png)
※対象のビューIDをメモしておきます（あとで使います）

## 5.GAデータの取得
以下がサンプルコードです（PHP）

APIを使いやすいようにラッパーを用意します。

```php:GAwrapper.php
<?php
require_once 'google-api-php-client/vendor/autoload.php';

Class GAwrapper {

	private $viewId;
	private $analytics;

	public function __construct($authKey, $viewId) {
		$this->viewId = $viewId;

		$client = new Google_Client();
		$client->setApplicationName("Analytics Reporting");
		$client->setAuthConfig($authKey);
		$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
		$analytics = new Google_Service_Analytics($client);

		$this->analytics = $analytics;
	}

	public function query($startDate='7daysAgo', $endDate='yesterday', $aryMetrics=array(), $aryDimensions=array(), $arySort=array(), $aryFilters=array(), $maxResults=1000) {
		// Metrics
		if (count($aryMetrics) > 0) {
			foreach ($aryMetrics as $key => $value) {
				$aryMetrics[$key] = 'ga:'.$value;
			}
			$metrics = implode(',', $aryMetrics);
		} else {
			$metrics = '';
		}
		// Dimensions
		if (count($aryDimensions) > 0) {
			foreach ($aryDimensions as $key => $value) {
				$aryDimensions[$key] = 'ga:'.$value;
			}
			$dimensions = implode(',', $aryDimensions);
		} else {
			$dimensions = '';
		}
		// Sort
		if (count($arySort) > 0) {
			foreach ($arySort as $key => $value) {
				if (strpos($value, '-') === 0) {
					$arySort[$key] = '-ga:'.substr($value, 1);
				} else {
					$arySort[$key] = 'ga:'.$value;
				}
			}
			$sort = implode(',', $arySort);
		} else {
			$sort = '';
		}
		// Filters
		if (count($aryFilters) > 0) {
			foreach ($aryFilters as $key => $value) {
				$aryFilters[$key] = 'ga:'.$value;
			}
			$filters = implode(';', $aryFilters);
		} else {
			$filters = '';
		}
		$optParams = array();
		if (strlen($dimensions) > 0) {
			$optParams['dimensions'] = $dimensions;
		}
		if (strlen($sort) > 0) {
			$optParams['sort'] = $sort;
		}
		if (strlen($filters) > 0) {
			$optParams['filters'] = $filters;
		}
		$optParams['max-results'] = $maxResults;
		// Excute Query
		$result = $this->analytics->data_ga->get('ga:'.$this->viewId, $startDate, $endDate, $metrics, $optParams);
		$data = array();
		foreach ($result->rows as $row) {
			$index = 0;
			$outDimensions = array();
			foreach ($aryDimensions as $dimension) {
				$value = $row[$index];
				if ($dimension == 'ga:date') {
					$value = substr($value, 0, 4).'-'.substr($value, 4, 2).'-'.substr($value, 6, 2);
				} else if ($dimension == 'ga:isoYearIsoWeek') {
					$value = $this->weekStartDate(substr($value, 0, 4), (int)substr($value, 4, 2), $startDate).'週';
				} else if ($dimension == 'ga:yearMonth') {
					$value = substr($value, 0, 4).'-'.substr($value, 4, 2);
				}
				$outDimensions[str_replace('ga:', '', $dimension)] = $value;
				$index++;
			}
			$outMetrics = array();
			foreach ($aryMetrics as $value) {
				$outMetrics[str_replace('ga:', '', $value)] = $row[$index];
				$index++;
			}
			$aryOut = array();
			foreach ($outDimensions as $key => $value) {
				$aryOut[$key] = $value;
			}
			$aryOut['metrics'] = $outMetrics;
			$data[] = $aryOut;
		}
		return $data;
	}

	// 年と週番号から、その週の最初の日付文字列を得る（ISO 8601準拠）
	private function weekStartDate($year, $weekNumber=1, $startDate) {
		$time = strtotime("{$year}-01-01");
		$week = date("w", $time);
		if ($week > 4 || $week == 0) {
			$time = strtotime("next Monday", $time);
		} elseif ($week != 1) {
			$time = strtotime("last Monday", $time);
		}
		$weekNumber--;
		$retData = date("Y-m-d", strtotime("+{$weekNumber} Week", $time));
		if ($startDate > $retData) {
			$retData = $startDate;
		}
		return $retData;
	}
}
```

実際の取得サンプルは下記のようになります。
`$authKey`に1.で取得したJSONファイルを指定します。
`$viewId`に4.でメモしたビューIDを指定します。

```php:gasample.php
<?php
/* Google Analytics API設定 */
$authKey = 'xxxxxx-9999999-xxxxxxxxxxxx.json';
$viewId  = '99999999';

/* 入力パラメータ */
if (isset($_REQUEST['startDate'])) {
	$startDate = $_REQUEST['startDate'];
} else {
	$startDate = date("Y-m-d", strtotime("-1 Month"));
}
if (isset($_REQUEST['endDate'])) {
	$endDate = $_REQUEST['endDate'];
} else {
	$endDate = date("Y-m-d", strtotime("-1 day"));
}
if (isset($_REQUEST['dateTerm'])) {
	$dateTerm = $_REQUEST['dateTerm'];
} else {
	$dateTerm = 'date';
}

/* データ取得準備 */
require_once 'GAwrapper.php';
$analytics = new GAwrapper($authKey, $viewId);

$metrics    = array();
$dimensions = array();
$sort       = array();
$filters    = array();
$maxResults = 1000;

/* ユーザー数、セッション数、PV数を取得する */
$metrics    = array('users', 'sessions', 'pageviews');
$dimensions = array($dateTerm);
$sort       = array($dateTerm);
$data = $analytics->query($startDate, $endDate, $metrics, $dimensions, $sort, $filters, $maxResults);

print_r($data);
```

※他のメトリックスやディメンションを指定する場合はこちらを参考にしてください。
[Dimensions & Metrics Explorer | アナリティクス Reporting API v4](https://developers.google.com/analytics/devguides/reporting/core/dimsmets)
※ラッパーを使用する場合、ラッパーが自動的に付与するので先頭の「ga:」は不要です。

# 参考にしたサイト
・[【最新版】GoogleAnalytics API 認証設定について画像多めで説明します。 | 東京上野のWeb制作会社LIG](https://liginc.co.jp/356517)

# おわりに
プログラムを作成した時点からしばらく間が空いてしまったため、一応現在も動作しているプログラムの一部を抜粋する形で記事を起こしましたが、古い書き方の箇所があるかもしれません。
Googleさんの画面やAPIはすぐに変わってしまいがち。。。