จัดการ Conversion ออฟไลน์

คุณสามารถใช้ Google Ads API เพื่อนําเข้า Conversion ออฟไลน์มายัง Google Ads เพื่อติดตามโฆษณาที่ทําให้เกิดยอดขายในโลกออฟไลน์ เช่น ทางโทรศัพท์หรือผ่านตัวแทนฝ่ายขาย

เราขอแนะนําให้ใช้ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายเพื่อใช้ประโยชน์จากการนําเข้าข้อมูล Conversion อย่างเต็มที่ ซึ่งใช้ประโยชน์จาก GCLID และข้อมูลที่ได้จากผู้ใช้เพื่อเพิ่มความคงทนและประสิทธิภาพสูงสุด

Conversion ที่ปรับปรุงแล้ว

Conversion ที่ปรับปรุงแล้วช่วยเพิ่มความแม่นยำของการวัด Conversion โดยเสริม Conversion ด้วยข้อมูล Conversion ของบุคคลที่หนึ่ง เช่น อีเมล ชื่อ ที่อยู่บ้าน และหมายเลขโทรศัพท์

Conversion ที่ปรับปรุงแล้วมี 2 ประเภท ดูรายละเอียดเพิ่มเติมได้ที่บทความเกี่ยวกับ Conversion ที่ปรับปรุงแล้วในศูนย์ช่วยเหลือ

ส่วนต่อไปนี้อธิบายวิธีเพิ่มประสิทธิภาพ Conversion ออฟไลน์ ซึ่งเป็นฟีเจอร์ที่เรียกอีกอย่างว่า Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย

Conversion ที่ปรับปรุงแล้วสำหรับโอกาสในการขายคืออะไร

Conversion ที่ปรับปรุงแล้วสำหรับโอกาสในการขายคือการนําเข้า Conversion ออฟไลน์เวอร์ชันที่อัปเกรดแล้ว ซึ่งใช้ข้อมูลที่ได้จากผู้ใช้ เช่น อีเมล เพื่อเสริมข้อมูล Conversion ออฟไลน์ที่นําเข้าเพื่อปรับปรุงความแม่นยําและประสิทธิภาพการเสนอราคา เมื่อคุณนําเข้า Conversion ออฟไลน์ ระบบจะใช้ข้อมูลลูกค้าที่แฮชที่ให้มาเพื่อระบุแหล่งที่มากลับไปยังแคมเปญ Google Ads โดยจับคู่กับข้อมูลเดียวกันที่เก็บรวบรวมในเว็บไซต์ เช่น โฆษณาแบบกรอกฟอร์ม และกับลูกค้าที่ลงชื่อเข้าใช้ซึ่งมีส่วนร่วมกับโฆษณา ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทํางานของ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายได้ในบทความเกี่ยวกับ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย

การติดตั้งใช้งาน Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายทำได้ 2 วิธี โดยขึ้นอยู่กับว่าคุณใช้แท็ก Google เพื่อติดตามเหตุการณ์การส่งแบบฟอร์มในหน้าเว็บหรือไม่ เราขอแนะนําอย่างยิ่งให้ใช้แท็ก Google สําหรับ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย เพื่อให้ได้ประสิทธิภาพและความเสถียรที่ดีที่สุด

  • หากต้องเริ่มตั้งแต่ต้น ให้เริ่มที่ส่วนข้อกําหนดเบื้องต้น
  • หากคุณตั้งค่าการนําเข้า Conversion ออฟไลน์ไว้แล้ว และต้องการอัปเกรดเป็น Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย เราขอแนะนําให้เริ่มต้นด้วยส่วนกําหนดค่าการติดแท็ก
  • หากคุณตั้งค่าแท็ก Google ไว้แล้ว หรือไม่ได้วางแผนที่จะใช้แท็ก Google และเริ่มการผสานรวม Google Ads API ให้ข้ามไปที่ส่วนการติดตั้งใช้งาน API
  • หากนําเข้าข้อมูลที่ได้จากผู้ใช้ไม่ได้ หรือใช้การระบุแหล่งที่มาภายนอกสําหรับ Conversion โปรดดูคู่มือการนําเข้า Conversion ออฟไลน์เดิม

ข้อกำหนดเบื้องต้น

ก่อนอื่น โปรดตรวจสอบว่าคุณได้ทำตามขั้นตอนในส่วนเริ่มต้นใช้งานของเราแล้ว

คุณต้องเลือกใช้ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายและยอมรับข้อกําหนดสําหรับข้อมูลลูกค้าก่อนจึงจะใช้ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายได้ คุณสามารถตรวจสอบว่ามีคุณสมบัติตามข้อกําหนดเบื้องต้นเหล่านี้แล้วหรือไม่โดยการส่งคําค้นหาต่อไปนี้ไปยังลูกค้า Conversion ของ Google Ads

SELECT
  customer.id,
  customer.conversion_tracking_setting.accepted_customer_data_terms,
  customer.conversion_tracking_setting.enhanced_conversions_for_leads_enabled
FROM customer

หาก accepted_customer_data_terms หรือ enhanced_conversions_for_leads_enabled เป็น false ให้ทำตามวิธีการในศูนย์ช่วยเหลือเพื่อดำเนินการตามข้อกําหนดเบื้องต้นเหล่านี้

กำหนดค่าการติดแท็ก

กําหนดค่าแท็ก Google เพื่อเปิดใช้ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายโดยทําตามวิธีการในศูนย์ช่วยเหลือ หากต้องการตั้งค่า Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายโดยใช้ Google Tag Manager ให้ทําตามวิธีการต่อไปนี้

การใช้งาน API

ขั้นตอนโดยรวมในการนําเข้า Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายโดยใช้ Google Ads API มีดังนี้

  1. ทำให้เป็นมาตรฐานและแฮชข้อมูลที่ได้จากผู้ใช้ เช่น อีเมล หมายเลขโทรศัพท์ และที่อยู่สำหรับจัดส่ง

  2. ป้อนข้อมูลออบเจ็กต์ ClickConversion ด้วยข้อมูลที่ได้จากผู้ใช้ซึ่งได้รับการแปลงเป็นรูปแบบมาตรฐานและแฮชแล้ว

  3. นําเข้าออบเจ็กต์ ClickConversion ไปยัง Google Ads API โดยใช้ ConversionUploadService

  4. ตรวจสอบการนําเข้า

แปลงและแฮชข้อมูลที่ได้จากผู้ใช้

ข้อมูลต่อไปนี้ต้องได้รับการแฮชโดยใช้ SHA-256 ก่อนที่จะนําเข้า เพื่อคํานึงถึงความเป็นส่วนตัว

  • อีเมล
  • หมายเลขโทรศัพท์
  • ชื่อ
  • นามสกุล
  • ที่อยู่

ก่อนแฮชค่าเหล่านี้ คุณต้องทำสิ่งต่อไปนี้เพื่อให้ผลลัพธ์การแฮชเป็นมาตรฐาน

  • นําช่องว่างขึ้นต้นและต่อท้ายออก
  • แปลงข้อความให้เป็นตัวพิมพ์เล็ก
  • จัดรูปแบบหมายเลขโทรศัพท์ตามมาตรฐาน E164
  • นําจุด (.) ที่อยู่ก่อนชื่อโดเมนในอีเมล gmail.com และ googlemail.com ออกทั้งหมด

อย่าแฮชข้อมูลต่อไปนี้

  • ประเทศ
  • รัฐ
  • เมือง
  • รหัสไปรษณีย์

ตัวอย่างโค้ด

ตัวอย่างนี้แสดงวิธีทำให้เป็นมาตรฐานและแฮชข้อมูลที่ได้จากผู้ใช้

Java

private String normalizeAndHash(MessageDigest digest, String s)
    throws UnsupportedEncodingException {
  // Normalizes by first converting all characters to lowercase, then trimming spaces.
  String normalized = s.toLowerCase();
  // Removes leading, trailing, and intermediate spaces.
  normalized = normalized.replaceAll("\\s+", "");
  // Hashes the normalized string using the hashing algorithm.
  byte[] hash = digest.digest(normalized.getBytes("UTF-8"));
  StringBuilder result = new StringBuilder();
  for (byte b : hash) {
    result.append(String.format("%02x", b));
  }

  return result.toString();
}

/**
 * Returns the result of normalizing and hashing an email address. For this use case, Google Ads
 * requires removal of any '.' characters preceding {@code gmail.com} or {@code googlemail.com}.
 *
 * @param digest the digest to use to hash the normalized string.
 * @param emailAddress the email address to normalize and hash.
 */
private String normalizeAndHashEmailAddress(MessageDigest digest, String emailAddress)
    throws UnsupportedEncodingException {
  String normalizedEmail = emailAddress.toLowerCase();
  String[] emailParts = normalizedEmail.split("@");
  if (emailParts.length > 1 && emailParts[1].matches("^(gmail|googlemail)\\.com\\s*")) {
    // Removes any '.' characters from the portion of the email address before the domain if the
    // domain is gmail.com or googlemail.com.
    emailParts[0] = emailParts[0].replaceAll("\\.", "");
    normalizedEmail = String.format("%s@%s", emailParts[0], emailParts[1]);
  }
  return normalizeAndHash(digest, normalizedEmail);
}
      

C#

/// <summary>
/// Normalizes the email address and hashes it. For this use case, Google Ads requires
/// removal of any '.' characters preceding <code>gmail.com</code> or
/// <code>googlemail.com</code>.
/// </summary>
/// <param name="emailAddress">The email address.</param>
/// <returns>The hash code.</returns>
private string NormalizeAndHashEmailAddress(string emailAddress)
{
    string normalizedEmail = emailAddress.ToLower();
    string[] emailParts = normalizedEmail.Split('@');
    if (emailParts.Length > 1 && (emailParts[1] == "gmail.com" ||
        emailParts[1] == "googlemail.com"))
    {
        // Removes any '.' characters from the portion of the email address before
        // the domain if the domain is gmail.com or googlemail.com.
        emailParts[0] = emailParts[0].Replace(".", "");
        normalizedEmail = $"{emailParts[0]}@{emailParts[1]}";
    }
    return NormalizeAndHash(normalizedEmail);
}

/// <summary>
/// Normalizes and hashes a string value.
/// </summary>
/// <param name="value">The value to normalize and hash.</param>
/// <returns>The normalized and hashed value.</returns>
private static string NormalizeAndHash(string value)
{
    return ToSha256String(digest, ToNormalizedValue(value));
}

/// <summary>
/// Hash a string value using SHA-256 hashing algorithm.
/// </summary>
/// <param name="digest">Provides the algorithm for SHA-256.</param>
/// <param name="value">The string value (e.g. an email address) to hash.</param>
/// <returns>The hashed value.</returns>
private static string ToSha256String(SHA256 digest, string value)
{
    byte[] digestBytes = digest.ComputeHash(Encoding.UTF8.GetBytes(value));
    // Convert the byte array into an unhyphenated hexadecimal string.
    return BitConverter.ToString(digestBytes).Replace("-", string.Empty);
}

/// <summary>
/// Removes leading and trailing whitespace and converts all characters to
/// lower case.
/// </summary>
/// <param name="value">The value to normalize.</param>
/// <returns>The normalized value.</returns>
private static string ToNormalizedValue(string value)
{
    return value.Trim().ToLower();
}
      

PHP

private static function normalizeAndHash(string $hashAlgorithm, string $value): string
{
    // Normalizes by first converting all characters to lowercase, then trimming spaces.
    $normalized = strtolower($value);
    // Removes leading, trailing, and intermediate spaces.
    $normalized = str_replace(' ', '', $normalized);
    return hash($hashAlgorithm, strtolower(trim($normalized)));
}

/**
 * Returns the result of normalizing and hashing an email address. For this use case, Google
 * Ads requires removal of any '.' characters preceding "gmail.com" or "googlemail.com".
 *
 * @param string $hashAlgorithm the hash algorithm to use
 * @param string $emailAddress the email address to normalize and hash
 * @return string the normalized and hashed email address
 */
private static function normalizeAndHashEmailAddress(
    string $hashAlgorithm,
    string $emailAddress
): string {
    $normalizedEmail = strtolower($emailAddress);
    $emailParts = explode("@", $normalizedEmail);
    if (
        count($emailParts) > 1
        && preg_match('/^(gmail|googlemail)\.com\s*/', $emailParts[1])
    ) {
        // Removes any '.' characters from the portion of the email address before the domain
        // if the domain is gmail.com or googlemail.com.
        $emailParts[0] = str_replace(".", "", $emailParts[0]);
        $normalizedEmail = sprintf('%s@%s', $emailParts[0], $emailParts[1]);
    }
    return self::normalizeAndHash($hashAlgorithm, $normalizedEmail);
}
      

Python

def normalize_and_hash_email_address(email_address):
    """Returns the result of normalizing and hashing an email address.

    For this use case, Google Ads requires removal of any '.' characters
    preceding "gmail.com" or "googlemail.com"

    Args:
        email_address: An email address to normalize.

    Returns:
        A normalized (lowercase, removed whitespace) and SHA-265 hashed string.
    """
    normalized_email = email_address.strip().lower()
    email_parts = normalized_email.split("@")

    # Check that there are at least two segments
    if len(email_parts) > 1:
        # Checks whether the domain of the email address is either "gmail.com"
        # or "googlemail.com". If this regex does not match then this statement
        # will evaluate to None.
        if re.match(r"^(gmail|googlemail)\.com$", email_parts[1]):
            # Removes any '.' characters from the portion of the email address
            # before the domain if the domain is gmail.com or googlemail.com.
            email_parts[0] = email_parts[0].replace(".", "")
            normalized_email = "@".join(email_parts)

    return normalize_and_hash(normalized_email)


def normalize_and_hash(s):
    """Normalizes and hashes a string with SHA-256.

    Private customer data must be hashed during upload, as described at:
    https://support.google.com/google-ads/answer/7474263

    Args:
        s: The string to perform this operation on.

    Returns:
        A normalized (lowercase, removed whitespace) and SHA-256 hashed string.
    """
    return hashlib.sha256(s.strip().lower().encode()).hexdigest()
      

Ruby

# Returns the result of normalizing and then hashing the string using the
# provided digest.  Private customer data must be hashed during upload, as
# described at https://support.google.com/google-ads/answer/7474263.
def normalize_and_hash(str)
  # Remove leading and trailing whitespace and ensure all letters are lowercase
  # before hashing.
  Digest::SHA256.hexdigest(str.strip.downcase)
end

# Returns the result of normalizing and hashing an email address. For this use
# case, Google Ads requires removal of any '.' characters preceding 'gmail.com'
# or 'googlemail.com'.
def normalize_and_hash_email(email)
  email_parts = email.downcase.split("@")
  # Removes any '.' characters from the portion of the email address before the
  # domain if the domain is gmail.com or googlemail.com.
  if email_parts.last =~ /^(gmail|googlemail)\.com\s*/
    email_parts[0] = email_parts[0].gsub('.', '')
  end
  normalize_and_hash(email_parts.join('@'))
end
      

Perl

sub normalize_and_hash {
  my $value = shift;

  # Removes leading, trailing, and intermediate spaces.
  $value =~ s/\s+//g;
  return sha256_hex(lc $value);
}

# Returns the result of normalizing and hashing an email address. For this use
# case, Google Ads requires removal of any '.' characters preceding 'gmail.com'
# or 'googlemail.com'.
sub normalize_and_hash_email_address {
  my $email_address = shift;

  my $normalized_email = lc $email_address;
  my @email_parts      = split('@', $normalized_email);
  if (scalar @email_parts > 1
    && $email_parts[1] =~ /^(gmail|googlemail)\.com\s*/)
  {
    # Remove any '.' characters from the portion of the email address before the
    # domain if the domain is 'gmail.com' or 'googlemail.com'.
    $email_parts[0] =~ s/\.//g;
    $normalized_email = sprintf '%s@%s', $email_parts[0], $email_parts[1];
  }
  return normalize_and_hash($normalized_email);
}
      

ป้อนข้อมูลออบเจ็กต์ ClickConversion

คอลเล็กชันออบเจ็กต์ ClickConversion ใน UploadClickConversionRequest แสดงชุด Conversion ที่ต้องการนําเข้า โปรดคำนึงถึงรายละเอียดต่อไปนี้เมื่อสร้างClickConversion ออบเจ็กต์

gclid

GCLID คือตัวระบุคลิกที่บันทึกจากพารามิเตอร์ของ URL เมื่อผู้ใช้คลิกโฆษณาและไปยังเว็บไซต์

user_identifiers

เมื่อใช้ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย คุณต้องต้องป้อนข้อมูลในช่อง user_identifiers ด้วยข้อมูลที่ได้จากผู้ใช้ซึ่งได้รับการแปลงค่าให้เป็นมาตรฐานและแฮชแล้ว หากคุณมีตัวระบุผู้ใช้หลายรายการ ให้สร้าง UserIdentifier แยกกันสำหรับแต่ละรายการ โดยสร้างได้สูงสุด 5 รายการ

conversion_date_time

วันที่และเวลาที่เกิด Conversion

ค่าต้องมีการระบุเขตเวลา และรูปแบบต้องเป็น yyyy-mm-dd HH:mm:ss+|-HH:mm เช่น 2022-01-01 19:32:45-05:00 (ไม่สนใจเวลาออมแสง)

เขตเวลาอาจเป็นค่าใดก็ได้ที่ถูกต้อง โดยไม่จำเป็นต้องตรงกับเขตเวลาของบัญชี อย่างไรก็ตาม หากคุณวางแผนที่จะเปรียบเทียบข้อมูล Conversion ที่นําเข้ากับข้อมูลใน UI ของ Google Ads เราขอแนะนําให้ใช้เขตเวลาเดียวกับบัญชี Google Ads เพื่อให้จํานวน Conversion ตรงกัน ดูรายละเอียดและตัวอย่างเพิ่มเติมได้ในศูนย์ช่วยเหลือ และดูรายการรหัสเขตเวลาที่ใช้ได้ในส่วนรหัสและรูปแบบ

conversion_action

ชื่อแหล่งข้อมูลของ ConversionAction สําหรับ Conversion ออฟไลน์

การกระทําที่ถือเป็น Conversion ต้องมี type เท่ากับ UPLOAD_CLICKS และต้องอยู่ในลูกค้า Conversion ของ Google Ads ของบัญชี Google Ads ที่เชื่อมโยงกับการคลิก

conversion_value

มูลค่าของ Conversion

currency_code

รหัสสกุลเงินของ conversion_value

consent

เราขอแนะนําอย่างยิ่งให้คุณป้อนข้อมูลในช่อง consent ของออบเจ็กต์ ClickConversion หากไม่ได้ตั้งค่า อาจมีสาเหตุที่ Conversion ของคุณไม่มีแหล่งที่มา

order_id

หรือที่เรียกว่ารหัสธุรกรรมของ Conversion คุณกรอกข้อมูลในช่องนี้หรือไม่ก็ได้ แต่เราขอแนะนําอย่างยิ่ง เนื่องจากจะช่วยให้อ้างอิง Conversion ที่นําเข้าได้ง่ายขึ้นเมื่อทําการปรับ หากตั้งค่าไว้ระหว่างการนําเข้า คุณต้องใช้รหัสดังกล่าวในการปรับเปลี่ยน ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้รหัสธุรกรรมเพื่อลดจํานวน Conversion ที่ซ้ำกันได้ที่บทความในศูนย์ช่วยเหลือนี้

custom_variables

ค่าของตัวแปร Conversion ที่กําหนดเอง

Google Ads ไม่รองรับตัวแปร Conversion ที่กําหนดเองร่วมกับ wbraid หรือ gbraid

conversion_environment

ระบุสภาพแวดล้อมที่บันทึก Conversion นี้ เช่น APP หรือ WEB

session_attributes_encoded และ session_attributes_key_value_pairs

แอตทริบิวต์เซสชันแสดงตัวระบุแบบรวมที่ใช้สำหรับการระบุแหล่งที่มาของ Conversion ซึ่งทำงานนอกเหนือจากตัวระบุคลิก (เช่น GCLID และ GBRAID) และข้อมูลที่ได้จากผู้ใช้ ซึ่งเป็นหัวใจสําคัญของ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย ในการนําเข้าแอตทริบิวต์เซสชันมี 2 วิธี ได้แก่ ระบุโทเค็นที่เข้ารหัสซึ่งสร้างโดยโค้ด JavaScript ในเบราว์เซอร์ หรือระบุคู่คีย์-ค่าแยกต่างหากสําหรับตัวระบุแต่ละรายการ

เราขอแนะนําให้นําเข้าตัวระบุคลิก ข้อมูลที่ได้จากผู้ใช้ และแอตทริบิวต์เซสชันพร้อมกับ Conversion ทั้งหมด หากทําได้ เพื่อเพิ่มประสิทธิภาพแคมเปญให้ได้สูงสุด

Java

This example is not yet available in Java; you can take a look at the other languages.
    

C#

if (!string.IsNullOrEmpty(sessionAttributesEncoded))
{
    clickConversion.SessionAttributesEncoded =
        ByteString.CopyFrom(sessionAttributesEncoded, Encoding.Unicode);
}
else if (!string.IsNullOrEmpty(sessionAttributes))
{
    IEnumerable<SessionAttributeKeyValuePair> parsedSessionAttributes =
        sessionAttributes.Split(';').Select(pair => {
            string[] split = pair.Split('=');
            return new SessionAttributeKeyValuePair()
            {
                SessionAttributeKey = split[0],
                SessionAttributeValue = split[1]
            };
        });

    clickConversion.SessionAttributesKeyValuePairs =
        new SessionAttributesKeyValuePairs();
    clickConversion.SessionAttributesKeyValuePairs.KeyValuePairs
        .AddRange(parsedSessionAttributes);
}
      

PHP

This example is not yet available in PHP; you can take a look at the other languages.
    

Python

# Set one of the session_attributes_encoded or
# session_attributes_key_value_pairs fields if either are provided.
if session_attributes_encoded:
    click_conversion.session_attributes_encoded = session_attributes_encoded
elif session_attributes_dict:
    for key, value in session_attributes_dict.items():
        pair = client.get_type("SessionAttributeKeyValuePair")
        pair.session_attribute_key = key
        pair.session_attribute_value = value
        click_conversion.session_attributes_key_value_pairs.key_value_pairs.append(
            pair
        )
      

Ruby

This example is not yet available in Ruby; you can take a look at the other languages.
    

Perl

# Set one of the session_attributes_encoded or session_attributes_key_value_pairs
# fields if either are provided.
if (defined $session_attributes_encoded) {
  $click_conversion->{sessionAttributesEncoded} = $session_attributes_encoded;
} elsif (defined $session_attributes_hash) {
  while (my ($key, $value) = each %$session_attributes_hash) {
    my $pair =
      Google::Ads::GoogleAds::V19::Services::ConversionUploadService::SessionAttributeKeyValuePair
      ->new({sessionAttributeKey => $key, sessionAttributeValue => $value});
    push @{$click_conversion->{sessionAttributesKeyValuePairs}{keyValuePairs}
    }, $pair;
  }
}
      

ตัวอย่างโค้ด

ตัวอย่างนี้แสดงวิธีตั้งค่าข้อมูลที่ได้จากผู้ใช้ซึ่งได้รับการทำให้เป็นมาตรฐานและแฮชแล้วลงในออบเจ็กต์ ClickConversion

Java

// Creates an empty builder for constructing the click conversion.
ClickConversion.Builder clickConversionBuilder = ClickConversion.newBuilder();

// Extracts user email and phone from the raw data, normalizes and hashes it, then wraps it in
// UserIdentifier objects.
// Creates a separate UserIdentifier object for each. The data in this example is hardcoded, but
// in your application you might read the raw data from an input file.

// IMPORTANT: Since the identifier attribute of UserIdentifier
// (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) is a
// oneof
// (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set only ONE of
// hashedEmail, hashedPhoneNumber, mobileId, thirdPartyUserId, or addressInfo. Setting more
// than one of these attributes on the same UserIdentifier will clear all the other members
// of the oneof. For example, the following code is INCORRECT and will result in a
// UserIdentifier with ONLY a hashedPhoneNumber.
//
// UserIdentifier incorrectlyPopulatedUserIdentifier =
//     UserIdentifier.newBuilder()
//         .setHashedEmail("...")
//         .setHashedPhoneNumber("...")
//         .build();

ImmutableMap.Builder<String, String> rawRecordBuilder =
    ImmutableMap.<String, String>builder()
        .put("email", "[email protected]")
        // Phone number to be converted to E.164 format, with a leading '+' as required.
        .put("phone", "+1 800 5550102")
        // This example lets you put conversion details as arguments, but in reality you might
        // store this data alongside other user data, so we include it in this sample user
        // record.
        .put("conversionActionId", Long.toString(conversionActionId))
        .put("conversionDateTime", conversionDateTime)
        .put("conversionValue", Double.toString(conversionValue))
        .put("currencyCode", "USD");

// Adds entries for the optional fields.
if (orderId != null) {
  rawRecordBuilder.put("orderId", orderId);
}
if (gclid != null) {
  rawRecordBuilder.put("gclid", gclid);
}
if (adUserDataConsent != null) {
  rawRecordBuilder.put("adUserDataConsent", adUserDataConsent.name());
}
if (sessionAttributesEncoded != null) {
  rawRecordBuilder.put("sessionAttributesEncoded", sessionAttributesEncoded);
}
if (sessionAttributesMap != null) {
  rawRecordBuilder.put("sessionAttributesMap", sessionAttributesMap);
}

// Builds the map representing the record.
Map<String, String> rawRecord = rawRecordBuilder.build();

// Creates a SHA256 message digest for hashing user identifiers in a privacy-safe way, as
// described at https://support.google.com/google-ads/answer/9888656.
MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256");

// Creates a list for the user identifiers.
List<UserIdentifier> userIdentifiers = new ArrayList<>();

// Creates a user identifier using the hashed email address, using the normalize and hash method
// specifically for email addresses.
UserIdentifier emailIdentifier =
    UserIdentifier.newBuilder()
        // Optional: specify the user identifier source.
        .setUserIdentifierSource(UserIdentifierSource.FIRST_PARTY)
        // Uses the normalize and hash method specifically for email addresses.
        .setHashedEmail(normalizeAndHashEmailAddress(sha256Digest, rawRecord.get("email")))
        .build();
userIdentifiers.add(emailIdentifier);

// Creates a user identifier using normalized and hashed phone info.
UserIdentifier hashedPhoneNumberIdentifier =
    UserIdentifier.newBuilder()
        .setHashedPhoneNumber(normalizeAndHash(sha256Digest, rawRecord.get("phone")))
        .build();
// Adds the hashed phone number identifier to the UserData object's list.
userIdentifiers.add(hashedPhoneNumberIdentifier);

// Adds the user identifiers to the conversion.
clickConversionBuilder.addAllUserIdentifiers(userIdentifiers);
      

C#

// Adds a user identifier using the hashed email address, using the normalize
// and hash method specifically for email addresses.
clickConversion.UserIdentifiers.Add(new UserIdentifier()
{
    HashedEmail = NormalizeAndHashEmailAddress("[email protected]"),
    // Optional: Specifies the user identifier source.
    UserIdentifierSource = UserIdentifierSource.FirstParty
});

// Adds a user identifier using normalized and hashed phone info.
clickConversion.UserIdentifiers.Add(new UserIdentifier()
{
    HashedPhoneNumber = NormalizeAndHash("+1 800 5550102"),
    // Optional: Specifies the user identifier source.
    UserIdentifierSource = UserIdentifierSource.FirstParty
});

// Adds a user identifier with all the required mailing address elements.
clickConversion.UserIdentifiers.Add(new UserIdentifier()
{
    AddressInfo = new OfflineUserAddressInfo()
    {
        // FirstName and LastName must be normalized and hashed.
        HashedFirstName = NormalizeAndHash("Alex"),
        HashedLastName = NormalizeAndHash("Quinn"),
        // CountryCode and PostalCode are sent in plain text.
        CountryCode = "US",
        PostalCode = "94045"
    }
});
      

PHP

// Creates a click conversion with the specified attributes.
$clickConversion = new ClickConversion();

// Extract user email and phone from the raw data, normalize and hash it, then wrap it in
// UserIdentifier objects. Creates a separate UserIdentifier object for each.
// The data in this example is hardcoded, but in your application you might read the raw
// data from an input file.

// IMPORTANT: Since the identifier attribute of UserIdentifier
// (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) is a
// oneof
// (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set only ONE
// of hashedEmail, hashedPhoneNumber, mobileId, thirdPartyUserId, or addressInfo. Setting
// more than one of these attributes on the same UserIdentifier will clear all the other
// members of the oneof. For example, the following code is INCORRECT and will result in a
// UserIdentifier with ONLY a hashedPhoneNumber.
//
// $incorrectlyPopulatedUserIdentifier = new UserIdentifier([
//    'hashed_email' => '...',
//    'hashed_phone_number' => '...'
// ]);

$rawRecord = [
    // Email address that includes a period (.) before the Gmail domain.
    'email' => '[email protected]',
    // Phone number to be converted to E.164 format, with a leading '+' as required.
    'phone' => '+1 800 5550102',
    // This example lets you input conversion details as arguments, but in reality you might
    // store this data alongside other user data, so we include it in this sample user
    // record.
    'orderId' => $orderId,
    'gclid' => $gclid,
    'conversionActionId' => $conversionActionId,
    'conversionDateTime' => $conversionDateTime,
    'conversionValue' => $conversionValue,
    'currencyCode' => 'USD',
    'adUserDataConsent' => $adUserDataConsent
];

// Creates a list for the user identifiers.
$userIdentifiers = [];

// Uses the SHA-256 hash algorithm for hashing user identifiers in a privacy-safe way, as
// described at https://support.google.com/google-ads/answer/9888656.
$hashAlgorithm = "sha256";

// Creates a user identifier using the hashed email address, using the normalize and hash
// method specifically for email addresses.
$emailIdentifier = new UserIdentifier([
    // Uses the normalize and hash method specifically for email addresses.
    'hashed_email' => self::normalizeAndHashEmailAddress(
        $hashAlgorithm,
        $rawRecord['email']
    ),
    // Optional: Specifies the user identifier source.
    'user_identifier_source' => UserIdentifierSource::FIRST_PARTY
]);
$userIdentifiers[] = $emailIdentifier;

// Checks if the record has a phone number, and if so, adds a UserIdentifier for it.
if (array_key_exists('phone', $rawRecord)) {
    $hashedPhoneNumberIdentifier = new UserIdentifier([
        'hashed_phone_number' => self::normalizeAndHash(
            $hashAlgorithm,
            $rawRecord['phone'],
            true
        )
    ]);
    // Adds the hashed email identifier to the user identifiers list.
    $userIdentifiers[] = $hashedPhoneNumberIdentifier;
}

// Adds the user identifiers to the conversion.
$clickConversion->setUserIdentifiers($userIdentifiers);
      

Python

# Extract user email and phone from the raw data, normalize and hash it,
# then wrap it in UserIdentifier objects. Create a separate UserIdentifier
# object for each. The data in this example is hardcoded, but in your
# application you might read the raw data from an input file.

# IMPORTANT: Since the identifier attribute of UserIdentifier
# (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier)
# is a oneof
# (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must
# set only ONE of hashed_email, hashed_phone_number, mobile_id,
# third_party_user_id, or address_info. Setting more than one of these
# attributes on the same UserIdentifier will clear all the other members of
# the oneof. For example, the following code is INCORRECT and will result in
# a UserIdentifier with ONLY a hashed_phone_number:
#
# incorrectly_populated_user_identifier = client.get_type("UserIdentifier")
# incorrectly_populated_user_identifier.hashed_email = "...""
# incorrectly_populated_user_identifier.hashed_phone_number = "...""

raw_record = {
    # Email address that includes a period (.) before the Gmail domain.
    "email": "[email protected]",
    # Phone number to be converted to E.164 format, with a leading '+' as
    # required.
    "phone": "+1 800 5550102",
    # This example lets you input conversion details as arguments,
    # but in reality you might store this data alongside other user data,
    # so we include it in this sample user record.
    "order_id": order_id,
    "gclid": gclid,
    "conversion_action_id": conversion_action_id,
    "conversion_date_time": conversion_date_time,
    "conversion_value": conversion_value,
    "currency_code": "USD",
    "ad_user_data_consent": ad_user_data_consent,
}

# Constructs the click conversion.
click_conversion = client.get_type("ClickConversion")
# Creates a user identifier using the hashed email address, using the
# normalize and hash method specifically for email addresses.
email_identifier = client.get_type("UserIdentifier")
# Optional: Specifies the user identifier source.
email_identifier.user_identifier_source = (
    client.enums.UserIdentifierSourceEnum.FIRST_PARTY
)
# Uses the normalize and hash method specifically for email addresses.
email_identifier.hashed_email = normalize_and_hash_email_address(
    raw_record["email"]
)
# Adds the user identifier to the conversion.
click_conversion.user_identifiers.append(email_identifier)

# Checks if the record has a phone number, and if so, adds a UserIdentifier
# for it.
if raw_record.get("phone") is not None:
    phone_identifier = client.get_type("UserIdentifier")
    phone_identifier.hashed_phone_number = normalize_and_hash(
        raw_record["phone"]
    )
    # Adds the phone identifier to the conversion adjustment.
    click_conversion.user_identifiers.append(phone_identifier)
      

Ruby

# Extract user email and phone from the raw data, normalize and hash it,
# then wrap it in UserIdentifier objects. Create a separate UserIdentifier
# object for each. The data in this example is hardcoded, but in your
# application you might read the raw data from an input file.

# IMPORTANT: Since the identifier attribute of UserIdentifier
# (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier)
# is a oneof
# (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must
# set only ONE of hashed_email, hashed_phone_number, mobile_id,
# third_party_user_id, or address_info. Setting more than one of these
# attributes on the same UserIdentifier will clear all the other members of
# the oneof. For example, the following code is INCORRECT and will result in
# a UserIdentifier with ONLY a hashed_phone_number:
#
# incorrectly_populated_user_identifier.hashed_email = "...""
# incorrectly_populated_user_identifier.hashed_phone_number = "...""

raw_record = {
  # Email address that includes a period (.) before the Gmail domain.
  "email" => "[email protected]",
  # Phone number to be converted to E.164 format, with a leading '+' as
  # required.
  "phone" => "+1 800 5550102",
  # This example lets you input conversion details as arguments,
  # but in reality you might store this data alongside other user data,
  # so we include it in this sample user record.
  "order_id" => order_id,
  "gclid" => gclid,
  "conversion_action_id" => conversion_action_id,
  "conversion_date_time" => conversion_date_time,
  "conversion_value" => conversion_value,
  "currency_code" => "USD",
  "ad_user_data_consent" => ad_user_data_consent,
  "session_attributes_encoded" => session_attributes_encoded,
  "session_attributes_hash" => session_attributes_hash
}

click_conversion = client.resource.click_conversion do |cc|
  cc.conversion_action = client.path.conversion_action(customer_id, conversion_action_id)
  cc.conversion_date_time = conversion_date_time
  cc.conversion_value = conversion_value.to_f
  cc.currency_code = 'USD'

  unless order_id.nil?
    cc.order_id = order_id
  end

  unless raw_record["gclid"].nil?
    cc.gclid = gclid
  end

  # Specifies whether user consent was obtained for the data you are
  # uploading. For more details, see:
  # https://www.google.com/about/company/user-consent-policy
  unless raw_record["ad_user_data_consent"].nil?
    cc.consent = client.resource.consent do |c|
      c.ad_user_data = ad_user_data_consent
    end
  end

  # Set one of the session_attributes_encoded or
  # session_attributes_key_value_pairs fields if either are provided.
  if session_attributes_encoded != nil
    cc.class.module_eval { attr_accessor :session_attributes_encoded}
    cc.session_attributes_encoded = session_attributes_encoded
  elsif session_attributes_hash != nil
    # Add new attribute to click conversion object
    cc.class.module_eval { attr_accessor :session_attributes_key_value_pairs}
    cc.session_attributes_key_value_pairs = ::Google::Ads::GoogleAds::V19::Services::SessionAttributesKeyValuePairs.new

    # Loop thru inputted session_attributes_hash to populate session_attributes_key_value_pairs
    session_attributes_hash.each do |key, value|
      pair = ::Google::Ads::GoogleAds::V19::Services::SessionAttributeKeyValuePair.new
      pair.session_attribute_key = key
      pair.session_attribute_value = value
      cc.session_attributes_key_value_pairs.key_value_pairs << pair
    end
  end    

  # Creates a user identifier using the hashed email address, using the
  # normalize and hash method specifically for email addresses.
  # If using a phone number, use the normalize_and_hash method instead.
  cc.user_identifiers << client.resource.user_identifier do |ui|
    ui.hashed_email = normalize_and_hash_email(raw_record["email"])
    # Optional: Specifies the user identifier source.
    ui.user_identifier_source = :FIRST_PARTY
  end

  # Checks if the record has a phone number, and if so, adds a UserIdentifier
  # for it.
  unless raw_record["phone"].nil?
    cc.user_identifiers << client.resource.user_identifier do |ui|
      ui.hashed_phone_number = normalize_and_hash(raw_record["phone"])
    end
  end
end
      

Perl

# Create an empty click conversion.
my $click_conversion =
  Google::Ads::GoogleAds::V19::Services::ConversionUploadService::ClickConversion
  ->new({});

# Extract user email and phone from the raw data, normalize and hash it,
# then wrap it in UserIdentifier objects. Create a separate UserIdentifier
# object for each.
# The data in this example is hardcoded, but in your application
# you might read the raw data from an input file.
#
# IMPORTANT: Since the identifier attribute of UserIdentifier
# (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier)
# is a oneof
# (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set
# only ONE of hashed_email, hashed_phone_number, mobile_id, third_party_user_id,
# or address-info. Setting more than one of these attributes on the same UserIdentifier
# will clear all the other members of the oneof. For example, the following code is
# INCORRECT and will result in a UserIdentifier with ONLY a hashed_phone_number:
#
# my $incorrect_user_identifier = Google::Ads::GoogleAds::V19::Common::UserIdentifier->new({
#   hashedEmail => '...',
#   hashedPhoneNumber => '...',
# });
my $raw_record = {
  # Email address that includes a period (.) before the Gmail domain.
  email => '[email protected]',
  # Phone number to be converted to E.164 format, with a leading '+' as
  # required.
  phone => '+1 800 5550102',
  # This example lets you input conversion details as arguments,
  # but in reality you might store this data alongside other user data,
  # so we include it in this sample user record.
  orderId            => $order_id,
  gclid              => $gclid,
  conversionActionId => $conversion_action_id,
  conversionDateTime => $conversion_date_time,
  conversionValue    => $conversion_value,
  currencyCode       => "USD",
  adUserDataConsent  => $ad_user_data_consent
};
my $user_identifiers = [];

# Create a user identifier using the hashed email address, using the normalize
# and hash method specifically for email addresses.
my $hashed_email = normalize_and_hash_email_address($raw_record->{email});
push(
  @$user_identifiers,
  Google::Ads::GoogleAds::V19::Common::UserIdentifier->new({
      hashedEmail => $hashed_email,
      # Optional: Specify the user identifier source.
      userIdentifierSource => FIRST_PARTY
    }));

# Create a user identifier using normalized and hashed phone info.
my $hashed_phone = normalize_and_hash($raw_record->{phone});
push(
  @$user_identifiers,
  Google::Ads::GoogleAds::V19::Common::UserIdentifier->new({
      hashedPhone => $hashed_phone,
      # Optional: Specify the user identifier source.
      userIdentifierSource => FIRST_PARTY
    }));

# Add the user identifiers to the conversion.
$click_conversion->{userIdentifiers} = $user_identifiers;
      

ตัวอย่างนี้แสดงวิธีตั้งค่าฟิลด์อื่นๆ ที่จําเป็นในClickConversion ออบเจ็กต์

Java

// Adds details of the conversion.
clickConversionBuilder.setConversionAction(
    ResourceNames.conversionAction(
        customerId, Long.parseLong(rawRecord.get("conversionActionId"))));
clickConversionBuilder.setConversionDateTime(rawRecord.get("conversionDateTime"));
clickConversionBuilder.setConversionValue(Double.parseDouble(rawRecord.get("conversionValue")));
clickConversionBuilder.setCurrencyCode(rawRecord.get("currencyCode"));

// Sets the order ID if provided.
if (rawRecord.containsKey("orderId")) {
  clickConversionBuilder.setOrderId(rawRecord.get("orderId"));
}

// Sets the Google click ID (gclid) if provided.
if (rawRecord.containsKey("gclid")) {
  clickConversionBuilder.setGclid(rawRecord.get("gclid"));
}

// Sets the consent information, if provided.
if (rawRecord.containsKey("adUserDataConsent")) {
  // Specifies whether user consent was obtained for the data you are uploading. See
  // https://www.google.com/about/company/user-consent-policy for details.
  clickConversionBuilder.setConsent(
      Consent.newBuilder()
          .setAdUserData(ConsentStatus.valueOf(rawRecord.get("adUserDataConsent"))));
}

// Sets one of the sessionAttributesEncoded or sessionAttributesKeyValuePairs if either is
// provided.
if (rawRecord.containsKey("sessionAttributesEncoded")) {
  clickConversionBuilder.setSessionAttributesEncoded(
      ByteString.copyFromUtf8(rawRecord.get("sessionAttributesEncoded")));
} else if (rawRecord.containsKey("sessionAttributesMap")) {
  List<String> pairings =
      Arrays.stream(rawRecord.get("sessionAttributesMap").split(" "))
          .map(String::trim)
          .collect(Collectors.toList());
  SessionAttributesKeyValuePairs.Builder sessionAttributePairs =
      SessionAttributesKeyValuePairs.newBuilder();
  for (String pair : pairings) {
    String[] parts = pair.split("=", 2);
    if (parts.length != 2) {
      throw new IllegalArgumentException(
          "Failed to read the sessionAttributesMap. SessionAttributesMap must use a "
              + "space-delimited list of session attribute key value pairs. Each pair should be"
              + " separated by an equal sign, for example: 'gad_campaignid=12345 gad_source=1'");
    }
    sessionAttributePairs.addKeyValuePairs(
        SessionAttributeKeyValuePair.newBuilder()
            .setSessionAttributeKey(parts[0])
            .setSessionAttributeValue(parts[1])
            .build());
  }
  clickConversionBuilder.setSessionAttributesKeyValuePairs(sessionAttributePairs.build());
}

// Calls build to build the conversion.
ClickConversion clickConversion = clickConversionBuilder.build();
      

C#

// Adds details of the conversion.
clickConversion.ConversionAction =
    ResourceNames.ConversionAction(customerId, conversionActionId);
clickConversion.ConversionDateTime = conversionDateTime;
clickConversion.ConversionValue = conversionValue;
clickConversion.CurrencyCode = "USD";

// Sets the order ID if provided.
if (!string.IsNullOrEmpty(orderId))
{
    clickConversion.OrderId = orderId;
}

// Sets the Google click ID (gclid) if provided.
if (!string.IsNullOrEmpty(gclid))
{
    clickConversion.Gclid = gclid;
}

if (!string.IsNullOrEmpty(sessionAttributesEncoded))
{
    clickConversion.SessionAttributesEncoded =
        ByteString.CopyFrom(sessionAttributesEncoded, Encoding.Unicode);
}
else if (!string.IsNullOrEmpty(sessionAttributes))
{
    IEnumerable<SessionAttributeKeyValuePair> parsedSessionAttributes =
        sessionAttributes.Split(';').Select(pair => {
            string[] split = pair.Split('=');
            return new SessionAttributeKeyValuePair()
            {
                SessionAttributeKey = split[0],
                SessionAttributeValue = split[1]
            };
        });

    clickConversion.SessionAttributesKeyValuePairs =
        new SessionAttributesKeyValuePairs();
    clickConversion.SessionAttributesKeyValuePairs.KeyValuePairs
        .AddRange(parsedSessionAttributes);
}

      

PHP

// Adds details of the conversion.
$clickConversion->setConversionAction(
    ResourceNames::forConversionAction($customerId, $rawRecord['conversionActionId'])
);
$clickConversion->setConversionDateTime($rawRecord['conversionDateTime']);
$clickConversion->setConversionValue($rawRecord['conversionValue']);
$clickConversion->setCurrencyCode($rawRecord['currencyCode']);

// Sets the order ID if provided.
if (!empty($rawRecord['orderId'])) {
    $clickConversion->setOrderId($rawRecord['orderId']);
}

// Sets the Google click ID (gclid) if provided.
if (!empty($rawRecord['gclid'])) {
    $clickConversion->setGclid($rawRecord['gclid']);
}

// Sets the ad user data consent if provided.
if (!empty($rawRecord['adUserDataConsent'])) {
    // Specifies whether user consent was obtained for the data you are uploading. See
    // https://www.google.com/about/company/user-consent-policy for details.
    $clickConversion->setConsent(
        new Consent(['ad_user_data' => $rawRecord['adUserDataConsent']])
    );
}
      

Python

# Add details of the conversion.
# Gets the conversion action resource name.
conversion_action_service = client.get_service("ConversionActionService")
click_conversion.conversion_action = (
    conversion_action_service.conversion_action_path(
        customer_id, raw_record["conversion_action_id"]
    )
)
click_conversion.conversion_date_time = raw_record["conversion_date_time"]
click_conversion.conversion_value = raw_record["conversion_value"]
click_conversion.currency_code = raw_record["currency_code"]

# Sets the order ID if provided.
if raw_record.get("order_id"):
    click_conversion.order_id = raw_record["order_id"]

# Sets the gclid if provided.
if raw_record.get("gclid"):
    click_conversion.gclid = raw_record["gclid"]

# Specifies whether user consent was obtained for the data you are
# uploading. For more details, see:
# https://www.google.com/about/company/user-consent-policy
if raw_record["ad_user_data_consent"]:
    click_conversion.consent.ad_user_data = client.enums.ConsentStatusEnum[
        raw_record["ad_user_data_consent"]
    ]

# Set one of the session_attributes_encoded or
# session_attributes_key_value_pairs fields if either are provided.
if session_attributes_encoded:
    click_conversion.session_attributes_encoded = session_attributes_encoded
elif session_attributes_dict:
    for key, value in session_attributes_dict.items():
        pair = client.get_type("SessionAttributeKeyValuePair")
        pair.session_attribute_key = key
        pair.session_attribute_value = value
        click_conversion.session_attributes_key_value_pairs.key_value_pairs.append(
            pair
        )
      

Ruby

cc.conversion_action = client.path.conversion_action(customer_id, conversion_action_id)
cc.conversion_date_time = conversion_date_time
cc.conversion_value = conversion_value.to_f
cc.currency_code = 'USD'

unless order_id.nil?
  cc.order_id = order_id
end

unless raw_record["gclid"].nil?
  cc.gclid = gclid
end

# Specifies whether user consent was obtained for the data you are
# uploading. For more details, see:
# https://www.google.com/about/company/user-consent-policy
unless raw_record["ad_user_data_consent"].nil?
  cc.consent = client.resource.consent do |c|
    c.ad_user_data = ad_user_data_consent
  end
end

# Set one of the session_attributes_encoded or
# session_attributes_key_value_pairs fields if either are provided.
if session_attributes_encoded != nil
  cc.class.module_eval { attr_accessor :session_attributes_encoded}
  cc.session_attributes_encoded = session_attributes_encoded
elsif session_attributes_hash != nil
  # Add new attribute to click conversion object
  cc.class.module_eval { attr_accessor :session_attributes_key_value_pairs}
  cc.session_attributes_key_value_pairs = ::Google::Ads::GoogleAds::V19::Services::SessionAttributesKeyValuePairs.new

  # Loop thru inputted session_attributes_hash to populate session_attributes_key_value_pairs
  session_attributes_hash.each do |key, value|
    pair = ::Google::Ads::GoogleAds::V19::Services::SessionAttributeKeyValuePair.new
    pair.session_attribute_key = key
    pair.session_attribute_value = value
    cc.session_attributes_key_value_pairs.key_value_pairs << pair
  end
end    
      

Perl

# Add details of the conversion.
$click_conversion->{conversionAction} =
  Google::Ads::GoogleAds::V19::Utils::ResourceNames::conversion_action(
  $customer_id, $raw_record->{conversionActionId});
$click_conversion->{conversionDateTime} = $raw_record->{conversionDateTime};
$click_conversion->{conversionValue}    = $raw_record->{conversionValue};
$click_conversion->{currencyCode}       = $raw_record->{currencyCode};

# Set the order ID if provided.
if (defined $raw_record->{orderId}) {
  $click_conversion->{orderId} = $raw_record->{orderId};
}

# Set the Google click ID (gclid) if provided.
if (defined $raw_record->{gclid}) {
  $click_conversion->{gclid} = $raw_record->{gclid};
}

# Set the consent information, if provided.
if (defined $raw_record->{adUserDataConsent}) {
  $click_conversion->{consent} =
    Google::Ads::GoogleAds::V19::Common::Consent->new({
      adUserData => $raw_record->{adUserDataConsent}});
}

# Set one of the session_attributes_encoded or session_attributes_key_value_pairs
# fields if either are provided.
if (defined $session_attributes_encoded) {
  $click_conversion->{sessionAttributesEncoded} = $session_attributes_encoded;
} elsif (defined $session_attributes_hash) {
  while (my ($key, $value) = each %$session_attributes_hash) {
    my $pair =
      Google::Ads::GoogleAds::V19::Services::ConversionUploadService::SessionAttributeKeyValuePair
      ->new({sessionAttributeKey => $key, sessionAttributeValue => $value});
    push @{$click_conversion->{sessionAttributesKeyValuePairs}{keyValuePairs}
    }, $pair;
  }
}
      

สร้างคำขอ

เมื่อกําหนดค่าออบเจ็กต์ ClickConversion และเพิ่มลงในช่อง conversions ของออบเจ็กต์ UploadClickConversionRequest แล้ว ให้ตั้งค่าช่องต่อไปนี้และส่งคําขอไปยังเมธอด UploadClickConversions ใน ConversionUploadService

customer_id
ตั้งค่านี้เป็นลูกค้า Conversion ของ Google Ads ของบัญชีที่เป็นที่มาของคลิก หากไม่แน่ใจว่าบัญชีใดถูกต้อง ให้ดูที่ช่อง customer.conversion_tracking_setting.google_ads_conversion_customer ในตัวอย่างการค้นหาในส่วนเริ่มต้นใช้งาน
job_id

มีกลไกในการเชื่อมโยงคําขอนําเข้ากับข้อมูลต่องานในการวินิจฉัยข้อมูลออฟไลน์

หากคุณไม่ได้ตั้งค่าช่องนี้ Google Ads API จะกําหนดค่าที่ไม่ซ้ำกันให้กับคําขอแต่ละรายการใน [2^31, 2^63) หากต้องการจัดกลุ่มคำขอหลายรายการเป็นงานเชิงตรรกะเดียว ให้ตั้งค่าช่องนี้เป็นค่าเดียวกันในช่วง [0, 2^31) ในคำขอทุกรายการในงาน

job_id ในการตอบกลับจะมีรหัสงานสําหรับคําขอ ไม่ว่าคุณจะระบุค่าหรือให้ Google Ads API กําหนดค่าก็ตาม

partial_failure

คุณต้องตั้งค่าช่องนี้เป็น true เมื่อนําเข้า Conversion ปฏิบัติตามหลักเกณฑ์การประมวลผลที่ดำเนินการไม่สำเร็จบางส่วนเมื่อประมวลผลการตอบกลับ

นําเข้าคําขอ

เมื่อป้อนข้อมูลออบเจ็กต์ ClickConversion และสร้างคำขอแล้ว คุณจะส่งการนําเข้าได้

Java

// Creates the conversion upload service client.
try (ConversionUploadServiceClient conversionUploadServiceClient =
    googleAdsClient.getLatestVersion().createConversionUploadServiceClient()) {
  // Uploads the click conversion. Partial failure should always be set to true.

  // NOTE: This request contains a single conversion as a demonstration.  However, if you have
  // multiple conversions to upload, it's best to upload multiple conversions per request
  // instead of sending a separate request per conversion. See the following for per-request
  // limits:
  // https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_upload_service
  UploadClickConversionsResponse response =
      conversionUploadServiceClient.uploadClickConversions(
          UploadClickConversionsRequest.newBuilder()
              .setCustomerId(Long.toString(customerId))
              .addConversions(clickConversion)
              // Enables partial failure (must be true).
              .setPartialFailure(true)
              .build());
      

C#

// Uploads the click conversion. Partial failure should always be set to true.
// NOTE: This request contains a single conversion as a demonstration.
// However, if you have multiple conversions to upload, it's best to upload multiple
// conversions per request instead of sending a separate request per conversion.
// See the following for per-request limits:
// https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_upload
UploadClickConversionsResponse response =
    conversionUploadService.UploadClickConversions(
        new UploadClickConversionsRequest()
        {
            CustomerId = customerId.ToString(),
            Conversions = { clickConversion },
            // Enables partial failure (must be true).
            PartialFailure = true
        });

      

PHP

// Issues a request to upload the click conversion.
$conversionUploadServiceClient = $googleAdsClient->getConversionUploadServiceClient();
// NOTE: This request contains a single conversion as a demonstration.  However, if you have
// multiple conversions to upload, it's best to upload multiple conversions per request
// instead of sending a separate request per conversion. See the following for per-request
// limits:
// https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_upload_service
$response = $conversionUploadServiceClient->uploadClickConversions(
    // Enables partial failure (must be true).
    UploadClickConversionsRequest::build($customerId, [$clickConversion], true)
);
      

Python

# Creates the conversion upload service client.
conversion_upload_service = client.get_service("ConversionUploadService")
# Uploads the click conversion. Partial failure should always be set to
# True.
# NOTE: This request only uploads a single conversion, but if you have
# multiple conversions to upload, it's most efficient to upload them in a
# single request. See the following for per-request limits for reference:
# https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_upload_service
response = conversion_upload_service.upload_click_conversions(
    customer_id=customer_id,
    conversions=[click_conversion],
    # Enables partial failure (must be true).
    partial_failure=True,
)
      

Ruby

response = client.service.conversion_upload.upload_click_conversions(
  customer_id: customer_id,
  conversions: [click_conversion],
  # Partial failure must be true.
  partial_failure: true,
)

if response.partial_failure_error
  puts "Partial failure encountered: #{response.partial_failure_error.message}"
else
  result = response.results.first
  puts "Uploaded click conversion that happened at #{result.conversion_date_time} " \
    "to #{result.conversion_action}."
end
      

Perl

# Upload the click conversion. Partial failure should always be set to true.
#
# NOTE: This request contains a single conversion as a demonstration.
# However, if you have multiple conversions to upload, it's best to
# upload multiple conversions per request instead of sending a separate
# request per conversion. See the following for per-request limits:
# https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_upload_service
my $response =
  $api_client->ConversionUploadService()->upload_click_conversions({
    customerId  => $customer_id,
    conversions => [$click_conversion],
    # Enable partial failure (must be true).
    partialFailure => "true"
  });
      

ตรวจสอบการนําเข้า

ใช้รายงานการวินิจฉัย Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายเพื่อตรวจสอบประสิทธิภาพโดยรวมของการนําเข้าครั้งล่าสุด

Conversion ที่นําเข้าจะแสดงในรายงานสำหรับวันที่การแสดงผลของการคลิกครั้งแรก ไม่ใช่วันที่ส่งคําขอนําเข้าหรือวันที่ของ conversion_date_time ของ ClickConversion

ระบบใช้เวลาสูงสุด 3 ชั่วโมงในการนําเข้าสถิติ Conversion ที่นําเข้าในบัญชี Google Ads สําหรับการระบุแหล่งที่มาของคลิกสุดท้าย สําหรับรูปแบบการระบุแหล่งที่มาของ Search อื่นๆ อาจใช้เวลานานกว่า 3 ชั่วโมง ดูข้อมูลเพิ่มเติมได้ที่คำแนะนำเกี่ยวกับความใหม่ของข้อมูล

เมื่อรายงานเมตริก Conversion สําหรับแคมเปญ โปรดดูการแมปเมตริกอินเทอร์เฟซผู้ใช้เพื่อเชื่อมโยงเมตริก UI ของ Google Ads กับช่องการรายงาน Google Ads API นอกจากนี้ คุณยังค้นหาแหล่งข้อมูล conversion_action เพื่อดูจํานวน Conversion ทั้งหมดและมูลค่า Conversion ทั้งหมดสําหรับการกระทําที่ถือเป็น Conversion หนึ่งๆ ได้ด้วย

แนวทางปฏิบัติแนะนำ

โปรดคำนึงถึงแนวทางปฏิบัติแนะนำต่อไปนี้เมื่อติดตั้งใช้งาน Conversion ที่ปรับปรุงแล้วสำหรับโอกาสในการขาย

ส่งข้อมูล Conversion ทั้งหมดโดยไม่คำนึงถึงความสมบูรณ์

นําเข้าเหตุการณ์ Conversion ออฟไลน์ทั้งหมดที่มี รวมถึงเหตุการณ์ที่อาจไม่ได้มาจาก Google Ads เพื่อให้การรายงาน Conversion สมบูรณ์และถูกต้อง Conversion ที่มีเฉพาะข้อมูลที่ได้จากผู้ใช้จะยังคงมีประโยชน์และส่งผลเชิงบวกต่อการเพิ่มประสิทธิภาพแคมเปญ Google Ads

หากคุณกําหนด order_id ให้กับ Conversion เราขอแนะนําให้รวม order_id นั้นไว้ หากคุณมี GCLID ของ Conversion เราขอแนะนําให้ส่ง GCLID นั้นควบคู่ไปกับ user_identifiers เพื่อประสิทธิภาพที่ดียิ่งขึ้น นอกจากนี้ หากคุณมี UserIdentifier มากกว่า 1 รายการสําหรับ Conversion ให้รวม UserIdentifier ทั้งหมดไว้ในออบเจ็กต์ ClickConversion เพื่อเพิ่มโอกาสในการจับคู่

ส่ง Conversion หลายรายการพร้อมกันในคําขอเดียว

หากต้องการนําเข้า Conversion หลายรายการ ให้จัดกลุ่ม Conversion เหล่านั้นเป็นกลุ่มเดียว UploadClickConversionsRequest แทนที่จะส่งคําขอนําเข้าต่อ Conversion

โปรดดูคําแนะนําเกี่ยวกับโควต้าเพื่อดูขีดจํากัดของจํานวน Conversion ต่อคําขอ

หากต้องการให้การวินิจฉัยข้อมูลออฟไลน์จัดกลุ่มชุดคําขอไว้ในงานเชิงตรรกะเดียวกัน ให้ตั้งค่า job_id ของคําขอทั้งหมดเป็นค่าเดียวกัน ซึ่งจะมีประโยชน์หากคุณมีงานหรือกระบวนการเดียวที่นําเข้า Conversion จํานวนมากโดยใช้คําขอหลายรายการ หากคุณตั้งค่า job_id ในคําขอแต่ละรายการเป็นค่าเดียวกัน คุณจะดึงข้อมูลรายการเดียวสําหรับงานจาก job_summaries ได้ หากคุณปล่อยให้ Google Ads API กําหนดค่าที่ระบบสร้างขึ้นให้กับ job_id ของคําขอแต่ละรายการแทน job_summaries จะมีรายการแยกกันสําหรับคําขอแต่ละรายการ ซึ่งอาจทําให้การวิเคราะห์ประสิทธิภาพโดยรวมของงานทํางานได้ยากขึ้น

อย่าใช้ข้อมูลการระบุแหล่งที่มาภายนอก

เมื่อใช้ Conversion ที่ปรับปรุงแล้วสำหรับโอกาสในการขาย อย่าตั้งค่า external_attribution_data ใน ClickConversion หรือระบุ conversion_action ที่ใช้รูปแบบการระบุแหล่งที่มาภายนอก Google Ads ไม่รองรับ Conversion ที่มาจากภายนอกสําหรับการนําเข้าโดยใช้ข้อมูลที่ได้จากผู้ใช้

การแก้ปัญหา

การวินิจฉัยข้อมูลออฟไลน์เป็นทรัพยากรแหล่งเดียวสําหรับตรวจสอบประสิทธิภาพโดยรวมของการนําเข้าอย่างต่อเนื่อง อย่างไรก็ตาม ในระหว่างการติดตั้งใช้งาน คุณสามารถใช้ข้อมูลในส่วนนี้เพื่อตรวจสอบข้อผิดพลาดที่รายงานในช่อง partial_failure_error ของคำตอบได้

ข้อผิดพลาดที่พบบ่อยที่สุดเมื่อนําเข้าการกระทําที่ถือเป็น Conversion คือข้อผิดพลาดในการให้สิทธิ์ เช่น USER_PERMISSION_DENIED ตรวจสอบอีกครั้งว่าคุณได้ตั้งค่ารหัสลูกค้าในคําขอเป็นลูกค้า Conversion ของ Google Ads ที่เป็นเจ้าของการกระทําที่ถือเป็น Conversion ดูรายละเอียดเพิ่มเติมได้ในคู่มือการให้สิทธิ์ และดูเคล็ดลับในการแก้ไขข้อผิดพลาดต่างๆ เหล่านี้ได้ในคู่มือข้อผิดพลาดที่พบบ่อย

แก้ไขข้อผิดพลาดที่พบบ่อย

ข้อผิดพลาด
NO_CONVERSION_ACTION_FOUND

การกระทำที่ถือเป็น Conversion ที่ระบุไว้ไม่ได้เปิดใช้งาน หรือบัญชีลูกค้าที่ระบุโดยช่อง `client_id` ในคําขอเข้าถึงไม่ได้ ตรวจสอบว่าการกระทำที่ถือเป็น Conversion ในการอัปโหลดเปิดใช้อยู่และลูกค้าซึ่งส่งคำขออัปโหลดเป็นเจ้าของการกระทำดังกล่าว

ข้อผิดพลาดนี้ยังอาจเกิดขึ้นได้หาก GCLID ในคําขอเป็นของบัญชีลูกค้าที่ไม่มีสิทธิ์เข้าถึงการกระทําที่ถือเป็น Conversion ที่ระบุไว้ในคําขอ คุณสามารถยืนยันได้ว่า GCLID เป็นของบัญชีลูกค้าหรือไม่โดยใช้แหล่งข้อมูล click_view โดยส่งการค้นหาที่กรองตาม click_view.gclid และ segments.date โดยที่วันที่คือวันที่เกิดคลิก

INVALID_CONVERSION_ACTION_TYPE การกระทําที่ถือเป็น Conversion ที่ระบุมีประเภทที่ไม่ถูกต้องสําหรับ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขาย ตรวจสอบว่า ConversionAction ที่ระบุในคำขออัปโหลดเป็นประเภท UPLOAD_CLICKS
CUSTOMER_NOT_ENABLED_ENHANCED_CONVERSIONS_FOR_LEADS ตรวจสอบว่าคุณได้เปิดใช้ Conversion ที่ปรับปรุงแล้วสําหรับโอกาสในการขายในการตั้งค่า Conversion ดูวิธีการได้ในคู่มือข้อกําหนดเบื้องต้น
DUPLICATE_ORDER_ID เหตุการณ์ที่นําเข้ามี Conversion หลายรายการที่มีรหัสคําสั่งซื้อเดียวกัน และไม่ได้รับการประมวลผล ตรวจสอบว่ารหัสคําสั่งซื้อไม่ซ้ำกัน แล้วลองอีกครั้ง
CLICK_NOT_FOUND ไม่พบการคลิกที่ตรงกับตัวระบุผู้ใช้ที่ระบุ Google Ads API จะแสดงข้อผิดพลาดนี้เฉพาะในกรณีที่ debug_enabled เป็น true ใน UploadClickConversionsRequest

หาก Conversion พบคําเตือนนี้ Google Ads API จะรวม Conversion นั้นไว้ใน successful_event_count ของการวินิจฉัยข้อมูลออฟไลน์ Google Ads API มีรายการ CLICK_NOT_FOUND ในคอลเล็กชัน alerts เพื่อให้คุณตรวจสอบความถี่ของคําเตือนนี้ได้

ข้อผิดพลาดนี้จะเกิดขึ้นหากการคลิกไม่ได้มาจากแคมเปญ Google Ads เช่น อาจมาจาก SA360 หรือ DV360 สาเหตุอื่นๆ ที่เป็นไปได้มีดังนี้

ในบางกรณีที่พบไม่บ่อยซึ่งลูกค้าที่ใช้การอัปโหลดไม่ใช่ลูกค้า Conversion ของ Google Ads ข้อผิดพลาดนี้อาจหมายความว่าลูกค้าที่ใช้การอัปโหลดยอมรับข้อกําหนดเกี่ยวกับข้อมูลลูกค้าแล้ว แต่ลูกค้าที่ใช้การแสดงโฆษณายังไม่ยอมรับ

คุณสามารถตรวจสอบว่าบัญชียอมรับข้อกําหนดสําหรับข้อมูลลูกค้าหรือไม่โดยค้นหาแหล่งข้อมูล customer และตรวจสอบช่อง customer.offline_conversion_tracking_info.accepted_customer_data_terms