Tech blog 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にアクセスして、[コンソール]をクリックします。

💡
Google Cloudのアカウントを持っていない場合は、作成する必要があります。

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

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

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

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

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

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

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

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

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

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

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

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

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

プロパティIDの取得

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

蛇足

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.

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.

⚠️
2023年2月13日現在、GA4では使えないという事は日本語のドキュメントには書いていないようです。

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

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

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

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

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

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

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

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

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

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

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

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

PHPコードから呼び出す

インストール

composer require 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のリファレンスは以下の通りです。

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 / Engineer

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