Вы можете использовать API Google Ads для импорта данных о конверсиях, совершенных в офлайн-режиме, в Google Ads, чтобы отслеживать объявления, которые привели к продажам в офлайн-среде, например, по телефону или через торгового представителя.
Для того чтобы в полной мере воспользоваться преимуществами импорта данных о конверсиях, мы рекомендуем внедрить расширенные алгоритмы конверсии для лидов, которые используют GCLID и предоставленные пользователем данные для максимальной надежности и эффективности.
Улучшенная конверсия
Улучшенные показатели конверсии помогают повысить точность измерения конверсий, дополняя их собственными данными о конверсиях, такими как адрес электронной почты и номер телефона.
Существует два типа расширенных преобразований. Подробнее см. раздел «О расширенных преобразованиях» .
В следующем разделе объясняется, как повысить конверсию в офлайн-режиме , функция, также называемая повышенной конверсией для лидов .
Что такое повышение конверсии лидов?
Улучшенная функция импорта офлайн-конверсий для лидов — это усовершенствованная версия импорта офлайн-конверсий, которая использует предоставленные пользователем данные, такие как адреса электронной почты, для дополнения импортированных данных об офлайн-конверсиях с целью повышения точности и эффективности назначения ставок. При импорте офлайн-конверсий предоставленные хэшированные данные о клиентах используются для сопоставления с кампанией Google Ads путем сопоставления с теми же данными, собранными на вашем веб-сайте, например, с формой лида, и с авторизованными клиентами, которые взаимодействовали с вашей рекламой. Для получения дополнительной информации см. раздел «Об улучшенной функции импорта офлайн-конверсий для лидов» .
Существует два способа повышения конверсии лидов в зависимости от того, используете ли вы тег Google для отслеживания событий отправки форм на вашей веб-странице. Для достижения наилучшей производительности и надежности мы рекомендуем использовать тег Google для повышения конверсии лидов.
- Если вы начинаете с нуля, начните с раздела «Предварительные требования» .
- Если у вас уже настроен импорт данных о конверсиях в офлайн-режиме и вы хотите перейти на расширенные данные о конверсиях для лидов, мы рекомендуем начать с раздела «Настройка тегов» .
- Если вы уже настроили тег Google или не планируете его использовать, и только начинаете работу над интеграцией API Google Ads, перейдите к разделу «Внедрение API» .
- Если у вас нет возможности импортировать предоставленные пользователем данные или вы полагаетесь на внешние источники данных для ваших конверсий, см. Руководство по импорту данных для офлайн-конверсий (Legacy Offline Conversion Imports Guide ).
Предварительные требования
Для начала убедитесь, что вы выполнили все шаги, описанные в разделе «Начало работы» .
Для использования расширенных показателей конверсии лидов необходимо дать согласие на их применение и принять условия обработки данных клиентов. Проверить выполнение этих условий можно, отправив следующий запрос клиенту, использующему конверсию Google Ads:
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 Tag Manager, следуйте этим инструкциям .
Реализация API
Вот общая схема импорта улучшенных показателей конверсии для лидов с использованием API Google Ads.
Нормализуйте и хешируйте предоставленные пользователем данные , такие как адрес электронной почты и номер телефона.
Заполните объекты
ClickConversionнормализованными и хешированными данными, предоставленными пользователем.Импортируйте объекты
ClickConversionв Google Ads API с помощьюConversionUploadService. Дополнительные сведения см. в разделеUploadClickConversions.
Получите имя ресурса действия конверсии.
Для загрузки данных о конверсиях необходимо указать имя ресурса ConversionAction настроенного в Google Ads для импорта конверсий по кликам. Имя ресурса можно найти, выполнив запрос к ресурсу conversion_action с помощью следующего GAQL-запроса:
SELECT
customer.id,
conversion_action.id,
conversion_action.name,
conversion_action.type,
conversion_action.resource_name
FROM conversion_action
WHERE conversion_action.type = 'UPLOAD_CLICKS'
AND conversion_action.status = 'ENABLED'
Нормализация и хеширование предоставленных пользователем данных.
В целях обеспечения конфиденциальности следующие данные перед импортом должны быть хешированы с использованием алгоритма SHA-256:
- Адрес электронной почты
- Номер телефона
Для стандартизации результатов хеширования выполните следующие действия перед хешированием этих значений:
- Удалите пробелы в начале и конце текста.
- Преобразовать текст в нижний регистр.
- Форматируйте телефонные номера в соответствии со стандартом E164 .
- Адреса электронной почты:
- Удалите все точки (
.) в имени пользователя (перед символом@). Например,jane.doe@example.comстановитсяjanedoe@example.com. - Удалите символ плюса (
+) и все символы, следующие за ним в имени пользователя (перед символом@). Например,janedoe+newsletter@example.comстановитсяjanedoe@example.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: str) -> str: """Returns the result of normalizing and hashing an email address. For this use case, Google Ads requires removal of any '.' characters preceding "gmail.com" or "googlemail.com" Args: email_address: An email address to normalize. Returns: A normalized (lowercase, removed whitespace) and SHA-265 hashed string. """ normalized_email: str = email_address.strip().lower() email_parts: list[str] = normalized_email.split("@") # Check that there are at least two segments if len(email_parts) > 1: # Checks whether the domain of the email address is either "gmail.com" # or "googlemail.com". If this regex does not match then this statement # will evaluate to None. if re.match(r"^(gmail|googlemail)\.com$", email_parts[1]): # Removes any '.' characters from the portion of the email address # before the domain if the domain is gmail.com or googlemail.com. email_parts[0] = email_parts[0].replace(".", "") normalized_email = "@".join(email_parts) return normalize_and_hash(normalized_email) def normalize_and_hash(s: str) -> str: """Normalizes and hashes a string with SHA-256. Private customer data must be hashed during upload, as described at: https://support.google.com/google-ads/answer/7474263 Args: s: The string to perform this operation on. Returns: A normalized (lowercase, removed whitespace) and SHA-256 hashed string. """ return hashlib.sha256(s.strip().lower().encode()).hexdigest()
Руби
# 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 GCLID — это идентификаторы, которые извлекаются из параметров URL-адреса, когда пользователь кликает на вашу рекламу и переходит на ваш веб-сайт.
-
gbraid Параметр
gbraid— это параметр URL, который присутствует, когда пользователь кликает на рекламу в интернете и перенаправляется в ваше iOS-приложение.-
wbraid Параметр
wbraid— это параметр URL, который присутствует, когда пользователь кликает на рекламу в приложении iOS и перенаправляется на вашу веб-страницу.-
cart_data Содержит подробную информацию о конверсии на уровне отдельных товаров. Заполнение поля
cart_dataнеобходимо для отображения данных о корзине — таких как купленные товары, цена и количество — в пользовательском интерфейсе Google Ads. См. определение объектаCartDataдля получения информации о необходимой структуре и узнайте больше о конверсиях с использованием данных корзины .-
user_identifiers При использовании расширенных показателей конверсии для лидов необходимо заполнить поле
user_identifiersнормализованными и хешированными данными, предоставленными пользователем. Если доступно несколько идентификаторов пользователей, создайте отдельныйUserIdentifierдля каждого из них, максимум пять идентификаторов.-
conversion_date_time Дата и время конвертации.
Значение должно содержать указание часового пояса, а формат должен быть следующим:
yyyy-mm-dd HH:mm:ss+|-HH:mm, например:2022-01-01 19:32:45-05:00(без учета летнего времени).Часовой пояс может быть любым допустимым значением: он не обязательно должен совпадать с часовым поясом аккаунта. Однако, если вы планируете сравнивать импортированные данные о конверсиях с данными в пользовательском интерфейсе Google Ads, мы рекомендуем использовать тот же часовой пояс, что и ваш аккаунт Google Ads, чтобы количество конверсий совпадало. Более подробную информацию и примеры можно найти в Справочном центре , а список допустимых идентификаторов часовых поясов см. в разделе «Коды и форматы» .
-
conversion_action Имя ресурса
ConversionActionдля офлайн-конверсии.Действие конверсии должно иметь
typeUPLOAD_CLICKSи должно существовать в клиенте конверсии Google Ads в аккаунте Google Ads, связанном с кликом.-
conversion_value Значение конверсии.
-
currency_code Код валюты для
conversion_value.-
consent Настоятельно рекомендуется заполнить поле
consentв объектеClickConversion. Если оно не задано, ваши конверсии могут быть не отнесены к определенному событию.-
order_id Также известен как идентификатор транзакции для преобразования. Это поле необязательно, но настоятельно рекомендуется, поскольку оно упрощает ссылку на импортированные преобразования при внесении корректировок . Если вы зададите его во время импорта, вы должны использовать его для любых корректировок. Чтобы узнать больше о том, как использовать идентификатор транзакции для минимизации дублирующих преобразований, см. эту статью в Справочном центре .
-
custom_variables Значения для пользовательских переменных преобразования .
Google Ads не поддерживает использование пользовательских переменных конверсии в сочетании с
wbraidилиgbraid.-
conversion_environment Указывает среду, в которой была зафиксирована данная конверсия. Например,
APPилиWEB.-
session_attributes_encodedиsession_attributes_key_value_pairs Атрибуты сессии представляют собой агрегированные идентификаторы, используемые для атрибуции конверсий. Они работают в дополнение к GCLID и параметрам URL (таким как GBRAID), а также к данным, предоставляемым пользователем, что имеет центральное значение для повышения конверсии лидов. Существует два способа импорта атрибутов сессии: путем предоставления закодированного токена, сгенерированного нашим кодом JavaScript в браузере, или путем предоставления отдельных пар ключ-значение для каждого из идентификаторов.
Для максимальной эффективности вашей кампании мы рекомендуем, по возможности, импортировать идентификаторы кликов, предоставленные пользователями данные и атрибуты сессий для всех ваших конверсий.
Java
// Sets one of the sessionAttributesEncoded or sessionAttributesKeyValuePairs if either is // provided. if (rawRecord.containsKey("sessionAttributesEncoded")) { clickConversionBuilder.setSessionAttributesEncoded( ByteString.copyFromUtf8(rawRecord.get("sessionAttributesEncoded"))); } else if (rawRecord.containsKey("sessionAttributesMap")) { List<String> pairings = Arrays.stream(rawRecord.get("sessionAttributesMap").split(" ")) .map(String::trim) .collect(Collectors.toList()); SessionAttributesKeyValuePairs.Builder sessionAttributePairs = SessionAttributesKeyValuePairs.newBuilder(); for (String pair : pairings) { String[] parts = pair.split("=", 2); if (parts.length != 2) { throw new IllegalArgumentException( "Failed to read the sessionAttributesMap. SessionAttributesMap must use a " + "space-delimited list of session attribute key value pairs. Each pair should be" + " separated by an equal sign, for example: 'gad_campaignid=12345 gad_source=1'"); } sessionAttributePairs.addKeyValuePairs( SessionAttributeKeyValuePair.newBuilder() .setSessionAttributeKey(parts[0]) .setSessionAttributeValue(parts[1]) .build()); } clickConversionBuilder.setSessionAttributesKeyValuePairs(sessionAttributePairs.build()); }
C#
if (!string.IsNullOrEmpty(sessionAttributesEncoded)) { clickConversion.SessionAttributesEncoded = ByteString.CopyFrom(sessionAttributesEncoded, Encoding.Unicode); } else if (!string.IsNullOrEmpty(sessionAttributes)) { IEnumerable<SessionAttributeKeyValuePair> parsedSessionAttributes = sessionAttributes.Split(';').Select(pair => { string[] split = pair.Split('='); return new SessionAttributeKeyValuePair() { SessionAttributeKey = split[0], SessionAttributeValue = split[1] }; }); clickConversion.SessionAttributesKeyValuePairs = new SessionAttributesKeyValuePairs(); clickConversion.SessionAttributesKeyValuePairs.KeyValuePairs .AddRange(parsedSessionAttributes); }
PHP
This example is not yet available in PHP; you can take a look at the other languages.
Python
# Set one of the session_attributes_encoded or # session_attributes_key_value_pairs fields if either are provided. if session_attributes_encoded: click_conversion.session_attributes_encoded = session_attributes_encoded elif session_attributes_dict: for key, value in session_attributes_dict.items(): pair: SessionAttributeKeyValuePair = client.get_type( "SessionAttributeKeyValuePair" ) pair.session_attribute_key = key pair.session_attribute_value = value click_conversion.session_attributes_key_value_pairs.key_value_pairs.append( pair )
Руби
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::V22::Services::ConversionUploadService::SessionAttributeKeyValuePair ->new({sessionAttributeKey => $key, sessionAttributeValue => $value}); push @{$click_conversion->{sessionAttributesKeyValuePairs}{keyValuePairs} }, $pair; } }
-
user_ip_address IP-адрес клиента в момент перехода на целевую страницу после клика по рекламе и до совершения конверсии. Это IP-адрес устройства клиента, а не сервера рекламодателя.
Это поле представляет собой строку, отображающую IP-адрес в формате IPv4 или IPv6 . Например:
- IPv4:
"192.0.2.0" - IPv6:
"2001:0DB8:1234:5678:9999:1111:0000:0001"
Пример кода
В этом примере показано, как присвоить нормализованные и хешированные данные, предоставленные пользователем, объекту 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()); } if (sessionAttributesEncoded != null) { rawRecordBuilder.put("sessionAttributesEncoded", sessionAttributesEncoded); } if (sessionAttributesMap != null) { rawRecordBuilder.put("sessionAttributesMap", sessionAttributesMap); } // Builds the map representing the record. Map<String, String> rawRecord = rawRecordBuilder.build(); // Creates a SHA256 message digest for hashing user identifiers in a privacy-safe way, as // described at https://support.google.com/google-ads/answer/9888656. MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256"); // Creates a list for the user identifiers. List<UserIdentifier> userIdentifiers = new ArrayList<>(); // Creates a user identifier using the hashed email address, using the normalize and hash method // specifically for email addresses. UserIdentifier emailIdentifier = UserIdentifier.newBuilder() // Optional: specify the user identifier source. .setUserIdentifierSource(UserIdentifierSource.FIRST_PARTY) // Uses the normalize and hash method specifically for email addresses. .setHashedEmail(normalizeAndHashEmailAddress(sha256Digest, rawRecord.get("email"))) .build(); userIdentifiers.add(emailIdentifier); // Creates a user identifier using normalized and hashed phone info. UserIdentifier hashedPhoneNumberIdentifier = UserIdentifier.newBuilder() .setHashedPhoneNumber(normalizeAndHash(sha256Digest, rawRecord.get("phone"))) .build(); // Adds the hashed phone number identifier to the UserData object's list. userIdentifiers.add(hashedPhoneNumberIdentifier); // Adds the user identifiers to the conversion. clickConversionBuilder.addAllUserIdentifiers(userIdentifiers);
C#
// Adds a user identifier using the hashed email address, using the normalize // and hash method specifically for email addresses. clickConversion.UserIdentifiers.Add(new UserIdentifier() { HashedEmail = NormalizeAndHashEmailAddress("alex.2@example.com"), // Optional: Specifies the user identifier source. UserIdentifierSource = UserIdentifierSource.FirstParty }); // Adds a user identifier using normalized and hashed phone info. clickConversion.UserIdentifiers.Add(new UserIdentifier() { HashedPhoneNumber = NormalizeAndHash("+1 800 5550102"), // Optional: Specifies the user identifier source. UserIdentifierSource = UserIdentifierSource.FirstParty }); // Adds a user identifier with all the required mailing address elements. clickConversion.UserIdentifiers.Add(new UserIdentifier() { AddressInfo = new OfflineUserAddressInfo() { // FirstName and LastName must be normalized and hashed. HashedFirstName = NormalizeAndHash("Alex"), HashedLastName = NormalizeAndHash("Quinn"), // CountryCode and PostalCode are sent in plain text. CountryCode = "US", PostalCode = "94045" } });
PHP
// Creates a click conversion with the specified attributes. $clickConversion = new ClickConversion(); // Extract user email and phone from the raw data, normalize and hash it, then wrap it in // UserIdentifier objects. Creates a separate UserIdentifier object for each. // The data in this example is hardcoded, but in your application you might read the raw // data from an input file. // IMPORTANT: Since the identifier attribute of UserIdentifier // (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) is a // oneof // (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set only ONE // of hashedEmail, hashedPhoneNumber, mobileId, thirdPartyUserId, or addressInfo. Setting // more than one of these attributes on the same UserIdentifier will clear all the other // members of the oneof. For example, the following code is INCORRECT and will result in a // UserIdentifier with ONLY a hashedPhoneNumber. // // $incorrectlyPopulatedUserIdentifier = new UserIdentifier([ // 'hashed_email' => '...', // 'hashed_phone_number' => '...' // ]); $rawRecord = [ // Email address that includes a period (.) before the Gmail domain. 'email' => 'alex.2@example.com', // Phone number to be converted to E.164 format, with a leading '+' as required. 'phone' => '+1 800 5550102', // This example lets you input conversion details as arguments, but in reality you might // store this data alongside other user data, so we include it in this sample user // record. 'orderId' => $orderId, 'gclid' => $gclid, 'conversionActionId' => $conversionActionId, 'conversionDateTime' => $conversionDateTime, 'conversionValue' => $conversionValue, 'currencyCode' => 'USD', 'adUserDataConsent' => $adUserDataConsent, 'sessionAttributesEncoded' => $sessionAttributesEncoded, 'sessionAttributesDict' => $sessionAttributesDict ]; // Creates a list for the user identifiers. $userIdentifiers = []; // Uses the SHA-256 hash algorithm for hashing user identifiers in a privacy-safe way, as // described at https://support.google.com/google-ads/answer/9888656. $hashAlgorithm = "sha256"; // Creates a user identifier using the hashed email address, using the normalize and hash // method specifically for email addresses. $emailIdentifier = new UserIdentifier([ // Uses the normalize and hash method specifically for email addresses. 'hashed_email' => self::normalizeAndHashEmailAddress( $hashAlgorithm, $rawRecord['email'] ), // Optional: Specifies the user identifier source. 'user_identifier_source' => UserIdentifierSource::FIRST_PARTY ]); $userIdentifiers[] = $emailIdentifier; // Checks if the record has a phone number, and if so, adds a UserIdentifier for it. if (array_key_exists('phone', $rawRecord)) { $hashedPhoneNumberIdentifier = new UserIdentifier([ 'hashed_phone_number' => self::normalizeAndHash( $hashAlgorithm, $rawRecord['phone'], true ) ]); // Adds the hashed email identifier to the user identifiers list. $userIdentifiers[] = $hashedPhoneNumberIdentifier; } // Adds the user identifiers to the conversion. $clickConversion->setUserIdentifiers($userIdentifiers);
Python
# Extract user email and phone from the raw data, normalize and hash it, # then wrap it in UserIdentifier objects. Create a separate UserIdentifier # object for each. The data in this example is hardcoded, but in your # application you might read the raw data from an input file. # IMPORTANT: Since the identifier attribute of UserIdentifier # (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) # is a oneof # (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must # set only ONE of hashed_email, hashed_phone_number, mobile_id, # third_party_user_id, or address_info. Setting more than one of these # attributes on the same UserIdentifier will clear all the other members of # the oneof. For example, the following code is INCORRECT and will result in # a UserIdentifier with ONLY a hashed_phone_number: # # incorrectly_populated_user_identifier = client.get_type("UserIdentifier") # incorrectly_populated_user_identifier.hashed_email = "..."" # incorrectly_populated_user_identifier.hashed_phone_number = "..."" raw_record: Dict[str, Union[str, float]] = { # Email address that includes a period (.) before the Gmail domain. "email": "alex.2@example.com", # Phone number to be converted to E.164 format, with a leading '+' as # required. "phone": "+1 800 5550102", # This example lets you input conversion details as arguments, # but in reality you might store this data alongside other user data, # so we include it in this sample user record. "order_id": order_id, "gclid": gclid, "conversion_action_id": conversion_action_id, "conversion_date_time": conversion_date_time, "conversion_value": conversion_value, "currency_code": "USD", "ad_user_data_consent": ad_user_data_consent, } # Constructs the click conversion. click_conversion: ClickConversion = client.get_type("ClickConversion") # Creates a user identifier using the hashed email address, using the # normalize and hash method specifically for email addresses. email_identifier: UserIdentifier = client.get_type("UserIdentifier") # Optional: Specifies the user identifier source. email_identifier.user_identifier_source = ( client.enums.UserIdentifierSourceEnum.FIRST_PARTY ) # Uses the normalize and hash method specifically for email addresses. email_identifier.hashed_email = normalize_and_hash_email_address( raw_record["email"] ) # Adds the user identifier to the conversion. click_conversion.user_identifiers.append(email_identifier) # Checks if the record has a phone number, and if so, adds a UserIdentifier # for it. if raw_record.get("phone") is not None: phone_identifier: UserIdentifier = client.get_type("UserIdentifier") phone_identifier.hashed_phone_number = normalize_and_hash( raw_record["phone"] ) # Adds the phone identifier to the conversion adjustment. click_conversion.user_identifiers.append(phone_identifier)
Руби
# Extract user email and phone from the raw data, normalize and hash it, # then wrap it in UserIdentifier objects. Create a separate UserIdentifier # object for each. The data in this example is hardcoded, but in your # application you might read the raw data from an input file. # IMPORTANT: Since the identifier attribute of UserIdentifier # (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) # is a oneof # (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must # set only ONE of hashed_email, hashed_phone_number, mobile_id, # third_party_user_id, or address_info. Setting more than one of these # attributes on the same UserIdentifier will clear all the other members of # the oneof. For example, the following code is INCORRECT and will result in # a UserIdentifier with ONLY a hashed_phone_number: # # incorrectly_populated_user_identifier.hashed_email = "..."" # incorrectly_populated_user_identifier.hashed_phone_number = "..."" raw_record = { # Email address that includes a period (.) before the Gmail domain. "email" => "alex.2@example.com", # Phone number to be converted to E.164 format, with a leading '+' as # required. "phone" => "+1 800 5550102", # This example lets you input conversion details as arguments, # but in reality you might store this data alongside other user data, # so we include it in this sample user record. "order_id" => order_id, "gclid" => gclid, "conversion_action_id" => conversion_action_id, "conversion_date_time" => conversion_date_time, "conversion_value" => conversion_value, "currency_code" => "USD", "ad_user_data_consent" => ad_user_data_consent, "session_attributes_encoded" => session_attributes_encoded, "session_attributes_hash" => session_attributes_hash } click_conversion = client.resource.click_conversion do |cc| cc.conversion_action = client.path.conversion_action(customer_id, conversion_action_id) cc.conversion_date_time = conversion_date_time cc.conversion_value = conversion_value.to_f cc.currency_code = 'USD' unless order_id.nil? cc.order_id = order_id end unless raw_record["gclid"].nil? cc.gclid = gclid end # Specifies whether user consent was obtained for the data you are # uploading. For more details, see: # https://www.google.com/about/company/user-consent-policy unless raw_record["ad_user_data_consent"].nil? cc.consent = client.resource.consent do |c| c.ad_user_data = ad_user_data_consent end end # Set one of the session_attributes_encoded or # session_attributes_key_value_pairs fields if either are provided. if session_attributes_encoded != nil cc.class.module_eval { attr_accessor :session_attributes_encoded} cc.session_attributes_encoded = session_attributes_encoded elsif session_attributes_hash != nil # Add new attribute to click conversion object cc.class.module_eval { attr_accessor :session_attributes_key_value_pairs} cc.session_attributes_key_value_pairs = ::Google::Ads::GoogleAds::V19::Services::SessionAttributesKeyValuePairs.new # Loop thru inputted session_attributes_hash to populate session_attributes_key_value_pairs session_attributes_hash.each do |key, value| pair = ::Google::Ads::GoogleAds::V19::Services::SessionAttributeKeyValuePair.new pair.session_attribute_key = key pair.session_attribute_value = value cc.session_attributes_key_value_pairs.key_value_pairs << pair end end # Creates a user identifier using the hashed email address, using the # normalize and hash method specifically for email addresses. # If using a phone number, use the normalize_and_hash method instead. cc.user_identifiers << client.resource.user_identifier do |ui| ui.hashed_email = normalize_and_hash_email(raw_record["email"]) # Optional: Specifies the user identifier source. ui.user_identifier_source = :FIRST_PARTY end # Checks if the record has a phone number, and if so, adds a UserIdentifier # for it. unless raw_record["phone"].nil? cc.user_identifiers << client.resource.user_identifier do |ui| ui.hashed_phone_number = normalize_and_hash(raw_record["phone"]) end end end
Perl
# Create an empty click conversion. my $click_conversion = Google::Ads::GoogleAds::V22::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::V22::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::V22::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::V22::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']]) ); } // Set one of the sessionAttributesEncoded or // SessionAttributeKeyValuePair fields if either are provided. if (!empty($sessionAttributesEncoded)) { $clickConversion->setSessionAttributesEncoded($sessionAttributesEncoded); } elseif (!empty($sessionAttributesDict)) { // Create a new container object to hold key-value pairs. $sessionAttributesKeyValuePairs = new SessionAttributesKeyValuePairs(); // Initialize an array to hold individual key-value pair messages. $keyValuePairs = []; // Append each key-value pair provided to the $keyValuePairs array foreach ($sessionAttributesDict as $key => $value) { $pair = new SessionAttributeKeyValuePair(); $pair->setSessionAttributeKey($key); $pair->setSessionAttributeValue($value); $keyValuePairs[] = $pair; } // Set the the full list of key-value pairs on the container object. $sessionAttributesKeyValuePairs->setKeyValuePairs($keyValuePairs); // Attach the container of key-value pairs to the ClickConversion object. $clickConversion->setSessionAttributesKeyValuePairs($sessionAttributesKeyValuePairs); }
Python
# Add details of the conversion. # Gets the conversion action resource name. conversion_action_service: ConversionActionServiceClient = ( client.get_service("ConversionActionService") ) click_conversion.conversion_action = ( conversion_action_service.conversion_action_path( customer_id, raw_record["conversion_action_id"] ) ) click_conversion.conversion_date_time = raw_record["conversion_date_time"] click_conversion.conversion_value = raw_record["conversion_value"] click_conversion.currency_code = raw_record["currency_code"] # Sets the order ID if provided. if raw_record.get("order_id"): click_conversion.order_id = raw_record["order_id"] # Sets the gclid if provided. if raw_record.get("gclid"): click_conversion.gclid = raw_record["gclid"] # Specifies whether user consent was obtained for the data you are # uploading. For more details, see: # https://www.google.com/about/company/user-consent-policy if raw_record["ad_user_data_consent"]: click_conversion.consent.ad_user_data = client.enums.ConsentStatusEnum[ raw_record["ad_user_data_consent"] ] # Set one of the session_attributes_encoded or # session_attributes_key_value_pairs fields if either are provided. if session_attributes_encoded: click_conversion.session_attributes_encoded = session_attributes_encoded elif session_attributes_dict: for key, value in session_attributes_dict.items(): pair: SessionAttributeKeyValuePair = client.get_type( "SessionAttributeKeyValuePair" ) pair.session_attribute_key = key pair.session_attribute_value = value click_conversion.session_attributes_key_value_pairs.key_value_pairs.append( pair )
Руби
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::V22::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::V22::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::V22::Services::ConversionUploadService::SessionAttributeKeyValuePair ->new({sessionAttributeKey => $key, sessionAttributeValue => $value}); push @{$click_conversion->{sessionAttributesKeyValuePairs}{keyValuePairs} }, $pair; } }
Составьте запрос
После того, как объекты ClickConversion будут настроены и добавлены в поле conversions объекта UploadClickConversionRequest , установите следующие поля и передайте запрос методу UploadClickConversions объекта ConversionUploadService .
-
customer_id - Укажите здесь клиента Google Ads, ответственного за конверсии в аккаунте, который является источником кликов. Если вы не уверены, какой аккаунт является правильным, обратитесь к полю
customer.conversion_tracking_setting.google_ads_conversion_customerв примере запроса в разделе « Начало работы» . -
job_id Предоставляет механизм для сопоставления ваших запросов на импорт с информацией по каждому заданию в диагностических данных в автономном режиме .
Если вы не зададите это поле, API Google Ads присвоит каждому запросу уникальное значение в диапазоне
[2^31, 2^63). Если вы предпочитаете объединять несколько запросов в одно логическое задание, установите для этого поля одинаковое значение в диапазоне[0, 2^31)для каждого запроса в вашем задании.В ответе поле
job_idсодержит идентификатор задания для запроса, независимо от того, указали ли вы значение или позволили API Google Ads присвоить его автоматически.-
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: ConversionUploadServiceClient = ( client.get_service("ConversionUploadService") ) # Uploads the click conversion. Partial failure should always be set to # True. # NOTE: This request only uploads a single conversion, but if you have # multiple conversions to upload, it's most efficient to upload them in a # single request. See the following for per-request limits for reference: # https://developers.google.com/google-ads/api/docs/best-practices/quotas#conversion_upload_service response: UploadClickConversionsResponse = ( conversion_upload_service.upload_click_conversions( customer_id=customer_id, conversions=[click_conversion], # Enables partial failure (must be true). partial_failure=True, ) )
Руби
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 Ads по методу «последний клик» может потребоваться до трех часов. Для других моделей атрибуции поисковых запросов это может занять больше трех часов. Для получения дополнительной информации обратитесь к руководству по актуальности данных .
При составлении отчетов по показателям конверсии для ваших кампаний используйте раздел «Сопоставление показателей пользовательского интерфейса» , чтобы сопоставить показатели пользовательского интерфейса Google Ads с полями отчетов API Google Ads. Вы также можете запросить ресурс conversion_action , чтобы просмотреть общее количество конверсий и общую стоимость конверсии для данного действия.
Передовые методы
При внедрении методов повышения конверсии лидов учитывайте следующие рекомендации.
Отправлять все данные о конверсиях независимо от их полноты.
Для обеспечения полной и точной отчетности по конверсиям импортируйте все доступные события конверсии в офлайн-режиме, включая те, которые могли быть совершены не через Google Ads. Конверсии, включающие только предоставленные пользователем данные, по-прежнему полезны и могут положительно повлиять на оптимизацию кампаний Google Ads.
Если вы присваиваете order_id конверсии, мы рекомендуем его указать. Если у вас есть GCLID для конверсии, мы рекомендуем передавать его в дополнение к user_identifiers для повышения производительности. Кроме того, если у вас более одного UserIdentifier для конверсии, включите все их в объект ClickConversion , чтобы повысить вероятность совпадения.
Объедините несколько преобразований в один запрос.
Если вам нужно импортировать несколько конверсий, объедините их в один запрос UploadClickConversionsRequest , вместо того чтобы отправлять отдельный запрос на импорт для каждой конверсии.
Ознакомьтесь с руководством по квотам, чтобы узнать об ограничениях на количество конверсий на один запрос.
Если вы хотите, чтобы диагностика данных в автономном режиме группировала набор запросов в рамках одной логической задачи, установите для всех запросов значение job_id одинаковым. Это может быть полезно, если у вас есть одна задача или процесс, который импортирует большое количество конверсий с помощью нескольких запросов. Если вы установите job_id для каждого из этих запросов одинаковым значением, то сможете получить одну запись для задачи из job_summaries . Если же вы позволите API Google Ads присваивать job_id каждого запроса значение, генерируемое системой, job_summaries будет содержать отдельную запись для каждого запроса, что может затруднить анализ общего состояния вашей задачи.
Не используйте внешние данные об атрибуции.
При использовании расширенных конверсий для лидов не следует устанавливать external_attribution_data для ClickConversion или указывать conversion_action , использующий внешнюю модель атрибуции. Google Ads не поддерживает конверсии с внешней атрибуцией для импорта данных, предоставленных пользователем.
Не включайте пользовательские переменные.
При использовании расширенных конверсий для лидов не включайте custom_variables . Google Ads не поддерживает использование пользовательских переменных с данными, предоставленными пользователем, при импорте конверсий. Если пользовательские переменные включены в конверсии, содержащие данные, предоставленные пользователем, эти конверсии будут считаться недействительными и отбрасываться.
Поиск неисправностей
Автономная диагностика данных предоставляет единый ресурс для постоянного анализа общего состояния импортируемых данных. Однако в процессе внедрения вы можете использовать информацию из этого раздела для исследования любых ошибок, указанных в поле partial_failure_error ответа.
Некоторые из наиболее распространенных ошибок при импорте действий по конверсии связаны с ошибками авторизации, такими как USER_PERMISSION_DENIED . Убедитесь, что в вашем запросе указан идентификатор клиента, которому принадлежит действие по конверсии в Google Ads. Более подробную информацию можно найти в нашем руководстве по авторизации , а советы по устранению этих ошибок — в руководстве по распространенным ошибкам.
Отладка распространенных ошибок
| Ошибка | |
|---|---|
NO_CONVERSION_ACTION_FOUND | Указанное действие по конвертации либо не включено, либо недоступно для учетной записи клиента, указанной в поле `client_id` в запросе. Убедитесь, что действие по конвертации в вашем запросе на загрузку включено и принадлежит клиенту, отправившему запрос на загрузку. Эта ошибка также может возникнуть, если GCLID в запросе принадлежит учетной записи клиента, которая не имеет доступа к действию конверсии, указанному в запросе. Вы можете проверить, принадлежит ли GCLID учетной записи клиента, используя ресурс |
INVALID_CONVERSION_ACTION_TYPE | Указанное действие конверсии имеет тип, недопустимый для расширенных конверсий лидов. Убедитесь, что ConversionAction указанное в вашем запросе на загрузку, имеет тип UPLOAD_CLICKS . |
CUSTOMER_NOT_ENABLED_ENHANCED_CONVERSIONS_FOR_LEADS | Убедитесь, что в настройках конверсии включены расширенные параметры конверсии для потенциальных клиентов. Инструкции по этому поводу вы найдете в руководстве по предварительным условиям . |
DUPLICATE_ORDER_ID | Импортированные события содержат несколько конверсий с одним и тем же идентификатором заказа и не были обработаны. Убедитесь, что идентификаторы заказов уникальны, и повторите попытку. |
CLICK_NOT_FOUND | Не найдено кликов, соответствующих предоставленным идентификаторам пользователей. API Google Ads возвращает эту ошибку только в том случае, если debug_enabled в запросе UploadClickConversionsRequest имеет true . Если при конверсии появляется это предупреждение, API Google Ads включает его в поле Эта ошибка ожидаема, если клик не связан с рекламной кампанией Google Ads. Например, он может исходить из SA360 или DV360 . Другие возможные причины следующие:
В редких случаях, когда клиент, загружающий данные, отличается от клиента, осуществляющего конверсию в Google Ads, эта ошибка может означать, что клиент, загружающий данные, принял условия обработки данных клиента, а клиент, предоставляющий данные, — нет. Определить, приняла ли учетная запись условия использования данных клиента, можно, запросив информацию оcustomer и проверив поле customer.offline_conversion_tracking_info.accepted_customer_data_terms . |