Produced by Fourier

PHP(Laravel)でGA4のPV数を取得してみた

Sena Sena カレンダーアイコン 2023.02.10

はじめに

記事のランキングを実装する際、自分でカウント処理を実装せずに Google Analyticsから自動的に取れると良いな と思ったことはありませんか?

今回は、 Google Analytics 4のデータをPHPから取得する方法 について記載したいと思います。 特にUniversal Analyticsから取得する記事は多かったのですが、 Google Analytics 4(GA4)で取得する記事は少なかった ので備忘録として残します。

💡
Universal Analyticsは2023年7月に廃止される予定です。

GA4からデータを取得するには工程が多いため、 迷子になることや注意点が多かった です。 本記事では写真と共に クリックする場所を丁寧に解説していきます ので、参考になるかと思います。

データ取得までの流れ

① Google Cloudで プロジェクト を作成

サービスアカウント を作成

③ 作成したサービスアカウントに、Google Analyticsの 閲覧権限 を付与

④ プロジェクトに Data APIライブラリ を追加

⑤ サービスアカウントにアクセスするため の秘密鍵 を入手

解説

Google Cloudでプロジェクトを作成する

Google Cloudにアクセスして、[コンソール]をクリックします。

https://cloud.google.com/apis?hl=ja
💡
Google Cloudのアカウントを持っていない場合は、作成する必要があります。

左上のプロジェクト選択ボックスを開いて、[新しいプロジェクト]をクリックします。

適切なプロジェクト名を決めて[作成]しましょう。

作成後、しばらく経つと通知が来てプロジェクトを選択出来るようになります。 選択しましょう。

サービスアカウントを作成する

[ダッシュボード]を選択します。

左上のメニューから[IAMと管理] > [サービスアカウント]を選択します。

サービスアカウントを開いたら、[サービスアカウントを作成]をクリックします。

サービスアカウント名を入力しましょう。 その後、[完了]をクリックします。

💡
サービスアカウントIDは自動入力されます。

しばらくするとサービスアカウント一覧に自動遷移します。 追加されたサービスアカウントのメールアドレスをメモ(クリップボードにコピー)します。 このページは後で戻ってくるので、次の作業は別タブでやりましょう。

Google Analyticsで取得したいプロパティにアクセス

取得したいプロパティのGoogle Analyticsのダッシュボードにアクセスします。

これからの内容は Universal Analyticsでは使えない方法 なので、下のIDが UA-始まっていない事 を確認して下さい。

https://analytics.google.com/analytics/web/

プロパティIDの取得

左下の[管理]をクリックします。

プロパティ欄の[プロパティ設定]をクリックします。

プロパティID が右上に表示されるので、メモします。

作成したサービスアカウントを紐付ける

先ほどと同じく、左下の[管理]をクリックします。

[プロパティのアクセス管理]を開きます。

右上の[+]をクリックします。

先ほどメモしたメールアドレスを入力します。 右上の[追加]をクリックします。

💡
Google Analyticsからデータを取得するだけであれば、データ制限は 閲覧者 で問題ありません。

その後、サービスアカウントが一覧に追加されていることを確認します。

プロジェクトにライブラリを追加します

Google Cloudに戻って、左上の[APIとサービス] > [ライブラリ]を選択します。

検索フォームがあるので”Analytics”と入力してEnterキーで確定します。

そうすると色々ヒットしますが、迷わず[ Google Analytics Data API ]を選択します。

https://console.cloud.google.com/apis/library/analyticsdata.googleapis.com

[有効にする]をクリックします。

蛇足

Google Analytics Reporting API

Google Analytics Reporting API v4 を使って取得する方法です。 一見見るとGA4に対応していそうな雰囲気がしますが、 Google Analytics Reporting API v4GA4(Google Analytics 4) は違う物です。

以下のドキュメントに書いてあるとおり GA4には対応していません。

This API does not support  Google Analytics 4 (GA4) properties. Please use the  Google Analytics Data API  to access the new reporting features for GA4 properties.

https://developers.google.com/analytics/devguides/reporting/core/v4?hl=en

Google Analytics API

Google Analytics Real Time Reporting API v3 を使って取得する方法です。 ライブラリのロゴが新しいGoogle Analyticsのロゴになっているので、GA4に対応していそうな雰囲気がしますが、これも英語のドキュメントに書いてあるとおり GA4には対応していません。

This API does not support GA4 properties. Please use the  realtime reporting functionality  of the  Google Analytics Data API  to access GA4 propreties.

https://developers.google.com/analytics/devguides/reporting/realtime/v3?hl=en
⚠️
2023年2月13日現在、GA4では使えないという事は日本語のドキュメントには書いていないようです。

サービスアカウントに認証情報を追加

左上のメニューの[APIとサービス] > [認証情報]を選択します。 そのページのサービスアカウント欄に、作成したサービスアカウントがあることを確認します。

左上のメニューの[IAMと管理] >[サービスアカウント]を選択し、サービスアカウントを追加したページに戻ります。

💡
順番通りやった方なら、タブに残っているかもしれません。

作成したサービスアカウントの操作から[鍵を管理]をクリックします。

[鍵を追加]をクリックし[新しい鍵を作成]をクリックします。

JSONを選択して[作成]すると、秘密鍵が生成されますので保存します。

⚠️
秘密鍵は、他人に見られないように 大切に保管 します。

保存した秘密鍵をサーバーに設置

保存した秘密鍵をサーバに設置しましょう。

ここでは /etc/pki/google-analytics-api-key.json に設置します。

💡
秘密鍵の権限設定はちゃんとしておきましょう。

PHPコードから呼び出す

インストール

composer require google/analytics-data
https://packagist.org/packages/google/analytics-data

Laravelのサンプルコード

例えば /techblog/articles/* の直近一週間のPV数を多い順に取得してみます。

Migration用のDBスキーマ

Schema::create('techblog_rankings', function (Blueprint $table) {
    $table->integer('rank')->comment('ランキング順位')->unique()->primary();
    $table->string('page')->comment('ページURL');
    $table->integer('page_view_count')->comment('GoogleAnalyticsから取った、一週間のページビュー数');
    $table->timestamps();
});

Model app/Models/TechblogRanking.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class TechblogRanking extends Model
{
    protected $primaryKey = 'rank';
    public $incrementing  = false;
    protected $fillable   = [
        'rank',
        'page_view_count',
    ];
}

Command app/Console/Commands/GoogleAnalytics/AnalyticsCommand.php

Data APIのリファレンスは以下の通りです。

https://developers.google.com/analytics/devguides/reporting/data/v1/rest?hl=ja

REST APIを書くように、ライブラリを使って書いていきます。

<?php

namespace App\Console\Commands\GoogleAnalytics;

use Exception;
use App\Models\TechblogRanking;
use Illuminate\Console\Command;
use Google\Analytics\Data\V1beta\BetaAnalyticsDataClient;
use Google\Analytics\Data\V1beta\Filter;
use Google\Analytics\Data\V1beta\Filter\StringFilter\MatchType;
use Google\Analytics\Data\V1beta\FilterExpression;
use Google\Analytics\Data\V1beta\OrderBy;
use Google\Analytics\Data\V1beta\DateRange;
use Google\Analytics\Data\V1beta\Dimension;
use Google\Analytics\Data\V1beta\Metric;

class AnalyticsCommand extends Command
{
    protected $signature   = 'analytics';
    protected $description = 'Command description';

    /**
     * consoleコマンドの実行
     *
     * @return void
     */
    public function handle(): void
    {
        $this->techBlogRanking();
    }

    /**
     * テックブログのランキングを集計してDBに保存
     *
     * @return void
     */
    public function techBlogRanking(): void
    {
        try {
						// プロパティIDを入力します。.envに書くと良いと思います。
						// $property_id = config('google.analytics.propertyId');
            $property_id = "123456789";

						// 秘密鍵のパスです。ここも.envに書くと良いと思います。
						// 'credentials' => config('google.analytics.credentials'),
            $client = new BetaAnalyticsDataClient([
                                                      'credentials' => "/etc/pki/google-analytics-api-key.json",
                                                  ]);

            $response = $client->runReport([
                                               // プロパティIDを指定します。
                                               'property'        => 'properties/' . $property_id,
                                               // 期間を指定します。
                                               'dateRanges'      => [
                                                   new DateRange([
                                                                     'start_date' => '7daysAgo',
                                                                     'end_date'   => 'today',
                                                                 ]),
                                               ],
                                               // フィルタリング用にデータの属性を指定します。
                                               'dimensions'      => [
                                                   new Dimension([
                                                                     'name' => 'pagePath',
                                                                 ]),
                                               ],
                                               // データの属性で制限を掛けます。
                                               // 今回は、/techblog/articles/でフィルタリングを掛けてみます。
                                               'dimensionFilter' =>
                                                   new FilterExpression([
                                                                            'filter' => new Filter([
                                                                                                       'field_name'    => 'pagePath',
                                                                                                       'string_filter' => new Filter\StringFilter([
                                                                                                                                                      'match_type' => MatchType::PARTIAL_REGEXP,
                                                                                                                                                      'value'      => '^/techblog/articles/',
                                                                                                                                                  ]),
                                                                                                   ]),
                                                                        ]),
                                               // 取得する測定値を指定します。
                                               'metrics'         => [
                                                   new Metric([
                                                                  'name' => 'screenPageViews', // PV数
                                                              ]),
                                                   new Metric([
                                                                  'name' => 'totalUsers', // 平均ページ滞在時間(秒)
                                                              ]),
                                               ],
                                               // 取得する順番を変更します。
                                               // 今回は、PV数が多い順に取ります。
                                               'orderBys'        => [
                                                   new OrderBy([
                                                                   'metric' => new OrderBy\MetricOrderBy([
                                                                                                             'metric_name' => 'screenPageViews',
                                                                                                         ]),
                                                                   'desc'   => true,
                                                               ]),
                                               ],
                                           ]);
            // 取得したReportを整形
            $result = collect();
            foreach ($response->getRows() as $key => $row) {
                // ディメンション
                $pageName = $row->getDimensionValues()[0]->getValue();

                // メトリクス
                $metricsValues = $row->getMetricValues();
                $viewCount     = $metricsValues[0]->getValue(); // PV数
                $time          = $metricsValues[1]->getValue(); // 平均ページ滞在時間(秒)
                $result->push(['rank' => $key + 1, 'page' => $pageName, 'page_view_count' => $viewCount]);
            }
            if ($result->isNotEmpty()) {
								// DBに保存
                TechblogRanking::query()->delete();
                TechblogRanking::upsert($result->toArray(), 'rank');
            }
        } catch (Exception $e) {
            dd($e);
        }
    }
}

サンプルコードの実行

php artisan analytics

結果(ダミーデータ)

+------+------------------------+-----------------+
| rank |          page          | page_view_count |
+------+------------------------+-----------------+
|    1 | /techblog/articles/*** |           10000 |
|    2 | /techblog/articles/    |            5000 |
+------+------------------------+-----------------+

まとめ

本記事ではGoogle Analytics4からPHPで取得する一連の流れについて書きました。

応用して Cronで実行すれば 、直近一週間ごとの記事ランキング取得の自動化が出来るかもしれませんね。 読者の皆様の参考になればと思います。

Sena

Sena slash forward icon Engineer

生涯に亘り技術を極めていきたい。

関連記事