この記事では、Google Analytics Data API (GA4) を利用してNext.jsブログに人気記事を表示する方法を解説します。
この記事でわかること:
- Google Cloud Platformでのサービスアカウント作成手順
- GA4とサービスアカウントの連携方法
- Next.js + TypeScriptでのAPI実装方法
- PV数に基づく人気記事ランキングの取得方法
Google Analytics Data API の概要 | Google for Developersdevelopers.google.com
参考に出来る記事ないかな?と思いつつググりまくったものの Google Analytics Reporting API v4を利用した記事 しかヒットしませんでした。 「GA4 API」みたいな検索が良くなかったのかもしれません。 まあ、それなら、記事にしちゃえばいいやと思って今に至ります。
機能が半分ぐらい実装される所で、良さげな記事を見つけました(僕の検索力に問題があったようです)。
本記事の実装は、恐らく当ブログで利用されます。参考になれば幸いです。
Google Analytics Data API (GA4) の使い方
ライブラリの準備
今回はNext.js + TypeScriptで実装していきます。好きなパッケージマネージャでインストールしましょう。
npm install @google-analytics/data# oryarn add @google-analytics/data必要なライブラリはこれだけです。
Home - Documentation
googleapis.dev
API利用の準備
これだけだとまだAPIを実行することは出来ません。 APIを実行するために、各種サービスの準備をしていきます。
- Google Cloud Platform
- サービスアカウントの作成
- サービスアカウントの鍵の発行と設定
- Google Analytics
- プロパティのアクセス管理
サービスアカウントの作成
(プロジェクトの作成については、ここでは省略します。)
Google Cloud Platformのページからサービスアカウントを作成します。
サービスアカウントのリストを開きます
サービスアカウントに作成するアカウントの詳細を入れます
念のため閲覧者のみのロールを割り当ててアカウントの作成を完了します
ここまででサービスアカウントの作成が完了します。簡単でしたね?
サービスアカウントから鍵の発行
ここでは、先の項で作成したサービスアカウントに紐づく鍵を発行します。
サービスアカウントのキータブを開いて、新しい鍵を作成ボタンを押下します
新しい鍵を作成ボタンを押下後、キーのタイプが選択できるのでJSONを選択します
環境変数の設定
また今回はNext.jsのSSGを利用します。 ですのでcredential等のファイル形式ではなく、必要な値を環境変数として埋め込むようにします。
{ "type": "service_account", "project_id": "aaa", "private_key_id": "bbb", "private_key": "-----BEGIN PRIVATE KEY-----\nccc\n-----END PRIVATE KEY-----\n", "client_email": "test-service-account@silver-adapter-374912.iam.gserviceaccount.com", "client_id": "ddd", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test-service-account%40silver-adapter-374912.iam.gserviceaccount.com"}JSONファイルがダウンロードされるので、以下の2つをメモっておいてください。
client_emailprivate_key
環境変数では以下として利用します。
GA_CLIENT_EMAIL=test-service-account@silver-adapter-374912.iam.gserviceaccount.comGA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----ccc-----END PRIVATE KEY-----"# 合わせてプロパティIDも設定しておくGA_PROPERTY_ID=xxxNext.jsではクライアント側にも見えるように NEXT_PUBLIC_* という指定が出来ますが、今回は利用しません。
APIキーが露出することによって、意図せずAPIが叩かれたり、情報が流出したりする可能性があります。
ここまで完了したらGoogle Cloud Platform側の設定は完了です。 Google Analyticsの設定に移ります。
プロパティのアクセス管理
先にGoogle Cloud Platformで作成したアカウントの権限をGoogle Anaylticsに登録します。
Google Analyticsの管理ページをから「プロパティのアクセス管理」を押下します
サイドバーを開いたら右上のプラスボタンを押下してアカウントの追加画面を開きます
役割とデータ制限の追加でアドレスを指定し、追加する
このページでは以下の順に実行します。
- サービスアカウントのメールアドレスを入力する
- 先の
test-service-account@silver-adapter-374912.iam.gserviceaccount.com
- 先の
- 「新規ユーザーにメールで通知する」のチェックボックスを外す
- 「追加」ボタンを押下する
上記でGoogle Analytics側の設定が完了します。これでようやくAPIを叩く準備が整いました。
APIを実行する
以下の様にNode.jsでAPIを実行することが可能です。
import { BetaAnalyticsDataClient } from '@google-analytics/data';
const analyticsDataClient = new BetaAnalyticsDataClient({ credentials: { client_email: process.env.GA_CLIENT_EMAIL, private_key: process.env.GA_PRIVATE_KEY?.replace(/\\n/g, '\n'), },});
export const fetchPopularPosts = async ( startDate: '7daysAgo' | '14daysAgo' | '30daysAgo', pageSize: number,) => { const [response] = await analyticsDataClient.runReport({ property: `properties/${process.env.GA_PROPERTY_ID}`, dateRanges: [ { startDate: startDate, endDate: 'today', }, ], dimensions: [ { name: 'pagePath', }, ], metrics: [ { name: 'screenPageViews', }, ], dimensionFilter: { filter: { fieldName: 'pagePath', stringFilter: { matchType: 5, // value: '^/(articles)/[0-9a-zA-Z\\-]+$', }, }, }, limit: pageSize, }); return response.rows?.map((row) => { console.log(row.dimensionValues[0], row.metricValues[0]); });};取得した結果を出力すると以下のような形式で表示されます。
使い易い様に Object に詰めたりしましょう。
{ value: '/articles/aaa', oneValue: 'value' } { value: '44', oneValue: 'value' }{ value: '/articles/ddd', oneValue: 'value' } { value: '38', oneValue: 'value' }{ value: '/articles/ccc', oneValue: 'value' } { value: '24', oneValue: 'value' }{ value: '/about', oneValue: 'value' } { value: '24', oneValue: 'value' }上記のデータから記事データのみでフィルタしたいのでdimensionFilter の部分に正規表現を入れます。
フィルタに利用する MatchType には FULL_REGEXP を利用しています。
namespace StringFilter { /** MatchType enum. */ enum MatchType { MATCH_TYPE_UNSPECIFIED = 0, EXACT = 1, BEGINS_WITH = 2, ENDS_WITH = 3, CONTAINS = 4, FULL_REGEXP = 5, PARTIAL_REGEXP = 6, }}実装
最終的な実装については添付しておきます。
blog/src/lib/ga.ts at main · paveg/bloggithub.com
コンポーネント側
blog/src/pages/popular.tsx at main · paveg/bloggithub.com
おわりに
思ったより実装自体は難しくなかったですが、下準備が大変なので面倒くさいかもしれません。
なお、この記事はNext.js時代のブログ用に書いたものです。現在のブログはAstroに移行し、Cloudflare Analyticsを利用しています。Astroでの実装方法については、以下の移行記事も参考にしてください。
関連記事
Next.jsからAstroへブログ移行|LightHouseフルスコア達成までの技術選定と実装 | フナイログwww.funailog.com
AstroブログにJSON-LDを実装してSEO強化する方法 | フナイログwww.funailog.com