サーバサイドタグ（サーバサイドGTM）を導入するまとめ（2024年版）

# サーバーサイドGTM
始めにサーバーサイドGTMというのはGoogleの公式用語ではないです。
用語だけ独り歩きしている感じがあるのですが、
実態は要素技術の組み合わせでしかありません。

Google公式ではサーバサイドタグと呼ばれています。

https://developers.google.com/tag-platform/tag-manager/server-side?hl=ja

## この記事を書いた動機

サーバサイドタグは要素技術の集合と冒頭で書きました。
情報が断片的だったり、情報自体が古かったりして設定方法が変わっており、
設定箇所も多く、総合的なwebの知識が必要でハマりどころがかなり多かったため、まとめたかったのが動機です。
（そもそもサーバサイドタグの導入ガイド的なものの情報があまりない…）

## なぜサーバサイドタグが必要なのか？

皆さんも一度は目にしたことがあろう、EUのウェブサイトを中心としたCookie許可のバナー。
これらは広告トラッキング用のサードパーティcookieを許可するかの確認バナーです。
(※画像はstack overflowのバナーです。)

<img width=300 src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/25912d16-6c56-a767-b051-a09b449f1d63.png' />

EUではこのバナー表示をプライバシー保護のため、法律で実装必須の義務化がされています。（幸い日本ではまだ必須ではないですが）
しかし、サードパーティcookieは使えなくなり、すでに多くの広告トラッキングに影響が出ている状態です。
（このため、精度が悪い広告に対し、無駄金を使っている状況）

[GA4とGTMで消えゆくCookieの実態を徹底調査：リピートユーザーの判定率はわずか47.8％](https://www.dentsudigital.co.jp/knowledge-charge/articles/2022/0519-ga4cookies)


特にMobile SafariはITP（Intelligent Tracking Prevention）と呼ばれるトラッキング防止機能で
サードパーティcookie（トラッキング用の別ドメインの第三者サーバcookie）をすでに排斥しています。
ITP2.3以降ではCookie以外にlocalStorageも最大7日間までしか保存できず、ファーストパーティcookieも24時間しか保存できない制限がすでにかかっています。

Google Chromeでもサードパーティcookie廃止の流れは来ており、
[段階的に2024年1月4日から1%、第3四半期から100%のユーザーに適用される予定です。](https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout?hl=ja)



クライアントサイドタグとサーバーサイドタグの違いは、
クライアントサイドタグはブラウザから直接各広告プラットフォームにトラッキング情報を送信するのに対し、
サーバーサイドタグはGTMサーバコンテナを中継（プロキシ）としてトラッキング情報をサーバ経由で送信します。
サーバ経由にすることのメリットとしては

- サーバコンテナにサブドメインを設定することで、サードパーティcookieをファーストパーティcookieとして扱える
- ブラウザで各トラッキング情報を送るのでなく、サーバ側でまとめて送る（まとめることが出来ればトラッキング情報を各広告プラットフォームに個別でブラウザから送る必要がなくなるため、ページのパフォーマンスが上がる）

![GDIDFcJb0AEkzte.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/7b610148-b9fa-cabf-d1cf-a8f9bc09fc25.png)


このため、従来の方法ではまともに広告経由での流入ユーザをトラッキングできなくなるはずなので
広告プラットフォーマーを中心として、広告導入している企業はサーバーサイドタグへの移行が求められます。


# サーバーサイドタグを導入する（サーバサイドからGA4アナリティクスに送信まで）

基本的にはGoogle公式の導入ガイドが一番わかり易いので、これをベースにはしますが
一部古い箇所があったりスクショのリンクが切れている箇所があるので本稿で説明します。

https://developers.google.com/tag-platform/learn/sst-fundamentals?hl=ja

サーバサイドタグの全体像は以下の図のようになっています。
Googleタグ経由でGA4 clientのイベントをサーバコンテナに送信し、
GA4アナリティクスタグを発火、もしくは各広告プラットフォームに送信するタグを発火します。

![GDIDDS_bQAAp-iZ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/435d6820-f709-a2b8-027c-5a7319d8a866.jpeg)

サーバタグでGA4アナリティクスにイベント送信する場合、サーバコンテナからGA４イベントを送信します。
![GDIDJZMasAABnrq.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/fd9274ec-7f86-fc76-90fa-f81298f9cd76.jpeg)


サーバサイドタグを発火させるためには以下の設定が必要です。

- GTMタグの設置
- GA4の設定
    - データストリームの設定
    - (Googleシグナルの設定)
- GTMサーバコンテナの設定
    - GCPにサーバコンテナ(Cloud Run)を作成
    - GA4クライアントを作成
    - GA4イベント発火トリガーを作成
    - サーバサイドタグ作成
    - (サーバコンテナにサブドメインを設定する)
- GTMウェブコンテナの設定
    - Googleアナリティクス：GA4イベントを設定
    - Googleタグを設定


まず、ウェブページにGTMタグの設置を行います。

```js
<script>
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${process.env.GTM_ID}');
</script>
```

次にGA4のデータの収集と修正→データストリームからデータストリームを作成します。
ストリームURLはホスティングしているサーバーのURLを指定します。
ストリームID、測定IDは自動で払い出しされます。
`測定ID`はGTM側で設定するのでメモしておいてください。

![スクリーンショット 2024-01-08 14.03.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/62e10e72-8246-5c8a-4c42-708f3dd497cf.png)

シグナルの設定は必須でありませんが、精度を上げたり、クロスプラットフォームのトラッキングをする上で有効にした方が良さそうです。
GA4側のデータ収集でGoogleシグナルのデータ収集をONにします。
![スクリーンショット 2024-01-08 14.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/efe97ea4-1305-f63a-6c89-0a52caa058a1.png)


サーバコンテナはGTM管理画面のダッシュボードのアカウントメニューで、[コンテナを作成] をクリックします。

<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/e15a77b9-79fd-b072-7070-8ad5fe0b4651.png" />

[コンテナの設定]画面で、作成するコンテナに名前を付け、[Server]を選択します。[作成] をクリックします。コンテナの作成が完了すると、セットアップ画面が表示されます。
[タグ設定サーバーを自動的にプロビジョニング]をクリックするとGCPのCloud Run上にサーバコンテナを稼働するサーバが作成されます。
`デフォルトURL`は後で使うのでメモしておいてください。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f35353037372f36616361356132372d633930372d326139382d636433392d3861386266306334643862342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/e5ee9ebf-275c-b4d1-5d48-87b9c892bd55.png)


![スクリーンショット 2024-01-08 14.34.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/551b9b1c-3bc5-caaf-5c09-72d97ac46976.png)

作成したサーバコンテナのクライアントからGA4 Clientを作成します。
測定IDは先程GAのデータストリームで払い出した測定IDを指定してください。
地域ごとの設定を有効にするの変数は組み込み変数から`Visitor Region`選択してください

![スクリーンショット 2024-01-09 11.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/47f88775-0164-59d0-89a4-d15e20855e4b.png)

![スクリーンショット 2024-01-09 11.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/9a91a6b7-37c8-2c5c-1ca3-44b2775af8d8.png)

次にサーバコンテナのトリガーでGA4イベントを受けるトリガーを作成します。
カスタムタイプのトリガーで一部のイベント、Event Nameで`GA4`を等しいの指定にしてください。
ウェブコンテナ側のGA4イベントのイベント名と合わせる必要があります。（後述）
![スクリーンショット 2024-01-08 14.41.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/43e80fd3-85dd-e9dd-5861-f05d53f6a350.png)

サーバコンテナでサーバサイドからGA4アナリティクスに送信するタグを作成します。
`測定ID`にはGA4のデータストリームから払い出された測定IDを指定してください。
トリガーは先程作成した、GA4イベントを受けるトリガーを指定します。
Googleシグナルは必須ではありませんが、有効にしたほうがトラッキング精度があがります。
![スクリーンショット 2024-01-08 14.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/11b659f2-7919-55f7-9d4a-a47a13e840b8.png)



次にウェブコンテナ側でGoogleタグを作成します。
タグIDにGA4データストリームの`測定ID`を指定してください。
イベントパラメータを追加し、`server_container_url`にサーバコンテナのCloud RunのURLを指定します。
トリガーは`Initailization All Pages`にする必要があります。

![スクリーンショット 2024-01-08 11.49.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/dff14788-0bd0-d731-26a6-3fddfb01d4ff.png)

ウェブコンテナ側でGoogleアナリティクス:GA4イベントのタグを作成します。
測定IDにはGA4のデータストリームの測定IDを指定してください。
イベント名を`GA4`に指定します。（先ほど作成したサーバコンテナのトリガー条件イベント名を合わせてください）
トリガーは`Initailization All Pages`にしています。（Googleタグ発火後にする）
![スクリーンショット 2024-01-08 14.54.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/d5b63a07-578a-c71b-41cc-c4de4bae4916.png)

ウェブコンテナとサーバコンテナを公開します。

## プレビューによるデバッグ
ウェブコンテナのプレビューおよびサーバコンテナのプレビューを開いた状態で
GTMが設置されているページにアクセスしてください。

ウェブコンテナ側はアクセス後Initializationのタイミングで
GoogleタグとGoogleアナリティクスGAイベントが発火します。
![スクリーンショット 2024-01-08 15.15.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/25eec888-b114-0f20-544a-f6b88611ad35.png)

Googleタグの方をクリックするとGA4イベントがサーバコンテナに送信されていることがわかります。
![スクリーンショット 2024-01-08 15.15.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/f415fea2-ef3d-151b-54c6-d2fb910061c6.png)

サーバコンテナの方もGA4イベントをトリガーにしてGA4タグが発火します。
![スクリーンショット 2024-01-08 15.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/5eb38353-d7ea-8e59-c791-ca0549fc943c.png)

GA4イベントのリクエスト内容はRequestタブのIncoming HTTP Requestと
Event Dataタブから確認ができます。
（これらの送信情報からサーバコンテナで独自のタグテンプレートを作成し、コンバージョン情報を送信することも可能です。）
![スクリーンショット 2024-01-08 15.18.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/3efd05bf-1645-0583-224f-8897e63c869b.png)

![スクリーンショット 2024-01-08 15.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/20540a9b-ec86-e461-2c1d-f2e777287a6e.png)



サーバコンテナ経由でGoogle Analyticsにイベントが送信されます。
![スクリーンショット 2024-01-08 15.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/2acb63fc-5d3f-aaf9-5320-27d982ea4c61.png)

GA4のデータストリームの設定画面のGoogleタグも連携が完了しています。
![スクリーンショット 2024-01-08 14.51.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/40969be2-c07b-be77-c5df-1d240dd557c4.png)

![スクリーンショット 2024-01-08 14.53.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/4f067017-3c78-7ee2-5040-f51799c7bd9c.png)

## サーバコンテナにサブドメインを設定する
サーバコンテナにサブドメインを設定することでサードパーティCookieをファーストパーティCookie扱いにすることができ、トラッキングCookieの共有が可能になります。（推奨）

![GDIDIe9boAAGcvB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/2ccbb5c6-729c-a65e-2d5b-108d74f20935.jpeg)

Cloud Runのカスタムドメイン設定方法の詳細は本稿では割愛します。
以下などを参考にしてください。
[カスタム ドメインのマッピング](https://cloud.google.com/run/docs/mapping-custom-domains?hl=ja)

# GA4 to BigQuery
幸いにもGoogleが[タグテンプレート](https://github.com/google/sgtm-ga4-to-bigquery)を用意してくれています。

事前にGA4イベントデータ保存用のBigQueryテーブルの作成に`bq`コマンドが必要になります。
`bq`コマンドのセットアップには[gcloud CLIをインストール](https://cloud.google.com/sdk/docs/install?hl=ja)が必要です。

bqのセットアップが完了していれば、git cloneしてきて`deploy.sh`を実行するだけで
BigQueryテーブルを作成してくれます。
以下の指定が必要です。

- GCPプロジェクトID
- BigQueryデータセット名
- BigQueryテーブル名

```
rm -rf sgtm-ga4-to-bigquery && git clone https://github.com/google/sgtm-ga4-to-bigquery.git && cd sgtm-ga4-to-bigquery && bash deploy.sh
```

後はrepository内にある`template.tpl`ファイルを
新規タグテンプレートでインポートするだけで使えるようになります。

![スクリーンショット 2024-01-08 11.24.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/5939ff29-60a8-be64-90de-945d580357a5.png)

インポートしたテンプレートを使ってタグを作成します。


![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/35a66cef-566d-4963-5650-6ac3555b309a.png)


同様にアクセス時にBigQueryタグが発火し、専用BigQueryテーブルにアクセスユーザデータがInsertされるのが確認できます。

![スクリーンショット 2024-01-08 11.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/b0c075ea-b176-61c4-7d99-77a5e086a71f.png)


![スクリーンショット 2024-01-08 11.25.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/d485d124-4c90-c6f8-a22c-192945771915.png)

# サードパーティーのタグテンプレートを使う
サードパーティがタグテンプレートを用意してくれている場合はコミュニティテンプレートギャラリーから使うことが出来ます。

![スクリーンショット 2024-01-08 13.56.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/d1b6922f-68f7-d0cd-44f8-090d04e9c1d6.png)
![スクリーンショット 2024-01-08 13.56.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/150cbf1f-fc10-1a6f-f8a6-cd5be2815b68.png)

# 独自のタグテンプレートを作成する
タグテンプレートを自作すれば、GA4イベント経由で送信情報をフックし、任意の送信先サーバに情報送信が可能になります。

[サーバーサイド タグ設定 API](https://developers.google.com/tag-manager/serverside/api?hl=ja)


ウェブコンテナ側から送信するGA4イベントにイベントパラメータを追加します。
（GTMのJavaScript変数などを割り当てれば柔軟に送信パラメータを追加できるはずです。）

![スクリーンショット 2024-01-08 15.35.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/a6e8699d-7fe9-e139-9aeb-ff196687ccb9.png)

公開するとGA4イベントに追加したイベントパラメータが付与されるようになります。
![スクリーンショット 2024-01-08 15.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/36f11ed4-dfde-22b4-3733-e13a5d9464c3.png)


新規タグテンプレートを作成し、指定のエンドポイントにイベントパラメータを送信するコードを実装します。
![スクリーンショット 2024-01-09 11.40.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/4c31d29d-90d9-69f3-633b-9e56ce1a1bcf.png)


```javascript
const getAllEventData = require('getAllEventData');
const queryPermission = require('queryPermission');
const sendHttpGet = require('sendHttpGet');
const logToConsole = require('logToConsole');

if (queryPermission('read_event_data')) {
  const events = [];
  const eventObj = getAllEventData();
  for (let key in eventObj) {
    // GA4イベントからカスタムパラメータを取得する
    if (key === 'custom_param') {
      const value = eventObj[key];
      events.push(key + '=' + value);
    }
  }
  logToConsole(events);

  // タグで定義するendpointを取得
  const endpoint = data.endpoint;
  // get_urlを作成
  const url = endpoint + '?' + events.join('&');
  logToConsole(url);

  sendHttpGet(url).then((result) => {
    const statusCode = result.statusCode;
    if (statusCode >= 200 && statusCode < 300) {
      data.gtmOnSuccess();
     } else {
      data.gtmOnFailure();
     }
  });
}
```

`data.endpoint`はテンプレートの引数として変数で受け取れるようにします。

![スクリーンショット 2024-01-08 16.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/ab4d78b5-8930-4f6c-6078-86d4daba129f.png)

権限は使用しているコードから自動的にリストアップされます。
権限を付与しないと動かないことがあるので適切に付与してください。

![スクリーンショット 2024-01-08 16.24.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/3c1426c1-d72a-c2da-9a6c-d0f3eb3f066c.png)

作成したタグテンプレートを使ってCustomタグを作成し、公開します。
トリガーは同様にGA４イベント名をトリガーとします。
![スクリーンショット 2024-01-09 11.41.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/4ceea2d8-3663-22db-45c6-3e2f12d07472.png)


Customタグ発火時にGA4イベントのパラメータを受け取り指定のサーバに転送することができました。
![スクリーンショット 2024-01-08 15.48.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55077/fc689415-9877-402c-b7a6-ddee12e44029.png)