Расширенное отслеживание конверсий

API офлайн-конверсии CM360 поддерживает улучшение конверсий на основе тегов веб-сайта с помощью идентификаторов пользователей.

Расширенное преобразование

  • Примите Условия использования расширенного отслеживания конверсий для вашей конфигурации Floodlight в CM360.
  • Инструментируйте свои веб-сайты с помощью идентификатора соответствия .
  • Записывайте конверсии Floodlight, происходящие на вашем сайте. Обязательно запишите все следующие поля, поскольку они являются обязательными полями в последующих вызовах API:
    • matchId
    • ordinal
    • timestampMicros
    • floodlightActivityId
    • floodlightConfigurationId
    • quantity
    • value
  • По прошествии 90 минут с момента регистрации конверсии онлайн-тегом вызовите conversions.batchupdate , чтобы улучшить эти конверсии с помощью идентификаторов пользователей.
    • Идентификаторы пользователей должны быть отформатированы, хешированы и добавлены в поле userIdentifiers объектов Conversion.
    • Необходимо указать количество и стоимость. При желании вы можете настроить количество и ценность конверсии в том же вызове conversions.batchupdate или указать исходное количество и ценность.
    • Каждая партия вставок и обновлений может содержать смесь успехов и неудач. Ошибки NOT_FOUND следует повторить, если задержка обработки преобразования превышает обычную (до 6 часов).
    • Конверсии должны быть дополнены идентификаторами пользователей в течение 24 часов после того, как они будут зафиксированы онлайн-тегами.

Нормализация и хеширование

Чтобы защитить конфиденциальность, адреса электронной почты, номера телефонов, имена, фамилии и почтовые адреса перед загрузкой должны быть хешированы с использованием алгоритма SHA-256. Чтобы стандартизировать результаты хеширования, перед хешированием одного из этих значений необходимо:

  • Удалите начальные или конечные пробелы.
  • Преобразуйте текст в нижний регистр.
  • Форматируйте номера телефонов по стандарту E164 .
  • Удалите все точки (.), стоящие перед именем домена в адресах электронной почты gmail.com и googlemail.com .

С#

/// <summary>
/// Normalizes the email address and hashes it. For this use case, Campaign Manager 360
/// 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();
}

Ява

private String normalizeAndHash(MessageDigest digest, String s)
    throws UnsupportedEncodingException {
  // Normalizes by removing leading and trailing whitespace and converting all characters to
  // lower case.
  String normalized = s.trim().toLowerCase();
  // 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, Campaign Manager 360
 * 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);
}

PHP

private static function normalizeAndHash(string $hashAlgorithm, string $value): string
{
    return hash($hashAlgorithm, strtolower(trim($value)));
}

/**
  * Returns the result of normalizing and hashing an email address. For this use case, Campaign
  * Manager 360 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);
}

Питон

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

    For this use case, Campaign Manager 360 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.lower()
    email_parts = normalized_email.split("@")
    # 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.
    is_gmail = re.match(r"^(gmail|googlemail)\.com$", email_parts[1])

    # Check that there are at least two segments and the second segment
    # matches the above regex expression validating the email domain name.
    if len(email_parts) > 1 and is_gmail:
        # 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()

Руби

# 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 hasing.
  Digest::SHA256.hexdigest(str.strip.downcase)
end

# Returns the result of normalizing and hashing an email address. For this use
# case, Campaign Manager 360 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

Добавьте идентификаторы пользователей в конверсии

Сначала подготовьте объект Conversion для загрузки или редактирования как обычно, затем прикрепите идентификатор пользователя следующим образом:

{
  "matchId": "my-match-id-846513278",
  "ordinal": "my-ordinal-12345678512",
  "quantity": 1,
  "value": 104.23,
  "timestampMicros": 1656950400000000,
  "floodlightConfigurationId": 99999,
  "floodlightActivityId": 8888,
  "userIdentifiers": [
    { "hashedEmail": "0c7e6a405862e402eb76a70f8a26fc732d07c32931e9fae9ab1582911d2e8a3b" },
    { "hashedPhoneNumber": "1fb1f420856780a29719b994c8764b81770d79f97e2e1861ba938a7a5a15dfb9" },
    {
      "addressInfo": {
        "hashedFirstName": "81f8f6dde88365f3928796ec7aa53f72820b06db8664f5fe76a7eb13e24546a2",
        "hashedLastName": "799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f",
        "hashedStreetAddress": "22b7e2d69b91e0ef4a88e81a73d897b92fd9c93ccfbe0a860f77db16c26f662e",
        "city": "seattle",
        "state": "washington",
        "countryCode": "US",
        "postalCode": "98101"
      }
    }
  ]
}

Успешный ответ должен выглядеть так:

{
  "hasFailures": false,
  "status": [
    {
      "conversion": {
        "floodlightConfigurationId": 99999,
        "floodlightActivityId": 8888,
        "timestampMicros": 1656950400000000,
        "value": 104.23,
        "quantity": 1,
        "ordinal": "my-ordinal-12345678512",
        "matchId": "my-match-id-846513278",
        "userIdentifiers": [
          { "hashedEmail": "0c7e6a405862e402eb76a70f8a26fc732d07c32931e9fae9ab1582911d2e8a3b" },
          { "hashedPhoneNumber": "1fb1f420856780a29719b994c8764b81770d79f97e2e1861ba938a7a5a15dfb9" },
          {
            "addressInfo": {
              "hashedFirstName": "81f8f6dde88365f3928796ec7aa53f72820b06db8664f5fe76a7eb13e24546a2",
              "hashedLastName": "799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f",
              "hashedStreetAddress": "22b7e2d69b91e0ef4a88e81a73d897b92fd9c93ccfbe0a860f77db16c26f662e",
              "city": "seattle",
              "state": "washington",
              "countryCode": "US",
              "postalCode": "98101"
            }
          }
        ],
        "kind": "dfareporting#conversion"
      },
      "kind": "dfareporting#conversionStatus"
    }
  ]
}

Распространенные ошибки

Вот некоторые ошибки, которые вы можете увидеть при улучшении конверсии с помощью идентификаторов пользователей:

Поле hashed_X не является допустимым хешем SHA-256.
Все поля с префиксом хэш принимают только хэши SHA-256, закодированные в шестнадцатеричном формате.
Поле Country_code имеет неправильную длину.
country_code должен состоять ровно из двух букв.
Конфигурация Floodlight не подписала Условия использования расширенного преобразования конверсий.
Условия использования расширенного отслеживания конверсий не были приняты для идентификатора конфигурации Floodlight запроса.
Указано более пяти идентификаторов user_identifiers.
Конверсия может иметь не более пяти идентификаторов пользователей.

Часто задаваемые вопросы

Почему рекомендуется использовать идентификатор совпадения?
Редактирование на основе идентификатора клика исключает конверсии, которым не предшествует клик, и ограничивает ценность расширенной интеграции конверсий.
Почему необходимо регистрировать количество и стоимость?
API офлайн-конверсий CM360 требует указания количества и стоимости.
Нужно ли мне получать точную отметку времени в микросекундах, записанную Google, чтобы редактировать онлайн-конверсию на основе тегов?
Для изменений на основе идентификатора соответствия API теперь принимает изменения, если временная метка, указанная в запросе, находится в пределах 1 минуты от временной метки, записанной Google.
Почему мне нужно ждать 90 минут после регистрации конверсии онлайн-тегом, прежде чем ее улучшать?
Чтобы онлайн-конверсия была проиндексирована API и стала доступна для редактирования, может пройти до 90 минут.
На что следует обратить внимание в ответе API?
Даже если API конверсий CM360 возвращает успешный ответ, некоторые отдельные конверсии могли не загрузиться или не обновиться. Проверьте отдельные поля ConversionStatus на наличие сбоев:
  • Ошибки NOT_FOUND можно и нужно повторять до 6 часов, если задержка в обработке преобразования превышает обычную. Также ознакомьтесь с часто задаваемыми вопросами о том, почему ошибки NOT_FOUND могут сохраняться более 6 часов.
  • Ошибки INVALID_ARGUMENT и PERMISSION_DENIED не следует повторять.