管理在线点击转化

您可以使用 Google Ads API 在 Google Ads 中管理在线点击转化。在线点击转化可帮助您跟踪在线(例如通过网站)促成销售的广告。

线上转化是使用 Google 代码跟踪的,但您可以使用 Google Ads API 对其进行调整或增强。

如果您已设置 Google 代码,并希望调整线上转化,请参阅转化调整页面。如果您已设置 Google 代码,并希望利用用户提供的数据(也称为增强型网站转化)来提升线上转化次数,请继续阅读。

增强型网站转化

以下部分介绍了如何提升线上点击转化(也称为增强型网站转化)。

若要使用增强型网站转化,您需要设置一个代码,以便在用户完成转化时自动向 Google Ads 发送点击标识符(例如 GCLID)和订单 ID。您可以通过 Google 跟踪代码管理器Google 代码或 Google Ads API 设置增强型转化。使用 Google Ads API 的好处在于,您可以在转化事件发生后的 24 小时内(而不是同时)发送第一方转化数据。这样,您就可以从各种来源(例如客户数据库或 CRM 系统)找到第一方数据。

“增强型网站转化”功能的运作方式

Google Ads API 中的增强型网站转化是对以下流程中第 3 步的补充。

在用户转化时,代码只会发送 GCLID 和订单 ID,而不是发送经过哈希处理的用户信息。您稍后可以通过导入订单 ID 和经过哈希处理的数据来发送经过哈希处理的用户信息。如需详细了解增强型网站转化,请访问我们的帮助中心

增强型网站转化

前提条件

您必须先接受客户数据条款,然后才能使用增强型网站转化。您可以向 Google Ads 转化客户发出以下查询,验证客户数据条款是否已接受:

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

如果 accepted_customer_data_termsfalse,请按照帮助中心中的说明完成此前提条件。

配置代码植入

您可以按照帮助中心中的说明为您的网站配置代码。建议您还向转化跟踪代码中添加交易 ID(订单 ID),以协助进行转化匹配。

API 实现

以下是 Google Ads API 中导入增强型网站转化的整体流程。

  1. 对用户提供的数据进行标准化和哈希处理,例如电子邮件地址、电话号码和邮寄地址。

  2. 使用经过标准化和哈希处理的用户提供的数据填充 ConversionAdjustment 对象

  3. ConversionAdjustment 对象导入 ConversionAdjustmentUploadService

  4. 查看导入内容

对用户提供的数据进行规范化和哈希处理

出于隐私保护方面的考虑,以下数据在上传之前必须使用 SHA-256 算法进行哈希处理:

  • 电子邮件地址
  • 电话号码
  • 名字
  • 姓氏
  • 街道地址

请勿对以下数据进行哈希处理

  • 国家/地区
  • 州/省级行政区
  • 城市
  • 邮编

为了使哈希结果实现标准化,在对其中某个值进行哈希处理之前,您必须执行以下操作:

  • 移除开头和结尾处的空格。
  • 将文字转换为小写形式。
  • 根据 E164 标准设置电话号码的格式。
  • 移除 gmail.comgooglemail.com 电子邮件地址中域名前面的所有句点 (.)。

Java

private String normalizeAndHash(MessageDigest digest, String s, boolean trimIntermediateSpaces)
    throws UnsupportedEncodingException {
  // Normalizes by first converting all characters to lowercase, then trimming spaces.
  String normalized = s.toLowerCase();
  if (trimIntermediateSpaces) {
    // Removes leading, trailing, and intermediate spaces.
    normalized = normalized.replaceAll("\\s+", "");
  } else {
    // Removes only leading and trailing spaces.
    normalized = normalized.trim();
  }
  // 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, true);
}
      

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,
    bool $trimIntermediateSpaces
): string {
    // Normalizes by first converting all characters to lowercase, then trimming spaces.
    $normalized = strtolower($value);
    if ($trimIntermediateSpaces === true) {
        // Removes leading, trailing, and intermediate spaces.
        $normalized = str_replace(' ', '', $normalized);
    } else {
        // Removes only leading and trailing spaces.
        $normalized = trim($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, true);
}
      

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/9888656

    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/9888656.
def normalize_and_hash(str)
  # Remove leading and trailing whitespace and ensure all letters are lowercase
  # before hasing.
  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;
  my $trim_intermediate_spaces = shift;

  if ($trim_intermediate_spaces) {
    $value =~ s/\s+//g;
  } else {
    $value =~ s/^\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, 1);
}
      

填充 ConversionAdjustment 对象

以下部分将演示如何构建包含订单 ID 以及电子邮件地址、电话号码和实际地址标识符的增强型调整,并根据需要应用标准化和哈希处理。最佳实践是,在调整中添加 gclid(如果有)。

此步骤与导入转化调整指南几乎完全相同,但有以下几点需要注意:

  • 使用经过标准化和哈希处理的用户数据填充 user_identifiers。如果您有多个用户标识符,请为每个标识符分别创建 UserIdentifier,最多可创建 5 个标识符。

Java

// Creates a builder for constructing the enhancement adjustment.
ConversionAdjustment.Builder enhancementBuilder =
    ConversionAdjustment.newBuilder().setAdjustmentType(ConversionAdjustmentType.ENHANCEMENT);

// Extracts user email, phone, and address info 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", "alex.2@example.com")
        // Email address that includes a period (.) before the Gmail domain.
        .put("email", "alex.2@example.com")
        // Address that includes all four required elements: first name, last name, country
        // code, and postal code.
        .put("firstName", "Alex")
        .put("lastName", "Quinn")
        .put("countryCode", "US")
        .put("postalCode", "94045")
        // 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("orderId", orderId)
        .put("conversionActionId", Long.toString(conversionActionId))
        .put("currencyCode", "USD");

// Adds entries for the optional fields.
if (conversionDateTime != null) {
  rawRecordBuilder.put("conversionDateTime", conversionDateTime);
}
if (userAgent != null) {
  rawRecordBuilder.put("userAgent", userAgent);
}

// 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);

// Checks if the record has a phone number, and if so, adds a UserIdentifier for it.
if (rawRecord.containsKey("phone")) {
  UserIdentifier hashedPhoneNumberIdentifier =
      UserIdentifier.newBuilder()
          .setHashedPhoneNumber(normalizeAndHash(sha256Digest, rawRecord.get("phone"), true))
          .build();
  // Adds the hashed phone number identifier to the UserData object's list.
  userIdentifiers.add(hashedPhoneNumberIdentifier);
}

// Checks if the record has all the required mailing address elements, and if so, adds a
// UserIdentifier for the mailing address.
if (rawRecord.containsKey("firstName")) {
  // Checks if the record contains all the other required elements of a mailing address.
  Set<String> missingAddressKeys = new HashSet<>();
  for (String addressKey : new String[] {"lastName", "countryCode", "postalCode"}) {
    if (!rawRecord.containsKey(addressKey)) {
      missingAddressKeys.add(addressKey);
    }
  }

  if (!missingAddressKeys.isEmpty()) {
    System.out.printf(
        "Skipping addition of mailing address information because the following required keys"
            + " are missing: %s%n",
        missingAddressKeys);
  } else {
    // Creates an OfflineUserAddressInfo object that contains all the required elements of a
    // mailing address.
    OfflineUserAddressInfo addressInfo =
        OfflineUserAddressInfo.newBuilder()
            .setHashedFirstName(
                normalizeAndHash(sha256Digest, rawRecord.get("firstName"), false))
            .setHashedLastName(normalizeAndHash(sha256Digest, rawRecord.get("lastName"), false))
            .setCountryCode(rawRecord.get("countryCode"))
            .setPostalCode(rawRecord.get("postalCode"))
            .build();
    UserIdentifier addressIdentifier =
        UserIdentifier.newBuilder().setAddressInfo(addressInfo).build();
    // Adds the address identifier to the UserData object's list.
    userIdentifiers.add(addressIdentifier);
  }
}

// Adds the user identifiers to the enhancement adjustment.
enhancementBuilder.addAllUserIdentifiers(userIdentifiers);
      

C#

// Normalize and hash the raw data, 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:
// UserIdentifier incorrectlyPopulatedUserIdentifier = new UserIdentifier()
// {
//         HashedEmail = "..."
//         HashedPhoneNumber = "..."
// }
UserIdentifier addressIdentifier = new UserIdentifier()
{
    AddressInfo = new OfflineUserAddressInfo()
    {
        HashedFirstName = NormalizeAndHash("Dana"),
        HashedLastName = NormalizeAndHash("Quinn"),
        HashedStreetAddress = NormalizeAndHash("1600 Amphitheatre Pkwy"),
        City = "Mountain View",
        State = "CA",
        PostalCode = "94043",
        CountryCode = "US"
    },
    // Optional: Specifies the user identifier source.
    UserIdentifierSource = UserIdentifierSource.FirstParty
};

// Creates a user identifier using the hashed email address.
UserIdentifier emailIdentifier = new UserIdentifier()
{
    UserIdentifierSource = UserIdentifierSource.FirstParty,
    // Uses the normalize and hash method specifically for email addresses.
    HashedEmail = NormalizeAndHashEmailAddress("dana@example.com")
};

// Adds the user identifiers to the enhancement adjustment.
enhancement.UserIdentifiers.AddRange(new[] { addressIdentifier, emailIdentifier });
      

PHP

// Creates the conversion enhancement.
$enhancement =
    new ConversionAdjustment(['adjustment_type' => ConversionAdjustmentType::ENHANCEMENT]);

// Extracts user email, phone, and address info 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.
//
// $incorrectlyPopulatedUserIdentifier = new UserIdentifier([
//    'hashed_email' => '...',
//    'hashed_phone_number' => '...'
// ]);

$rawRecord = [
    // Email address that includes a period (.) before the Gmail domain.
    'email' => 'alex.2@example.com',
    // Address that includes all four required elements: first name, last name, country
    // code, and postal code.
    'firstName' => 'Alex',
    'lastName' => 'Quinn',
    'countryCode' => 'US',
    'postalCode' => '94045',
    // 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,
    'conversionActionId' => $conversionActionId,
    'conversionDateTime' => $conversionDateTime,
    'currencyCode' => 'USD'
];

// 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;
}

// Checks if the record has all the required mailing address elements, and if so, adds a
// UserIdentifier for the mailing address.
if (array_key_exists('firstName', $rawRecord)) {
    // Checks if the record contains all the other required elements of a mailing
    // address.
    $missingAddressKeys = [];
    foreach (['lastName', 'countryCode', 'postalCode'] as $addressKey) {
        if (!array_key_exists($addressKey, $rawRecord)) {
            $missingAddressKeys[] = $addressKey;
        }
    }
    if (!empty($missingAddressKeys)) {
        printf(
            "Skipping addition of mailing address information because the "
            . "following required keys are missing: %s%s",
            json_encode($missingAddressKeys),
            PHP_EOL
        );
    } else {
        // Creates an OfflineUserAddressInfo object that contains all the required
        // elements of a mailing address.
        $addressIdentifier = new UserIdentifier([
            'address_info' => new OfflineUserAddressInfo([
                'hashed_first_name' => self::normalizeAndHash(
                    $hashAlgorithm,
                    $rawRecord['firstName'],
                    false
                ),
                'hashed_last_name' => self::normalizeAndHash(
                    $hashAlgorithm,
                    $rawRecord['lastName'],
                    false
                ),
                'country_code' => $rawRecord['countryCode'],
                'postal_code' => $rawRecord['postalCode']
            ])
        ]);
        // Adds the address identifier to the user identifiers list.
        $userIdentifiers[] = $addressIdentifier;
    }
}

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

Python

# Extracts user email, phone, and address info 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 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": "alex.2@example.com",
    # Address that includes all four required elements: first name, last
    # name, country code, and postal code.
    "first_name": "Alex",
    "last_name": "Quinn",
    "country_code": "US",
    "postal_code": "94045",
    # 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,
    "conversion_action_id": conversion_action_id,
    "conversion_date_time": conversion_date_time,
    "currency_code": "USD",
    "user_agent": user_agent,
}

# Constructs the enhancement adjustment.
conversion_adjustment = client.get_type("ConversionAdjustment")
conversion_adjustment.adjustment_type = (
    client.enums.ConversionAdjustmentTypeEnum.ENHANCEMENT
)

# 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 email identifier to the conversion adjustment.
conversion_adjustment.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.
    conversion_adjustment.user_identifiers.append(phone_identifier)

# Checks if the record has all the required mailing address elements, and if
# so, adds a UserIdentifier for the mailing address.
if raw_record.get("first_name") is not None:
    # Checks if the record contains all the other required elements of a
    # mailing address.
    required_keys = ["last_name", "country_code", "postal_code"]
    # Builds a new list of the required keys that are missing from
    # raw_record.
    missing_keys = [
        key for key in required_keys if key not in raw_record.keys()
    ]
    if len(missing_keys) > 0:
        print(
            "Skipping addition of mailing address information because the"
            f"following required keys are missing: {missing_keys}"
        )
    else:
        # Creates a user identifier using sample values for the user address,
        # hashing where required.
        address_identifier = client.get_type("UserIdentifier")
        address_info = address_identifier.address_info
        address_info.hashed_first_name = normalize_and_hash(
            raw_record["first_name"]
        )
        address_info.hashed_last_name = normalize_and_hash(
            raw_record["last_name"]
        )
        address_info.country_code = raw_record["country_code"]
        address_info.postal_code = raw_record["postal_code"]
        # Adds the address identifier to the conversion adjustment.
        conversion_adjustment.user_identifiers.append(address_identifier)
      

Ruby

# Extracts user email, phone, and address info 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 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" => "alex.2@example.com",
    # Address that includes all four required elements: first name, last
    # name, country code, and postal code.
    "first_name" => "Alex",
    "last_name" => "Quinn",
    "country_code" => "US",
    "postal_code" => "94045",
    # 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,
    "conversion_action_id" => conversion_action_id,
    "conversion_date_time" => conversion_date_time,
    "currency_code" => "USD",
    "user_agent" => user_agent,
}

enhancement = client.resource.conversion_adjustment do |ca|
  ca.conversion_action = client.path.conversion_action(customer_id, conversion_action_id)
  ca.adjustment_type = :ENHANCEMENT
  ca.order_id = order_id

  # Sets the conversion date and time if provided. Providing this value is
  # optional but recommended.
  unless conversion_date_time.nil?
    ca.gclid_date_time_pair = client.resource.gclid_date_time_pair do |pair|
      pair.conversion_date_time = conversion_date_time
    end
  end

  # Creates a user identifier using the hashed email address, using the
  # normalize and hash method specifically for email addresses.
  ca.user_identifiers << client.resource.user_identifier do |ui|
    # Uses the normalize and hash method specifically for email addresses.
    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?
    ca.user_identifiers << client.resource.user_identifier do |ui|
      ui.hashed_phone_number = normalize_and_hash_email(raw_record["phone"])
    end
  end

  # Checks if the record has all the required mailing address elements, and if
  # so, adds a UserIdentifier for the mailing address.
  unless raw_record["first_name"].nil?
    # Checks if the record contains all the other required elements of a
    # mailing address.
    required_keys = ["last_name", "country_code", "postal_code"]
    # Builds a new list of the required keys that are missing from
    # raw_record.
    missing_keys = required_keys - raw_record.keys
    if missing_keys
        puts(
            "Skipping addition of mailing address information because the" \
            "following required keys are missing: #{missing_keys}"
        )
    else
      ca.user_identifiers << client.resource.user_identifier do |ui|
        ui.address_info = client.resource.offline_user_address_info do |info|
          # Certain fields must be hashed using SHA256 in order to handle
          # identifiers in a privacy-safe way, as described at
          # https://support.google.com/google-ads/answer/9888656.
          info.hashed_first_name = normalize_and_hash( raw_record["first_name"])
          info.hashed_last_name = normalize_and_hash( raw_record["last_name"])
          info.postal_code = normalize_and_hash(raw_record["country_code"])
          info.country_code = normalize_and_hash(raw_record["postal_code"])
        end
      end
    end
  end
      

Perl

# Construct the enhancement adjustment.
my $enhancement =
  Google::Ads::GoogleAds::V20::Services::ConversionAdjustmentUploadService::ConversionAdjustment
  ->new({
    adjustmentType => ENHANCEMENT
  });

# Extract user email, phone, and address info 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::V20::Common::UserIdentifier->new({
#   hashedEmail => '...',
#   hashedPhoneNumber => '...',
# });
my $raw_record = {
  # Email address that includes a period (.) before the Gmail domain.
  email => 'alex.2@example.com',
  # Address that includes all four required elements: first name, last
  # name, country code, and postal code.
  firstName   => 'Alex',
  lastName    => 'Quinn',
  countryCode => 'US',
  postalCode  => '94045',
  # 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,
  conversionActionId => $conversion_action_id,
  conversionDateTime => $conversion_date_time,
  currencyCode       => "USD",
  userAgent          => $user_agent,
};
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::V20::Common::UserIdentifier->new({
      hashedEmail => $hashed_email,
      # Optional: Specify the user identifier source.
      userIdentifierSource => FIRST_PARTY
    }));

# Check if the record has a phone number, and if so, add a UserIdentifier for it.
if (defined $raw_record->{phone}) {
  # Add the hashed phone number identifier to the list of UserIdentifiers.
  push(
    @$user_identifiers,
    Google::Ads::GoogleAds::V20::Common::UserIdentifier->new({
        hashedPhoneNumber => normalize_and_hash($raw_record->{phone}, 1)}));
}

# Confirm the record has all the required mailing address elements, and if so, add
# a UserIdentifier for the mailing address.
if (defined $raw_record->{firstName}) {
  my $required_keys = ["lastName", "countryCode", "postalCode"];
  my $missing_keys  = [];

  foreach my $key (@$required_keys) {
    if (!defined $raw_record->{$key}) {
      push(@$missing_keys, $key);
    }
  }

  if (@$missing_keys) {
    print
      "Skipping addition of mailing address information because the following"
      . "keys are missing: "
      . join(",", @$missing_keys);
  } else {
    push(
      @$user_identifiers,
      Google::Ads::GoogleAds::V20::Common::UserIdentifier->new({
          addressInfo =>
            Google::Ads::GoogleAds::V20::Common::OfflineUserAddressInfo->new({
              # First and last name must be normalized and hashed.
              hashedFirstName => normalize_and_hash($raw_record->{firstName}),
              hashedLastName  => normalize_and_hash($raw_record->{lastName}),
              # Country code and zip code are sent in plain text.
              countryCode => $raw_record->{countryCode},
              postalCode  => $raw_record->{postalCode},
            })}));
  }
}

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

  • 请务必将 order_id 设置为要调整的转化的订单 ID,该 ID 应与代码发送的订单 ID 一致。

  • adjustment_type 设置为 ENHANCEMENT

  • conversion_action 设置为 ConversionAction 的资源名称,typeWEBPAGE

  • (可选)如果可能,请填充 gclid_date_time_pair,以便获得最准确的衡量结果。将 conversion_date_time 设置为具有指定 order_id 的转化发生的日期和时间。包含时区偏移量,并使用 yyyy-mm-dd HH:mm:ss+|-HH:mm 格式,例如:2022-01-01 19:32:45-05:00(忽略夏令时)。

  • (可选)将 user_agent 设置为发送原始转化的请求的用户代理,以便将转化及其增强型转化都归因于同一设备或跨设备。

Java

// Sets the conversion action.
enhancementBuilder.setConversionAction(
    ResourceNames.conversionAction(
        customerId, Long.parseLong(rawRecord.get("conversionActionId"))));

// Sets the order ID. Enhancements MUST use order ID instead of GCLID date/time pair.
enhancementBuilder.setOrderId(rawRecord.get("orderId"));

// Sets the conversion date and time if provided. Providing this value is optional but
// recommended.
if (rawRecord.containsKey("conversionDateTime")) {
  enhancementBuilder.setGclidDateTimePair(
      GclidDateTimePair.newBuilder()
          .setConversionDateTime(rawRecord.get("conversionDateTime")));
}

// Sets the user agent if provided. This should match the user agent of the request that sent
// the original conversion so the conversion and its enhancement are either both attributed as
// same-device or both attributed as cross-device.
if (rawRecord.containsKey("userAgent")) {
  enhancementBuilder.setUserAgent(rawRecord.get("userAgent"));
}
      

C#

// Set the conversion action.
enhancement.ConversionAction =
    ResourceNames.ConversionAction(customerId, conversionActionId);

// Set the order ID. Enhancements MUST use order ID instead of GCLID date/time pair.
enhancement.OrderId = orderId;

// Sets the conversion date and time if provided. Providing this value is optional but
// recommended.
if (string.IsNullOrEmpty(conversionDateTime))
{
    enhancement.GclidDateTimePair = new GclidDateTimePair()
    {
        ConversionDateTime = conversionDateTime
    };
}

// Sets optional fields where a value was provided.
if (!string.IsNullOrEmpty(userAgent))
{
    // Sets the user agent. This should match the user agent of the request that
    // sent the original conversion so the conversion and its enhancement are either
    // both attributed as same-device or both attributed as cross-device.
    enhancement.UserAgent = userAgent;
}

      

PHP

// Sets the conversion action.
$enhancement->setConversionAction(
    ResourceNames::forConversionAction($customerId, $rawRecord['conversionActionId'])
);

// Sets the order ID. Enhancements MUST use order ID instead of GCLID date/time pair.
if (!empty($rawRecord['orderId'])) {
    $enhancement->setOrderId($rawRecord['orderId']);
}

// Sets the conversion date and time if provided. Providing this value is optional but
// recommended.
if (!empty($rawRecord['conversionDateTime'])) {
    // Sets the conversion date and time if provided. Providing this value is optional but
    // recommended.
    $enhancement->setGclidDateTimePair(new GclidDateTimePair([
        'conversion_date_time' => $rawRecord['conversionDateTime']
    ]));
}

// Sets the user agent if provided. This should match the user agent of the request that
// sent the original conversion so the conversion and its enhancement are either both
// attributed as same-device or both attributed as cross-device.
if (!empty($rawRecord['userAgent'])) {
    $enhancement->setUserAgent($rawRecord['userAgent']);
}
      

Python

conversion_action_service = client.get_service("ConversionActionService")
# Sets the conversion action.
conversion_adjustment.conversion_action = (
    conversion_action_service.conversion_action_path(
        customer_id, raw_record["conversion_action_id"]
    )
)

# Sets the order ID. Enhancements MUST use order ID instead of GCLID
# date/time pair.
conversion_adjustment.order_id = order_id

# Sets the conversion date and time if provided. Providing this value is
# optional but recommended.
if raw_record.get("conversion_date_time"):
    conversion_adjustment.gclid_date_time_pair.conversion_date_time = (
        raw_record["conversion_date_time"]
    )

# Sets optional fields where a value was provided
if raw_record.get("user_agent"):
    # Sets the user agent. This should match the user agent of the request
    # that sent the original conversion so the conversion and its
    # enhancement are either both attributed as same-device or both
    # attributed as cross-device.
    conversion_adjustment.user_agent = user_agent
      

Ruby

ca.conversion_action = client.path.conversion_action(customer_id, conversion_action_id)
ca.adjustment_type = :ENHANCEMENT
ca.order_id = order_id

# Sets the conversion date and time if provided. Providing this value is
# optional but recommended.
unless conversion_date_time.nil?
  ca.gclid_date_time_pair = client.resource.gclid_date_time_pair do |pair|
    pair.conversion_date_time = conversion_date_time
  end
end

# Creates a user identifier using the hashed email address, using the
# normalize and hash method specifically for email addresses.
ca.user_identifiers << client.resource.user_identifier do |ui|
  # Uses the normalize and hash method specifically for email addresses.
  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?
  ca.user_identifiers << client.resource.user_identifier do |ui|
    ui.hashed_phone_number = normalize_and_hash_email(raw_record["phone"])
  end
end

# Checks if the record has all the required mailing address elements, and if
# so, adds a UserIdentifier for the mailing address.
unless raw_record["first_name"].nil?
  # Checks if the record contains all the other required elements of a
  # mailing address.
  required_keys = ["last_name", "country_code", "postal_code"]
  # Builds a new list of the required keys that are missing from
  # raw_record.
  missing_keys = required_keys - raw_record.keys
  if missing_keys
      puts(
          "Skipping addition of mailing address information because the" \
          "following required keys are missing: #{missing_keys}"
      )
  else
    ca.user_identifiers << client.resource.user_identifier do |ui|
      ui.address_info = client.resource.offline_user_address_info do |info|
        # Certain fields must be hashed using SHA256 in order to handle
        # identifiers in a privacy-safe way, as described at
        # https://support.google.com/google-ads/answer/9888656.
        info.hashed_first_name = normalize_and_hash( raw_record["first_name"])
        info.hashed_last_name = normalize_and_hash( raw_record["last_name"])
        info.postal_code = normalize_and_hash(raw_record["country_code"])
        info.country_code = normalize_and_hash(raw_record["postal_code"])
      end
    end
  end
end

# Sets optional fields where a value was provided.
unless user_agent.nil?
  # Sets the user agent. This should match the user agent of the request
  # that sent the original conversion so the conversion and its enhancement
  # are either both attributed as same-device or both attributed as
  # cross-device.
  ca.user_agent = user_agent
end
      

Perl

# Set the conversion action.
$enhancement->{conversionAction} =
  Google::Ads::GoogleAds::V20::Utils::ResourceNames::conversion_action(
  $customer_id, $raw_record->{conversionActionId});

# Set the order ID. Enhancements MUST use order ID instead of GCLID date/time pair.
$enhancement->{orderId} = $raw_record->{orderId};

# Set the conversion date and time if provided. Providing this value is optional
# but recommended.
if (defined $raw_record->{conversionDateTime}) {
  $enhancement->{gclidDateTimePair} =
    Google::Ads::GoogleAds::V20::Services::ConversionAdjustmentUploadService::GclidDateTimePair
    ->new({
      conversionDateTime => $raw_record->{conversionDateTime}});
}

# Set the user agent if provided. This should match the user agent of the
# request that sent the original conversion so the conversion and its enhancement
# are either both attributed as same-device or both attributed as cross-device.
if (defined $raw_record->{userAgent}) {
  $enhancement->{userAgent} = $raw_record->{userAgent};
}
      

导入转化数据增强功能

Java

// Creates the conversion adjustment upload service client.
try (ConversionAdjustmentUploadServiceClient conversionUploadServiceClient =
    googleAdsClient.getLatestVersion().createConversionAdjustmentUploadServiceClient()) {
  // Uploads the enhancement adjustment. Partial failure should always be set to true.

  // NOTE: This request contains a single adjustment as a demonstration. However, if you have
  // multiple adjustments to upload, it's best to upload multiple adjustments per request
  // instead of sending a separate request per adjustment. See the following for per-request
  // limits:
  // https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_adjustment_upload_service
  UploadConversionAdjustmentsResponse response =
      conversionUploadServiceClient.uploadConversionAdjustments(
          UploadConversionAdjustmentsRequest.newBuilder()
              .setCustomerId(Long.toString(customerId))
              .addConversionAdjustments(enhancementBuilder)
              // Enables partial failure (must be true).
              .setPartialFailure(true)
              .build());
      

C#

// Uploads the enhancement adjustment. Partial failure should always be set to true.
//
// NOTE: This request contains a single adjustment as a demonstration.
// However, if you have multiple adjustments to upload, it's best to upload
// multiple adjustmenst per request instead of sending a separate request per
// adjustment. See the following for per-request limits:
// https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_adjust
UploadConversionAdjustmentsResponse response =
    conversionAdjustmentUploadService.UploadConversionAdjustments(
        new UploadConversionAdjustmentsRequest()
        {
            CustomerId = customerId.ToString(),
            ConversionAdjustments = { enhancement },
            // Enables partial failure (must be true).
            PartialFailure = true,
        });
      

PHP

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

Python

# Creates the conversion adjustment upload service client.
conversion_adjustment_upload_service = client.get_service(
    "ConversionAdjustmentUploadService"
)
# Uploads the enhancement adjustment. 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 still best 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_adjustment_upload_service.upload_conversion_adjustments(
    customer_id=customer_id,
    conversion_adjustments=[conversion_adjustment],
    # Enables partial failure (must be true).
    partial_failure=True,
)
      

Ruby

response = client.service.conversion_adjustment_upload.upload_conversion_adjustments(
  customer_id: customer_id,
  # NOTE: This request only uploads a single conversion, but if you have
  # multiple conversions to upload, it's still best 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
  conversion_adjustments: [enhancement],
  # Partial failure must be set to true.
  partial_failure: true,
)
      

Perl

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

查看导入内容

您可以使用增强型转化 API 诊断报告来验证增强型网站转化是否在有效运行,以及诊断设置中存在的问题。

使用线下数据诊断可查看近期导入数据的整体运行状况。

在报告广告系列的转化指标时,请参阅映射界面指标,将 Google Ads 界面指标与 Google Ads API 报告字段相关联。您还可以查询 conversion_action 资源,查看指定转化操作的总转化次数和总转化价值。

最佳做法

在为网站实现增强型转化时,请牢记以下最佳实践。

检查客户标识符

导入转化数据时,客户 ID 必须设置为包含转化操作并进行转化跟踪的账号。如需检查此设置,请查询相应 ConversionTrackingSetting 的广告投放 Google Ads Customer 资源。使用 GoogleAdsService.SearchStream 发出以下查询,以查找 customer.conversion_tracking_setting.google_ads_conversion_customer 的值。

SELECT
  customer.conversion_tracking_setting.google_ads_conversion_customer,
  customer.conversion_tracking_setting.conversion_tracking_status,
  customer.conversion_tracking_setting.conversion_tracking_id,
  customer.conversion_tracking_setting.cross_account_conversion_tracking_id
FROM customer

在请求中将 customer_id 设为 google_ads_conversion_customer 值,以导入转化。

添加多个标识符(如果有)

如果您有转化的 gclid,我们建议您除了发送 user_identifiers 之外,还发送 gclid,以便提升效果。此外,如果您为转化设置了多个 UserIdentifier,则添加所有这些 UserIdentifier 可以提高匹配的可能性。在同一 ConversionAdjustment 中包含所有标识符。

查看设置集成时出现的部分失败错误

首次设置增强型网站转化集成时,请检查响应中的 partial_failure_error 字段,并解决其中的任何部分错误。如果您的设置存在问题,您可以检查此字段以进行调查并解决问题。如需详细了解与部分失败错误处理相关的示例,请参阅专门的部分失败指南

解决出现在“部分失败”错误中的所有问题并完成集成后,请改用线下数据诊断定期检查转化的健康状况。

在单个请求中批量处理多个调整

如果您要导入多个调整,请将这些操作批量到一个 UploadConversionAdjustmentsRequest 中,而不是针对每个调整发送一个导入请求。

请参阅配额指南,了解每次请求的调整次数限制。如果您希望离线数据诊断将一组请求归为一项逻辑作业,请将所有请求的 job_id 设置为相同的值。

问题排查

您可以使用增强型转化 API 诊断报告来验证增强型网站转化是否在有效运行,以及诊断设置中存在的问题。

调试常见错误

错误
CONVERSION_NOT_FOUND 找不到所提供的转化操作和转化标识符对或 order_id 对应的转化数据。验证相应转化是否为请求的 customer_id 中指定的 Google Ads 转化客户的 Google Ads 转化。
此外,请验证转化不是来自于填充了 gbraid wbraid(而非 gclid)的点击。 Google Ads 不支持针对这些转化使用增强型网站转化。
CUSTOMER_NOT_ACCEPTED_CUSTOMER_DATA_TERMS 请求的customer_id尚未接受客户数据条款及条件。如需了解相关说明,请参阅前提条件指南。
CONVERSION_ALREADY_ENHANCED 此转化已收到使用给定 order_idconversion_action 进行的调整。请务必为每次转化提供唯一的 order_id
CONVERSION_ACTION_NOT_ELIGIBLE_FOR_ENHANCEMENT 您提供的 conversion_action 不符合使用增强型网站转化的条件。在 Google Ads 界面中,请务必勾选您在请求中提及的转化操作的启用增强型转化复选框。如需了解相关说明,请访问帮助中心