第8回 GA4 Data APIで記事別PVを取得する―Google Analyticsからアクセスデータを取得

Google Analytics Data APIを有効化し、gcloud CLIとOAuth Desktop ClientでADC認証を設定。Node.jsからpagePathとscreenPageViewsを取得し、ゆまラボの記事別PVを実データで確認した記録です。

執筆:ゆまラボ運営者

公開:
第8回 GA4 Data APIで記事別PVを取得する―Google Analyticsからアクセスデータを取得

第7回では、Bing Webmaster Toolsへbringain.comを登録し、X投稿に付けたUTMからGA4でx / socialの流入まで確認した。

一方、第3回 人気記事を自動表示したい―Cloudflareでも見られるがGoogle Analyticsを使うことにするでは、将来トップページへ直近30日の人気記事を自動表示するため、Google Analytics Data APIから記事別の表示回数を取得する方針を決めていた。

第4回 Google Analyticsをゆまラボへ導入する―GA4を設定してリアルタイム計測まで確認でGA4を導入してからデータもたまってきた。

今回は、そのデータを管理画面で見るのではなく、Google Analytics Data APIから実際に取得するところまで進める。

トップページへの人気記事表示はまだ作らない。今回の範囲は、/blog/配下のpagePathscreenPageViewsをAPIから取得し、ターミナルで確認するところまでとした。

GA4のプロパティIDを確認する#

Data APIを呼び出す前に、Google Analyticsでゆまラボのプロパティを確認した。

Google Analyticsのプロパティ詳細でゆまラボのプロパティIDを確認している画面

Data APIでは、Googleタグで使うG-から始まる測定IDではなく、GA4の数値プロパティIDを指定する。

今回使用するプロパティは既存のゆまラボ用GA4プロパティで、新しく作り直してはいない。

Google Analytics Data APIを有効にする#

Google Cloud側では、今回使うプロジェクトからGoogle Analytics Data APIを開いた。

最初はまだ有効になっておらず、「有効にする」が表示されている。

Google CloudでGoogle Analytics Data APIを有効化する前の画面

そのままAPIを有効化した。

Google Analytics Data APIのステータスが有効になった画面

ここで外部サービス側の準備はできたが、ローカルのNode.jsからAPIを呼ぶには認証も必要になる。

gcloud CLIが入っていなかった#

既存環境を確認すると、gcloud CLIは未導入。

そのため、認証やAPI実装へ進む前にGoogle Cloud CLIをWindowsへインストールした。

インストール後にPowerShellを開き直し、gcloud --versionを確認した。

PowerShellでgcloud CLIのバージョンを確認した画面

確認時点ではGoogle Cloud SDK 585.0.0が起動している。

ここからApplication Default Credentials(ADC)を使って、Node.jsクライアントからGoogle Analytics Data APIへアクセスする準備を進めた。

最初のADC認証は「このアプリはブロックされます」で失敗した#

最初は、ユーザーアカウントでADCを作る通常の流れとして、analytics.readonlyを含むスコープで認証を開始した。

しかしGoogleの認可画面まで進むと、次の表示で止まった。

最初のADC認証で「このアプリはブロックされます」と表示された画面

「このアプリはブロックされます」と表示され、そのまま認証を完了できなかった。通常のADC認証でそのまま進めるつもりだったので、ここは予想外だった。

ここでサービスアカウントへ切り替えたり、認証情報を別方式で保存したりはしなかった。

Google CloudのADCドキュメントを確認すると、Google Cloud以外のサービス向けスコープを追加してユーザー認証を使う場合は、OAuthクライアントIDを作り、gcloud auth application-default login--client-id-file--scopesを指定する方法が案内されている。

今回はその方法へ変更した。

Google Auth Platformを構成する#

Google Cloud ConsoleでGoogle Auth Platformを開くと、まだ構成されていない。

Google Auth Platformがまだ構成されていない開始画面

今回の用途は自分のローカル環境からゆまラボのGA4を読むことなので、外部向けのテスト状態で設定し、実際に認証へ使うGoogleアカウントをテストユーザーへ追加した。

Google Auth Platformのテストユーザーを登録した画面

※ 公開不要なメールアドレス部分は画像内で伏せている。

続いてData AccessからGoogle Analyticsの読み取りスコープを追加した。

Google Auth Platformでanalytics.readonlyスコープを追加している画面

追加したスコープは次のもの。

https://www.googleapis.com/auth/analytics.readonly

さらに、ローカルで使うOAuthクライアントをDesktop appとして作成した。

Google Auth PlatformでDesktop appのOAuthクライアントを作成している画面

ここで発行したOAuthクライアントのJSONはリポジトリ外へ保存した。記事用ファイルやGit管理対象には含めていない。

OAuth Desktop Clientを指定してADC認証をやり直す#

作成したOAuthクライアントを--client-id-fileで指定し、ADC認証をもう一度実行した。

認可画面では、Google Analyticsのデータ参照とGoogle Cloud側の権限が表示された。

OAuth Desktop Clientを使ったADC認証で要求スコープを確認している画面

※ Googleアカウントを特定できる表示は画像内で伏せている。

この認可を続行でき、gcloud CLI側でも認証完了まで進んだ。

OAuth Desktop Clientを指定したADC認証が完了した画面

その後、gcloud auth application-default print-access-tokenでADCが利用できることだけ確認した。

アクセストークン自体は記事へ残していない。ファイルへ保存もしていない。

なお、Codexを実行していたPowerShellではインストール後のPATHがまだ反映されていなかったため、確認時はインストール済みのgcloud.cmdを絶対パスで実行した。認証方式を変えたわけではない。

Node.jsからData APIを呼ぶ#

認証が通ったところで、Astroリポジトリ側へGoogle Analytics Data APIのNode.jsクライアントを追加した。

追加したパッケージは次の1つ。

@google-analytics/data 7.1.0

変更したファイルは3つ。

package.json
package-lock.json
scripts/ga-pageviews.mjs

AstroのページやTOPページは変更していない。PVデータを保存するJSONや定期実行も追加していない。

scripts/ga-pageviews.mjsではBetaAnalyticsDataClientからrunReport()を実行する形にした。

指定した条件は以下。

property      properties/553074385
dimension     pagePath
metric        screenPageViews
startDate     30daysAgo
endDate       yesterday
filter        pagePath BEGINS_WITH /blog/
order         screenPageViews DESC

Google Analytics Data APIでは、pagePathはホスト名とクエリ文字列の間にあるページパス、screenPageViewsはWebページまたはアプリ画面の表示回数として取得できる。

今回はBEGINS_WITH /blog/で絞り、記事に関係するURLを先に取得する形にした。

まだ「公開済みMarkdownと一致するURLだけに限定する」「一覧ページを除外する」といった追加処理は入れていない。

記事別PVを74件取得できた#

実行したコマンドはこれだけ。

node scripts/ga-pageviews.mjs

実際の取得結果では74行が返った。

Google Analytics Data APIからpagePathとscreenPageViewsを取得したターミナル画面

取得時点の上位10件は次の結果。

/blog/                                           416
/blog/codex-luna-astra-astro-comparison/          66
/blog/sns-publishing-candidates/                  38
/blog/27-astro-image-optimization-lazy-loading/   30
/blog/technical-blog-monetization/                30
/blog/01-blog-monetization-models/                26
/blog/chatgpt-url-cache-miss-web-search/           25
/blog/02-google-adsense-application/              19
/blog/codex-full-access-permission-profile/       19
/blog/yumalabo-responsive-browser-test/           18

ここで1つ分かったことがある。

/blog/で始まるパスをそのまま対象にしたため、記事詳細だけではなく記事一覧の/blog/も含まれている。取得結果では/blog/が416で先頭になった。

さらに、GA4に残っている実データには次のような不自然なpagePathも1件あった。

/blog/28-astro-eyecatch-image/](https:/bringain.com/blog/28-astro-eyecatch-image/

APIから何が返るかを確認する回なので、この段階では削除も正規化もしていない。

人気記事として実際にTOPへ表示するときは、/blog/一覧を除外し、現在公開されている記事slugとの照合も必要になる。

この確認ができたことで、「Data APIを呼べればそのまま人気記事ランキングになる」わけではなく、取得後の絞り込みがもう1段必要なことも分かった。

Astroのビルドを確認する#

Data API取得後にnpm run buildを実行した。

Data API取得処理の追加後にAstroのビルドが成功した画面

結果は成功。

確認できた内容は以下。

Astro              235ページ生成
Pagefind           78ページをインデックス
内部リンク         9536件確認
broken links       0件

既存のFrontmatter警告7件、npm install時のWindows権限警告、node-domexception@1.0.0のdeprecated警告、npm auditのhigh severity 3件は出ているが、今回のData API実装によるビルドエラーは発生していない。

今回の範囲外なので、それらの既存警告や依存関係の修正は行わなかった。

最終的なGitの変更も、今回の3ファイルだけになっている。

M  package-lock.json
M  package.json
?? scripts/ga-pageviews.mjs

pagePathとPVを取得できた#

第3回で考えていた「Google Analyticsのデータをプログラムから取得する」ところまで、実データで確認できた。

今回行った作業をまとめる。

GA4プロパティを確認

Google Analytics Data APIを有効化

gcloud CLIを導入

通常のADC認証を試す

「このアプリはブロックされます」で停止

Google Auth Platformを構成

OAuth Desktop Clientを作成

--client-id-file付きでADC認証

@google-analytics/dataを追加

runReport()でpagePath / screenPageViewsを取得

74行の実データを確認

npm run build成功

今回はPVを取得しただけで、TOPページの「注目コンテンツ」はまだ変更していない。

次に人気記事を自動表示する場合は、今回見つかった/blog/一覧や不自然なpagePathをどう扱うかを決め、公開中の記事と照合してから上位3~5件を表示する処理へ進む。

参考#