はじめに
サイトを公開したあと「最近どのページがよく見られているか」「どこから流入しているか」を確認するのに、毎回GA4の管理画面を開くのは地味に面倒だ。
そこでClaude Codeに「アクセス状況を確認して」と話しかけるだけで、ターミナルにレポートが出力される仕組みを作った。
📊 DevLife Hacks GA4 レポート(過去 30 日間)
============================================================
## 概要
セッション数 : 126
アクティブユーザー : 101
ページビュー : 216
直帰率 : 66.7%
平均セッション時間 : 476秒
## 流入経路 TOP10
1. Direct セッション: 125 ユーザー: 100
2. Organic Search セッション: 1 ユーザー: 1
## よく見られているページ TOP10
1. / PV: 60 UU: 42
2. /blog PV: 17 UU: 17
3. /products/ PV: 15 UU: 1この記事では、この仕組みを作るまでの手順と、途中でハマったエラーの原因・解決策を正直に書く。
使用技術・前提条件
項目 | 内容 |
|---|---|
ランタイム | Node.js v18以上 |
認証ライブラリ | google-auth-library |
API | Google Analytics Data API v1beta |
Claude Code | スキル機能( |
対象サイト | Astroで構築したブログ |
Step 1: Google Cloud の設定
プロジェクトとAPIの有効化
Google Cloud Consoleで以下の順に設定する。
- プロジェクトを選択(または新規作成)
- APIとサービス → ライブラリ から「Google Analytics Data API」を検索して有効化
- 請求先アカウントをリンク(無料枠でも必要。これを忘れるとAPIが動かない)
サービスアカウントの作成
- IAM → サービスアカウント → 作成
- 名前は任意(例:
ga4-report-bot) - ロールは「閲覧者」で十分
- 作成後、「キー」タブ → 鍵を追加 → JSON でキーファイルをダウンロード
Step 2: GA4 へのアクセス権付与
ダウンロードしたJSONに記載されているサービスアカウントのメールアドレス(xxxxx@project.iam.gserviceaccount.com 形式)を、GA4側に登録する。
- GA4管理画面 → プロパティのアクセス管理
- 「+」ボタンからメールアドレスを追加
- ロールは「閲覧者」を選択
これを忘れると、後でAPIを叩いたときに 403 Permission denied エラーが出る。
Step 3: JSONファイルの配置と環境変数の設定
JSONはプロジェクト外に置く
サービスアカウントのJSONキーは秘密情報なので、プロジェクトディレクトリの外に置く。これにより .gitignore の設定ミスによる誤コミットを防げる。
C:\Users\<YOUR_USERNAME>\.config\gcloud\devlifehacks-sa.json環境変数を .env.local に追加
.env.local はすでに .gitignore に含まれているため、ここに記載する。
GA4_PROPERTY_ID=your-property-id
GOOGLE_APPLICATION_CREDENTIALS=C:/Users/<YOUR_USERNAME>/.config/gcloud/devlifehacks-sa.jsonGA4_PROPERTY_ID はGA4管理画面の プロパティ設定 に表示されている9桁の数字だ。
Step 4: レポートスクリプトの実装
当初の方針:ライブラリなしで実装しようとした
最初は npm install を避けてNode.js標準の fetch と手動JWT実装で認証を行う方針で進めた。GA4 Data APIはREST APIなので、JWTを自前で生成してアクセストークンを取得する流れ自体は可能なはずだった。
しかし、ここで想定外のエラーが続いた。
ハマりどころ:unsupported_grant_type エラー
OAuth 2.0のJWT Bearer フローでは、以下のような形式でGoogleにリクエストを送る必要がある。
POST https://oauth2.googleapis.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth2:grant-type:jwt-bearer&assertion=<JWT>問題は grant_type の値に含まれる :(コロン) だ。
Node.jsの URLSearchParams を使うと、: が %3A にURLエンコードされてしまう。
const params = new URLSearchParams();
params.set('grant_type', 'urn:ietf:params:oauth2:grant-type:jwt-bearer');
console.log(params.toString());
// → grant_type=urn%3Aietf%3Aparams%3Aoauth2%3Agrant-type%3Ajwt-bearerGoogleのトークンエンドポイントはこのエンコードされた値を認識できず、unsupported_grant_type エラーを返す。
手動で文字列を組み立てる方法も試した。
const body = 'grant_type=urn:ietf:params:oauth2:grant-type:jwt-bearer&assertion=' + jwt;これで : はエンコードされなくなったが、それでも同じエラーが出続けた。JWTの構造・署名は正しかったが、Google側が検証前に弾いていた。
curl で直接叩いても同様で、問題の切り分けに時間がかかった。
解決策:google-auth-library を使う
結論として、Googleの公式ライブラリ google-auth-library を使うのが正解 だった。このライブラリはJWTの生成・エンコード・トークン取得の一連の処理を正しく行ってくれる。
npm install google-auth-library --save-dev認証部分のコードはシンプルになった。
import { GoogleAuth } from 'google-auth-library';
async function getAccessToken() {
const auth = new GoogleAuth({
keyFile: process.env.GOOGLE_APPLICATION_CREDENTIALS,
scopes: ['https://www.googleapis.com/auth/analytics.readonly'],
});
const client = await auth.getClient();
const token = await client.getAccessToken();
return token.token;
}「インストールなしで実現する」という方針にこだわりすぎた。JWTのエンコード仕様はGoogleの内部実装に依存している部分があり、公式ライブラリを使うのが素直な正解だった。
GA4 Data APIの呼び出し
アクセストークンが取れれば、あとは fetch でAPIを叩くだけだ。
async function runReport(token, body) {
const res = await fetch(
`https://analyticsdata.googleapis.com/v1beta/properties/${PROPERTY_ID}:runReport`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
}
);
const data = await res.json();
if (data.error) throw new Error(`API エラー: ${JSON.stringify(data.error)}`);
return data;
}レポートのリクエスト本体は、取得したいディメンション・メトリクス・期間を指定する。たとえば流入経路を取得する場合はこうなる。
const traffic = await runReport(token, {
dateRanges: [{ startDate: '30daysAgo', endDate: 'today' }],
dimensions: [{ name: 'sessionDefaultChannelGroup' }],
metrics: [{ name: 'sessions' }, { name: 'activeUsers' }],
orderBys: [{ metric: { metricName: 'sessions' }, desc: true }],
limit: 10,
});スクリプト全体は scripts/ga4-report.mjs に保存し、実行は以下のコマンドで行う。
export $(grep -v '^#' .env.local | xargs) && node scripts/ga4-report.mjs 30数字を変えれば集計期間を変更できる(7日間なら 7、90日間なら 90)。
Step 5: Claude Code スキルの作成
スクリプトが動くようになったら、Claude Codeのスキルとして登録する。スキルとは ~/.claude/skills/ 以下に置くMarkdownファイルで、「いつ使うか」を description に書くことでClaude Codeが自動で呼び出してくれる。
~/.claude/skills/ga4-report/SKILL.md---
name: ga4-report
description: Use when the user wants to check GA4 analytics — traffic sources, popular pages, device breakdown, or any site analytics report
---
# GA4 レポート生成
## 実行方法
```bash
cd "C:/Users/<YOUR_USERNAME>/MyProject"
export $(grep -v '^#' .env.local | xargs) && node scripts/ga4-report.mjs
```これで「アクセス状況を確認して」「先週のPVを見せて」といった発言に対してClaude Codeが自動でスクリプトを実行してくれるようになる。
まとめ
GA4 Data APIとClaude Codeのスキル機能を組み合わせることで、アクセス解析レポートの取得を自動化できた。
ステップ | ポイント |
|---|---|
Google Cloud設定 | 請求先アカウントのリンクを忘れずに |
JSONの配置 | プロジェクト外( |
JWT認証 | 手動実装より |
スキル登録 |
|
GA4 Data APIは無料枠が十分に広いため(1日あたり200,000リクエスト)、個人サイトの用途であれば費用を気にせず使える。Claude Codeと組み合わせることでアクセス解析の確認コストをゼロに近づけられる。