Erweiterte Conversions

Die CM360 Offline-Conversion API unterstützt die Anreicherung von Website-Tag-basierten Conversions mit Nutzer-IDs.

Erweiterte Conversions

  • Akzeptieren Sie die Nutzungsbedingungen für erweiterte Conversions für Ihre Floodlight-Konfiguration in CM360.
  • Implementieren Sie die Abgleichs-ID auf Ihren Websites.
  • Floodlight-Conversions auf Ihrer Website erfassen Achten Sie darauf, dass Sie alle folgenden Informationen aufzeichnen, da sie in nachfolgenden API-Aufrufen Pflichtfelder sind:
    • matchId
    • ordinal
    • timestampMicros
    • floodlightActivityId
    • floodlightConfigurationId
    • quantity
    • value
  • Rufen Sie 90 Minuten nach der Erfassung der Conversion durch das Online-Tag conversions.batchupdate auf, um diese Conversions mit Nutzer-IDs zu optimieren.
    • Nutzerkennungen müssen formatiert und gehasht und dem Feld userIdentifiers in Conversion-Objekten hinzugefügt werden.
    • Menge und Wert müssen angegeben werden. Sie können die Menge und den Wert der Conversion optional im selben conversions.batchupdate-Aufruf anpassen oder die ursprüngliche Menge und den ursprünglichen Wert angeben.
    • Jeder Batch mit Einfügungen und Aktualisierungen kann eine Mischung aus Erfolgen und Fehlern enthalten. Bei NOT_FOUND-Fehlern sollten Sie es noch einmal versuchen, falls es bei der Verarbeitung von Conversions zu einer längeren als üblichen Verzögerung von bis zu sechs Stunden kommt.
    • Conversions müssen innerhalb von 24 Stunden nach der Erfassung durch Online-Tags mit Nutzer-IDs angereichert werden.

Normalisierung und Hashing

Zum Schutz der Privatsphäre müssen E-Mail-Adressen, Telefonnummern, Vor- und Nachnamen sowie Adressen mit dem SHA-256-Algorithmus gehasht werden, bevor sie hochgeladen werden. Um die Hash-Ergebnisse zu standardisieren, müssen Sie vor dem Hashen eines dieser Werte Folgendes tun:

  • Entfernen Sie Leerzeichen am Anfang und Ende.
  • Verwenden Sie nur Kleinbuchstaben im Text.
  • Formatieren Sie Telefonnummern gemäß E164-Standard.
  • Entfernen Sie alle Punkte (.) vor dem Domainnamen in gmail.com- und googlemail.com-E-Mail-Adressen.

C#

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

Java

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

Python

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()

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

Conversions Nutzer-IDs hinzufügen

Bereiten Sie zuerst das Conversion-Objekt wie gewohnt zum Hochladen oder Bearbeiten vor und hängen Sie dann die Nutzer-ID an:

{
  "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"
      }
    }
  ]
}

Eine erfolgreiche Antwort sollte so aussehen:

{
  "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"
    }
  ]
}

Häufige Fehler

Hier sind einige Fehler, die beim Erweitern einer Conversion mit Nutzer-IDs auftreten können:

Das Feld „hashed_X“ ist kein gültiger SHA-256-Hashwert
Für alle Felder mit dem Präfix „hashed“ sind nur SHA-256-Hashes zulässig, die hexadezimal codiert sind.
Das Feld „country_code“ hat die falsche Länge.
country_code muss genau zwei Buchstaben umfassen.
Die Nutzungsbedingungen für erweiterte Conversions wurden für die Floodlight-Konfiguration nicht unterzeichnet.
Die Nutzungsbedingungen für erweiterte Conversions wurden für die Floodlight-Konfigurations-ID der Anfrage nicht akzeptiert.
Mehr als fünf user_identifiers angegeben
Eine Conversion kann maximal fünf Nutzer-IDs haben.

Häufig gestellte Fragen

Warum wird die Match-ID empfohlen?
Bei Änderungen auf Grundlage von Klick-IDs werden Conversions ausgeschlossen, die nicht auf einen Klick zurückzuführen sind. Das schränkt den Wert der Einbindung erweiterter Conversions ein.
Warum sollten Menge und Wert erfasst werden?
Für die CM360 Offline Conversions API müssen Menge und Wert angegeben werden.
Muss ich den von Google aufgezeichneten Zeitstempel auf Mikrosekundenebene abrufen, um eine Tag-basierte Online-Conversion zu bearbeiten?
Bei Änderungen, die auf der Match-ID basieren, akzeptiert die API jetzt eine Änderung, solange der in der Anfrage angegebene Zeitstempel innerhalb von einer Minute nach dem von Google aufgezeichneten Zeitstempel liegt.
Warum muss ich 90 Minuten warten, nachdem eine Conversion von einem Online-Tag erfasst wurde, bevor ich sie optimieren kann?
Es kann bis zu 90 Minuten dauern, bis die Online-Conversion von der API indexiert wird und für Änderungen verfügbar ist.
Worauf sollte ich bei der API-Antwort achten?
Auch wenn die CM360 Conversion API eine erfolgreiche Antwort zurückgibt, konnten einige einzelne Conversions möglicherweise nicht hochgeladen oder aktualisiert werden. Prüfen Sie die einzelnen ConversionStatus-Felder auf Fehler:
  • NOT_FOUND-Fehler können und sollten bis zu 6 Stunden lang wiederholt werden, falls es zu einer längeren als üblichen Verzögerung bei der Verarbeitung von Conversions kommt. Häufig gestellte Fragen dazu, warum NOT_FOUND-Fehler länger als 6 Stunden bestehen können.
  • Bei INVALID_ARGUMENT- und PERMISSION_DENIED-Fehlern sollten keine Wiederholungsversuche unternommen werden.