Google Analytics Data API (GA4)をPHPで実行する方法

GA4の閲覧データを「Google Analytics Data API (GA4)」をPHPで使って呼び出す方法を残しておく。GA4の一部データを関係者のみに公開したいが、GA4の管理画面を見るのは難易度が高く、アカウントの運用も煩雑になるため、PHPの管理画面にてGA4の閲覧データをCSVファイルでダウンロードできるようにする。

API Quickstart  |  Google Analytics Data API

以下を参考に進めていく。

■API Quickstart  |  Google Analytics Data API  |  Google for Developers
https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries?hl=en

Step1.APIを有効にする

上記のAPI Quickstartのページの「Enable the Google Analytics Data API v1」ボタンをクリック。サービスアカウントが作成される。

DOWNLOAD PRIVATE KEY AS JSON

「DOWNLOAD PRIVATE KEY AS JSON」ボタンをクリックしてJSONファイルをダウンロードして保存する。

ダウンロードしたJSONファイル

「client_email」をコピーしておく。

Step2.Google アナリティクス 4 プロパティにサービス アカウントを追加する

GA4の設定ページを開き「アカウントのアクセス管理」をクリック。

アカウントのアクセス管理

右上の「+」から「ユーザーを追加」をクリック。

ユーザーを追加

「役割とデータ制限の追加」ページで先ほどコピーしたメールアドレスを貼り付け「閲覧者」を選んで「追加」をクリック。

役割とデータ制限の追加

Step3.認証の構成

ダウンロードしたJSONファイルはソースプログラムで指定するため割愛する。

Step4.クライアントライブラリをインストールする

以下を参照して進めていく。

■googleapis/php-analytics-data
https://github.com/googleapis/php-analytics-data#installation

composer require google/analytics-data

最も苦労したのがこのパート。4時間近くトラブルシュートに時間を費やした。上記をインストールすれば済むはずなのだが、DockerDesktopに慣れていないため以下のように様々なエラーが発生した。

以下は、composerが入っていない初歩的なエラー。

Fatal error: Uncaught Error: Class "Google\Analytics\Data\V1beta\BetaAnalyticsDataClient" not found in /var/www/html/gaphp

以下は、new BetaAnalyticsDataClient()でJSONファイルの指定が間違っていた際のエラー。

Fatal error: Uncaught DomainException: Cloud not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information in /var/www/html/vendor/google/auth/src/ApplicationDefaultCredentials.php

以下は、bccomp()が呼び出せないエラー。PHPのbcmathをインストールする必要がある。

Fatal error: Uncaught Error: Call to undefined function Google\Protobuf\Internal\bccomp() in /var/www/html/vendor/google/protobuf/src/Google/Protobuf/Internal/Message.php:961

Dockerfile ファイルを以下に修正。

FROM php:fpm
RUN apt-get update
RUN apt-get install -y vim
RUN apt-get install zip unzip
RUN docker-php-ext-install bcmath

COPY php.ini /usr/local/etc/php/
COPY --from=composer /usr/bin/composer /usr/bin/composer

以下を実行する。

docker-compose build
docker-compose up -d

phpinfo()で、以下のようにbcmathが有効になっていれば成功。

bcmathが有効になった

API呼び出しを行う

掲載されていたサンプルソースを少し修正して実行してみる。

<?php
require 'vendor/autoload.php';
use Google\Analytics\Data\V1beta\BetaAnalyticsDataClient;
use Google\Analytics\Data\V1beta\DateRange;
use Google\Analytics\Data\V1beta\Dimension;
use Google\Analytics\Data\V1beta\Metric;

echo "test...";

$credentials = "./xxx.json";
$property_id = 'YOUR-GA4-PROPERTY-ID';

// Using a default constructor instructs the client to use the credentials
// specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
$client = new BetaAnalyticsDataClient([
    'credentials' => $credentials,
]);

// Make an API call.
$response = $client->runReport([
    'property' => 'properties/' . $property_id,
    'dateRanges' => [
        new DateRange([
            'start_date' => '2023-02-01',
            'end_date' => '2023-02-01',
        ]),
    ],
    'dimensions' => [new Dimension(
        [
            'name' => 'city',
        ]
    ),
    ],
    'metrics' => [new Metric(
        [
            'name' => 'activeUsers',
        ]
    )
    ]
]);

// Print results of an API call.
print 'Report result: ' . PHP_EOL;

foreach ($response->getRows() as $row) {
    print $row->getDimensionValues()[0]->getValue()
        . ' ' . $row->getMetricValues()[0]->getValue() . PHP_EOL;
}

?>

テスト的に実行した結果は以下の通り。

最終のソースコード

以下を参考にしてディメンションとメトリクスを設定する。

■API Dimensions & Metrics  |  Google Analytics Data API  |  Google Developers // https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema?hl=en

ディメンションに「itemCategory4」を指定するとなぜかエラーが発生したのでカットする。

Fatal error: Uncaught Google\ApiCore\ApiException: { "message": "Please remove itemCategory4 to make the request compatible. The request's dimensions & metrics are incompatible. To learn more, see https:\/\/ga-dev-tools.web.app\/ga4\/dimensions-metrics-explorer\/", "code": 3, "status": "INVALID_ARGUMENT", "details": [] } thrown in /var/www/html/vendor/google/gax/src/ApiException.php on line 267

最終のソースコードは以下になる。

<?php
require 'vendor/autoload.php';
use Google\Analytics\Data\V1beta\BetaAnalyticsDataClient;
use Google\Analytics\Data\V1beta\DateRange;
use Google\Analytics\Data\V1beta\Dimension;
use Google\Analytics\Data\V1beta\Metric;
use Google\Analytics\Data\V1beta\FilterExpression;
use Google\Analytics\Data\V1beta\Filter;
use Google\Analytics\Data\V1beta\Filter\StringFilter;
use Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType;

echo "<h1>Google Analytics Data API(GA4)</h1>";

$credentials = "./GoogleAnalyticsDataAPI_Quickstart-425006f8e158.json";
$property_id = '999999999';

// Using a default constructor instructs the client to use the credentials
// specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
$client = new BetaAnalyticsDataClient([
    'credentials' => $credentials,
]);

$response = $client->runReport([
    'property' => 'properties/' . $property_id,
    'dateRanges' => [
        new DateRange([
            'start_date' => '2023-05-01',
            'end_date' => '2023-05-01',
        ]),
    ],
    'dimensions' => [
        new Dimension([
            'name' => 'pagePath',
            ],
        ),
        new Dimension([
            'name' => 'date',
            ],
        ),
        
    ],
    'metrics' => [
        new Metric([
            'name' => 'sessions',
            ]
        ),
        new Metric([
            'name' => 'screenPageViews',
            ]
        ),
        new Metric([
            'name' => 'averageSessionDuration',
            ]
        ),
        
    ],
    
    'dimensionFilter' => new FilterExpression([
        'filter' => new Filter([
            'field_name' => 'pagePath',
            'string_filter' => new StringFilter([
                'match_type' => MatchType::BEGINS_WITH,
                //'value' => '/conversion',
            ])
        ]),
    ]),
    
]);

$i=0;
// Print results of an API call.
print('<table border="1" style="border-collapse: collapse; font-size:11px;">');
print('<tr>');
    print('<th>No</th>');
    print('<th>pagePath</th>');
    print('<th>date</th>');
    print('<th>sessions</th>');
    print('<th>screenPageViews</th>');
    print('<th>averageSessionDuration</th>');
    
foreach ($response->getRows() as $row) {
    print('<tr>');
    print('<td>' . $i+1 . '</td>'
        . '<td>' . $row->getDimensionValues()[0]->getValue() . '</td>'
        . '<td>' . $row->getDimensionValues()[1]->getValue() . '</td>'
        . '<td>' . $row->getMetricValues()[0]->getValue() . '</td>'
        . '<td>' . $row->getMetricValues()[1]->getValue() . '</td>'
        . '<td>' . $row->getMetricValues()[2]->getValue() . '</td>'
        . '');
    print('</tr>');
    print PHP_EOL;
    $i++;
    if ($i>=1000) {
        die;
    }
}
print('</table>');
?>

結果、以下のように出力される。

最終出力結果