Cookie マッチングとは、おおまかに言えば、広告主様またはベンダーが、自社ドメインの Cookie と Google のドメインの Cookie を関連付けることを指します。これによって、同じユーザーについてのファーストパーティ データと Google の広告データ(ディスプレイ&ビデオ 360 およびキャンペーン マネージャー 360 でトラッキングされたもの)を接続し、CRM のデータも組み込んだ分析でユーザー行動への理解を深めることができます。プライバシーを重視した結合によってこれらのデータを組み合わせると、以下が可能になります。
- 自社の広告およびドメインと接触したユーザーを、ショッピング カートに入れたまま放棄した商品アイテムを基準にオーディエンスにまとめ、ターゲティングする。
- 自社ドメインの滞在時間が長くなる広告を特定する。
- 購入履歴とキャンペーン後のデータを結合したものを分析する。
制限事項とエンドユーザーのプライバシー
Cookie マッチングは強力ですが、次のような制限事項も存在します。
*_match
テーブルと非*_match
テーブルの結合は禁止されています。- 広告主様側でも Google 側でもエンジニアの作業が必要です。
- 通常は Google の広告データをすべてマッチングできるわけではありません。マッチ率はさまざまな要素の影響を受け、使用ケースやクライアント サイドの構成によって変化します。マッチ率が想定より低いことも珍しくありません。Cookie マッチングの対象にできるのは、広告主様のドメインと広告の両方と接触したことがあるユーザーのみです。
- マッチテーブルへのデータ取得は、セットアップが完了してから始まります。ユーザーがサイトを訪れてマッチング ピクセルを受け取る頻度によっては、マッチテーブルに包括的かつ安定的なユーザーデータが揃うまでに何か月かかかる可能性があります。
- 一人のユーザーを複数のデバイスと関連付けることができるのは、デバイスをまたいで同一ユーザーを識別できる方法をご自身でお持ちの場合のみです。
- 同一ユーザーを複数の Cookie によってマッチングすることはできません(ユーザーが Cookie を削除した場合など)。
- マッチテーブル上で実行するジョブには、Ads Data Hub の他のジョブと同様のデータ集約の要件が適用されます。マッチ率が低く、ユーザーがドメインを訪問する頻度も低いと、データの取得が難しくなることがあります。そのため、データ集約の要件を満たすためにはマッチ率も考慮する必要があります1。
- エンドユーザーのプライバシーに関する Google のポリシーにも規定されているとおり、以下に注意する必要があります。
- 同一ユーザーのログイン中のデータとログアウト中のデータをマッチングすることは禁止されています。
- 広告のパーソナライズからオプトアウトしているユーザーをデータとマッチングすることはできません。
- iOS でのイベントについては、iOS 14.5 以降のアプリに由来するデータをマッチングできるのは、該当ユーザーが Apple の App Tracking Transparency フレームワーク内で許可を出している場合のみです。
ファーストパーティによる同意取得の確認
Ads Data Hub でファーストパーティ データを使用するには、EU ユーザーの同意ポリシーと Ads Data Hub ポリシーに則って、Google へのデータ共有に対する EEA のエンドユーザーによる適切な同意を取得していることを確認する必要があります。同意取得の確認は、Ads Data Hub アカウントごとに、新しいファーストパーティ データをアップロードするたびに行う必要があります。1 人のユーザーがアカウント全体を代表してこの確認を行うことができます。
分析クエリに適用される同じ Google サービス クエリルールが Cookie マッチング クエリにも適用されます。たとえば、マッチテーブルを作成する際、EEA 内のユーザーに対してサービス間クエリを実行することはできません。
Ads Data Hub で同意獲得を確認する方法については、欧州経済領域の同意に関する要件をご覧ください。
Cookie マッチングの仕組み
Google マッチテーブルを埋められるようにするためには、ドメイン内で広告データのマッチングを実施したいすべてのページで、マッチタグを配信する必要があります。ピクセルを配置する位置は、広告掲載の目標に応じて異なります。たとえばドメインを訪問するすべてのユーザーをマッチングしたい場合は、ほぼすべてのページでピクセルが必要になり、コンバージョンに至ったユーザーをマッチングしたい場合はコンバージョン ページでピクセルが必要になります。マッチ率を高めるうえでは、基本的には幅広くピクセルを配置したほうが有利です。
マッチタグは透明な 1×1 ピクセルで、Cookie マッチングのプロファイル ID と、エンコードされたユーザー ID または Cookie ID が含まれています。
<img src="https://cm.g.doubleclick.net/pixel?google_nid=adh_customername&google_hm=Q29va2llIG51bWJlciAxIQ" />
広告主様と Google の Cookie マッチング サービスの間のやりとりは、このマッチタグによって開始されます。
おおまかな流れ
- マッチタグが設置されたページをユーザーが訪問します。
- マッチタグが、Google マーケティング プラットフォーム、Google 広告、および YouTube のマッチング サービスへのリダイレクトを開始します。各リクエストには、広告主様のウェブサイトにおける該当ユーザーの ID または Cookie と、各マッチング サービスの ID 空間における Google の Cookie が含まれています。
- リクエストの処理が完了したことを伝えるため、透明な 1×1 ピクセルがブラウザに返されます。
このプロセスを図にすると、次のようになります。
セットアップ
Ads Data Hub で Cookie マッチングをセットアップする際のプロセスは次のとおりです。
- アカウント担当者に連絡し、Cookie マッチングに興味があることを伝えます。担当者が広告主様の目標についてご相談のうえ、ドメインへのトラッキング ピクセルの配備について詳細をご案内します。
- Ads Data Hub のスペシャリストが、技術要件や使用ケースについて再度ご相談します。
- 広告主様がトラッキング ピクセルとエラー エンドポイントを配備されている間、Google がマッチテーブルを作成します。
以上の手順を完了後は、当面必要なアクションはありません。マッチテーブルへのデータ追加は 1 日ごとに行われます2。テーブルに十分なデータが蓄積して意味のあるマッチが発生し、データ集約の要件が満たされるまで、しばらくお待ちください。所要時間は広告主様のサイトのアクセス頻度によって変わり、たとえば毎日ユーザーが訪れるサイトであれば、月に 1 回ユーザーが訪れるサイトよりもずっと早く要件が満たされることになります。新規マッチングの発生ペースが落ち着くにつれ、マッチテーブルに含まれるデータの包括性が増してきます。
マッチテーブルでのクエリ実行
マッチテーブルにプライバシー チェックの発動に十分なデータが蓄積されている場合は、テーブルでクエリを実行できます。
Ads Data Hub スキーマ内で user_id
フィールドを含むテーブルは、それぞれ対応する *_match
テーブルを持ちます。たとえば adh.google_ads_impressions
テーブルに対しては adh.google_ads_impressions_match
というマッチテーブルが自動的に生成され、後者にはユーザー ID が含まれています。ポリシー分離テーブル用に個別のマッチテーブルが作成されます。たとえば adh.google_ads_impressions_policy_isolated_youtube
テーブルに対しては adh.google_ads_impressions_policy_isolated_youtube_match
というマッチテーブルが自動的に生成され、後者にはユーザー ID が含まれています。
生成されたテーブルには、元のテーブルのユーザーの中から、user_id
によるマッチがあったものだけを抽出したサブセットが格納されています。たとえば、元のテーブルにユーザー A とユーザー B のデータが含まれていて、ユーザー A のみにマッチがある場合、ユーザー B はマッチテーブルに格納されません。
マッチテーブルには external_cookie
という列があり、Cookie がバイト型で保存されます。
クエリを記述する際は、フィールドのデータ型を考慮することが重要です。SQL の比較演算子では、比較するリテラル同士は同じデータ型であることを期待されます。自社データのテーブルの user_id
の格納方法によっては、データをマッチングする前に、テーブル内の値のエンコードが必要となることもあります。マッチングを成功させるには、結合キーをバイトに型変換する必要があります。
JOIN ON
adh.google_ads_impressions_match.external_cookie = CAST(my_data.user_id AS BYTES)
また、SQL の文字列比較では大文字と小文字が区別されます。正確な比較ができるよう、必要に応じて双方の文字列をエンコードしてください。
ユーザー ID のエンコード
ユーザー ID をクライアントサイドでエンコードする
さまざまな ID 形式を安全に URL 経由で伝達するため、ID はすべて URL 用 Base64 エンコードにしたうえで送信する必要があります。URL 用 Base64 からデコードした ID は、Ads Data Hub の external_cookie
フィールドで提供されます。エンコード前になんらかの変換処理を加えていた場合は、逆変換することによって元の ID が得られます。
広告主様側の ID が常に半角 24 文字(24 バイト)以内であれば、下の「例 1」のように、URL 用 Base64 エンコードの ID をピクセルに含めることが可能です。ID が半角 24 文字(24 バイト)を超える場合、24 バイト以内で表現できる形式に変換する必要があります。場合によっては(「例 2」の GUID のように)バイト表現に変換するだけで済みますが、そうでない場合は ID のサブセット(またはハッシュ)を Google に送信することになります。いずれの場合も、自社データテーブル内の ID を同じ方法で変換する SQL の JOIN 句を、ご自身で記述できる必要がある点に注意しましょう。
例 1
自社データのユーザー ID の値が常に 24 バイトの制限以内となる場合の例です。この場合、ユーザー ID を(URL 転送できるよう URL 用 Base64 でエンコードしたうえで)そのまま Ads Data Hub に送ることをおすすめします。
var userId = 'abcdef123456789';
// Encode the string (or number) in normal base64.
var userIdBase64 = btoa(userId);
// Ensure that the uploaded user IDs use web-safe Base64 encoding.
userIdBase64 = userIdBase64.replace(/\+/g, '-').replace(/\//g, '_')
.replace(/=+$/, '');
// After encoding the UUID correctly, you can create the request tag and
// insert it into the DOM.
var imgElement = Document.createElement('img');
imgElement.src =
'https://cm.g.doubleclick.net/pixel?google_nid=adh_customername&google_hm='
+ userIdBase64;
document.body.appendChild(imgElement);
例 2
ユーザー ID として「123e4567-e89b-12d3-a456-426655440000
」のような UUID(Universally Unique Identifier)を割り当てている場合の例です。
この場合、Ads Data Hub でのマッチングの際は次のような変換を行うことをおすすめします。
- 16 進法による 36 文字の文字列値の UUID を使用します。
- 文字列値の UUID を 16 進法デコードします。
- UUID はバイト値になります。
- バイト値の UUID を URL 用 Base64 エンコードします。
- 制限字数以内の文字列値の UUID が得られます。
これを実装したコードは次のようになります。
JavaScript
var userId = '123e4567-e89b-12d3-a456-426655440000';
// A helper function for converting a hex string to a byte array.
function strToBytes(str) {
for (var bytes = [], i = 0; i < str.length; i += 2) {
bytes.push(parseInt(str.substr(i, 2), 16));
}
return bytes;
}
// Remove the formatting dashes from the UUID.
userId = userId.replace(/-/g, '');
// Encode the hex string as a byte array.
var userIdBytes = strToBytes(userId);
// Encode the byte array in normal base64.
var userIdBase64 = btoa(String.fromCharCode(...new Uint8Array(userIdBytes)));
// Ensure that the uploaded user IDs use web-safe Base64 encoding.
userIdBase64 = userIdBase64.replace(/\+/g, '-').replace(/\//g, '_').replace(
/=+$/, '');
// After encoding the UUID correctly, you can create the request tag and
// insert it into the DOM.
var imgElement = Document.createElement('img');
imgElement.src =
'https://cm.g.doubleclick.net/pixel?google_nid=adh_customername&google_hm='
+ userIdBase64;
document.body.appendChild(imgElement);
Python
import base64
user_id = '123e4567-e89b-12d3-a456-426655440000'
user_id_as_bytes = bytes.fromhex(user_id.replace('-', ''))
base64.urlsafe_b64encode(user_id_as_bytes)
Google ユーザー ID とのマッチが発生すると、広告主様側の ID が external_cookie
フィールドにバイト値として出力されます。元の ID を復元するには、次の変換処理が必要となります。
external_cookie
がバイト値で提供されます。- バイト値の
external_cookie
を 16 進法エンコードします。 - 文字列値の
external_cookie
が得られます。
ユーザー ID を Ads Data Hub 内でエンコードする
ファーストパーティ データで UUID 文字列をフィールドに格納している場合、データ結合を正しく行うためには、上の例と同様に、UUID を文字列値からバイト値に変換する必要があります。
次の例は、UUID をエンコードして外部 Cookie フィールドで結合する方法を示したものです。
JOIN my_data ON imp.external_cookie = FROM_HEX(REPLACE(my_data.uuid, '-', ''))
整数値をバイト値にキャスト(変換)することはできない点に注意しましょう。自社データのユーザー ID が(「例 1」のように)整数値の場合、まずは次のように文字列値にキャストします。
JOIN my_data ON imp.external_cookie = CAST(CAST(my_data.user_id AS STRING) AS BYTES)
データをマッチングするために必要なエンコード処理は、自社データの保存形態と、Ads Data Hub へ送信する前に行ったエンコード処理によって決まる点に留意しましょう。
クエリの例
次の例では、まずファーストパーティ データを google_ads_impressions_match
と結合し、その結果を 2 つ目のクエリで adh_google_ads_impressions
と結合しています。
SELECT
imp.campaign_id as campaign_id,
sum(my_data.recent_orders) as orders,
average(my_data.lifetime_value) as ltv
FROM
adh.google_ads_impressions_match as imp
LEFT JOIN
my_data ON imp.external_cookie = my_data.company_guest_id_bytes
GROUP BY
campaign_id
previous_results
として保存された前クエリの結果を使って、google_ads_impressions
との結合を行います。これにより、インプレッション 0 件のキャンペーンのデータが結果に追加されます。
SELECT
campaign_id,
COALESCE(orders, 0) as orders,
COALESCE(ltv, 0) as ltv,
FROM (SELECT DISTINCT campaign_id
FROM adh.google_ads_impressions)
LEFT JOIN previous_results USING (campaign_id)