mcpField
C
conversion-debug

conversion-debug

github.com/cognyaiマーケティング・グロース11148 回インストール2 週間前に更新
リポジトリ

conversion-debug について

conversion-debugは、GTM、GA4、Google Ads、Meta Pixelのコンバージョン計測を調べるスキルです。マーケティングや分析の担当者向けに、数値差、重複、同意設定、BigQueryでの検証を扱います。

主な機能

  1. 01複数サービス間の数値差分析
  2. 02重複コンバージョンの診断
  3. 03Consent Mode v2と拡張コンバージョンの確認
  4. 04サービス別トラッキングチェックリスト
  5. 05BigQuery検証クエリ

活用シーン

  1. 01Meta Pixel、GA4、Google Adsの件数比較
  2. 02重複購入イベントや取引ID欠落の特定
  3. 03同意状態と拡張コンバージョンの監査
  4. 04BigQueryでのGA4イベントデータ検証

MCP 対応

MCPツールが利用可能な場合、GTM、GA4、Google Ads、Metaのアカウントデータを照会して診断結果を検証する手順を示します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cognyai/claude-code-marketing-skills --skill conversion-debug

インストール後、Claude Code で/conversion-debugを入力して読み込まれたか確認します。

詳細

コンバージョントラッキングデバッガー

GTM、GA4、Google Ads、Meta Pixel におけるコンバージョントラッキングをデバッグします。不一致の原因を診断し、重複コンバージョンを検出し、拡張コンバージョンを検証し、Consent Mode v2 を監査して、BigQuery の検証クエリを実行します。

完全なドキュメント:https://cogny.com/docs/conversion-tracking-debugger

使い方

/conversion-debug                          # Full debugging overview
/conversion-debug duplicate conversions    # Diagnose duplicate purchases
/conversion-debug consent mode             # Consent Mode v2 audit
/conversion-debug meta vs ga4              # Cross-platform discrepancy analysis
/conversion-debug enhanced conversions     # Validate enhanced conversion setup
/conversion-debug server-side tagging      # Server-side GTM overview
/conversion-debug value wrong              # Debug incorrect conversion values

手順

あなたはコンバージョントラッキングのデバッグを専門としています。このリファレンスと利用可能な MCP ツールを使って、GTM、GA4、Google Ads、Meta Pixel におけるコンバージョントラッキングの問題をユーザーが診断し、修正できるよう支援してください。

ユーザーから質問されたら、以下から関連するセクションを見つけ、正確で実行可能な回答を提供してください。MCP ツールを利用できる場合は、ユーザーのアカウントから最新のデータを取得し、調査結果を検証してください。

ユーザーが引数として特定のトピックを指定した場合は、その内容に焦点を当ててください。それ以外の場合は、どのプラットフォームまたは問題について支援が必要かを尋ねてください。

MCP ツールを利用できる場合は、次の診断手順に従ってください。

  1. GTM ツールを使ってタグ、トリガー、ワークスペースの状態を確認する
  2. GA4 ツールを使ってコンバージョンイベントを確認し、レポートを実行して、データストリームを検証する
  3. Google Ads ツールを使ってコンバージョン アクションのステータスとパフォーマンスを照会する
  4. Meta ツールを使ってピクセルの設定を確認し、コンバージョン数を比較する
  5. 各プラットフォームの調査結果を相互に照合して、根本原因を特定する

コンバージョントラッキングの仕組み

データの流れを理解することが、デバッグの第一歩です。

User Action (click, form submit, purchase)
        |
        v
+-------------------+
|   Website / App   |
|   (dataLayer)     |
+-------------------+
        |
        v
+-------------------+       +-------------------+
|  Google Tag       | ----> |  GA4              |
|  Manager (GTM)    |       |  (Measurement     |
|                   |       |   Protocol)       |
|  - GA4 Config Tag |       +-------------------+
|  - GA4 Event Tag  |               |
|  - Google Ads Tag |               v
|  - Meta Pixel Tag |       +-------------------+
+-------------------+       |  BigQuery Export  |
        |                   |  (daily/intraday) |
        |                   +-------------------+
        |
        +----------> +-------------------+
        |            |  Google Ads       |
        |            |  (Conversion      |
        |            |   Tracking)       |
        |            +-------------------+
        |
        +----------> +-------------------+
                     |  Meta Pixel       |
                     |  + Conversions    |
                     |    API (CAPI)     |
                     +-------------------+

主なデータフロー:

  1. dataLayer へのプッシュ -- ウェブサイトがイベントデータを window.dataLayer にプッシュします
  2. GTM トリガー -- dataLayer イベントに一致するトリガー条件に基づいてタグが発火します
  3. ネットワークリクエスト -- 各タグが送信先に個別の HTTP リクエストを送信します
  4. プラットフォームでの処理 -- 各プラットフォームが独立して処理、重複排除、アトリビューションを行います
  5. BigQuery へのエクスポート -- GA4 は生イベントを BigQuery にエクスポートします(プロパティのタイムゾーンで毎日午前 5 時頃)

よくある不一致とその理由

GA4 と Google Ads のコンバージョン数の違い

GA4 と Google Ads の数値が一致することはほとんどありません。これは想定どおりです。

要因GA4Google Ads
アトリビューションモデルデータドリブン(クロスチャネル)データドリブン(Google チャネルのみ)
カウント方法設定可能:セッションごとに 1 回、またはイベントごとに 1 回設定可能:コンバージョン 1 回、またはすべて
コンバージョン期間デフォルト 30 日デフォルト 30 日(最大 90 日)
クロスデバイスGoogle シグナル + User-IDGoogle アカウントへのログイン
ビュースルーデフォルトではカウントされないディスプレイ/動画では含まれる(デフォルトは 1 日)
データの鮮度処理に 24~72 時間の遅延コンバージョンは数時間以内に表示
モデル化されたコンバージョン同意が得られない場合の行動モデリング観測できないコンバージョンのモデリング

一般的な差異は 5~20% で、正常な範囲です。20% を超える場合は調査が必要です。

MCP による診断方法:

1. GA4: tool_list_conversion_events → check which events are marked as conversions
2. GA4: tool_run_report → pull conversion counts by date
3. Google Ads: tool_execute_gaql → query conversion_action metrics
4. Compare the numbers and identify the gap source
Meta Pixel と GA4 の違い
要因MetaGA4
クリック後の計測期間7 日(デフォルト)30 日(デフォルト)
ビュースルーデフォルトで 1 日分を含むデフォルトではカウントされない
アトリビューションMeta 内のラストタッチデータドリブンのクロスチャネル
重複排除ブラウザーと CAPI の重複排除に eventID を使用transaction_id パラメーター
クロスデバイスFacebook のログイングラフGoogle シグナル + User-ID

Meta の数値が高くなりやすい理由: ビュースルーコンバージョンが含まれるためです。ユーザーが Meta 広告を見てもクリックせず、その後 Google 検索経由でコンバージョンした場合、Meta はこれを計上しますが、GA4 はオーガニック/CPC にアトリビューションします。

GTM は発火しているのに GA4 がデータを受信しない
  1. 同意モードによるブロック -- タグは発火しますが、同意が拒否されるとデータを送信しません
  2. 広告ブロッカー -- ユーザーの約 25~30% が google-analytics.com へのリクエストをブロックします
  3. 競合状態 -- リクエストの完了前にページが閉じられます(フォームの送信、外部リンクへの移動など)
  4. 測定 ID の不一致 -- タグ設定の G-XXXXXXX が間違っています
  5. データフィルタ -- GA4 プロパティのフィルタによってイベントが非表示または変更されています
  6. 下書きと公開済みの違い -- GTM プレビューでは下書きが使われ、ライブサイトでは公開済みのバージョンが使われます
コンバージョンの重複

トラッキングで最もコストのかかる不具合です。一般的な原因は次のとおりです。

  1. transaction_id がない -- 一意の ID がないと、GA4 は重複を排除できません
  2. タグの二重発火 -- 複数のタグが同じコンバージョンを送信しています
  3. サンクスページの再読み込み -- ユーザーが確認ページを更新します
  4. 戻るボタン -- ユーザーが確認ページに戻ります
  5. CAPI の重複排除がない -- 一致する eventID がないため、Meta Pixel と CAPI の両方が発火します

防止策:

// dataLayer push with transaction_id for deduplication
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T-12345',  // REQUIRED for dedup
    value: 99.99,
    currency: 'USD',
    items: [/* ... */]
  }
});
// Prevent duplicate pushes on page reload
if (!window.sessionStorage.getItem('purchase_tracked_T-12345')) {
  window.dataLayer.push({
    event: 'purchase',
    ecommerce: { transaction_id: 'T-12345', value: 99.99, currency: 'USD' }
  });
  window.sessionStorage.setItem('purchase_tracked_T-12345', 'true');
}

プラットフォーム別のデバッグチェックリスト

Google Tag Manager(GTM)

プレビューモードの確認:

  • 正しいワークスペース/コンテナのバージョンが有効ですか?
  • イベントがタイムラインに表示されていますか?
  • タグのステータスが「発火済み」になっていますか?
  • 予期しないタグの重複発火はありませんか?

トリガー条件:

  • イベント名は dataLayer.push({ event: '...' }) と完全に一致していますか(大文字と小文字を区別します)?
  • すべてのフィルタ条件は正しいですか?
  • 発火を妨げるブロッキングトリガーはありませんか?

変数の値(プレビューモード):

  • transaction_id に値が設定され、一意になっていますか?
  • value と currency が存在し、型は正しいですか?
  • カスタム JS 変数は期待どおりの値を返しますか?

dataLayer の確認:

// View full dataLayer
console.table(window.dataLayer);

// Filter for purchase events
window.dataLayer.filter(e => e.event === 'purchase');

// Check ecommerce data
window.dataLayer.filter(e => e.event === 'purchase').map(e => e.ecommerce);

ネットワークリクエストの確認(DevTools > Network):

  • google-analytics.com/g/collect -- GA4
  • googleads.g.doubleclick.net/pagead/conversion -- Google Ads
  • facebook.com/tr -- Meta Pixel

MCP による診断:

tool_list_tags → see all tags in the container
tool_search_tags → find conversion-related tags
tool_get_tag → inspect specific tag configuration
tool_list_triggers → verify trigger setup
tool_get_workspace_status → check for unpublished changes
GA4

DebugView:

// Enable debug mode
gtag('config', 'G-XXXXXXX', { debug_mode: true });

次に、GA4 > Admin > DebugView でイベント、パラメータ、ユーザープロパティを確認します。

リアルタイムレポート:

  • トリガー時にイベント数が増加していますか?
  • コンバージョンカードにイベントが表示されていますか?

MCP による診断:

tool_list_conversion_events → verify which events are marked as conversions
tool_run_realtime_report → check real-time event data
tool_run_report → pull historical conversion data by date
tool_list_data_streams → verify stream configuration

BigQuery による検証:

-- Check conversion events in BigQuery
SELECT
  event_name,
  COUNT(*) as event_count,
  COUNT(DISTINCT user_pseudo_id) as unique_users,
  MIN(TIMESTAMP_MICROS(event_timestamp)) as earliest,
  MAX(TIMESTAMP_MICROS(event_timestamp)) as latest
FROM `project.analytics_PROPERTY_ID.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 3 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
  AND event_name IN ('purchase', 'generate_lead', 'sign_up', 'add_to_cart', 'begin_checkout')
GROUP BY event_name
ORDER BY event_count DESC
Google Ads

コンバージョンアクションのステータス:

  • 「コンバージョンを記録中」(緑色)= 正常に動作しています
  • 「最近のコンバージョンはありません」= タグは設置されていますが、発火していないか、データが遅延しています
  • 「タグが無効です」= 7 日以上ヒットがありません
  • 「未確認」= タグが一度も検出されていません

MCP による診断:

tool_execute_gaql →
  SELECT
    conversion_action.name,
    conversion_action.status,
    conversion_action.type,
    conversion_action.tag_snippets,
    metrics.conversions,
    metrics.conversions_value
  FROM conversion_action
  WHERE segments.date DURING LAST_7_DAYS

tool_get_gaql_doc → look up conversion_action fields

Google タグの確認:

// Check gtag is loaded
typeof gtag === 'function'  // Should be true

// Check conversion linker cookie
document.cookie.split(';').filter(c => c.includes('_gcl'))
Meta Pixel

イベントマネージャのテストイベント:

  • ウェブサイトの URL を入力し、コンバージョンを実行して、イベントが表示されることを確認します
  • イベントパラメータ(value、currency、content_ids)を確認します
  • イベントマッチクオリティスコアを確認します(6 以上を目指します)

CAPI の重複排除: ブラウザーの Pixel と CAPI のイベントは、同じ eventID を共有する必要があります。

// Browser-side
fbq('track', 'Purchase', {
  value: 99.99,
  currency: 'USD',
  content_ids: ['SKU-123'],
  content_type: 'product'
}, { eventID: 'purchase_T-12345' });
# Server-side CAPI
curl -X POST \
  "https://graph.facebook.com/v18.0/PIXEL_ID/events?access_token=TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "data": [{
      "event_name": "Purchase",
      "event_time": 1700000000,
      "event_id": "purchase_T-12345",
      "action_source": "website",
      "user_data": {
        "em": ["HASHED_EMAIL"],
        "client_ip_address": "1.2.3.4",
        "client_user_agent": "Mozilla/5.0..."
      },
      "custom_data": {
        "value": 99.99,
        "currency": "USD",
        "content_ids": ["SKU-123"]
      }
    }]
  }'

MCP による診断:

tool_get_pixels → verify pixel configuration
tool_get_insights → pull conversion data for comparison with GA4/Google Ads

BigQuery による検証クエリ

日別のコンバージョン数をカウントする(GA4 UI と比較)
SELECT
  PARSE_DATE('%Y%m%d', event_date) as date,
  event_name,
  COUNT(*) as total_events,
  COUNT(DISTINCT user_pseudo_id) as unique_users,
  COUNT(DISTINCT
    CONCAT(user_pseudo_id, '-',
      (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id'))
  ) as unique_sessions
FROM `project.analytics_PROPERTY_ID.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
  AND event_name IN ('purchase', 'generate_lead', 'sign_up')
GROUP BY 1, 2
ORDER BY 1 DESC, 2

しきい値処理、サンプリング、モデル化されたコンバージョン(UI には表示されますが、BigQuery には表示されません)により、BigQuery と GA4 UI の間に小さな差(1~5%)が生じるのは正常です。

重複したトランザクション ID を検出する
WITH purchase_events AS (
  SELECT
    PARSE_DATE('%Y%m%d', event_date) as date,
    user_pseudo_id,
    (SELECT value.string_value FROM UNNEST(event_params)
     WHERE key = 'transaction_id') as transaction_id,
    TIMESTAMP_MICROS(event_timestamp) as event_time,
    ecommerce.purchase_revenue_in_usd as revenue
  FROM `project.analytics_PROPERTY_ID.events_*`
  WHERE _TABLE_SUFFIX BETWEEN
    FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
    AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
    AND event_name = 'purchase'
)

SELECT
  transaction_id,
  COUNT(*) as occurrence_count,
  COUNT(DISTINCT user_pseudo_id) as distinct_users,
  MIN(event_time) as first_occurrence,
  MAX(event_time) as last_occurrence,
  TIMESTAMP_DIFF(MAX(event_time), MIN(event_time), SECOND) as seconds_between,
  SUM(revenue) as total_revenue_recorded,
  MAX(revenue) as actual_revenue
FROM purchase_events
WHERE transaction_id IS NOT NULL
GROUP BY transaction_id
HAVING COUNT(*) > 1
ORDER BY occurrence_count DESC
-- Find purchases with NULL transaction_id (cannot be deduplicated)
SELECT
  PARSE_DATE('%Y%m%d', event_date) as date,
  COUNT(*) as purchases_without_txn_id,
  SUM(ecommerce.purchase_revenue_in_usd) as revenue_at_risk
FROM `project.analytics_PROPERTY_ID.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
  AND event_name = 'purchase'
  AND (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'transaction_id') IS NULL
GROUP BY 1
ORDER BY 1 DESC
コンバージョンイベントのパラメータがすべて揃っているか確認する
SELECT
  event_name,
  param.key,
  COUNT(*) as events_with_param,
  COUNT(DISTINCT user_pseudo_id) as users_with_param,
  COUNTIF(param.value.string_value IS NOT NULL) as has_string_value,
  COUNTIF(param.value.int_value IS NOT NULL) as has_int_value,
  COUNTIF(param.value.float_value IS NOT NULL) as has_float_value
FROM `project.analytics_PROPERTY_ID.events_*`,
  UNNEST(event_params) as param
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
  AND event_name IN ('purchase', 'generate_lead', 'sign_up', 'begin_checkout')
GROUP BY 1, 2
ORDER BY 1, events_with_param DESC
-- Check required ecommerce fields on purchase events
SELECT
  PARSE_DATE('%Y%m%d', event_date) as date,
  COUNT(*) as total_purchases,
  COUNTIF(ecommerce.transaction_id IS NOT NULL) as has_transaction_id,
  COUNTIF(ecommerce.purchase_revenue_in_usd > 0) as has_revenue,
  COUNTIF(ecommerce.total_item_quantity > 0) as has_quantity,
  COUNTIF(ARRAY_LENGTH(items) > 0) as has_items,
  ROUND(SAFE_DIVIDE(
    COUNTIF(
      ecommerce.transaction_id IS NOT NULL
      AND ecommerce.purchase_revenue_in_usd > 0
      AND ARRAY_LENGTH(items) > 0
    ), COUNT(*)
  ) * 100, 1) as pct_fully_complete
FROM `project.analytics_PROPERTY_ID.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
  AND event_name = 'purchase'
GROUP BY 1
ORDER BY 1 DESC
拡張コンバージョンのデータを検証する
SELECT
  PARSE_DATE('%Y%m%d', event_date) as date,
  event_name,
  COUNT(*) as total_events,
  COUNTIF(user_id IS NOT NULL) as has_user_id,
  COUNTIF(
    (SELECT value.string_value FROM UNNEST(user_properties) WHERE key = 'email') IS NOT NULL
    OR (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'user_data_email') IS NOT NULL
  ) as has_email_signal,
  COUNTIF(
    (SELECT value.string_value FROM UNNEST(user_properties) WHERE key = 'phone') IS NOT NULL
    OR (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'user_data_phone') IS NOT NULL
  ) as has_phone_signal
FROM `project.analytics_PROPERTY_ID.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
  AND event_name IN ('purchase', 'generate_lead', 'sign_up')
GROUP BY 1, 2
ORDER BY 1 DESC, 2
予想イベントと実際のイベントを照合する
WITH expected_events AS (
  SELECT event_name FROM UNNEST([
    'purchase', 'add_to_cart', 'begin_checkout', 'view_item',
    'generate_lead', 'sign_up', 'add_payment_info', 'add_shipping_info'
  ]) as event_name
),
actual_events AS (
  SELECT
    event_name,
    COUNT(*) as event_count,
    MAX(TIMESTAMP_MICROS(event_timestamp)) as last_seen
  FROM `project.analytics_PROPERTY_ID.events_*`
  WHERE _TABLE_SUFFIX BETWEEN
    FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
    AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
  GROUP BY event_name
)

SELECT
  e.event_name,
  COALESCE(a.event_count, 0) as event_count,
  a.last_seen,
  CASE
    WHEN a.event_count IS NULL THEN 'MISSING - never received'
    WHEN a.last_seen < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 48 HOUR) THEN 'STALE - no events in 48h'
    ELSE 'OK'
  END as status
FROM expected_events e
LEFT JOIN actual_events a USING(event_name)
ORDER BY
  CASE WHEN a.event_count IS NULL THEN 0 WHEN a.last_seen < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 48 HOUR) THEN 1 ELSE 2 END,
  e.event_name

Consent Mode v2

コンバージョントラッキングへの影響

Google Consent Mode v2(2024 年 3 月以降、EEA で必須)は、ユーザーの同意に基づいてデータ収集を制御します。

必須シグナル:

シグナル制御対象
analytics_storageGA4 の Cookie と完全な測定
ad_storageGoogle Ads の Cookie とコンバージョン測定
ad_user_data広告配信のためにユーザーデータを Google に送信すること
ad_personalizationリマーケティングとパーソナライズド広告

動作:

  • granted -- データを完全に収集し、Cookie を設定して、ユーザーレベルのデータを送信します
  • denied -- Cookie を使用しない ping を送信し、Google がコンバージョンをモデル化します(UI には表示されますが、BigQuery には表示されません)
実装
// Set defaults BEFORE GTM snippet
gtag('consent', 'default', {
  analytics_storage: 'denied',
  ad_storage: 'denied',
  ad_user_data: 'denied',
  ad_personalization: 'denied',
  wait_for_update: 500
});

// Update on user choice (called by CMP)
gtag('consent', 'update', {
  analytics_storage: 'granted',
  ad_storage: 'granted',
  ad_user_data: 'granted',
  ad_personalization: 'granted'
});
実装チェックリスト
  • GTM スニペットの読み込み前にデフォルトの同意状態が設定されていますか?
  • 4 つの v2 シグナルがすべて設定されていますか?
  • CMP はユーザーの選択時に gtag('consent', 'update', ...) を呼び出しますか?
  • GTM の組み込み同意チェックが有効になっていますか?
  • wait_for_update は設定されていますか(500ms を推奨)?
  • 同意状態はページ間で保持されますか?
  • 拒否状態:Cookie を使用しない Ping が送信されていますか(Network タブで gcs=G100 を確認)?
  • 許可状態:完全な計測が再開されますか?
BigQuery:同意の影響分析
SELECT
  PARSE_DATE('%Y%m%d', event_date) as date,
  COUNTIF(user_pseudo_id IS NOT NULL) as events_with_user_id,
  COUNTIF(user_pseudo_id IS NULL) as events_without_user_id,
  COUNTIF(
    (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') IS NOT NULL
  ) as events_with_session,
  ROUND(SAFE_DIVIDE(
    COUNTIF((SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') IS NULL),
    COUNT(*)
  ) * 100, 1) as pct_likely_consent_denied
FROM `project.analytics_PROPERTY_ID.events_*`
WHERE _TABLE_SUFFIX BETWEEN
  FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))
  AND FORMAT_DATE('%Y%m%d', CURRENT_DATE() - 1)
GROUP BY 1
ORDER BY 1 DESC

拡張コンバージョン

送信されるデータ

コンバージョンタグとともに送信されるハッシュ化されたファーストパーティ顧客データです。照合精度が向上します。

フィールド形式必須
メールアドレスSHA-256 ハッシュ化、小文字、前後の空白を削除メールアドレス、電話番号、または氏名+住所のいずれか 1 つ以上
電話番号SHA-256 ハッシュ化、E.164 形式任意ですが推奨
姓/名SHA-256 ハッシュ化、小文字任意
住所フィールドSHA-256 ハッシュ化任意
国ISO 3166-1 alpha-2、ハッシュ化なし任意
GTM を使用した設定(dataLayer 方式)
window.dataLayer.push({
  event: 'purchase',
  user_data: {
    email: '[email protected]',       // Auto-hashed by GTM
    phone_number: '+11234567890',
    address: {
      first_name: 'John',
      last_name: 'Doe',
      street: '123 Main St',
      city: 'New York',
      region: 'NY',
      postal_code: '10001',
      country: 'US'
    }
  },
  ecommerce: {
    transaction_id: 'T-12345',
    value: 99.99,
    currency: 'USD'
  }
});
gtag.js を使用した設定
gtag('set', 'user_data', {
  email: '[email protected]',
  phone_number: '+11234567890',
  address: {
    first_name: 'John', last_name: 'Doe',
    street: '123 Main St', city: 'New York',
    region: 'NY', postal_code: '10001', country: 'US'
  }
});
検証チェックリスト
  • Google Ads > コンバージョン > 診断 > 拡張コンバージョンのステータスが「記録中」になっていますか?
  • 48~72 時間後にマッチ率が表示されますか?
  • GTM プレビュー:「ユーザー提供データ」タブにハッシュ化された値が表示されますか?
  • ネットワークリクエストに em=(ハッシュ化されたメールアドレス)が含まれていますか?

サーバーサイド タグ設定

メリット
  1. 広告ブロッカーへの耐性 — ファーストパーティドメインを使用するため、ブロックされません
  2. Cookie の有効期間の延長 — ITP の 7 日間に対して 2 年以上
  3. ページ容量の削減 — ブラウザーのスクリプト数が減少します
  4. データの制御 — ベンダーに送信する前に検査・変更できます
  5. 同意管理の強化 — 一元的な適用ポイントを設けられます
アーキテクチャ
Browser                    Server                          Endpoints
GTM Web Container  --->  GTM Server Container  --->  GA4 / Google Ads / Meta CAPI
                         (Cloud Run)
                         gtm.yourdomain.com
ファーストパーティドメインの設定
// GA4 Config tag: set server container URL
gtag('config', 'G-XXXXXXX', {
  server_container_url: 'https://gtm.yourdomain.com'
});
# DNS: CNAME to Cloud Run service
gtm.yourdomain.com  CNAME  your-cloud-run-service.run.app

トラブルシューティングのフローチャート

コンバージョンが表示されない
Tag installed? --NO--> Install tag. Publish GTM container.
  |YES
  v
Tag fires in GTM Preview? --NO--> Check trigger: event name exact match?
  |YES                              Conditions met? Blocking triggers?
  v
Network request in DevTools? --NO--> Consent Mode blocking?
  |YES                                Ad blocker? CSP blocking?
  v
Request returning 200/204? --NO--> Check endpoint URL, measurement ID, credentials.
  |YES
  v
Platform-specific:
- GA4: Wait 24-48h. Check DebugView. Check data filters.
- Google Ads: Wait 24h. Check conversion action status. Is it "Primary"?
- Meta: Check Events Manager > Test Events. Check event match quality.
コンバージョン数が一致しない
Difference > 20%? --NO--> Normal variance. Document baseline.
  |YES
  v
Which platform shows MORE?
- Google Ads > GA4: Counting "every"? View-through? Longer window? Modeled?
- GA4 > Google Ads: All channels vs Google-only? Action set to Primary?
- Meta > GA4: View-through included? iOS modeling?
- GA4 > Meta: Ad blockers? No CAPI? Low match quality?
  |
  v
Run BigQuery validation queries to get ground truth.
コンバージョン値が正しくない
Value always 0/NULL? --YES--> Check: 'value' in dataLayer? 'currency' present?
  |NO                          value is number not string? Variable mapping?
  v
Value consistently wrong? --YES--> Static value override? Currency conversion?
  |NO
  v
Value doubled? --YES--> Duplicate events. Multiple tags. Double dataLayer push.
  |NO
  v
Check: tax/shipping included? cents vs dollars? string formatting? locale?

クイックリファレンス:dataLayer の例

E コマースの購入
window.dataLayer.push({ ecommerce: null });  // Clear previous
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T-12345',
    value: 99.99,
    tax: 8.50,
    shipping: 5.99,
    currency: 'USD',
    items: [{
      item_id: 'SKU-001',
      item_name: 'Product Name',
      item_brand: 'Brand',
      item_category: 'Category',
      price: 99.99,
      quantity: 1
    }]
  }
});
リード獲得
window.dataLayer.push({
  event: 'generate_lead',
  value: 50.00,
  currency: 'USD',
  lead_source: 'contact_form'
});
gtag.js 直接使用(GTM なし)
// Google Ads conversion
gtag('event', 'conversion', {
  send_to: 'AW-XXXXXXXXX/CONVERSION_LABEL',
  value: 99.99,
  currency: 'USD',
  transaction_id: 'T-12345'
});

// GA4 purchase
gtag('event', 'purchase', {
  transaction_id: 'T-12345',
  value: 99.99,
  currency: 'USD',
  items: [{ item_id: 'SKU-001', item_name: 'Product', price: 99.99, quantity: 1 }]
});

リソース

コメント