Çevrimdışı Dönüşümleri Yönetme

Telefonla veya bir satış temsilcisi aracılığıyla yapılan satışlar gibi çevrimdışı dünyada satışa yol açan reklamları izlemek için Google Ads API'yi kullanarak çevrimdışı dönüşümleri Google Ads'e aktarabilirsiniz.

Dönüşüm verilerini içe aktarmanın avantajlarından tam olarak yararlanmak için dayanıklılığı ve performansı en üst düzeye çıkarmak üzere GCLID'lerden ve kullanıcı tarafından sağlanan verilerden yararlanan potansiyel müşteriler için gelişmiş dönüşümleri uygulamanızı öneririz.

Gelişmiş dönüşümler

Gelişmiş dönüşümler, dönüşümlerinizi e-posta adresi, ad, ev adresi ve telefon numarası gibi birinci taraf dönüşüm verileriyle destekleyerek dönüşüm ölçümünüzün doğruluğunu artırmanıza yardımcı olur.

İki tür gelişmiş dönüşüm vardır. Daha fazla bilgi için Gelişmiş dönüşümler hakkında başlıklı Yardım Merkezi makalesine bakın.

Aşağıdaki bölümde, çevrimdışı dönüşümlerin nasıl iyileştirileceği açıklanmaktadır. Bu özellik, potansiyel müşteriler için gelişmiş dönüşümler olarak da bilinir.

Potansiyel müşteriler için gelişmiş dönüşümler nedir?

Potansiyel müşteriler için gelişmiş dönüşümler, çevrimdışı dönüşümleri içe aktarma özelliğinin gelişmiş bir sürümüdür. Bu sürümde, ölçümlerin doğruluk düzeyini ve teklif performansını iyileştirmek amacıyla içe aktarılan çevrimdışı dönüşüm verilerini tamamlamak için kullanıcı tarafından sağlanan veriler (ör. e-posta adresleri) kullanılır. Çevrimdışı dönüşümlerinizi içe aktardığınızda, sağlanan karma oluşturma işlemi uygulanmış müşteri verileri, web sitenizde toplanan aynı verilerle (ör. potansiyel müşteri formu) ve reklamınızla etkileşimde bulunan oturum açmış müşterilerle eşleştirilerek Google Ads kampanyasıyla ilişkilendirilir. Potansiyel müşteriler için gelişmiş dönüşümlerin işleyiş şekli hakkında daha fazla bilgi edinmek için Potansiyel müşteriler için gelişmiş dönüşümler hakkında başlıklı makalemizi inceleyin.

Potansiyel müşteriler için gelişmiş dönüşümleri uygulamak için iki yöntem vardır. Bu yöntemler, web sayfanızdaki form gönderme etkinliklerini izlemek için Google etiketini kullanıp kullanmadığınıza bağlıdır. En iyi performans ve dayanıklılık için potansiyel müşteriler için gelişmiş dönüşümlerde Google etiketini kullanmanızı önemle tavsiye ederiz.

  • Sıfırdan başlıyorsanız Ön koşullar bölümüyle başlayın.
  • Çevrimdışı dönüşüm içe aktarma özelliğini zaten ayarladıysanız ve potansiyel müşteriler için gelişmiş dönüşümlere geçmek istiyorsanız Etiketlemeyi yapılandırma bölümünden başlamanızı öneririz.
  • Google etiketini zaten ayarladıysanız veya Google etiketini kullanmayı planlamıyorsanız ve Google Ads API entegrasyonunuz üzerinde çalışmaya başlıyorsanız API Uygulaması bölümüne geçin.
  • Kullanıcı tarafından sağlanan verileri içe aktaramıyorsanız veya dönüşümleriniz için harici ilişkilendirmeye güveniyorsanız Eski Çevrimdışı Dönüşüm İçe Aktarma Kılavuzu'na bakın.

Ön koşullar

Öncelikle Başlarken bölümündeki adımları tamamladığınızdan emin olun.

Potansiyel müşteriler için gelişmiş dönüşümleri kullanabilmek üzere potansiyel müşteriler için gelişmiş dönüşümleri etkinleştirmeniz ve müşteri verisi şartlarını kabul etmeniz gerekir. Google Ads dönüşüm müşterisine aşağıdaki sorguyu göndererek bu ön koşulların karşılanıp karşılanmadığını doğrulayabilirsiniz:

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

accepted_customer_data_terms veya enhanced_conversions_for_leads_enabled seçeneklerinden biri false ise bu ön koşulları tamamlamak için Yardım Merkezi'ndeki talimatları uygulayın.

Etiketlemeyi yapılandırma

Yardım Merkezi'ndeki talimatları uygulayarak Google etiketini potansiyel müşteriler için gelişmiş dönüşümleri etkinleştirecek şekilde yapılandırın. Google Etiket Yöneticisi'ni kullanarak potansiyel müşteriler için gelişmiş dönüşümleri ayarlamak üzere bu talimatları uygulayın.

API Uygulaması

Google Ads API'yi kullanarak potansiyel müşteriler için gelişmiş dönüşümleri içe aktarmaya ilişkin genel akışı aşağıda bulabilirsiniz.

  1. E-posta adresi, telefon numarası ve posta adresi gibi kullanıcı tarafından sağlanan verileri normalleştirin ve bu verilere karma oluşturma işlemi uygulayın.

  2. ClickConversion nesnelerini normalleştirilmiş ve karma oluşturma işlemi uygulanmış kullanıcı tarafından sağlanan verilerle doldurun.

  3. ClickConversion nesnelerini ConversionUploadService kullanarak Google Ads API'ye aktarın.

  4. İçe aktarma işlemlerinizi inceleyin.

Kullanıcı tarafından sağlanan verileri normalleştirme ve karma oluşturma işlemi uygulama

Gizlilik nedeniyle, aşağıdaki veriler içe aktarılmadan önce SHA-256 kullanılarak anonimleştirilmelidir (hashed):

  • E-posta adresi
  • Telefon numarası
  • Ad
  • Soyadı
  • Açık adres

Anonimleştirme (hash) sonuçlarını standart hale getirmek için bu değerleri anonimleştirmeden (hash) önce şunları yapmanız gerekir:

  • Baştaki ve sondaki boşlukları kaldırın.
  • Metni küçük harfe dönüştürün.
  • Telefon numaralarını E164 standardına göre biçimlendirin.
  • gmail.com ve googlemail.com e-posta adreslerinde alan adından önce gelen tüm noktaları (.) kaldırın.

Aşağıdaki verileri anonimleştirmeyin (karma oluşturma):

  • Ülke
  • Eyalet
  • Şehir
  • Posta kodu

Kod örneği

Bu örnekte, kullanıcı tarafından sağlanan verilerin nasıl normalleştirileceği ve karma oluşturma işlemi uygulanacağı gösterilmektedir.

Java

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

  return result.toString();
}

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

C#

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

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

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

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

PHP

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

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

Python

def normalize_and_hash_email_address(email_address: str) -> str:
    """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: str = email_address.strip().lower()
    email_parts: list[str] = 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: str) -> str:
    """Normalizes and hashes a string with SHA-256.

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

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

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

Ruby

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

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

Perl

sub normalize_and_hash {
  my $value = shift;

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

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

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

ClickConversion nesnelerini doldurma

UploadClickConversionRequest içindeki ClickConversion nesnelerinin koleksiyonu, içe aktarmak istediğiniz dönüşümler grubunu temsil eder. ClickConversion nesneleri oluştururken aşağıdaki ayrıntıları göz önünde bulundurun:

gclid

GCLID'ler, bir kullanıcı reklamınızı tıklayıp web sitenize gittiğinde URL parametrelerinden yakalanan tıklama tanımlayıcılarıdır.

user_identifiers

Potansiyel müşteriler için gelişmiş dönüşümleri kullanırken alanını, kullanıcı tarafından sağlanan normalleştirilmiş ve karma oluşturma işlemi uygulanmış verilerle doldurmanız user_identifiers gerekir. Kullanabileceğiniz birden fazla kullanıcı tanımlayıcısı varsa her biri için ayrı bir UserIdentifier oluşturun (en fazla beş tanımlayıcı).

conversion_date_time

Dönüşümün tarihi ve saati.

Değerde saat dilimi belirtilmelidir ve biçim yyyy-mm-dd HH:mm:ss+|-HH:mm olmalıdır. Örneğin: 2022-01-01 19:32:45-05:00 (yaz saati uygulaması dikkate alınmaz) .

Saat dilimi herhangi bir geçerli değer olabilir. Hesap saat dilimiyle eşleşmesi gerekmez. Ancak içe aktarılan dönüşüm verilerinizi Google Ads kullanıcı arayüzündeki verilerle karşılaştırmayı planlıyorsanız dönüşüm sayılarının eşleşmesi için Google Ads hesabınızla aynı saat dilimini kullanmanızı öneririz. Daha fazla ayrıntı ve örneği Yardım Merkezi'nde bulabilir, geçerli saat dilimi kimliklerinin listesi için Kodlar ve biçimler'i inceleyebilirsiniz.

conversion_action

Çevrimdışı dönüşüm için ConversionAction öğesinin kaynak adı.

Dönüşüm işleminin type değeri UPLOAD_CLICKS olmalı ve tıklamayla ilişkili Google Ads hesabının Google Ads dönüşüm müşterisinde bulunmalıdır.

conversion_value

Dönüşümün değeri.

currency_code

conversion_value öğesinin para birimi kodu.

consent

ClickConversion nesnesinin consent alanını doldurmanız kesinlikle önerilir. Ayarlanmazsa dönüşümlerinizin ilişkilendirilememesi mümkündür.

order_id

Dönüşümün işlem kimliği olarak da bilinir. Bu alan isteğe bağlıdır ancak düzenleme yaparken içe aktarılan dönüşümlere referans vermeyi kolaylaştırdığı için önemle tavsiye edilir. İçe aktarma sırasında ayarladıysanız tüm ayarlamalar için bu değeri kullanmanız gerekir. Yinelenen dönüşümleri en aza indirmek için işlem kimliğinin nasıl kullanılacağı hakkında daha fazla bilgi edinmek için bu Yardım Merkezi makalesine göz atın.

custom_variables

Özel dönüşüm değişkenlerinin değerleri.

Google Ads, özelleştirilebilen dönüşüm değişkenlerini wbraid veya gbraid ile birlikte desteklemez.

conversion_environment

Bu dönüşümün kaydedildiği ortamı gösterir. Örneğin, APP veya WEB.

session_attributes_encoded ve session_attributes_key_value_pairs

Oturum özellikleri, dönüşüm ilişkilendirmesi için kullanılan toplu tanımlayıcıları ifade eder. Bu tanımlayıcılar, tıklama tanımlayıcılarına (ör. GCLID'ler ve GBRAID'ler) ve potansiyel müşteriler için gelişmiş dönüşümlerin temelini oluşturan kullanıcı tarafından sağlanan verilere ek olarak çalışır. Oturum özelliklerini içe aktarmanın iki yolu vardır: Tarayıcıda JavaScript kodumuz tarafından oluşturulan kodlanmış jetonu sağlayarak veya tanımlayıcıların her biri için ayrı anahtar/değer çiftleri sağlayarak.

Kampanya performansınızı en üst düzeye çıkarmak için mümkünse tıklama tanımlayıcıları, kullanıcı tarafından sağlanan veriler ve oturum özelliklerini tüm dönüşümlerinizle birlikte içe aktarmanızı öneririz.

Java

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

C#

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

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

PHP

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

Python

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

Ruby

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

Perl

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

user_ip_address

Müşterinin bir reklamı tıkladıktan sonra açılış sayfasına ulaştığı ve dönüşüm etkinliğinden önce kullandığı IP adresi. Bu, reklamverenin sunucusunun değil, müşterinin cihazının IP adresidir.

Bu alan, IPv4 veya IPv6 biçiminde bir IP adresini temsil eden dizedir. Örneğin:

  • IPv4: "192.0.2.0"
  • IPv6: "2001:0DB8:1234:5678:9999:1111:0000:0001"

Kod örneği

Bu örnekte, kullanıcı tarafından sağlanan normalleştirilmiş ve karma oluşturma işlemi uygulanmış verilerinizi nasıl ClickConversion nesnesine ayarlayacağınız gösterilmektedir.

Java

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

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

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

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

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

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

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

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

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

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

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

C#

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

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

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

PHP

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

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

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

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

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

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

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

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

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

Python

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

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

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

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

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

Ruby

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

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

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

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

  unless order_id.nil?
    cc.order_id = order_id
  end

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

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

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

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

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

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

Perl

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

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

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

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

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

Bu örnekte, bir ClickConversion nesnesinde gerekli diğer alanların nasıl ayarlanacağı gösterilmektedir.

Java

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

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

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

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

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

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

C#

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

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

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

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

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

      

PHP

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

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

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

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

// Set one of the sessionAttributesEncoded or
// SessionAttributeKeyValuePair fields if either are provided.
if (!empty($sessionAttributesEncoded)) {
    $clickConversion->setSessionAttributesEncoded($sessionAttributesEncoded);
} elseif (!empty($sessionAttributesDict)) {
    // Create a new container object to hold key-value pairs.
    $sessionAttributesKeyValuePairs = new SessionAttributesKeyValuePairs();
    // Initialize an array to hold individual key-value pair messages.
    $keyValuePairs = [];
    // Append each key-value pair provided to the $keyValuePairs array
    foreach ($sessionAttributesDict as $key => $value) {
        $pair = new SessionAttributeKeyValuePair();
        $pair->setSessionAttributeKey($key);
        $pair->setSessionAttributeValue($value);
        $keyValuePairs[] = $pair;
    }
    // Set the the full list of key-value pairs on the container object.
    $sessionAttributesKeyValuePairs->setKeyValuePairs($keyValuePairs);
    // Attach the container of key-value pairs to the ClickConversion object.
    $clickConversion->setSessionAttributesKeyValuePairs($sessionAttributesKeyValuePairs);
}
      

Python

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

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

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

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

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

Ruby

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

unless order_id.nil?
  cc.order_id = order_id
end

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

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

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

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

Perl

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

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

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

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

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

İsteği oluşturma

ClickConversion nesneleriniz yapılandırılıp UploadClickConversionRequest nesnesinin conversions alanına eklendikten sonra aşağıdaki alanları ayarlayın ve isteği ConversionUploadService üzerindeki UploadClickConversions yöntemine iletin.

customer_id
Bunu, tıklamaların kaynağı olan hesabın Google Ads dönüşüm müşterisi olarak ayarlayın. Doğru hesabın hangisi olduğundan emin değilseniz customer.conversion_tracking_setting.google_ads_conversion_customer alanına bakın. Bu alan, başlarken bölümündeki örnek sorguda yer alır.
job_id

İçe aktarma isteklerinizi çevrimdışı veri teşhisindeki iş başına bilgilerle ilişkilendirmek için bir mekanizma sağlar.

Bu alanı ayarlamazsanız Google Ads API, her isteğe [2^31, 2^63) aralığında benzersiz bir değer atar. Birden fazla isteği tek bir mantıksal işte gruplandırmak isterseniz bu alanı, işinizdeki her istekte [0, 2^31) aralığındaki aynı değere ayarlayın.

Yanıt içindeki job_id, bir değer belirtip belirtmediğinizden veya Google Ads API'nin bir değer atamasına izin verip vermediğinizden bağımsız olarak isteğin iş kimliğini içerir.

partial_failure

Bu alan, dönüşümler içe aktarılırken true olarak ayarlanmalıdır. Yanıtı işlerken kısmi başarısızlık yönergelerini uygulayın.

İsteği içe aktarma

ClickConversion nesnelerinizi doldurup isteğinizi oluşturduktan sonra içe aktarma işleminizi gönderebilirsiniz.

Java

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

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

C#

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

      

PHP

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

Python

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

Ruby

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

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

Perl

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

İçe aktarılan öğelerinizi inceleme

Son içe aktarma işlemlerinizin genel durumunu incelemek için potansiyel müşteriler için gelişmiş dönüşümler teşhis raporunu kullanın.

İçe aktarılan dönüşümler, içe aktarma isteğinin tarihi veya ClickConversion'nin conversion_date_time tarihi için değil, orijinal tıklamanın gösterim tarihi ile ilgili raporlara yansıtılır.

İçe aktarılan dönüşüm istatistiklerinin son tıklama ilişkilendirmesi için Google Ads hesabınızda görünmesi üç saati bulabilir. Diğer arama ilişkilendirme modelleri için bu süre üç saatten uzun olabilir. Daha fazla bilgi için veri güncelliği rehberine bakın.

Kampanyalarınızın dönüşüm metrikleriyle ilgili rapor oluştururken Google Ads kullanıcı arayüzü metriklerini Google Ads API raporlama alanlarıyla ilişkilendirmek için Kullanıcı arayüzü metriklerini eşleme başlıklı makaleyi inceleyin. Belirli bir dönüşüm işlemi için toplam dönüşüm sayısını ve toplam dönüşüm değerini görüntülemek üzere conversion_action kaynağını da sorgulayabilirsiniz.

En iyi uygulamalar

Potansiyel müşteriler için gelişmiş dönüşümleri uygularken aşağıdaki en iyi uygulamaları dikkate alın.

Kapsamlılık düzeyinden bağımsız olarak tüm dönüşüm verilerini gönderme

Tam ve doğru dönüşüm raporları almak için Google Ads üzerinden gelmeyenler de dahil olmak üzere mevcut tüm çevrimdışı dönüşüm etkinliklerini içe aktarın. Yalnızca kullanıcı tarafından sağlanan verileri içeren dönüşümler yine de yararlıdır ve Google Ads kampanya optimizasyonuna olumlu katkıda bulunabilir.

Bir dönüşüme order_id atarsanız bunu eklemenizi öneririz. Bir dönüşümün GCLID'si varsa performansı artırmak için user_identifiers ile birlikte göndermenizi öneririz. Ayrıca, dönüşüm için birden fazla UserIdentifier varsa eşleşme olasılığını artırmak için bunların tümünü ClickConversion nesnesine ekleyin.

Tek bir istekte birden fazla dönüşümü toplu olarak işleme

İçe aktarılacak birden fazla dönüşümünüz varsa dönüşüm başına içe aktarma isteği göndermek yerine dönüşümleri tek bir UploadClickConversionsRequest halinde gruplandırın.

İstek başına dönüşüm sayısı sınırları için kota kılavuzunu inceleyin.

Çevrimdışı veri teşhislerinin bir dizi isteği aynı mantıksal iş altında gruplandırmasını istiyorsanız tüm isteklerin job_id değerini aynı değere ayarlayın. Bu özellik, birden fazla istek kullanarak çok sayıda dönüşümün içe aktarıldığı tek bir işiniz veya süreciniz varsa yararlı olabilir. Bu isteklerin her birinde job_id değerini aynı değere ayarlarsanız job_summaries üzerinden iş için tek bir giriş alabilirsiniz. Bunun yerine Google Ads API'nin her isteğin job_id için sistem tarafından oluşturulan bir değer atamasına izin verirseniz job_summaries, her istek için ayrı bir giriş içerir. Bu da işinizin genel durumunu analiz etmeyi zorlaştırabilir.

Harici ilişkilendirme verilerini kullanmayın

Potansiyel müşteriler için gelişmiş dönüşümleri kullanırken external_attribution_data ayarını ClickConversion üzerinde ayarlamayın veya harici bir ilişkilendirme modeli kullanan bir conversion_action belirtmeyin. Google Ads, kullanıcı tarafından sağlanan veriler kullanılarak yapılan içe aktarma işlemlerinde harici olarak ilişkilendirilen dönüşümleri desteklemez.

Özel değişkenleri dahil etmeyin

Potansiyel müşteriler için gelişmiş dönüşümleri kullanırken custom_variables eklemeyin. Google Ads, dönüşüm içe aktarma işlemlerinde kullanıcı tarafından sağlanan verilerle özelleştirilebilen değişkenlerin kullanılmasını desteklemez. Kullanıcı tarafından sağlanan veriler içeren dönüşümlere özel değişkenler eklenirse bu dönüşümler geçersiz kabul edilir ve bırakılır.

Sorun giderme

Çevrimdışı veri teşhisleri, içe aktarma işlemlerinizin genel durumunu sürekli olarak inceleyebileceğiniz tek bir kaynak sağlar. Ancak uygulama sırasında, yanıttaki partial_failure_error alanında bildirilen hataları araştırmak için bu bölümdeki bilgileri kullanabilirsiniz.

Dönüşüm işlemleri içe aktarılırken en sık karşılaşılan hatalardan bazıları, USER_PERMISSION_DENIED gibi yetkilendirme hatalarıdır. İsteğinizde, dönüşüm işleminin sahibi olan Google Ads dönüşüm müşterisi olarak ayarlanmış müşteri kimliğinin bulunduğunu tekrar kontrol edin. Daha fazla bilgi için yetkilendirme kılavuzumuzu ziyaret edin. Ayrıca, bu farklı hataları nasıl ayıklayacağınızla ilgili ipuçları için sık karşılaşılan hatalar kılavuzumuza göz atın.

Sık karşılaşılan hataları ayıklama

Hata
NO_CONVERSION_ACTION_FOUND

Belirtilen dönüşüm işlemi etkinleştirilmemiş veya istekteki "client_id" alanı tarafından belirtilen müşteri hesabı tarafından erişilemiyor. Yüklemenizdeki dönüşüm işleminin etkinleştirildiğinden ve yükleme isteğini gönderen müşteriye ait olduğundan emin olun.

Bu hata, istekteki GCLID'nin, istekte belirtilen dönüşüm işlemine erişimi olmayan bir müşteri hesabına ait olması durumunda da oluşabilir. click_view kaynağını kullanarak bir GCLID'nin müşteri hesabına ait olup olmadığını doğrulayabilirsiniz. Bunun için click_view.gclid ve segments.date ile filtreleme yapan bir sorgu gönderin. Tarih, tıklamanın gerçekleştiği tarihtir.

INVALID_CONVERSION_ACTION_TYPE Belirtilen dönüşüm işlemi, potansiyel müşteriler için gelişmiş dönüşümler açısından geçerli olmayan bir türe sahip. Yükleme isteğinizde belirtilen ConversionAction öğesinin türünün UPLOAD_CLICKS olduğundan emin olun.
CUSTOMER_NOT_ENABLED_ENHANCED_CONVERSIONS_FOR_LEADS Dönüşüm ayarlarınızda potansiyel müşteriler için gelişmiş dönüşümleri etkinleştirdiğinizden emin olun. Bu işlemle ilgili talimatları ön koşullar kılavuzunda bulabilirsiniz.
DUPLICATE_ORDER_ID İçe aktarılan etkinlikler, aynı Sipariş Kimliği'ne sahip birden çok dönüşüm içerdiği için işlenmedi. Sipariş kimliklerinin benzersiz olduğundan emin olup tekrar deneyin.
CLICK_NOT_FOUND Sağlanan kullanıcı tanımlayıcılarıyla eşleşen tıklama bulunamadı. Google Ads API, bu hatayı yalnızca debug_enabled, UploadClickConversionsRequest üzerinde true ise döndürür.

Bir dönüşüm bu uyarıyla karşılaşırsa Google Ads API, dönüşümü çevrimdışı veri teşhislerinizin successful_event_count bölümüne dahil eder. Google Ads API, CLICK_NOT_FOUND için alerts koleksiyonunda bir giriş içerir. Böylece bu uyarının sıklığını izleyebilirsiniz.

Tıklama bir Google Ads kampanyasından gelmiyorsa bu hatanın oluşması beklenir. Örneğin, SA360 veya DV360'tan gelebilir. Diğer olası nedenler şunlardır:

Yükleme yapan müşterinin Google Ads dönüşüm müşterisinden farklı olduğu nadir durumlarda bu hata, yükleme yapan müşterinin müşteri verileri şartlarını kabul ettiği ancak reklam yayınlayan müşterinin kabul etmediği anlamına gelebilir.

Bir hesabın müşteri verisi şartlarını kabul edip etmediğini customer kaynağını sorgulayıp customer.offline_conversion_tracking_info.accepted_customer_data_terms alanını kontrol ederek belirleyebilirsiniz.