Erweiterte Conversions

Die CM360 API für Offline-Conversions unterstützt das Anreichern 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.
  • Instrumentieren Sie Ihre Websites mit der ID zum Abgleich.
  • Floodlight-Conversions auf Ihrer Website erfassen Notieren Sie sich alle folgenden Angaben, da sie in nachfolgenden API-Aufrufen als Pflichtfelder erforderlich sind:
    • matchId
    • ordinal
    • timestampMicros
    • floodlightActivityId
    • floodlightConfigurationId
    • quantity
    • value
  • Rufen Sie 90 Minuten, nachdem das Online-Tag die Conversion erfasst hat, conversions.batchupdate auf, um diese Conversions mit Nutzer-IDs zu erweitern.
    • Nutzer-IDs müssen formatiert und gehasht und dem Feld userIdentifiers in Conversion-Objekten hinzugefügt werden.
    • Menge und Wert müssen angegeben werden. Optional können Sie die Menge und den Wert der Conversion im selben conversions.batchupdate-Aufruf anpassen oder die ursprüngliche Menge und den ursprünglichen Wert angeben.
    • Jeder Batch von Einfügungen und Aktualisierungen kann eine Mischung aus Erfolgen und Fehlern enthalten. Bei NOT_FOUND- und INTERNAL-Fehlern sollte ein erneuter Versuch unternommen werden, falls die Conversion-Verarbeitung länger als üblich dauert (bis zu 6 Stunden).
    • Conversions müssen innerhalb von 24 Stunden nach der Erfassung durch Online-Tags mit Nutzer-IDs erweitert werden.

Normalisierung und Hashing

Aus Datenschutzgründen müssen E-Mail-Adressen, Telefonnummern, Vor- und Nachnamen sowie Adressen vor dem Hochladen mit dem SHA-256-Algorithmus gehasht werden. Um die Hash-Ergebnisse zu standardisieren, müssen Sie vor dem Hashen eines dieser Werte folgende Schritte ausführen:

  • Entfernen Sie Leerzeichen am Anfang und Ende.
  • Verwenden Sie nur Kleinbuchstaben im Text.
  • Formatieren Sie Telefonnummern gemäß E164-Standard. Geben Sie das Pluszeichen (+) und die Landesvorwahl an. Beispielsweise sollte die US-amerikanische Telefonnummer (800)555-0200 als +18005550200 formatiert und normalisiert werden.
  • 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

Nutzer-IDs zu Conversions hinzufügen

Bereiten Sie zuerst das Conversion-Objekt wie gewohnt für das Hochladen oder Bearbeiten vor und hängen Sie dann die Nutzer-ID so 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

Die folgenden Fehler können auftreten, wenn Sie eine Conversion mit Nutzer-IDs optimieren:

Das Feld „hashed_X“ ist kein gültiger SHA-256-Hashwert
Alle Felder mit dem Präfix „hashed“ akzeptieren nur SHA-256-Hashes, die hexadezimal codiert sind.
Das Feld „country_code“ hat die falsche Länge
country_code muss genau zwei Buchstaben enthalten.
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 5 Nutzer-IDs haben.

Häufig gestellte Fragen

Warum wird die ID zum Abgleich empfohlen?
Bei klick-ID-basierten Änderungen werden Conversions ohne vorherigen Klick ausgeschlossen. Dadurch wird der Wert der Einbindung von erweiterten Conversions eingeschränkt.
Warum sollten Menge und Wert erfasst werden?
Bei der CM360 Offline Conversions API müssen Menge und Wert angegeben werden.
Muss ich den genauen, von Google aufgezeichneten Zeitstempel in Mikrosekunden abrufen, um eine tagbasierte Online-Conversion zu bearbeiten?
Bei Bearbeitungen, die auf der ID des Spiels basieren, akzeptiert die API jetzt eine Bearbeitung, solange der in der Anfrage angegebene Zeitstempel innerhalb von 1 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-Konvertierung von der API indexiert wird und für Bearbeitungen verfügbar ist.
Worauf sollte ich in der API-Antwort achten?
Auch wenn die CM360 Conversion API eine erfolgreiche Antwort zurückgibt, kann es sein, dass einige einzelne Conversions nicht hochgeladen oder aktualisiert werden konnten. Prüfen Sie die einzelnen ConversionStatus-Felder auf Fehler:
  • NOT_FOUND- und INTERNAL-Fehler können und sollten bis zu 6 Stunden lang wiederholt werden, falls die Conversion-Verarbeitung länger als üblich dauert.
  • INVALID_ARGUMENT- und PERMISSION_DENIED-Fehler sollten nicht wiederholt werden.
  • Weitere Informationen finden Sie in den FAQs.