تبدیل های پیشرفته را برای سرنخ ها پیاده سازی کنید

تبدیل‌های پیشرفته برای سرنخ‌ها شما را قادر می‌سازد تا دقت اندازه‌گیری تبدیل آفلاین خود را با آپلود تبدیل‌های کلیکی که حاوی شناسه‌های کاربر هش‌شده و برخی جزئیات اضافی اختیاری است که به Google Ads کمک می‌کند تا تبدیل را به تبلیغی که منجر به پیشروی شده است، افزایش دهید.

قبل از ادامه اجرا، حتماً راهنمای شروع کار را مرور کرده و پیش نیازهای تبدیل افزایش یافته برای سرنخ ها را اجرا کنید.

می‌توانید تبدیل‌های پیشرفته برای سرنخ‌ها را از طریق رابط کاربری Google Ads، همانطور که در مرکز راهنمایی توضیح داده شده است، یا از طریق Google Ads API، همانطور که در این راهنما توضیح داده شده است، آپلود کنید.

ادغام خود را طراحی کنید

جریان استفاده

در اینجا جریان کلی برای آپلود تبدیل های پیشرفته برای سرنخ ها در Google Ads API آمده است.

  1. مطمئن شوید که پیش نیازها را اجرا کرده اید که شامل موارد زیر است:

    1. ردیابی تبدیل را فعال کنید.

    2. شرایط داده های مشتری را بپذیرید.

    3. برچسب گذاری را در فرم های هدایت وب سایت خود پیکربندی کنید.

    برای راهنمایی دقیق به اجرای پیش نیازها مراجعه کنید.

  2. داده های سرنخ مانند آدرس ایمیل، شماره تلفن و آدرس پستی را عادی و هش کنید.

  3. داده های سرنخ نرمال شده و هش شده را در اشیاء ClickConversion قرار دهید. برای هر ClickConversion :

    1. user_identifiers را با داده های سرنخ عادی و هش شده پر کنید. اگر چندین شناسه کاربری در دسترس دارید، یک UserIdentifier جداگانه برای هر یک، حداکثر تا پنج شناسه ایجاد کنید.

    2. (اختیاری اما به شدت توصیه می شود) order_id پر کنید.

    3. (اختیاری) gclid برای دقیق ترین اندازه گیری پر کنید.

    4. با شروع نسخه V15 API Google Ads، باید فیلد consent شی ClickConversion را پر کنید.

    5. conversion_action را به نام منبع یک ConversionAction با یک type UPLOAD_CLICKS تنظیم کنید. این باید نام منبع ConversionAction باشد که هنگام اجرای پیش نیازها ایجاد کردید.

  4. عملیات ایجاد ClickConversion را در ConversionUploadService آپلود کنید و partial_failure را روی true تنظیم کنید.

  5. آپلودهای خود را مرور کنید

بهترین شیوه ها

هنگام اجرای تبدیل های پیشرفته برای سرنخ ها، بهترین شیوه های زیر را در نظر داشته باشید.

در صورت داشتن شناسه های متعدد، آنها را وارد کنید

اگر یک order_id به یک تبدیل اختصاص می‌دهید، اکیداً توصیه می‌کنیم آن را اضافه کنید. اگر gclid برای تبدیل دارید، توصیه می‌کنیم آن را علاوه بر user_identifiers برای بهبود عملکرد ارسال کنید. علاوه بر این، اگر بیش از یک UserIdentifier برای تبدیل دارید، شامل چندین مورد می‌تواند احتمال تطابق را افزایش دهد. همه شناسه‌ها را روی همان ClickConversion قرار دهید.

هنگام تنظیم ادغام، خطاهای شکست جزئی را مرور کنید

هنگامی که برای اولین بار تبدیل های پیشرفته خود را برای یکپارچه سازی سرنخ ها تنظیم می کنید، خطاهای جزئی را در قسمت partial_failure_error پاسخ بررسی کرده و به آن رسیدگی کنید. اگر مشکلاتی در راه اندازی شما وجود دارد، برای بررسی و رفع آنها باید این قسمت را بررسی کنید. برای جزئیات بیشتر و مثال‌هایی درباره مدیریت خطای شکست جزئی، از راهنمای اختصاصی خرابی جزئی دیدن کنید.

همانطور که خطاهای شکست جزئی را مرور می کنید، به جدول خطاهای رایج در راهنمای عیب یابی مراجعه کنید. هنگامی که مشکلاتی را که در خطاهای نارسایی جزئی ظاهر می‌شوند حل کردید و ادغام شما کامل شد، به استفاده از تشخیص داده‌های آفلاین بروید تا به طور منظم سلامت تبدیل‌های خود را بررسی کنید.

تبدیل های چندگانه را در یک درخواست انجام دهید

اگر چندین تبدیل برای آپلود دارید، به جای ارسال درخواست آپلود به ازای هر تبدیل، عملیات ها را در یک UploadClickConversionsRequest دسته بندی کنید.

راهنمای سهمیه را برای محدودیت در تعداد تبدیل در هر درخواست بررسی کنید.

اگر می‌خواهید تشخیص داده‌های آفلاین مجموعه‌ای از درخواست‌ها را در یک شغل منطقی گروه‌بندی کند، job_id همه درخواست‌ها را روی یک مقدار تنظیم کنید. اگر یک کار یا فرآیند واحد دارید که تعداد زیادی تبدیل را با استفاده از چندین درخواست آپلود می کند، می تواند مفید باشد. اگر job_id برای هر یک از این درخواست‌ها روی یک مقدار تنظیم کنید، می‌توانید یک ورودی برای کار از job_summaries بازیابی کنید. اگر به جای آن به Google Ads API اجازه دهید یک مقدار ایجاد شده توسط سیستم را به job_id هر درخواست اختصاص دهد، job_summaries شامل یک ورودی جداگانه برای هر درخواست است که می تواند تجزیه و تحلیل سلامت کلی شغل شما را چالش برانگیزتر کند.

همه رویدادهای تبدیل آفلاین موجود را بارگذاری کنید

برای اطمینان از گزارش کامل و دقیق تبدیل، همه رویدادهای تبدیل آفلاین موجود را آپلود کنید، از جمله مواردی که ممکن است از Google Ads نبوده باشند.

بارگذاری همه رویدادهای تبدیل منجر به CLICK_NOT_FOUND خطا برای هر رویدادی می‌شود که از Google Ads نیست. از آنجایی که این خطاها هنگام بارگذاری همه رویدادهای تبدیل انتظار می‌رود، UploadClickConversionsRequest دارای یک فیلد debug_enabled است.

  • اگر debug_enabled false باشد یا تنظیم نشده باشد، Google Ads API فقط اعتبار ورودی اولیه را انجام می‌دهد، بررسی‌های آپلود بعدی را نادیده می‌گیرد و حتی اگر هیچ کلیکی برای user_identifiers ارائه‌شده پیدا نشود، موفقیت را باز می‌گرداند.

    این پیش فرض است.

  • اگر debug_enabled true باشد، Google Ads API همه اعتبارسنجی‌ها را انجام می‌دهد و یک خطای CLICK_NOT_FOUND را برای هر ClickConversion که در آن هیچ تبدیل Google Ads برای user_identifiers ارائه شده وجود ندارد، برمی‌گرداند.

در طول توسعه و آزمایش، می‌توانید debug_enabled روی true تنظیم کنید تا به شناسایی مشکلات کمک کند. برای مثال، اگر مجموعه‌ای از تبدیل‌ها و user_identifiers دارید که می‌دانید از تبدیل‌های Google Ads هستند، می‌توانید از تنظیمات true برای تأیید اینکه آن آپلودها منجر به خطای CLICK_NOT_FOUND نمی‌شود استفاده کنید. با این حال، هنگامی که توسعه و آزمایش قبلی را ادامه می دهید، توصیه می کنیم debug_enabled روی false تنظیم کنید تا از خطاهای بیش از حد جلوگیری شود.

از داده های اسناد خارجی استفاده نکنید

external_attribution_data روی ClickConversion تنظیم نکنید یا یک conversion_action که از یک مدل انتساب خارجی استفاده می‌کند، مشخص نکنید. Google Ads از تبدیل های منتسب به خارج برای آپلود با استفاده از شناسه ها پشتیبانی نمی کند.

داده ها را برای آپلود آماده کنید

برای ملاحظات حفظ حریم خصوصی، داده های زیر باید قبل از آپلود با استفاده از SHA-256 هش شوند:

  • آدرس ایمیل
  • شماره تلفن
  • نام کوچک
  • نام خانوادگی
  • آدرس خیابان

داده های زیر را هش نکنید :

  • کشور
  • حالت
  • شهر
  • کد پستی

برای استاندارد کردن نتایج هش، باید قبل از هش کردن یکی از این مقادیر، موارد زیر را انجام دهید:

  • فضاهای سفید پیشرو و انتهایی را حذف کنید.
  • متن را به حروف کوچک تبدیل کنید.
  • فرمت شماره تلفن ها بر اساس استاندارد E164 .
  • تمام نقاط ( . ) که قبل از نام دامنه در آدرس های ایمیل gmail.com و googlemail.com قرار دارند را حذف کنید.

جاوا

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

سی شارپ

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

پایتون

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.lower()
    email_parts = normalized_email.split("@")
    # Checks whether the domain of the email address is either "gmail.com"
    # or "googlemail.com". If this regex does not match then this statement
    # will evaluate to None.
    is_gmail = re.match(r"^(gmail|googlemail)\.com$", email_parts[1])

    # Check that there are at least two segments and the second segment
    # matches the above regex expression validating the email domain name.
    if len(email_parts) > 1 and is_gmail:
        # Removes any '.' characters from the portion of the email address
        # before the domain if the domain is gmail.com or googlemail.com.
        email_parts[0] = email_parts[0].replace(".", "")
        normalized_email = "@".join(email_parts)

    return normalize_and_hash(normalized_email)


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

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

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

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

روبی

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

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

پرل

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

تبدیل های پیشرفته را آپلود کنید

قطعه‌های زیر نشان می‌دهند که چگونه می‌توان یک آپلود تبدیلی ایجاد کرد که حاوی شناسه‌هایی برای آدرس ایمیل و شماره تلفن باشد، با استانداردسازی و هش‌سازی در صورت لزوم. به عنوان بهترین روش، در صورت موجود بودن، gclid و order_id را در تبدیل قرار دهید.

شناسه های کاربر را به ClickConversion اضافه کنید

جاوا

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

Map<String, String> rawRecord =
    ImmutableMap.<String, String>builder()
        // Email address that includes a period (.) before the Gmail domain.
        .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 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.
        .put("orderId", orderId)
        .put("gclid", gclid)
        .put("conversionActionId", Long.toString(conversionActionId))
        .put("conversionDateTime", conversionDateTime)
        .put("conversionValue", Double.toString(conversionValue))
        .put("currencyCode", "USD")
        .put("adUserDataConsent", adUserDataConsent == null ? null : adUserDataConsent.name())
        .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);
      

سی شارپ

// 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
];

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

پایتون

# 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": "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 = 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_phone_number = 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)
      

روبی

# 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,
}

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

  # 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_phone_number = 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_email(raw_record["phone"])
    end
  end
end
      

پرل

# Create an empty click conversion.
my $click_conversion =
  Google::Ads::GoogleAds::V16::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::V16::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::V16::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::V16::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 اضافه کنید

جاوا

// 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.get("orderId") != null) {
  clickConversionBuilder.setOrderId(rawRecord.get("orderId"));
}

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

// Sets the consent information, if provided.
if (rawRecord.get("adUserDataConsent") != null) {
  // 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"))));
}

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

سی شارپ

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

      

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

پایتون

# 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"]
    ]
      

روبی

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
      

پرل

# Add details of the conversion.
$click_conversion->{conversionAction} =
  Google::Ads::GoogleAds::V16::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::V16::Common::Consent->new({
      adUserData => $raw_record->{adUserDataConsent}});
}
      

ClickConversion را آپلود کنید

جاوا

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

سی شارپ

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

پایتون

# 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,
)
      

روبی

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
      

پرل

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

آپلودهای خود را مرور کنید

از تشخیص داده های آفلاین برای بررسی سلامت کلی آپلودهای اخیر خود استفاده کنید. توجه داشته باشید که موفقیت آپلود لزوماً به این معنا نیست که آپلودها مطابقت داشته باشند.

هنگام گزارش معیارهای تبدیل برای کمپین‌های خود، به معیارهای رابط کاربری Mapping مراجعه کنید تا معیارهای رابط کاربری Google Ads را با فیلدهای گزارش API Google Ads مرتبط کنید. همچنین می‌توانید از منبع conversion_action پرس و جو کنید تا تعداد کل تبدیل‌ها و کل ارزش تبدیل را برای یک اقدام تبدیل مشخص مشاهده کنید.

مراحل بعدی

اگر نیاز به تنظیم تبدیل‌های خود دارید، از راهنمای تنظیمات تبدیل آپلود دیدن کنید.

برای راهنمایی در مورد عیب یابی تبدیل های پیشرفته خود برای یکپارچه سازی سرنخ ها، به راهنمای عیب یابی ادامه دهید.