環境
フレームワーク:express.js (node.js)
node: v16
背景
node.js では、universal-analystics という有名なGoogle Analystics用のパッケージがあり、今まではUAから始まるIDを指定することでアクセスデータをGoogle Analysticsで解析できていました。
しかし、UAは2023年7月に終了する予定となっており、GA4に移行しなければいけない状況です。
そこでGA4に移行したいのですが、GA4に対応したnodeのパッケージが存在しません。
現在存在するパッケージのほとんどはフロントエンド用で、バックエンド用(サーバー用)のパッケージが存在しないのです。
手順
自身で作成する必要があります。
サーバーからGA4を使用してアクセスデータを送信する方法は、Googleが提供している「Measurement Protocol 」を使用します。要するにAPIです。
公式のリファレンスはこちらなのですが、どうやらここに掲載されていない実装があるようで少々厄介です。
![](https://ryuden.org/wp-content/uploads/cocoon-resources/blog-card-cache/427db16025a0237045ed56531896e8e9.png)
API Secretを生成
まず、API KEYを作成します。
Google Analystics → 管理 → データストリーム → ウェブ → ウェブ ストリームの詳細 → Measurement Protocol API Secrets からAPIを作成します。
公式のマニュアルは以下です。
コーディング
次にコードを書きます。
エンドポイントに指定されたフォーマットのJSONをPOSTする構成とする必要があります。
私は、app.jsに次のようなコードを追加しました。
measurement_id は G- から始まるGA4のタグです。
api_secret には取得したAPI KEYを入力します。
const fetch = require('node-fetch');
const crypto = require('crypto');
app.use(async function (req, res, next) {
const measurement_id = "G-AAAAAAAAA"
const api_secret = "BBBBBBBBBBBBBBB"
const reqip = req.headers['x-real-ip'] || req.socket.remoteAddress
const iphash = crypto.createHash('md5').update(reqip).digest('hex')
console.log(req.path)
const reqjson = {
client_id: 'myserver',
user_id: iphash ,
non_personalized_ads: false,
events: [
{
name: 'page_view',
params: {
event_source: 'server',
page_title: req.path,
page_location: 'https://your-domain' + req.path,
page_path: req.path,
engagement_time_msec: 100,
session_id: 123,
},
}
]
}
fetch("https://www.google-analytics.com/mp/collect?measurement_id=" + measurement_id + "&api_secret=" + api_secret, {
method: 'POST',
body: JSON.stringify(reqjson),
headers: { 'Content-Type': 'application/json' }
})
next()
});
このコードでは、IPアドレスをハッシュ化してuser_idとして送信しています。
※ nginxの裏にあるサーバーのため、x-real-ip を取得しようとします。
なお、page_viewイベントや、page_title、page_location、page_pathなどのパラメーターは公式のマニュアルには存在しないのですが、海外フォーラムによると動くそうで、実際に動きます。
サポートされていないのか、マニュアル不備なのか、私の調査不足かは分からないので、この点は無保証だと思ってください。gtag.jsの方にはpage_viewイベントあるんですけどね。
まとめ
この件で想像以上に詰まったので、後の誰かの参考になれば幸いです。
とはいえ、GA4はアクセス記録に向いたサービスではないので他の方法を模索した方が良いかもしれませんが。
参考
![](https://qiita-user-contents.imgix.net/https%3A%2F%2Fcdn.qiita.com%2Fassets%2Fpublic%2Fadvent-calendar-ogp-background-f625e957b80c4bd8dd47b724be996090.jpg?ixlib=rb-4.0.0&w=1200&mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTkxNiZoPTMzNiZ0eHQ9R29vZ2xlJTIwQW5hbHl0aWNzJTIwNCUyMCVFMyU4MSVBRSVFMyU4MiVBNCVFMyU4MyU5OSVFMyU4MyVCMyVFMyU4MyU4OCVFMyU4MiU5MiVFMyU4MiVCNSVFMyU4MyVCQyVFMyU4MyU5MCVFMyU4MyVCQyVFNSU4MSVCNCVFMyU4MSU4QiVFMyU4MiU4OSVFOSU4MCU4MSVFNCVCRiVBMSVFMyU4MSU5OSVFMyU4MiU4QiVFNiU5NiVCOSVFNiVCMyU5NSVFMyU4MiU5MiVFOCVBQSVCRiVFMyU4MSVCOSVFMyU4MSVBNiVFMyU4MSVCRiVFMyU4MSU5RiZ0eHQtY29sb3I9JTIzM0EzQzNDJnR4dC1mb250PUhpcmFnaW5vJTIwU2FucyUyMFc2JnR4dC1zaXplPTU2JnR4dC1jbGlwPWVsbGlwc2lzJnR4dC1hbGlnbj1sZWZ0JTJDbWlkZGxlJnM9ZDk0ODFkM2RkZjBmODExZDMyZTA1YjVjZjI1MDYzOTg&mark-x=142&mark-y=151&blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTYxNiZ0eHQ9JTQwaW51a2FpLW1hc2Fub3JpJnR4dC1jb2xvcj0lMjMzQTNDM0MmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9MzYmdHh0LWFsaWduPWxlZnQlMkN0b3Amcz01ODU3ZDY3YWZhMDI2NmEzM2I3YzJjZGM5ZTYwNTE4YQ&blend-x=142&blend-y=491&blend-mode=normal&s=3947815e1b5b8a29a1835a090a508f3c)
![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a)
![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a)
![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a)
コメント