Tính năng lượt chuyển đổi nâng cao cho khách hàng tiềm năng giúp bạn cải thiện độ chính xác của kết quả đo lường lượt chuyển đổi ngoại tuyến bằng cách tải các lượt chuyển đổi từ lượt nhấp lên. Những lượt chuyển đổi này chứa giá trị nhận dạng người dùng đã băm và một số thông tin bổ sung không bắt buộc giúp Google Ads liên kết lượt chuyển đổi với quảng cáo đã thu hút khách hàng tiềm năng.
Hãy nhớ xem lại hướng dẫn Bắt đầu và triển khai các điều kiện tiên quyết để sử dụng tính năng lượt chuyển đổi nâng cao cho khách hàng tiềm năng trước khi tiếp tục triển khai.
Bạn có thể tải lượt chuyển đổi nâng cao cho khách hàng tiềm năng lên thông qua giao diện người dùng Google Ads, như mô tả trong Trung tâm trợ giúp, hoặc thông qua API Google Ads, như mô tả trong hướng dẫn này.
Thiết kế chế độ tích hợp
Bạn có thể thiết kế chế độ tích hợp.
Luồng sử dụng
Dưới đây là quy trình tổng thể để tải lượt chuyển đổi nâng cao cho khách hàng tiềm năng lên trong API Google Ads.
Đảm bảo rằng bạn đã triển khai các điều kiện tiên quyết, bao gồm:
Bật tính năng theo dõi lượt chuyển đổi.
Chấp nhận các điều khoản về dữ liệu khách hàng.
Định cấu hình tính năng gắn thẻ trên biểu mẫu khách hàng tiềm năng trên trang web của bạn.
Hãy xem phần Triển khai các điều kiện tiên quyết để biết hướng dẫn chi tiết.
Chuẩn hoá và băm dữ liệu khách hàng tiềm năng, chẳng hạn như địa chỉ email, số điện thoại và địa chỉ gửi thư.
Đặt dữ liệu khách hàng tiềm năng đã chuẩn hoá và băm vào các đối tượng
ClickConversion
. Đối với mỗiClickConversion
:Điền dữ liệu khách hàng tiềm năng đã chuẩn hoá và băm vào
user_identifiers
. Nếu bạn có nhiều giá trị nhận dạng người dùng, hãy tạo mộtUserIdentifier
riêng cho mỗi giá trị nhận dạng, tối đa là 5 giá trị nhận dạng.(Không bắt buộc nhưng bạn nên thực hiện) Điền vào
order_id
.(Không bắt buộc) Điền
gclid
để đo lường chính xác nhất.Đảm bảo bạn điền trường
consent
của đối tượngClickConversion
.Đặt
conversion_action
thành tên tài nguyên củaConversionAction
cótype
làUPLOAD_CLICKS
. Đây phải là tên tài nguyên củaConversionAction
mà bạn đã tạo khi triển khai các điều kiện tiên quyết.
Tải các thao tác tạo
ClickConversion
lênConversionUploadService
, đặtpartial_failure
thànhtrue
.Xem lại nội dung bạn đã tải lên.
Các phương pháp hay nhất
Hãy lưu ý các phương pháp hay nhất sau đây khi triển khai tính năng lượt chuyển đổi nâng cao cho khách hàng tiềm năng.
Kiểm tra mã nhận dạng khách hàng
Khi bạn tải lượt chuyển đổi lên, mã khách hàng phải được đặt thành tài khoản chứa hành động chuyển đổi và thực hiện tính năng theo dõi lượt chuyển đổi. Để kiểm tra chế độ cài đặt này, hãy truy vấn tài nguyên Customer
phân phát Google Ads cho ConversionTrackingSetting
. Thực hiện truy vấn sau với GoogleAdsService.SearchStream
để tìm giá trị của customer.conversion_tracking_setting.google_ads_conversion_customer
.
Thêm nhiều giá trị nhận dạng nếu bạn có
Nếu chỉ định order_id
cho một lượt chuyển đổi, bạn nên thêm order_id
đó.
Nếu có gclid
cho một lượt chuyển đổi, bạn nên gửi gclid
đó cùng với user_identifiers
để cải thiện hiệu suất. Hơn nữa, nếu bạn có nhiều UserIdentifier
cho lượt chuyển đổi, thì việc thêm nhiều UserIdentifier
có thể làm tăng khả năng trùng khớp. Đưa tất cả giá trị nhận dạng vào cùng một ClickConversion
.
Xem lại các lỗi không thành công một phần khi thiết lập chế độ tích hợp
Trong lần đầu tiên thiết lập tính năng lượt chuyển đổi nâng cao để tích hợp khách hàng tiềm năng, hãy xem xét và khắc phục mọi lỗi một phần trong trường partial_failure_error
của phản hồi. Nếu có vấn đề trong quá trình thiết lập, bạn cần kiểm tra trường này để điều tra và giải quyết vấn đề. Để biết thêm thông tin chi tiết và ví dụ về cách xử lý lỗi không thành công một phần, hãy truy cập vào hướng dẫn dành riêng cho lỗi không thành công một phần.
Khi bạn xem xét các lỗi không thành công một phần, hãy tham khảo bảng các lỗi thường gặp trong hướng dẫn khắc phục sự cố. Sau khi bạn đã giải quyết mọi vấn đề xuất hiện trong lỗi không thành công một phần và quá trình tích hợp đã hoàn tất, hãy chuyển sang sử dụng tính năng chẩn đoán dữ liệu ngoại tuyến để thường xuyên xem xét tình trạng của lượt chuyển đổi.
Tạo nhiều lượt chuyển đổi theo lô trong một yêu cầu
Nếu bạn có nhiều lượt chuyển đổi cần tải lên, hãy nhóm các thao tác thành một UploadClickConversionsRequest
thay vì gửi một yêu cầu tải lên cho mỗi lượt chuyển đổi.
Hãy xem hướng dẫn về hạn mức để biết các giới hạn về số lượt chuyển đổi trên mỗi yêu cầu.
Nếu bạn muốn chẩn đoán dữ liệu ngoại tuyến nhóm một tập hợp các yêu cầu trong cùng một công việc logic, hãy đặt job_id
của tất cả các yêu cầu thành cùng một giá trị. Điều này có thể hữu ích nếu bạn có một công việc hoặc quy trình tải lên một số lượng lớn lượt chuyển đổi bằng nhiều yêu cầu. Nếu đặt job_id
trên mỗi yêu cầu đó thành cùng một giá trị, thì bạn có thể truy xuất một mục duy nhất cho công việc từ job_summaries
.
Thay vào đó, nếu bạn cho phép API Google Ads chỉ định một giá trị do hệ thống tạo cho job_id
của mỗi yêu cầu, thì job_summaries
sẽ chứa một mục riêng cho mỗi yêu cầu, điều này có thể khiến việc phân tích tình trạng tổng thể của công việc trở nên khó khăn hơn.
Tải tất cả sự kiện lượt chuyển đổi ngoại tuyến hiện có lên
Để đảm bảo báo cáo lượt chuyển đổi đầy đủ và chính xác, hãy tải tất cả sự kiện lượt chuyển đổi ngoại tuyến hiện có lên, bao gồm cả những sự kiện có thể không đến từ Google Ads.
Việc tải tất cả sự kiện chuyển đổi lên sẽ dẫn đến lỗi CLICK_NOT_FOUND
cho mọi sự kiện không phải của Google Ads. Vì những lỗi này là dự kiến khi tải tất cả sự kiện chuyển đổi lên, nên UploadClickConversionsRequest
có trường debug_enabled
.
Nếu
debug_enabled
làfalse
hoặc không được đặt, API Google Ads sẽ chỉ thực hiện xác thực đầu vào cơ bản, bỏ qua các bước kiểm tra tải lên tiếp theo và trả về kết quả thành công ngay cả khi không tìm thấy lượt nhấp nào chouser_identifiers
đã cung cấp.Đây là tuỳ chọn mặc định.
Nếu
debug_enabled
làtrue
, API Google Ads sẽ thực hiện tất cả các quy trình xác thực và trả về lỗiCLICK_NOT_FOUND
cho mọiClickConversion
không có lượt chuyển đổi trên Google Ads chouser_identifiers
đã cung cấp.
Trong quá trình phát triển và kiểm thử, bạn có thể đặt debug_enabled
thành true
để giúp xác định vấn đề. Ví dụ: nếu có một tập hợp các lượt chuyển đổi và user_identifiers
mà bạn biết là từ lượt chuyển đổi trên Google Ads, thì bạn có thể sử dụng chế độ cài đặt true
để xác thực rằng các lượt tải lên đó không dẫn đến lỗi CLICK_NOT_FOUND
. Tuy nhiên, khi bạn tiếp tục phát triển và thử nghiệm, bạn nên đặt debug_enabled
thành false
để tránh lỗi quá mức.
Không sử dụng dữ liệu phân bổ bên ngoài
Đừng đặt external_attribution_data
trên ClickConversion
hoặc chỉ định một conversion_action
sử dụng mô hình phân bổ bên ngoài. Google Ads không hỗ trợ lượt chuyển đổi được phân bổ bên ngoài cho các lượt tải lên bằng mã nhận dạng.
Chuẩn bị dữ liệu để tải lên
Để bảo vệ quyền riêng tư, bạn phải băm những dữ liệu sau bằng thuật toán SHA-256 trước khi tải lên:
- Địa chỉ email
- Số điện thoại
- Tên
- Họ
- Địa chỉ đường phố
Không băm những dữ liệu sau:
- Quốc gia
- Tiểu bang
- Thành phố
- Mã vùng
Để chuẩn hoá kết quả băm, bạn phải làm như sau trước khi băm một trong các giá trị này:
- Xoá khoảng trắng ở đầu và cuối.
- Chuyển đổi văn bản thành chữ thường.
- Định dạng số điện thoại theo tiêu chuẩn E164.
- Xoá tất cả dấu chấm (
.
) đứng trước tên miền trong địa chỉ emailgmail.com
và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.lower() email_parts = normalized_email.split("@") # Checks whether the domain of the email address is either "gmail.com" # or "googlemail.com". If this regex does not match then this statement # will evaluate to None. is_gmail = re.match(r"^(gmail|googlemail)\.com$", email_parts[1]) # Check that there are at least two segments and the second segment # matches the above regex expression validating the email domain name. if len(email_parts) > 1 and is_gmail: # Removes any '.' characters from the portion of the email address # before the domain if the domain is gmail.com or googlemail.com. email_parts[0] = email_parts[0].replace(".", "") normalized_email = "@".join(email_parts) return normalize_and_hash(normalized_email) def normalize_and_hash(s): """Normalizes and hashes a string with SHA-256. Private customer data must be hashed during upload, as described at: https://support.google.com/google-ads/answer/7474263 Args: s: The string to perform this operation on. Returns: A normalized (lowercase, removed whitespace) and SHA-256 hashed string. """ return hashlib.sha256(s.strip().lower().encode()).hexdigest()
Ruby
# Returns the result of normalizing and then hashing the string using the # provided digest. Private customer data must be hashed during upload, as # described at https://support.google.com/google-ads/answer/7474263. def normalize_and_hash(str) # Remove leading and trailing whitespace and ensure all letters are lowercase # before hasing. Digest::SHA256.hexdigest(str.strip.downcase) end # Returns the result of normalizing and hashing an email address. For this use # case, 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); }
Tải lượt chuyển đổi nâng cao lên
Các đoạn mã sau đây minh hoạ cách tạo tệp tải lượt chuyển đổi lên chứa giá trị nhận dạng cho địa chỉ email và số điện thoại, với việc chuẩn hoá và băm được áp dụng khi cần. Tốt nhất là bạn nên thêm gclid
và order_id
vào lượt chuyển đổi nếu có.
Thêm giá trị nhận dạng người dùng vào 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", "alex.2@example.com") // Phone number to be converted to E.164 format, with a leading '+' as required. .put("phone", "+1 800 5550102") // This example lets you put conversion details as arguments, but in reality you might // store this data alongside other user data, so we include it in this sample user // record. .put("conversionActionId", Long.toString(conversionActionId)) .put("conversionDateTime", conversionDateTime) .put("conversionValue", Double.toString(conversionValue)) .put("currencyCode", "USD"); // Adds entries for the optional fields. if (orderId != null) { rawRecordBuilder.put("orderId", orderId); } if (gclid != null) { rawRecordBuilder.put("gclid", gclid); } if (adUserDataConsent != null) { rawRecordBuilder.put("adUserDataConsent", adUserDataConsent.name()); } // Builds the map representing the record. Map<String, String> rawRecord = rawRecordBuilder.build(); // Creates a SHA256 message digest for hashing user identifiers in a privacy-safe way, as // described at https://support.google.com/google-ads/answer/9888656. MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256"); // Creates a list for the user identifiers. List<UserIdentifier> userIdentifiers = new ArrayList<>(); // Creates a user identifier using the hashed email address, using the normalize and hash method // specifically for email addresses. UserIdentifier emailIdentifier = UserIdentifier.newBuilder() // Optional: specify the user identifier source. .setUserIdentifierSource(UserIdentifierSource.FIRST_PARTY) // Uses the normalize and hash method specifically for email addresses. .setHashedEmail(normalizeAndHashEmailAddress(sha256Digest, rawRecord.get("email"))) .build(); userIdentifiers.add(emailIdentifier); // Creates a user identifier using normalized and hashed phone info. UserIdentifier hashedPhoneNumberIdentifier = UserIdentifier.newBuilder() .setHashedPhoneNumber(normalizeAndHash(sha256Digest, rawRecord.get("phone"))) .build(); // Adds the hashed phone number identifier to the UserData object's list. userIdentifiers.add(hashedPhoneNumberIdentifier); // Adds the user identifiers to the conversion. clickConversionBuilder.addAllUserIdentifiers(userIdentifiers);
C#
// Adds a user identifier using the hashed email address, using the normalize // and hash method specifically for email addresses. clickConversion.UserIdentifiers.Add(new UserIdentifier() { HashedEmail = NormalizeAndHashEmailAddress("alex.2@example.com"), // Optional: Specifies the user identifier source. UserIdentifierSource = UserIdentifierSource.FirstParty }); // Adds a user identifier using normalized and hashed phone info. clickConversion.UserIdentifiers.Add(new UserIdentifier() { HashedPhoneNumber = NormalizeAndHash("+1 800 5550102"), // Optional: Specifies the user identifier source. UserIdentifierSource = UserIdentifierSource.FirstParty }); // Adds a user identifier with all the required mailing address elements. clickConversion.UserIdentifiers.Add(new UserIdentifier() { AddressInfo = new OfflineUserAddressInfo() { // FirstName and LastName must be normalized and hashed. HashedFirstName = NormalizeAndHash("Alex"), HashedLastName = NormalizeAndHash("Quinn"), // CountryCode and PostalCode are sent in plain text. CountryCode = "US", PostalCode = "94045" } });
PHP
// Creates a click conversion with the specified attributes. $clickConversion = new ClickConversion(); // Extract user email and phone from the raw data, normalize and hash it, then wrap it in // UserIdentifier objects. Creates a separate UserIdentifier object for each. // The data in this example is hardcoded, but in your application you might read the raw // data from an input file. // IMPORTANT: Since the identifier attribute of UserIdentifier // (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) is a // oneof // (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set only ONE // of hashedEmail, hashedPhoneNumber, mobileId, thirdPartyUserId, or addressInfo. Setting // more than one of these attributes on the same UserIdentifier will clear all the other // members of the oneof. For example, the following code is INCORRECT and will result in a // UserIdentifier with ONLY a hashedPhoneNumber. // // $incorrectlyPopulatedUserIdentifier = new UserIdentifier([ // 'hashed_email' => '...', // 'hashed_phone_number' => '...' // ]); $rawRecord = [ // Email address that includes a period (.) before the Gmail domain. 'email' => 'alex.2@example.com', // Phone number to be converted to E.164 format, with a leading '+' as required. 'phone' => '+1 800 5550102', // This example lets you input conversion details as arguments, but in reality you might // store this data alongside other user data, so we include it in this sample user // record. 'orderId' => $orderId, 'gclid' => $gclid, 'conversionActionId' => $conversionActionId, 'conversionDateTime' => $conversionDateTime, 'conversionValue' => $conversionValue, 'currencyCode' => 'USD', 'adUserDataConsent' => $adUserDataConsent ]; // 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": "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)
Ruby
# Extract user email and phone from the raw data, normalize and hash it, # then wrap it in UserIdentifier objects. Create a separate UserIdentifier # object for each. The data in this example is hardcoded, but in your # application you might read the raw data from an input file. # IMPORTANT: Since the identifier attribute of UserIdentifier # (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) # is a oneof # (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must # set only ONE of hashed_email, hashed_phone_number, mobile_id, # third_party_user_id, or address_info. Setting more than one of these # attributes on the same UserIdentifier will clear all the other members of # the oneof. For example, the following code is INCORRECT and will result in # a UserIdentifier with ONLY a hashed_phone_number: # # incorrectly_populated_user_identifier.hashed_email = "..."" # incorrectly_populated_user_identifier.hashed_phone_number = "..."" raw_record = { # Email address that includes a period (.) before the Gmail domain. "email" => "alex.2@example.com", # Phone number to be converted to E.164 format, with a leading '+' as # required. "phone" => "+1 800 5550102", # This example lets you input conversion details as arguments, # but in reality you might store this data alongside other user data, # so we include it in this sample user record. "order_id" => order_id, "gclid" => gclid, "conversion_action_id" => conversion_action_id, "conversion_date_time" => conversion_date_time, "conversion_value" => conversion_value, "currency_code" => "USD", "ad_user_data_consent" => ad_user_data_consent, } 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
Perl
# Create an empty click conversion. my $click_conversion = Google::Ads::GoogleAds::V18::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::V18::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::V18::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::V18::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;
Thêm thông tin chi tiết về lượt chuyển đổi vào 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")))); } // 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; }
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"] ]
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
Perl
# Add details of the conversion. $click_conversion->{conversionAction} = Google::Ads::GoogleAds::V18::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::V18::Common::Consent->new({ adUserData => $raw_record->{adUserDataConsent}}); }
Tải ClickConversion lên
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" });
Xem lại nội dung bạn tải lên
Sử dụng tính năng chẩn đoán dữ liệu ngoại tuyến để xem xét tổng thể tình trạng của các video tải lên gần đây. Xin lưu ý rằng việc tải lên thành công không nhất thiết có nghĩa là nội dung tải lên có kết quả trùng khớp.
Khi báo cáo về các chỉ số lượt chuyển đổi cho chiến dịch, hãy tham khảo bài viết Liên kết các chỉ số giao diện người dùng để liên kết các chỉ số giao diện người dùng của Google Ads với các trường báo cáo API Google Ads. Bạn cũng có thể truy vấn tài nguyên conversion_action
để xem tổng số lượt chuyển đổi và tổng giá trị lượt chuyển đổi cho một hành động chuyển đổi nhất định.
Các bước tiếp theo
Nếu bạn cần điều chỉnh lượt chuyển đổi, hãy xem hướng dẫn Tải mức điều chỉnh lượt chuyển đổi lên.
Để biết hướng dẫn khắc phục sự cố khi tích hợp tính năng lượt chuyển đổi nâng cao cho khách hàng tiềm năng, hãy tiếp tục xem hướng dẫn Khắc phục sự cố.