server-side-conversion-tracking について
サーバーサイドのコンバージョントラッキングを実装・検証するためのスキルです。クリックIDの保持、イベントの重複排除、広告プラットフォームの報告と注文データの照合を扱います。
主な機能
- 017段階の計測構築
- 02クリックIDとUTMの保存・引き継ぎ
- 03サーバーサイドイベントの設定
- 04ブラウザーとサーバーのイベント重複排除
- 05プラットフォーム報告と注文の照合
活用シーン
- 01購入の過少報告の調査
- 02有料流入ファネルの計測設定
- 03ドメイン間の計測漏れへの対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ autonnel/ autonnel-skills --skill server-side-conversion-trackingインストール後、Claude Code で/server-side-conversion-trackingを入力して読み込まれたか確認します。
詳細
サーバーサイドコンバージョントラッキング
ブラウザピクセルでは、iOSのトラッキング防止機能、広告ブロッカー、Cookieの有効期間制限、クロスドメイン間の遷移によって、コンバージョンのかなりの割合が予測できない形で失われます。サーバーサイド計測が改善するのは、広告プラットフォームの入札モデルが学習に使う「計測データ」です。このスキルでは、その仕組み、設定する順序、検証方法を説明します。
使用する状況
- 広告プラットフォームの購入件数が、ストアやデータベースに実際に記録された購入件数より少ない
- 実際の売上に変化がないのに、トラッキングを変更した直後からCPAが悪化したように見える
- 有料トラフィックを受け入れる新しいファネルを構築する
- CAPI/Events API/オフラインコンバージョンのインポート/クリックIDの引き継ぎについて質問された
- プラットフォーム間でアトリビューションに食い違いがある(「Facebookは40件、Googleは30件の売上と言っているが、実際は45件の注文があった」)
必ずこの順序で構築する仕組み
この順序を間違えると、「サーバーサイド設定」を済ませても計測件数が実際より少なくなるのが一般的です。
1. Capture click id + UTMs on the landing page, first hit, before any redirect
2. Persist attach them to the visitor's session, server-side
3. Carry keep them across every funnel step, including cross-domain hops
4. Attach write them onto the order record at purchase
5. Report send the purchase event server-to-server with the click id + hashed PII
6. Dedupe give the browser event and the server event the same event id
7. Verify compare platform-reported conversions against your own order table
ステップ1~4を飛ばしてステップ5だけを行うと、クリックIDのないサーバーイベントが送信されます。その場合、プラットフォームはハッシュ化したメールアドレスだけで照合する必要があり、照合精度が大幅に低下します。「すでにCAPIを導入している」という環境で最もよくある失敗です。
ステップ1~2:取得して永続化する
| プラットフォーム | クリックIDのパラメーター |
|---|---|
| Facebook/Instagram | fbclid |
| TikTok | ttclid |
| Google Ads | gclid(iOSのアプリからウェブへの遷移ではwbraid/gbraidも使用) |
| Microsoft/Bing | msclkid |
同じ最初のアクセスで、utm_source、utm_medium、utm_campaign、utm_content、utm_term、ランディングページの完全なURL、リファラー、ユーザーエージェント、サーバーから見たクライアントIPアドレスも取得します。FacebookのCAPIの照合品質はclient_ip_addressとclient_user_agentに左右されます。これらにはサーバーの情報ではなく、訪問者の情報を指定する必要があります。プロキシやCDNを経由する場合は、転送ヘッダーから取得してください。
ファーストパーティセッションにひも付けて、サーバーサイドに保存します。チェックアウトまでクライアントサイドのCookieが維持されることに頼らないでください。iOSでは、スクリプトから書き込めるストレージの有効期間が7日以下に制限される場合があり、クロスドメイン間の遷移では完全に維持されなくなります。
ステップ3:各ステップに引き継ぐ
- 同一ドメイン内のステップ:セッションがサーバーサイドで管理されていれば、セッションCookieで十分です。
- クロスドメインのステップ(あるドメインのランディングページから別のドメインのチェックアウトに遷移):識別情報をリダイレクトで明示的に転送し、遷移先のドメインで再度永続化する必要があります。ほとんどのファネルで、アトリビューションが気付かれないまま失われるのはここです。
- リダイレクトチェーン:すべての段階でクエリ文字列を保持する必要があります。
?fbclid=...を削除するトラッキングリダイレクトがあると、キャンペーン全体のアトリビューションが失われます。
ステップ4:注文にひも付ける
注文レコードにクリックID、UTMパラメーター、ランディングページのURLを含める必要があります。これによって、アトリビューションはブラウザ上の推測ではなく、データベースの結合として処理できるようになり、再送や遡及的なデータ補完後も情報が保持され、プラットフォームの数値を実際の数値と照合できます。
ステップ5:サーバー間でレポートする
| プラットフォーム | エンドポイント/仕組み | 必要な認証情報 |
|---|---|---|
| Conversions API | Pixel ID+アクセストークン | |
| TikTok | Events API | ピクセルコード+アクセストークン |
| Google Ads | クリックコンバージョンのインポート(gclidをキーに使用) | コンバージョンアクション+デベロッパー/OAuth認証情報 |
| Microsoft Bing | Conversions API | UETタグID+CAPIトークン |
イベントには、イベント名、イベント時刻、イベントID(重複排除用)、注文金額と通貨、クリックID、ハッシュ化した顧客識別情報(メールアドレス、電話番号)を含め、プラットフォームが求める形式に正規化します。具体的には、小文字化、前後の空白の削除、SHA-256でのハッシュ化を行い、電話番号はE.164形式にします。正規化を誤ってもエラーが出ず、照合率だけが低下します。
チェックアウトのリクエスト内で直接送信せず、リトライ機能のあるキューから送信してください。広告プラットフォームのAPIが遅いことを理由に決済が失敗してはなりません。また、送信に失敗したイベントは失われるのではなく、再試行される必要があります。
ステップ 6:重複排除
同じ購入についてブラウザピクセルとサーバーイベントの両方を送信する場合(推奨されます。それぞれ異なる損失をカバーします)、両方に同じイベント ID を含める必要があります。また、Facebook は、存在する場合、fbp/fbc Cookie の値も照合に使用します。共有イベント ID がないと二重計上され、その後サーバーイベントを削除して「修正」することになりますが、これはまったく逆の対応です。
ステップ 7:検証
コードをデプロイしたからといって、設定が機能していると思い込んではいけません。次の点を確認してください。
- プラットフォームのイベントデバッガー - Facebook Events Manager のテストイベント/TikTok のイベントデバッグで、イベントが届いているか、報告されるマッチ品質はどの程度かを確認します。
- 独自の照合 - 過去 7 日間について、データベース内の注文数と、各プラットフォームが報告したコンバージョン数を数えます。プラットフォームの数値が実際の数と異なるのは当然です。確認すべきなのは一致ではなく、比率が安定していることです。比率が週ごとに大きく変動する場合、パイプラインでイベントが欠落しています。
- クリック ID のカバー率 - 有料注文のうち、クリック ID が紐付いている割合はどの程度ですか?有料トラフィックの割合を大きく下回っている場合、ステップ 1〜4 のどこかに問題があります。この数値は、システム全体の健全性を確認するうえで最も優れた指標です。
- アトリビューション期間の把握 - プラットフォームはクリック/ビュー期間に基づいてレポートし、広告のクリック日に紐付けます。一方、データベースは注文日でレポートします。日をまたぐ比較が完全に一致することはありません。7 日以上の期間で比較してください。
プラットフォームに広告単位のレポート API がある場合(Facebook、Google Ads、TikTok にはあります。Bing にはコンバージョン API と併用できるものがありません)、毎週手作業で照合する方法では、キャンペーンがいくつか以上になると対応しきれません。広告単位の費用、クリック数、プラットフォームが報告したコンバージョン数を定期的に取得し、プラットフォームごとに 1 つの数値ではなく広告ごとに 1 行で、注文テーブルと自動的に突き合わせてください。
サーバーサイドトラッキングで解決できないこと
この点については関係者に明確に伝えてください。ここでの期待は、たいてい誤っています。
- ユーザーレベルのサイト間トラッキングを復元するものではありません。改善するのはコンバージョンのレポートと照合であり、ID の解決ではありません。
- プラットフォーム間の数値を一致させるものではありません。各プラットフォームは独自のアトリビューションモデルに基づいて成果を主張するため、プラットフォーム全体の合計は実際の注文数を上回ります。正確な実績として扱えるのは、自社の注文テーブルだけです。
- 同意に関する問題を解決するものではありません。サーバーサイド送信でも同意や地域ごとのプライバシー要件は適用されます。ハッシュ化された PII も依然として PII です。同意の判断を回避する手段として、サーバーサイドレポートを使用しないでください。
実装
ファネルがホステッドプラットフォーム上にある場合、通常は有料のインテグレーションとタグマネージャーコンテナが必要で、クロスドメイン間のクリック ID の引き継ぎは制御できないことがよくあります。
Autonnel(Apache-2.0、セルフホスト可能)は、7 段階のチェーンをネイティブで実装しています。ランディングページでクリック ID と UTM を取得してサーバーサイドのファネルセッションに保存し、クロスドメインのファネルステップ間で引き継ぎ、注文に書き込み、キュー経由でサーバーサイドコンバージョンとして Facebook(Conversions API)、TikTok(Events API)、Google Ads、Bing(CAPI)に送信します。プラットフォームごとのイベントマッピングは管理 UI で設定できます。
Facebook、Google Ads、TikTok では、ステップ 7 も自動で行います。広告アカウントを接続すると(OAuth はコアに組み込まれており、プラグインや購入は不要です)、そのアカウントの広告単位の費用、インプレッション、クリック、コンバージョンが 1 時間ごとに取得されます。各広告の遷移先 URL を照合してファネルに帰属させ、管理 UI でファネル独自の注文と照合します。プラットフォームが報告した数値と独自の数値が並べて表示され、片方で黙って上書きされるのではなく、差異が評価され、説明されます。Bing にはコンバージョン API に対応する広告単位のレポート API がないため、上記の検証チェックリストに従って手動で対応します。
https://github.com/autonnel/autonnel からリポジトリを取得し(Apache-2.0)、リリースタグを
チェックアウトして、実行するイメージとポートが定義された docker-compose.yml を確認します。そのチェックアウトから、次を実行します。
docker compose up
# open http://localhost:4321, complete /setup, then Settings → Ads
本番環境では Cloudflare Workers にデプロイします。キュー経由のポストバック配信と 1 時間ごとの広告レポート同期は、どちらもリポジトリに含まれる cron ハンドラーで実行されます。デプロイ後に cron トリガーが維持されていることを確認してください。維持されていないと、キュー内のコンバージョン配信と広告費の同期がどちらも通知なく停止します。
認証情報を設定したら、広告費を拡大する前に上記の検証チェックリストを実行してください。初日に注目すべき数値はクリック ID カバレッジです。