إدارة الإحالات الناجحة بلا إنترنت

يمكنك استخدام Google Ads API لاستيراد الإحالات الناجحة بلا إنترنت إلى "إعلانات Google" من أجل تتبُّع الإعلانات التي أدّت إلى تحقيق مبيعات بلا إنترنت، مثل المبيعات التي تتم عبر الهاتف أو من خلال ممثّل مبيعات.

للاستفادة بالكامل من مزايا استيراد بيانات الإحالات الناجحة، ننصح بتنفيذ ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين" التي تستفيد من معرّفات النقرة من Google والبيانات المقدَّمة من المستخدِم لزيادة الاستدامة والأداء إلى أقصى حدّ.

الإحالات الناجحة المحسّنة

تساعدك ميزة "الإحالات الناجحة المحسّنة" على تحسين دقة قياس الإحالات الناجحة من خلال إضافة بيانات الإحالات الناجحة التابعة لطرف أول إلى إحالاتك الناجحة، مثل عنوان البريد الإلكتروني والاسم وعنوان المنزل ورقم الهاتف.

هناك نوعان من الإحالات الناجحة المحسّنة. لمزيد من التفاصيل، يُرجى الاطّلاع على مقالة لمحة عن الإحالات الناجحة المحسّنة في مركز المساعدة.

يوضّح القسم التالي كيفية تحسين الإحالات الناجحة بلا إنترنت، وهي ميزة تتمثّل في الإحالات الناجحة المحسّنة للعملاء المحتملين.

ما هي "الإحالات الناجحة المحسّنة للعملاء المحتملين"؟

"الإحالات الناجحة المحسّنة للعملاء المحتملين" هي نسخة مُعدَّلة من ميزة "استيراد الإحالات الناجحة غير الإلكترونية" التي تستخدِم البيانات المقدَّمة من المستخدِم، مثل عناوين البريد الإلكتروني، لتكملة بيانات الإحالات الناجحة غير الإلكترونية المستورَدة من أجل تحسين الدقّة وأداء عروض الأسعار. عند استيراد إحالاتك الناجحة بلا إنترنت، يتم استخدام بيانات العملاء المجزّأة المقدَّمة لتحديد مصدرها على أنّه الحملة على "إعلانات Google" عن طريق مطابقتها مع البيانات نفسها التي تم جمعها على موقعك الإلكتروني، مثل نموذج العملاء المحتملين، والعملاء الذين سجَّلوا الدخول وتفاعلوا مع إعلانك. لمزيد من المعلومات عن آلية عمل ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين"، راجِع مقالتنا لمحة عن ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين".

تتوفّر طريقتان لتنفيذ ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين" استنادًا إلى ما إذا كنت تستخدِم علامة التتبّع من Google لتتبُّع أحداث إرسال النماذج على صفحتك الإلكترونية. للحصول على أفضل أداء و متانة، ننصحك بشدة باستخدام علامة Google للإحالات الناجحة المحسّنة للعملاء المحتملين.

المتطلبات الأساسية

أولاً، تأكَّد من إكمال الخطوات الواردة في قسم "البدء".

يجب تفعيل ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين" وقبول بنود data العملاء قبل أن تتمكّن من استخدام هذه الميزة. يمكنك التحقّق مما إذا كانت هذه المتطلّبات الأساسية قد تم استيفاؤها من خلال إصدار الطلب التالي إلى العميل المُحدِّد للإحالة الناجحة في "إعلانات Google":

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 أو enhanced_conversions_for_leads_enabled هو false، اتّبِع التعليمات الواردة في مركز المساعدة لإكمال هذه المتطلبات الأساسية.

ضبط ميزة وضع العلامات

اضبط علامة Google لتفعيل ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين" باتّباع التعليمات الواردة في مركز المساعدة. لإعداد ميزة الإحالات الناجحة المحسّنة للعملاء المحتملين باستخدام أداة "إدارة العلامات من Google"، اتّبِع هذه التعليمات.

تنفيذ واجهة برمجة التطبيقات

في ما يلي الخطوات العامة لاستيراد ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين" باستخدام واجهة برمجة التطبيقات Google Ads API.

  1. تسويف البيانات المقدَّمة من المستخدِم وتجزئتها، مثل عنوان البريد الإلكتروني ورقم الهاتف والعنوان البريدي

  2. املأ عناصر ClickConversion بالبيانات المقدَّمة من المستخدِم التي تمّت تسويتها وتجزئتها.

  3. استيراد عناصر ClickConversion إلى Google Ads API باستخدام ConversionUploadService

  4. راجِع عمليات الاستيراد.

تسويت البيانات المقدَّمة من المستخدِم وتجزئتها

لمراعاة اعتبارات الخصوصية، يجب تجزئة البيانات التالية باستخدام SHA-256 قبل استيرادها:

  • عنوان البريد الإلكتروني
  • رقم الهاتف
  • الاسم الأول
  • اسم العائلة
  • عنوان الشارع

لتوحيد نتائج التجزئة، عليك إجراء ما يلي قبل تجزئة هذه القيم:

  • إزالة المسافات البيضاء البادئة واللاحقة
  • تحويل النص إلى أحرف لاتينية صغيرة
  • تنسيق أرقام الهواتف وفقًا لمعيار E164
  • إزالة جميع النقاط (.) التي تسبق اسم النطاق في عناوين البريد الإلكتروني gmail.com و googlemail.com

يجب عدم تجزئة البيانات التالية:

  • البلد
  • الولاية
  • المدينة
  • الرمز البريدي

مثال على الرمز البرمجي

يوضِّح هذا المثال كيفية تسويتها وتجزئتها.

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):
    """Returns the result of normalizing and hashing an email address.

    For this use case, Google Ads requires removal of any '.' characters
    preceding "gmail.com" or "googlemail.com"

    Args:
        email_address: An email address to normalize.

    Returns:
        A normalized (lowercase, removed whitespace) and SHA-265 hashed string.
    """
    normalized_email = email_address.strip().lower()
    email_parts = normalized_email.split("@")

    # Check that there are at least two segments
    if len(email_parts) > 1:
        # Checks whether the domain of the email address is either "gmail.com"
        # or "googlemail.com". If this regex does not match then this statement
        # will evaluate to None.
        if re.match(r"^(gmail|googlemail)\.com$", email_parts[1]):
            # Removes any '.' characters from the portion of the email address
            # before the domain if the domain is gmail.com or googlemail.com.
            email_parts[0] = email_parts[0].replace(".", "")
            normalized_email = "@".join(email_parts)

    return normalize_and_hash(normalized_email)


def normalize_and_hash(s):
    """Normalizes and hashes a string with SHA-256.

    Private customer data must be hashed during upload, as described at:
    https://support.google.com/google-ads/answer/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

تمثّل مجموعة عناصر ClickConversion في UploadClickConversionRequest مجموعة الإحالات الناجحة التي تريد استيرادها. يُرجى مراعاة التفاصيل التالية عند إنشاء ClickConversion العناصر:

gclid

معرّفات النقرة من Google هي معرّفات للنقرات يتمّ تسجيلها من مَعلمات عناوين URL عندما ينقر أحد المستخدِمين على إعلانك وينتقل إلى موقعك الإلكتروني.

user_identifiers

عند استخدام ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين"، يجب ملء الحقل user_identifiers بالبيانات المقدَّمة من المستخدِم والتي تمّت تسويتها وتجزئتها. إذا كان لديك عدة معرّفات للمستخدمين، أنشئ UserIdentifier منفصلاً لكل معرّف، ويصل عدد المعرّفات إلى خمسة.

conversion_date_time

تاريخ الإحالة الناجحة ووقتها

يجب أن تحتوي القيمة على منطقة زمنية محدّدة، ويجب أن يكون التنسيق yyyy-mm-dd HH:mm:ss+|-HH:mm، على سبيل المثال: 2022-01-01 19:32:45-05:00 (مع تجاهل التوقيت الصيفي) .

يمكن أن تكون المنطقة الزمنية لأي قيمة صالحة: ليس من الضروري أن تتطابق مع المنطقة الزمنية للحساب. ومع ذلك، إذا كنت تخطّط لمقارنة data الإحالات الناجحة التي تمّ استيرادها مع تلك الواردة في واجهة مستخدِم "إعلانات Google"، ننصحك باستخدام المنطقة الزمنية نفسها المستخدَمة في حسابك على "إعلانات Google" حتى تتطابق أعداد الإحالات الناجحة. يمكنك العثور على مزيد من التفاصيل والأمثلة في مركز المساعدة والاطّلاع على الرموز والتنسيقات للحصول على قائمة بأرقام تعريف المناطق الزمنية الصالحة.

conversion_action

اسم مورد ConversionAction للإحالة الناجحة بلا إنترنت.

يجب أن يكون للإجراء الإحالة الناجحة typeUPLOAD_CLICKS، ويجب أن يكون موجودًا في ملف تعريف العميل للإحالة الناجحة على "إعلانات Google" للحساب المرتبط بالنقرة.

conversion_value

قيمة الإحالة الناجحة.

currency_code

رمز العملة conversion_value

consent

ننصحك بشدّة بملء حقل consent في عنصر ClickConversion. وفي حال عدم ضبطه، من المحتمل ألا يتم تحديد مصدر إحالاتك الناجحة.

order_id

يُعرف أيضًا باسم معرّف المعاملة للإحالة الناجحة. هذا الحقل اختياري، ولكنه يُنصح به بشدة، لأنّه يسهّل الإشارة إلى الإحالات الناجحة المستورَدة عند إجراء التعديلات. إذا ضبطت هذا الإعداد أثناء الاستيراد، يجب استخدامه لإجراء أي تعديلات. لمزيد من المعلومات عن كيفية استخدام معرِّف المعاملة لتقليل الإحالات الناجحة المكرّرة، يمكنك الاطّلاع على مقالة مركز المساعدة هذه.

custom_variables

قيم متغيّرات الإحالات الناجحة المخصّصة

لا تتيح "إعلانات Google" استخدام متغيّرات الإحالات الناجحة المخصّصة مع wbraid أو gbraid.

conversion_environment

يشير إلى البيئة التي تم تسجيل هذه الإحالة الناجحة فيها. على سبيل المثال، APP أو WEB.

session_attributes_encoded وsession_attributes_key_value_pairs

تمثّل سمات الجلسة المعرّفات المجمّعة المستخدَمة لتحديد مصدر الإحالة الناجحة. وتعمل هذه الحلول إلى جانب معرّفات النقرات (مثل معرّفات GCLID و معرّفات GBRAID) والبيانات المقدّمة من المستخدِم، والتي تشكّل عاملاً أساسيًا في ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملِين". هناك طريقتان لاستيراد سمات الجلسة: من خلال تقديم رمز مميّز مُشفَّر تم إنشاؤه بواسطة رمز JavaScript في المتصفّح، أو من خلال تقديم أزواج مفتاح/قيمة فردية لكل معرّف.

لتحسين أداء حملتك إلى أقصى حدّ، ننصحك باستيراد معرّفات النقرات والبيانات المقدَّمة من المستخدِم وخصائص الجلسات مع كل إحالاتك الناجحة، إن أمكن.

Java

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

#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 = 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::V19::Services::ConversionUploadService::SessionAttributeKeyValuePair
      ->new({sessionAttributeKey => $key, sessionAttributeValue => $value});
    push @{$click_conversion->{sessionAttributesKeyValuePairs}{keyValuePairs}
    }, $pair;
  }
}
      

مثال على الرمز البرمجي

يوضِّح هذا المثال كيفية ضبط البيانات المقدَّمة من المستخدِم التي تمّت تسويتها وتجزئتها على عنصر ClickConversion.

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", "[email protected]")
        // 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("[email protected]"),
    // 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' => '[email protected]',
    // 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
];

// 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 = {
    # Email address that includes a period (.) before the Gmail domain.
    "email": "[email protected]",
    # 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 = 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 = 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 = 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" => "[email protected]",
  # 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::V19::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::V19::Common::UserIdentifier->new({
#   hashedEmail => '...',
#   hashedPhoneNumber => '...',
# });
my $raw_record = {
  # Email address that includes a period (.) before the Gmail domain.
  email => '[email protected]',
  # 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::V19::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::V19::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;
      

يوضّح هذا المثال كيفية ضبط الحقول الأخرى اللازمة في ClickConversion عنصر.

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

Python

# Add details of the conversion.
# Gets the conversion action resource name.
conversion_action_service = 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 = 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::V19::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::V19::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::V19::Services::ConversionUploadService::SessionAttributeKeyValuePair
      ->new({sessionAttributeKey => $key, sessionAttributeValue => $value});
    push @{$click_conversion->{sessionAttributesKeyValuePairs}{keyValuePairs}
    }, $pair;
  }
}
      

إنشاء الطلب

بعد ضبط عناصر ClickConversion وإضافتها إلى الحقل conversions في عنصر UploadClickConversionRequest، اضبط الحقول التالية واضبط الطلب على طريقة UploadClickConversions في ConversionUploadService.

customer_id
اضبط هذا الخيار على عميل الإحالة الناجحة في "إعلانات Google" للحساب الذي يمثّل مصدر النقرات. إذا لم تكن متأكدًا من الحساب الصحيح، يمكنك الرجوع إلى الحقل customer.conversion_tracking_setting.google_ads_conversion_customer في مثال طلب البحث في القسم البدء .
job_id

يوفّر آلية لربط طلبات الاستيراد بمعلومات كل وظيفة في بيانات التشخيص بلا إنترنت.

في حال عدم ضبط هذا الحقل، تحدّد Google Ads API قيمة فريدة لكل طلب في النطاق [2^31, 2^63). إذا كنت تفضّل تجميع طلبات متعددة في وظيفة منطقية واحدة، اضبط هذا الحقل على القيمة نفسها في النطاق [0, 2^31) في كل طلب في وظيفتك.

يحتوي العنصر job_id في الاستجابة على معرّف الوظيفة للطلب، بغض النظر عمّا إذا حدّدت قيمة أو سمحت لواجهة Google Ads API بتعيين قيمة.

partial_failure

يجب ضبط هذا الحقل على true عند استيراد الإحالات الناجحة. اتّبِع إرشادات حالات الفشل الجزئي عند معالجة الردّ.

استيراد الطلب

بعد تعبئة عناصر ClickConversion وإنشاء الطلب، يمكنك إرسال عملية الاستيراد.

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

مراجعة عمليات الاستيراد

استخدِم تقرير بيانات تشخيص الإحالات الناجحة المحسّنة للعملاء المحتملين لمراجعة الحالة العامة لعمليات الاستيراد الأخيرة.

تظهر الإحالات الناجحة المستورَدة في تقارير تاريخ الظهور ل النقرة الأصلية، وليس تاريخ طلب الاستيراد أو تاريخ conversion_date_time ل ClickConversion.

يستغرق ظهور إحصاءات الإحالات الناجحة المستورَدة في حسابك على "إعلانات Google" لتحديد مصدر النقرة الأخيرة مدّةً تصل إلى ثلاث ساعات. بالنسبة إلى نماذج تحديد المصدر الأخرى للبحث، قد يستغرق ذلك أكثر من ثلاث ساعات. يمكنك الرجوع إلى دليل حداثة البيانات للحصول على مزيد من المعلومات.

عند إعداد تقارير عن مقاييس الإحالات الناجحة لحملاتك، يمكنك الرجوع إلى مقالة ربط مقاييس واجهة المستخدِم لربط مقاييس واجهة المستخدِم في "إعلانات Google" بحقول إعداد التقارير في Google Ads API. يمكنك أيضًا إجراء طلب بحث في مورد conversion_action للاطّلاع على إجمالي عدد الإحالات الناجحة وإجمالي قيمة الإحالة الناجحة لهدف إحالة ناجحة معيّن.

أفضل الممارسات

يُرجى مراعاة أفضل الممارسات التالية عند تنفيذ ميزة الإحالات الناجحة المحسَّنة للعملاء المحتملين.

إرسال جميع بيانات الإحالات الناجحة بغض النظر عن اكتمالها

لضمان إعداد تقارير إحالات ناجحة كاملة ودقيقة، استورِد جميع أحداث الإحالات الناجحة بلا إنترنت المتاحة، بما في ذلك تلك التي قد لا تكون واردة من "إعلانات Google". لا تزال الإحالات الناجحة التي تتضمّن البيانات المقدَّمة من المستخدِم فقط مفيدة ويمكن أن تسهم بشكل إيجابي في تحسين الحملات على "إعلانات Google".

إذا عيّنت order_id لإحالة ناجحة، ننصحك بتضمينها. إذا كان لديك معرّف النقرة من Google لإحالة ناجحة، ننصحك بإرساله بالإضافة إلى user_identifiers لتحسين الأداء. بالإضافة إلى ذلك، إذا كان لديك أكثر من UserIdentifier واحد للإحالة الناجحة، أدرِج كلّها في عنصر ClickConversion لزيادة احتمالية المطابقة.

تجميع عدّة إحالات ناجحة في طلب واحد

إذا كانت لديك إحالات ناجحة متعددة تريد استيرادها، يمكنك تجميع الإحالات الناجحة في ملف واحد UploadClickConversionsRequest، بدلاً من إرسال طلب استيراد لكل إحالة ناجحة.

اطّلِع على دليل الحصص لمعرفة الحدود القصوى لعدد الإحالات الناجحة لكل طلب.

إذا كنت تريد أن تُجمِّع بيانات بيانات بلا إنترنت مجموعة من الطلبات ضمن المهمة المنطقية نفسها، اضبط job_id لجميع الطلبات على القيمة نفسها. يمكن أن يكون ذلك مفيدًا إذا كانت لديك مهمة واحدة أو عملية واحدة تستورد عددًا كبيرًا من الإحالات الناجحة باستخدام طلبات متعددة. إذا ضبطتjob_id في كلّ من هذه الطلبات على القيمة نفسها، يمكنك استرداد إدخال واحد للوظيفة من job_summaries. إذا سمحت بدلاً من ذلك لواجهة برمجة التطبيقات Google Ads API بتعيين قيمة من إنشاء النظام إلى job_id لكل طلب، سيتضمّن job_summaries إدخالًا منفصلاً لكل طلب، ما قد يجعل تحليل الصحة العامة لوظيفتك أكثر صعوبة.

عدم استخدام بيانات تحديد المصدر الخارجية

عند استخدام ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملين"، لا تضبط external_attribution_data على ClickConversion أو تحدِّد conversion_action يستخدِم conversion_action نموذج تحديد مصدر خارجي. لا تتيح "إعلانات Google" الإحالات الناجحة التي تمّ تحديد مصدرها خارجيًا لعمليات الادخال التي تستخدِم البيانات المقدَّمة من المستخدِم.

تحديد المشاكل وحلّها

توفّر بيانات تشخيص المعلومات المتوفّرة بلا إنترنت مرجعًا واحدًا لمراجعة الحالة العامة لعمليات الاستيراد بشكلٍ مستمر. ومع ذلك، أثناء التنفيذ، يمكنك استخدام المعلومات الواردة في هذا القسم للتحقيق في أي أخطاء تم الإبلاغ عنها في حقل partial_failure_error الردّ.

إنّ بعض الأخطاء الأكثر شيوعًا عند استيراد إجراءات الإحالات الناجحة هي أخطاء التفويض، مثل USER_PERMISSION_DENIED. تحقّق جيدًا من أنّه تم ضبط رقم تعريف العميل في طلبك على العميل الذي أجرى الإحالة الناجحة في "إعلانات Google" الذي يملك إجراء الإحالة الناجحة. يمكنك الانتقال إلى دليل التفويض للحصول على مزيد من التفاصيل والاطّلاع على دليل الأخطاء الشائعة للحصول على نصائح حول كيفية debugging these different errors.

تصحيح الأخطاء الشائعة

خطأ
NO_CONVERSION_ACTION_FOUND

إجراء الإحالة الناجحة المحدّد غير مفعّل أو لا يمكن للحساب العميل الوصول إليه، وهو الحساب المحدّد من خلال الحقل client_id في الطلب. تأكّد من أنّ إجراء الإحالة الناجحة في عملية التحميل مفعّل وأنّه مملوك للعميل الذي يرسل طلب التحميل.

قد يحدث هذا الخطأ أيضًا إذا كانت معرّفة GCLID في الطلب تنتمي إلى حساب عميل ليس لديه إذن بالوصول إلى إجراء الإحالة الناجحة المحدّد في الطلب. يمكنك التحقّق مما إذا كان GCLID ينتمي إلى حساب عميل باستخدام موارد click_view، وذلك من خلال إرسال طلب بحث يتمّ تصفيته حسب click_view.gclid و segments.date، حيث يكون التاريخ هو تاريخ حدوث النقرة.

INVALID_CONVERSION_ACTION_TYPE إجراء الإحالة الناجحة المحدّد له نوع غير صالح للإحالات الناجحة المحسّنة للعملاء المحتملين. تأكَّد من أنّ ConversionAction المحدّد في طلب التحميل من النوع UPLOAD_CLICKS.
CUSTOMER_NOT_ENABLED_ENHANCED_CONVERSIONS_FOR_LEADS تأكّد من أنّك فعّلت ميزة "الإحالات الناجحة المحسّنة للعملاء المحتملِين" في إعدادات الإحالات الناجحة. يمكنك العثور على تعليمات حول ذلك في دليل المتطلبات الأساسية.
DUPLICATE_ORDER_ID تتضمّن الأحداث المستورَدة إحالات ناجحة متعددة بمعرّف الطلب نفسه ولم تتم معالجتها. يُرجى التأكّد من أنّ معرّفات الطلبات فريدة وإعادة المحاولة.
CLICK_NOT_FOUND لم يتم العثور على أي نقرة تطابق مع معرّفات المستخدِمين المقدّمة. لا تعرِض Google Ads API هذا الخطأ إلا إذا كان debug_enabled true في UploadClickConversionsRequest.

إذا واجهت إحدى الإحالات الناجحة هذا التحذير، تضمّنه Google Ads API في successful_event_count من بيانات التشخيص المتعلّقة بالبيانات بلا إنترنت. تتضمّن Google Ads API إدخالاً لـ CLICK_NOT_FOUND في مجموعة alerts حتى تتمكّن من تتبُّع معدّل تكرار هذا التحذير.

من المتوقّع حدوث هذا الخطأ إذا لم تكن النقرة واردة من حملة على "إعلانات Google". على سبيل المثال، قد تأتي من SA360 أو DV360. في ما يلي الأسباب المحتملة الأخرى:

في حالات نادرة يكون فيها العميل الذي يحمّل البيانات مختلفًا عن العميل صاحب الإحالة الناجحة في "إعلانات Google"، يمكن أن يعني هذا الخطأ أنّ العميل الذي يحمّل البيانات قد وافق على بنود بيانات العميل، ولكنّ العميل الذي يعرض الإعلانات لم يوافق عليها.

يمكنك تحديد ما إذا كان حساب قد قبل بنود بيانات العملاء من خلال طلب البحث في مورد customer والتحقّق من الحقل customer.offline_conversion_tracking_info.accepted_customer_data_terms.