התאמה לפרטים שהמשתמשים סיפקו (UPDM)

התכונה UPDM (התאמה לפרטים שהמשתמשים סיפקו) מאפשרת לצרף את הנתונים מאינטראקציה ישירה (First-Party) שנאספו לגבי משתמש – כמו מידע מהאתרים, מהאפליקציות או מהחנויות הפיזיות – לפעילות של אותו המשתמש המחובר, שנאספה בכל נתוני המודעות מ-Google, כולל נתונים שבבעלות Google ובניהול Google. הנתונים האלה כוללים נתונים שנרכשו דרך מוצרי Google Marketing Platform‏ (GMP), למשל נתונים של YouTube שנרכשו באמצעות Display & Video 360. אין תמיכה במוצרים אחרים של GMP שאינם בבעלות Google ולא מופעלים על ידה.

כדי שאפשר יהיה להשתמש בהתאמה לפרטים שהמשתמשים סיפקו (UPDM), אירוע המודעה חייב להיות מקושר למשתמש מחובר בנתוני מודעות ממוצרי Google.

במסמך הזה מתוארת התכונה 'התאמת נתונים שהמשתמשים סיפקו', ומפורטות הנחיות להגדרה ולשימוש.

סקירה כללית

כדי לקבל תובנות פרסום חשובות, לרוב צריך לשלב נתונים ממקורות שונים. פיתוח פתרון משלכם לבעיה הזו בצינור הנתונים מחייב השקעה משמעותית של זמן והנדסה. הדף Connections (חיבורים) ב-Ads Data Hub מאפשר לייבא, לשנות ולהתאים נתונים ל-BigQuery בצורה יעילה יותר, באמצעות ממשק מודרך שמנחה אתכם שלב אחרי שלב. כך תוכלו להשתמש בנתונים האלה בשאילתות של Ads Data Hub או בכל מוצר אחר שקורא מ-BigQuery. העשרת השאילתות בנתונים מאינטראקציה ישירה (First-Party) יכולה לספק חוויות לקוח עשירות יותר, והיא עמידה יותר לשינויים בתחום המעקב אחר מודעות.

בדף Connections יש כלים שמאפשרים להצפין ולשתף פרטים אישיים מזהים (PII) עם שותפים באופן שמתמקד בפרטיות. אחרי שבוחרים אילו עמודות מכילות מידע אישי מזהה (PII), מערכת Ads Data Hub מצפינה את הנתונים כדי לוודא שרק אנשים שיש להם הרשאה יכולים לייצא או לקרוא את הנתונים מאינטראקציה ישירה. לפעמים קשה לדעת אילו נתונים מאינטראקציה ישירה נדרשים לתרחיש לדוגמה של מדידה או הפעלה, לכן מערכת Ads Data Hub מספקת רשימה מקיפה של תרחישים מוגדרים מראש, ולאחר מכן מנחה אתכם בכל תהליך החילוץ, הטרנספורמציה והטעינה של הנתונים. אפשר ליצור כמה סוגים של חיבורים, אבל במסמך הזה נניח שאתם משתמשים בדף Connections להתאמת נתונים שהמשתמשים סיפקו.

מקורות נתונים מאינטראקציה ישירה (First-Party) נתמכים

אפשר לייבא נתונים ממקורות הנתונים הבאים:

  • BigQuery
  • Cloud Storage
  • FTP מאובטח (SFTP)
  • פתית שלג
  • MySQL
  • PostgreSQL
  • Amazon Redshift
  • Amazon S3

התכונה לא מושפעת מהוצאה משימוש בעתיד של קובצי cookie של צד שלישי, מפני שהתאמה לפרטים שהמשתמשים סיפקו (UPDM) זמינה רק במלאי שטחי פרסום שנמצא בבעלות ובהפעלה של Google, עבור משתמשים מחוברים. מכיוון שהנתונים האלה עמידים יותר לשינויים בתחום בהשוואה לנתונים מצד שלישי, הם יכולים לספק תובנות מפורטות יותר, שיכולות להוביל למעורבות גבוהה יותר מצד הלקוחות.

לומדים את המונחים

  • חיבור לנתונים שהמשתמשים סיפקו: מגדירים חיבור לנתונים שהמשתמשים סיפקו כדי לייבא את הנתונים ולהתאים אותם, לתזמן ייבוא נתונים, לבצע טרנספורמציה של נתונים ולהתאים את נתוני המודעות באמצעות מזהה משתמש. אירוע המודעה חייב להיות מקושר למשתמש מחובר בנתוני מודעות ממוצרי Google. נדרשים כמה פרויקטים ב-Google Cloud.
  • חיבור לנתונים מאינטראקציה ישירה (First-Party): מגדירים חיבור לנתונים מאינטראקציה ישירה (First-Party) ככלי להכנת נתונים, כדי לתזמן ייבוא נתונים ולבצע טרנספורמציה של נתונים בלי להשתמש בתכונות המתקדמות של UPDM. כדי ליצור חיבור כזה נדרש רק פרויקט אחד ב-Google Cloud.
  • מקור נתונים: מוצר מקושר, קובץ מיובא או שילוב עם צד שלישי. למשל: BigQuery.
  • יעד: תרחיש שימוש, בדרך כלל מוצר או תכונה במוצר של Google שמופעלים בהם נתונים מיובאים. למשל: התאמה של פרטים שהמשתמשים סיפקו ב-Ads Data Hub.
  • פרויקט ניהול: הפרויקט ב-Google Cloud שמכיל את נתוני הפרסום הקנייניים שלכם בפורמט הגולמי.
  • מערך נתוני הפלט: מערך הנתונים ב-BigQuery שאליו מתבצע הכתיבה ב-Ads Data Hub. כברירת מחדל, זהו מערך נתונים בפרויקט הניהול שלכם. כדי לשנות אותו לפרויקט אחר ב-Google Cloud, תוכלו לעיין במאמר הגדרת חשבונות שירות.

סיכום התהליך

  1. הגדרה של הטמעת נתונים והתאמה שלהם
  2. הטמעה והתאמה של נתונים מאינטראקציה ישירה (First-Party)
    • אתם צריכים לעצב ולהעלות את הנתונים מאינטראקציה ישירה (First-Party) למערך הנתונים ב-BigQuery. כדי להקל על תהליך ההגדרה, כדאי להשתמש בפרויקט האדמין. עם זאת, תוכלו להשתמש בכל מערך נתונים ב-BigQuery שבבעלותכם.
    • אתם יוצרים בקשה להתאמת נתונים על ידי יצירת חיבור והגדרת לוח זמנים לייבוא.
    • Google משלבת נתונים בין הפרויקט שלכם לבין נתונים שבבעלות Google, שמכילים את מזהה המשתמש של Google ונתונים שהמשתמשים סיפקו ועבר גיבוב, כדי ליצור ולעדכן טבלאות התאמה.
    • הטמעת נתונים מאינטראקציה ישירה
  3. שאילתות מתמשכות ב-Ads Data Hub, על סמך נתונים מותאמים

מידע על דרישות הפרטיות

איסוף נתוני לקוחות

כשמשתמשים בהתאמה לנתונים שהמשתמשים סיפקו, צריך להעלות נתונים מאינטראקציה ישירה (First-Party). הנתונים האלה יכולים להיות מידע שאספתם מהאתרים, מהאפליקציות או מהחנויות הפיזיות שלכם, או מידע שהלקוחות שיתפו איתכם ישירות.

פעולות שצריך לבצע:

  • לוודא שמדיניות הפרטיות שלכם כוללת גילוי נאות על כך שאתם משתפים את נתוני הלקוחות עם צדדים שלישיים כדי שיספקו שירותים מטעמכם, וכן לבקש את הסכמת הלקוחות לשיתוף כזה היכן שהדבר נדרש על פי חוק
  • להשתמש רק בממשק או ב-API שאושרו על ידי Google כדי להעלות נתוני לקוחות
  • לפעול בהתאם לכל התקנות והחוקים החלים, כולל כללים לרגולציה עצמית או כללים הנהוגים בתחום, אם חלים כאלו

אישור להסכמה מאינטראקציה ישירה

כדי לוודא שתוכלו להשתמש בנתונים מאינטראקציה ישירה (First-Party) ב-Ads Data Hub, עליכם לאשר שקיבלת הסכמה מתאימה לשיתוף נתונים ממשתמשי קצה באזור הכלכלי האירופי (EEA) עם Google, בהתאם למדיניות Google בנושא הסכמת משתמשים באיחוד האירופי ולמדיניות של Ads Data Hub. הדרישה הזו חלה על כל חשבון Ads Data Hub, וצריך לעדכן אותה בכל פעם שמעלים נתונים חדשים מאינטראקציה ישירה (First-Party). כל משתמש יכול להביע את הסכמתו בשם החשבון כולו.

חשוב לזכור שאותן כללי שאילתות של שירותי Google שחלים על שאילתות ניתוח חלים גם על שאילתות UPDM. לדוגמה, אי אפשר להריץ שאילתות בכמה שירותים על משתמשים באיחוד הכלכלי האירופי כשיוצרים טבלת התאמה.

במאמר הדרישות לקבלת הסכמה באזור הכלכלי האירופי (EEA) מוסבר איך מאשרים הסכמה ב-Ads Data Hub.

גודל הנתונים

כדי להגן על פרטיות משתמשי הקצה, התאמת הנתונים שהמשתמשים סיפקו אוכפת את הדרישות הבאות לגבי גודל הנתונים:

  • צריך להעלות לפחות 1,000 רשומות לרשימת המשתמשים.
  • כל עדכון מוצלח של טבלת ההתאמות חייב לכלול מספר מינימלי של משתמשים חדשים שהותאמו. ההתנהגות הזו דומה לבדיקות ההבדלים.
  • הרשימה לא יכולה להכיל יותר מהמספר המקסימלי של רשומות. כדי לקבל מידע על מגבלת הנתונים המקסימלית, אפשר לפנות לנציג Google.

הגדרת הטמעת נתונים

לפני שמתחילים, צריך להגדיר את חשבון Ads Data Hub כך שיאפשר ליצור חיבורי נתונים. כך תוכלו ליצור את צינור עיבוד הנתונים להתאמת נתונים. צריך לבצע את השלבים פעם אחת בלבד.

בדף Connections, לוחצים על Begin setup כדי לפתוח את האשף להגדרת החשבון בשלב ההפעלה של UPDM.

כניסה לדף Connections

אילו הרשאות ניתנות ל-BigQuery ול-Cloud Storage?

אם מגדירים את UPDM לשימוש עם BigQuery או Cloud Storage, אפשר להיעזר במסמך העזרה הזה כדי להבין את ההרשאות שמוקצות לחשבונות השירות של Ads Data Hub.

BigQuery

חשבון שירות Datafusion
מטרה חשבון השירות ב-Data Fusion משמש להצגת רשימה של שדות המקור בממשק המשתמש של Ads Data Hub.
פורמט service-some-number@gcp-sa-datafusion.iam.gserviceaccount.com
הגישה הנדרשת
BigQuery Data Viewer
roles/bigquery.dataViewer
למערכי נתונים ספציפיים בפרויקטים של מקור הנתונים ויעד
Storage Admin
roles/storage.admin
לפרויקט Data Source, או לקטגוריית אחסון ייעודית
חשבון שירות Dataproc
מטרה חשבון השירות ב-Dataproc אחראי להפעלת צינורות הנתונים ברקע.
פורמט some-number-compute@developer.gserviceaccount.com
הגישה הנדרשת
BigQuery Data Viewer
roles/bigquery.dataViewer
למערכי נתונים ספציפיים בפרויקטים של מקור הנתונים ויעד
BigQuery Data Editor
roles/bigquery.dataEditor
למערכי נתונים ספציפיים בפרויקט Destination
BigQuery Job User
roles/bigquery.jobUser
גם בפרויקטים מסוג מקור נתונים וגם בפרויקטים מסוג יעד
Storage Admin
roles/storage.admin
גם לפרויקטים של מקור הנתונים וגם לפרויקטים של יעד, או לקטגוריית אחסון ייעודית
חשבון השירות של UPDM
מטרה חשבון השירות של UPDM משמש להפעלת המשימה התואמת.
פורמט service-some-number@gcp-sa-adsdataconnector.iam.gserviceaccount.com
הגישה הנדרשת
BigQuery Data Viewer
roles/bigquery.dataViewer
בפרויקט Destination
BigQuery Job User
roles/bigquery.jobUser
בפרויקט Destination

Cloud Storage

חשבון שירות Datafusion
מטרה חשבון השירות ב-Data Fusion משמש להצגת רשימה של שדות המקור בממשק המשתמש של Ads Data Hub.
פורמט service-some-number@gcp-sa-datafusion.iam.gserviceaccount.com
הגישה הנדרשת
Storage Object Viewer
roles/storage.objectViewer
בקטגוריות אחסון ספציפיות בפרויקט מקור הנתונים
BigQuery Data Viewer
roles/bigquery.dataViewer
לפרויקט Data Source, או לקטגוריית אחסון ייעודית
Storage Admin
roles/storage.admin
לפרויקט Data Source, או לקטגוריית אחסון ייעודית
חשבון שירות Dataproc
מטרה חשבון השירות ב-Dataproc אחראי להפעלת צינורות הנתונים ברקע.
פורמט some-number-compute@developer.gserviceaccount.com
הגישה הנדרשת
Storage Admin
roles/storage.admin
גם לפרויקטים של מקור הנתונים וגם לפרויקטים של יעד, או לקטגוריית אחסון ייעודית
BigQuery Job User
roles/bigquery.jobUser
בפרויקט Destination
חשבון השירות של UPDM
מטרה חשבון השירות של UPDM משמש להפעלת המשימה התואמת.
פורמט service-some-number@gcp-sa-adsdataconnector.iam.gserviceaccount.com
הגישה הנדרשת
BigQuery Data Viewer
roles/bigquery.dataViewer
בפרויקט Destination
BigQuery Job User
roles/bigquery.jobUser
בפרויקט Destination

מקורות נתונים אחרים

לא נדרשת למקורות נתונים אחרים

הטמעה והתאמה של נתונים מאינטראקציה ישירה (First-Party)

פורמט הנתונים לקלט

כדי שהנתונים יתואמו בצורה נכונה, הם צריכים לעמוד בדרישות הפורמט הבאות:

  • במקרים שמפורטים בתיאורים הבאים של שדות הקלט, צריך להעלות את הנתונים באמצעות גיבוב SHA256.
  • שדות הקלט חייבים להיות בפורמט של מחרוזות. לדוגמה, אם משתמשים בפונקציית הגיבוב SHA256 של BigQuery עם פונקציית הקידוד Base16‏ (TO_HEX), צריך להשתמש בטרנספורמציה הבאה: TO_HEX(SHA256(user_data)).
  • UPDM תומך בקידוד Base16 וגם בקידוד Base64. צריך להתאים את הקידוד של הנתונים מאינטראקציה ישירה (First-Party) לפענוח שנעשה בשאילתה ב-Ads Data Hub. אם משנים את קידוד הנתונים מאינטראקציה ישירה (First-Party), צריך לעדכן את השאילתה ב-Ads Data Hub כדי לבצע פענוח מאותה בסיס. בדוגמאות הבאות נעשה שימוש בקידוד Base16.

מזהה המשתמש

  • טקסט רגיל
  • גיבוב (hashing): ללא

אימייל

  • הסרת רווחים לבנים
  • יש להשתמש באותיות קטנות בלבד
  • כל כתובות האימייל צריכות לכלול שמות דומיינים, כמו gmail.com או hotmail.co.jp
  • מסירים סימנים דיאקריטיים – לדוגמה, משנים את האותיות è,‏ é,‏ ê או ë ל-e
  • גיבוב: SHA256 עם קידוד Base16

תקף: TO_HEX(SHA256("jeffersonloveshiking@gmail.com"))

לא חוקי: TO_HEX(SHA256("JéffersonLôvesHiking@gmail.com"))

טלפון

  • הסרת רווחים לבנים
  • הפורמט צריך להיות E.164. לדוגמה, בארה"ב: ‎+14155552671, בבריטניה: ‎+442071838750
  • יש לכלול את קוד המדינה (כולל ארה"ב)
  • מסירים את כל התווים המיוחדים מלבד הסימן '+' לפני קידומת המדינה
  • גיבוב: SHA256 עם קידוד Base16

תקף: TO_HEX(SHA256("+18005550101"))

לא חוקי: TO_HEX(SHA256("(800) 555-0101"))

שם פרטי

  • הסרת רווחים לבנים
  • יש להשתמש באותיות קטנות בלבד
  • מסירים את כל הקידומות, כמו 'גב'.
  • לא מסירים סימנים דיאקריטיים – לדוגמה, è,‏ é,‏ ê או ë
  • גיבוב: SHA256 עם קידוד Base16

תקף: TO_HEX(SHA256("daní"))

לא חוקי: TO_HEX(SHA256("Daní"))

שם משפחה

  • הסרת רווחים לבנים
  • יש להשתמש באותיות קטנות בלבד
  • מסירים את כל הקידומות, כמו 'Jr'.
  • לא מסירים סימנים דיאקריטיים – לדוגמה, è,‏ é,‏ ê או ë
  • גיבוב: SHA256 עם קידוד Base16

תקף: TO_HEX(SHA256("delacruz"))

לא חוקי: TO_HEX(SHA256("de la Cruz, Jr."))

מדינה

  • צריך לכלול את קוד המדינה גם אם כל הלקוחות בקובץ הם אזרחי אותה מדינה
  • אין לבצע גיבוב של נתוני המדינה
  • צריך להשתמש בקודי מדינה לפי תקן ISO 3166-1 alpha-2
  • גיבוב (hashing): ללא

תקף: US

לא תקף: United States of America או USA

מיקוד

  • אין לבצע גיבוב של נתוני המיקוד
  • אפשר להזין מיקוד של ארה"ב וגם של מדינות אחרות
  • בארה"ב:
    • מותר להזין מיקוד בן 5 ספרות – לדוגמה, 94043
    • מותר גם להזין מיקוד בן 5 ספרות עם תוספת של 4 ספרות. לדוגמה, 94043-1351 או 940431351
  • בכל שאר המדינות:
    • אין צורך בפורמט (אין צורך להשתמש באותיות קטנות או להסיר רווחים ותווים מיוחדים)
    • אין לכלול תוספות למיקוד
  • גיבוב (hashing): ללא

אימות גיבוב וקידוד נתונים

אפשר להשתמש בסקריפטים הבאים לאימות גיבוב כדי לוודא שהפורמט של הנתונים נכון.

JavaScript

Base16

/**
 * @fileoverview Provides the hashing algorithm for User-Provided Data Match, as
 * well as some valid hashes of sample data for testing.
*/

async function hash(token) {
  const formattedToken = token.trim().toLowerCase();
  const hashArrayBuffer = await crypto.subtle.digest(
      'SHA-256', (new TextEncoder()).encode(formattedToken));
  return Array.from(new Uint8Array(hashArrayBuffer))
      .map((b) => b.toString(16).padStart(2, '0'))
      .join('');
}

function main() {
  // Expected hash for test@gmail.com:
  // 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  hash('test@gmail.com').then(result => console.log(result));

  // Expected hash for +18005551212:
  // 61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  hash('+18005551212').then(result => console.log(result));

  // Expected hash for John:
  // 96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  hash('John').then(result => console.log(result));

  // Expected hash for Doe:
  // 799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f
  hash('Doe').then(result => console.log(result));
}

main()

Base64

/**
 * @fileoverview Provides the hashing algorithm, as well as some valid hashes of
 * sample data for testing.
*/

async function hash(token) {
  const formattedToken = token.trim().toLowerCase();
  const hashBuffer = await crypto.subtle.digest(
      'SHA-256', (new TextEncoder()).encode(formattedToken));
  const base64Str = btoa(String.fromCharCode(...new Uint8Array(hashBuffer)));
  return base64Str;
}

function main() {
  // Expected hash for test@gmail.com:
  // h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  hash('test@gmail.com').then(result => console.log(result));

  // Expected hash for +18005551212:
  // YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  hash('+18005551212').then(result => console.log(result));

  // Expected hash for John: ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  hash('John').then(result => console.log(result));

  // Expected hash for Doe: eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
  hash('Doe').then(result => console.log(result));
}

main()

Python

Base16

"""Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Supports: Python 2, Python 3

Sample hashes:

  - Email 'test@gmail.com': 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  - Phone '+18005551212':   61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  - First name 'John':      96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  - Last name 'Doe':        799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f
"""

import base64
import hashlib

def updm_hash(token):
  return hashlib.sha256(token.strip().lower().encode('utf-8')).hexdigest()

def print_updm_hash(token):
  print('Hash: "{}"\t(Token: {})'.format(updm_hash(token), token))

def main():
  print_updm_hash('test@gmail.com')
  print_updm_hash('+18005551212')
  print_updm_hash('John')
  print_updm_hash('Doe')

if __name__ == '__main__':
  main()

Base64

"""Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Supports: Python 2, Python 3

Sample hashes:

  - Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  - Phone '+18005551212':   YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  - First name 'John':      ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  - Last name 'Doe':        eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
"""

import base64
import hashlib

def hash(token):
  return base64.b64encode(
      hashlib.sha256(
          token.strip().lower().encode('utf-8')).digest()).decode('utf-8')

def print_hash(token, expected=None):
  hashed = hash(token)

  if expected is not None and hashed != expected:
    print(
        'ERROR: Incorrect hash for token "{}". Expected "{}", got "{}"'.format(
            token, expected, hashed))
    return

  print('Hash: "{}"\t(Token: {})'.format(hashed, token))

def main():
  print_hash(
      'test@gmail.com', expected='h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=')
  print_hash(
      '+18005551212', expected='YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=')
  print_hash('John', expected='ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=')
  print_hash('Doe', expected='eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=')

if __name__ == '__main__':
  main()

Go

Base16

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Sample hashes:

  - Email 'test@gmail.com': 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  - Phone '+18005551212':   61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  - First name 'John':      96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  - Last name 'Doe':        799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f
*/
package main

import (
  "crypto/sha256"
  "fmt"
  "strings"
)

// Hash hashes an email, phone, first name, or last name into the correct format.
func Hash(token string) string {
  formatted := strings.TrimSpace(strings.ToLower(token))
  hashed := sha256.Sum256([]byte(formatted))
  encoded := fmt.Sprintf("%x", hashed[:])
  return encoded
}

// PrintHash prints the hash for a token.
func PrintHash(token string) {
  fmt.Printf("Hash: \"%s\"\t(Token: %s)\n", Hash(token), token)

}

func main() {
  PrintHash("test@gmail.com")
  PrintHash("+18005551212")
  PrintHash("John")
  PrintHash("Doe")
}

Base64

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

Sample hashes:

  - Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  - Phone '+18005551212':   YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  - First name 'John':      ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  - Last name 'Doe':        eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
*/
package main

import (
  "crypto/sha256"
  "encoding/base64"
  "fmt"
  "strings"
)

// Hash hashes an email, phone, first name, or last name into the correct format.
func Hash(token string) string {
  formatted := strings.TrimSpace(strings.ToLower(token))
  hashed := sha256.Sum256([]byte(formatted))
  encoded := base64.StdEncoding.EncodeToString(hashed[:])
  return encoded
}

// PrintHash prints the hash for a token.
func PrintHash(token string) {
  fmt.Printf("Hash: \"%s\"\t(Token: %s)\n", Hash(token), token)

}

func main() {
  PrintHash("test@gmail.com")
  PrintHash("+18005551212")
  PrintHash("John")
  PrintHash("Doe")
}

Java

Base16

package updm.hashing;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Ascii;
import com.google.common.hash.Hashing;

/**
 * Example of the UPDM hashing algorithm using hex-encoded SHA-256.
*
* <p>This uses the Guava Hashing to generate the hash: https://github.com/google/guava
*
* <p>Sample valid hashes:
*
* <ul>
*   <li>Email "test@gmail.com": "87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674"
*   <li>Phone "+18005551212": "61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44"
*   <li>First name "John": "96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a"
*   <li>Last name "Doe": "799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f"
* </ul>
*/
public final class HashExample {

  private HashExample() {}

  public static String hash(String token) {
    String formattedToken = Ascii.toLowerCase(token).strip();
    return Hashing.sha256().hashString(formattedToken, UTF_8).toString();
  }

  public static void printHash(String token) {
    System.out.printf("Hash: \"%s\"\t(Token: %s)\n", hash(token), token);
  }

  public static void main(String[] args) {
    printHash("test@gmail.com");
    printHash("+18005551212");
    printHash("John");
    printHash("Doe");
  }
}

Base64

package updm.hashing;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
* Example of the hashing algorithm.
*
* <p>Sample hashes:
*
* <ul>
*   <li>Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
*   <li>Phone '+18005551212': YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
*   <li>First name 'John': ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
*   <li>Last name 'Doe': eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=
* </ul>
*/
public final class HashExample {

private HashExample() {}

public static String hash(String token) {
  String formattedToken = token.toLowerCase().strip();

  byte[] hash;
  try {
    hash = MessageDigest.getInstance("SHA-256").digest(formattedToken.getBytes(UTF_8));
  } catch (NoSuchAlgorithmException e) {
    throw new IllegalStateException("SHA-256 not supported", e);
  }

  return Base64.getEncoder().encodeToString(hash);
}

public static void printHash(String token) {
  System.out.printf("Hash: \"%s\"\t(Token: %s)\n", hash(token), token);
}

public static void main(String[] args) {
  printHash("test@gmail.com");
  printHash("+18005551212");
  printHash("John");
  printHash("Doe");
}
}

SQL

Base16

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

The following code uses Google Standard SQL and can be run on BigQuery to generate match tables from unhashed data.

Sample hashes:

  - Email 'test@gmail.com': 87924606b4131a8aceeeae8868531fbb9712aaa07a5d3a756b26ce0f5d6ca674
  - Phone '+18005551212':   61d9111bed3e6d9cfc1bc3b5cb35a402687c4f1546bee061a2bd444fbdd64c44
  - First name 'John':      96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a
  - Last name 'Doe':        799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f

The unhashed input table schema is assumed to be:

- Column name: UserID, Type: String
- Column name: Email, Type: String
- Column name: Phone, Type: String
- Column name: FirstName, Type: String
- Column name: LastName, Type: String
- Column name: PostalCode, Type: String
- Column name: CountryCode, Type: String
*/

CREATE TABLE `your_project_name.your_dataset_name.output_hashed_table_name`
AS
SELECT
  UserID,
  TO_HEX(SHA256(LOWER(Email))) AS Email,
  TO_HEX(SHA256(Phone)) AS Phone,
  TO_HEX(SHA256(LOWER(FirstName))) AS FirstName,
  TO_HEX(SHA256(LOWER(LastName))) AS LastName,
  PostalCode,
  CountryCode,
FROM
  `your_project_name.your_dataset_name.input_unhashed_table_name`;

Base64

/*
Provides the hashing algorithm, as well as some valid hashes of sample data for testing.

The following code uses Google Standard SQL and can be run on BigQuery to generate match tables from unhashed data.

Sample hashes:

  - Email 'test@gmail.com': h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ=
  - Phone '+18005551212':   YdkRG+0+bZz8G8O1yzWkAmh8TxVGvuBhor1ET73WTEQ=
  - First name 'John':      ltljLzY1ZMwwMlIUCc8iqFLyAy7sCZ7VlnwNAAzsYHo=
  - Last name 'Doe':        eZ75KhGvkY4/t0HfQpNPO1aO0tk6wd908bjUGieTKm8=

The unhashed input table schema is assumed to be:

- Column name: UserID, Type: String
- Column name: Email, Type: String
- Column name: Phone, Type: String
- Column name: FirstName, Type: String
- Column name: LastName, Type: String
- Column name: PostalCode, Type: String
- Column name: CountryCode, Type: String
*/

CREATE TABLE `your_project_name.your_dataset_name.output_hashed_table_name`
AS
SELECT
  UserID,
  TO_BASE64(SHA256(LOWER(Email))) AS Email,
  TO_BASE64(SHA256(Phone)) AS Phone,
  TO_BASE64(SHA256(LOWER(FirstName))) AS FirstName,
  TO_BASE64(SHA256(LOWER(LastName))) AS LastName,
  PostalCode,
  CountryCode,
FROM
  `your_project_name.your_dataset_name.input_unhashed_table_name`;

מפתחות איחוד

יש שילובים של פרטים שהמשתמשים סיפקו חזקים יותר מאחרים. בהמשך מופיעה רשימה של שילובים שונים של נתונים שהמשתמשים סיפקו, לפי דירוג של חוזק יחסי. אם משתמשים בכתובת, צריך לכלול את הפרטים הבאים: שם פרטי, שם משפחה, מדינה ומיקוד.

  1. אימייל, טלפון, כתובת (החזק ביותר)
  2. טלפון, כתובת
  3. אימייל, כתובת
  4. אימייל, טלפון
  5. כתובת
  6. טלפון
  7. אימייל (האפשרות החלשה ביותר)

יצירת טבלת התאמות

  1. לוחצים על Connections (קישורים) > Create connection (יצירת קישור) > User-provided data matching (התאמה לפרטים שהמשתמשים סיפקו).
  2. בוחרים מקור נתונים ולוחצים על קישור.
  3. מבצעים אימות, אם מוצגת בקשה כזו, ואז לוחצים על הבא:

    BigQuery

    לוחצים על 'אישור' כדי להעניק גישה ל-BigQuery.

    Cloud Storage

    לוחצים על 'אישור' כדי להעניק גישה ל-Cloud Storage.

    MySQL

    מזינים את המיקום, היציאה, שם המשתמש והסיסמה של מסד הנתונים ב-MySQL.

    S3

    מזינים את מפתח הגישה הסודי של Amazon S3.

    PostgreSQL

    מזינים את המיקום, היציאה, שם המשתמש, הסיסמה ומסד הנתונים של מסד הנתונים ב-PostgreSQL.

    Redshift

    מזינים את המיקום, היציאה, שם המשתמש, הסיסמה ומסד הנתונים של מסד הנתונים ב-Redshift.

    sFTP

    מזינים את המיקום, שם המשתמש והסיסמה של שרת ה-SFTP.

    פתית שלג

    מזינים את שם המשתמש, הסיסמה ומזהה החשבון ב-Snowflake.

  4. מגדירים את מקור הנתונים ולוחצים על הבא:

    BigQuery

    בוחרים את טבלת BigQuery לייבוא.

    Cloud Storage

    מזינים את הנתיב של gsutil, למשל gs://my-bucket/folder/, ובוחרים את הפורמט של הקובץ.

    בפעם הראשונה שמקשרים את מקור המידע, מופיעה התראה. לוחצים על 'אישור' כדי להעניק גישה, ולוחצים על 'הבא'. הערה: צריכה להיות לכם הרשאה לתת גישה ל-storage.buckets.setIamPolicy בקטגוריה הרלוונטית.

    MySQL

    בוחרים את הטבלה ומסד הנתונים ב-MySQL שבהם רוצים להשתמש.

    S3

    מזינים את ה-URI לקובץ שרוצים להעלות, ביחס לכתובת המארח.

    PostgreSQL

    מזינים את שם הסכימה והטבלה (או התצוגה) ב-PostgreSQL.

    Redshift

    מזינים את שם הסכימה והטבלה (או התצוגה) ב-Redshift. כברירת מחדל, ב-Redshift נעשה שימוש בכתובות URL של מיקומי מסדי נתונים בפורמט הבא: cluster-identifier.account-number.aws-region.redshift.amazonaws.com .

    sFTP

    מזינים את שם הקובץ ואת נתיב הקובץ בפורמט הבא: /PATH/FILENAME.csv

    פתית שלג

    מזינים את מסד הנתונים, הסכימה והטבלה (או התצוגה) ב-Snowflake שבהם רוצים להשתמש.

  5. בוחרים מערך נתונים ב-BigQuery שישמש כיעד ביניים, ולוחצים על הבא. השלב הזה עוזר לוודא שהנתונים בפורמט הנכון.
  6. אם רוצים, משנים את הפורמט של הנתונים. הטרנספורמציות כוללות גיבוב (hashing) ממוחשב, הגדרת פורמט של אותיות רישיות/קטנות, מיזוג/פיצול של שדות.
    1. לוחצים על פעולה > > טרנספורמציה.
    2. בחלונית הקופצת, לוחצים על Add transformation או על Add another transformation.
    3. בוחרים סוג טרנספורמציה מהתפריט הנפתח ומזינים את הדרישות.
    4. לוחצים על שמירה.
  7. בוחרים לפחות מפתח צירוף אחד וממפים את השדות שבהם תשתמשו. מערכת Ads Data Hub תמפה באופן אוטומטי שדות עם שמות זהים, שיסומנו ב-. עורכים את הפרטים לפי הצורך ולוחצים על הבא.
  8. מגדירים לוח זמנים:
    1. נותנים שם לחיבור.
    2. מגדירים תדירות, שמציינת באיזו תדירות הנתונים ייובאו למערך הנתונים שבחרתם בשלב הקודם. כל הפעלה תגרום למחיקה של הנתונים בטבלה destination.
    3. מציינים איך רוצים לטפל במקרים של התנגשויות בין מזהי משתמשים. תוכלו לבחור אם לשמור את ההתאמה הקיימת או להחליף אותה בנתונים חדשים.
  9. לוחצים על סיום. בדרך כלל אפשר להריץ שאילתות לגבי טבלאות ההתאמה 12 שעות אחרי היצירה שלהן.

הצגת פרטי החיבור

בדף פרטי החיבור מוצג מידע על ההפעלות והשגיאות האחרונות של חיבור נתון. כדי להציג פרטים לגבי חיבור ספציפי:

  1. לוחצים על חיבורים.
  2. לוחצים על שם החיבור כדי להציג את הפרטים שלו.
  3. עכשיו אפשר לראות את פרטי החיבור ואת ההפעלות האחרונות. בכל אחד מהם מוצגים שני סוגים אפשריים של שגיאות: שגיאות ברמת החיבור (החיבור לא הופעל) ושגיאות ברמת השורה (שורה לא יובאה).
    1. סטטוס Failed מציין שהחיבור כולו לא הופעל (למשל, בעיה בהרשאות של חשבון השירות). לוחצים על סטטוס השגיאה כדי לראות אילו שגיאות השפיעו על החיבור.
    2. הסטטוס Completed מציין שהחיבור הופעל בהצלחה. עם זאת, יכול להיות שעדיין יהיו שגיאות ברמת השורה – הן יצוינו בערך שאינו אפס בעמודה Rows with errors (שורות עם שגיאות). לוחצים על הערך כדי לקבל מידע נוסף על הרשומות שנכשלו.

עריכת חיבור

אפשר לערוך את הפרטים הבאים:

  • שם החיבור
  • תזמון
  • טבלת היעד
  • מיפוי שדות

אין תמיכה בעריכת מקור הנתונים. כדי לשנות מקור נתונים, יוצרים קישור חדש ומוחקים את הקישור הישן.

כדי לערוך את פרטי החיבור:

  1. לוחצים על חיבורים.
  2. לוחצים על שם החיבור שרוצים לערוך.
  3. עורכים את הפרטים שרוצים לשנות:
    • שם החיבור: לוחצים על עריכה, מזינים את השם החדש ומקישים על Enter.
    • לוח זמנים: לוחצים על עריכה, מגדירים את לוח הזמנים החדש ולוחצים על שמירה.
    • טבלת היעדים: לוחצים על Edit, מזינים את שם היעד החדש ולוחצים על Save.
    • מיפוי שדות: לוחצים על , מבצעים שינויים בשדות ולוחצים על Save.
  4. לוחצים על .

שאילתות של נתונים תואמים

הרצת שאילתות על טבלאות ההתאמות

כשטבלאות ההתאמה מכילות מספיק נתונים כדי לעמוד בבדיקות הפרטיות, אפשר להריץ שאילתות בטבלאות.

הטבלה המקורית של נתונים מאינטראקציה ישירה (First-Party) (1PD) מיוצגת על ידי my_data. הנתונים האלה כוללים פרטים אישיים מזהים (PII) ונתונים שאינם PII. שימוש בטבלה המקורית יכול לשפר את הדוחות ולספק תובנות נוספות, כי היא מייצגת את כל נתוני ה-1PD שכלולים בהיקף, בהשוואה לטבלת התאמה.

לכל טבלה בסכימה של Ads Data Hub שמכילה את השדה user_id מצורפת טבלת התאמות. לדוגמה, לטבלה adh.google_ads_impressions, מערכת Ads Data Hub יוצרת גם טבלת התאמות שנקראת adh.google_ads_impressions_updm שמכילה את מזהי המשתמשים. נוצרות טבלאות התאמה נפרדות לטבלאות מבודדות מבחינה מדינית. לדוגמה, לטבלה adh.google_ads_impressions_policy_isolated_youtube, מערכת Ads Data Hub יוצרת גם טבלת התאמות שנקראת adh.google_ads_impressions_policy_isolated_youtube_updm ומכילה את מזהי המשתמשים.

הטבלאות האלה מכילות קבוצת משנה של המשתמשים שזמינים בטבלאות המקוריות, שבהן יש התאמה ב-user_id. לדוגמה, אם הטבלה המקורית מכילה נתונים של משתמש א' ומשתמש ב', אבל רק משתמש א' תואם, משתמש ב' לא יופיע בטבלת ההתאמות.

טבלאות ההתאמה מכילות עמודה נוספת שנקראת customer_data_user_id, שבה מאוחסן מזהה המשתמש כבייטים.

חשוב להביא בחשבון את סוג השדה כשכותבים את השאילתות. אופרטורים להשוואה ב-SQL מצפים שהליטרלים שאתם משווים יהיו מאותו סוג. בהתאם לאופן שבו השדה user_id מאוחסן בטבלה של הנתונים מאינטראקציה ישירה, יכול להיות שתצטרכו לקודד את הערכים בטבלה לפני שתבצעו התאמה של הנתונים. כדי שההתאמות יתבצעו בהצלחה, צריך להמיר את מפתח המיזוג ל-BYTES:

JOIN ON
  adh.google_ads_impressions_updm.customer_data_user_id = CAST(my_data.user_id AS BYTES)

בנוסף, השוואות של מחרוזות ב-SQL תלויות אותיות רישיות, לכן יכול להיות שתצטרכו לקודד מחרוזות משני צידי ההשוואה כדי לוודא שאפשר להשוות ביניהן בצורה מדויקת.

שאילתות לדוגמה

ספירת משתמשים תואמים

השאילתה הזו סופרת את מספר המשתמשים שתואמים בטבלת החשיפות ב-Google Ads.

/* Count matched users in Google Ads impressions table */

SELECT COUNT(DISTINCT user_id)
FROM adh.google_ads_impressions_updm

השאילתה הזו מדגימה איך לחבר בין נתונים מאינטראקציה ישירה (First-Party) לנתונים מ-Google Ads:

/* Join first-party data with Google Ads data. The customer_data_user_id field
contains your ID as BYTES. You need to cast your join key into BYTES for
successful matches. */

SELECT
  inventory_type,
  COUNT(*) AS impressions
FROM
  adh.yt_reserve_impressions_updm AS google_data_imp
LEFT JOIN
  `my_data`
ON
  google_data_imp.customer_data_user_id = CAST(my_data.user_id AS BYTES)
GROUP BY
  inventory_type

שאלות נפוצות על שיעור הבקשות שמולאו ב-UPDM

רשימה של שאלות נפוצות בנושא שיעור ההתאמה של UPDM מופיעה במאמר שאלות נפוצות בנושא שיעור ההתאמה של UPDM.