オフライン コンバージョンを管理する

Google Ads API を使用してオフライン コンバージョンを Google 広告にインポートすると、電話や営業担当者など、オフラインで販売につながった広告をトラッキングできます。

コンバージョン データのインポートのメリットを最大限に活用するには、リードの拡張コンバージョンを実装することをおすすめします。リードの拡張コンバージョンでは、GCLID とユーザー提供データを利用して、持続性とパフォーマンスを最大限に高めることができます。

拡張コンバージョン

拡張コンバージョンを使用すると、メールアドレス、氏名、住所、電話番号などのファースト パーティ コンバージョン データでコンバージョンを補完し、コンバージョン測定の精度を高めることができます。

拡張コンバージョンには 2 種類があります。詳しくは、拡張コンバージョンについてのヘルプセンター記事をご覧ください。

次のセクションでは、オフライン コンバージョンを拡張する方法について説明します。この機能は、リードの拡張コンバージョンとも呼ばれます。

リードの拡張コンバージョンとは

リードの拡張コンバージョンは、オフライン コンバージョンのインポートがアップグレードされたもので、メールアドレスなどのユーザー提供データを使って、インポートされたオフライン コンバージョン データを補完することにより、精度と入札のパフォーマンスを高めます。オフライン コンバージョンをインポートすると、ユーザー提供のハッシュ化済み顧客データが、ウェブサイトで収集された同じデータ(リードフォームなど)と、広告の操作を行ったログイン済みのユーザーと照合され、Google 広告の広告キャンペーンに関連付けられます。リードの拡張コンバージョンの仕組みについて詳しくは、リードの拡張コンバージョンについてをご覧ください。

リードの拡張コンバージョンを実装する方法は、Google タグを使用してウェブページ上のフォーム送信イベントをトラッキングするかどうかによって異なります。最適なパフォーマンスと耐久性を得るには、見込み顧客の拡張コンバージョンに Google タグを使用することを強くおすすめします。

  • 最初から構築する場合は、前提条件セクションから始めてください。
  • オフライン コンバージョンのインポートをすでに設定していて、リードの拡張コンバージョンにアップグレードする場合は、タグ設定を構成するセクションから始めることをおすすめします。
  • Google タグをすでに設定している場合や、Google タグを使用しない場合で、Google Ads API の統合を開始する場合は、API の実装セクションに進んでください。
  • ユーザー提供データをインポートできない場合や、コンバージョンの外部アトリビューションに依存している場合は、従来のオフライン コンバージョン インポート ガイドをご覧ください。

前提条件

まず、スタートガイドの手順が完了していることを確認してください。

リードの拡張コンバージョンを使用するには、リードの拡張コンバージョンを有効にして顧客データに関する規約に同意する必要があります。これらの前提条件がすでに満たされているかどうかを確認するには、Google 広告のコンバージョン カスタマーに対して次のクエリを実行します。

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

accepted_customer_data_terms または enhanced_conversions_for_leads_enabled のいずれかが false の場合は、ヘルプセンターの手順に沿って、これらの前提条件を満たしてください。

タグ設定を構成する

ヘルプセンターの手順に沿って、リードの拡張コンバージョンを有効にするように Google タグを設定します。Google タグ マネージャーでリードの拡張コンバージョンを設定する手順は、こちらをご覧ください。

API の実装

Google Ads API を使用してリードの拡張コンバージョンをインポートする全体的なフローについては、以下をご覧ください。

  1. メールアドレス、電話番号、郵送先住所など、ユーザー提供データを正規化してハッシュ化します。

  2. 正規化されハッシュ化されたユーザー提供データを ClickConversion オブジェクトに入力します。

  3. ConversionUploadService を使用して、ClickConversion オブジェクトを Google Ads API にインポートします。

  4. インポートを確認する

ユーザー提供データを正規化、ハッシュ化する

プライバシー保護の観点から、次のデータはインポートする前に SHA-256 を使用してハッシュ化する必要があります。

  • メールアドレス
  • 電話番号
  • 番地

ハッシュ結果を標準化するには、これらの値をハッシュ化する前に次の作業を行う必要があります。

  • 先頭と末尾の空白文字を削除する。
  • テキストを小文字に変換する。
  • 電話番号を E164 規格の形式にする。
  • gmail.comgooglemail.com のメールアドレスのドメイン名の前にあるすべてのピリオド(.)を削除する。

次のデータはハッシュ化しないでください

  • 都道府県
  • 市区町村
  • 郵便番号

サンプルコード

この例では、ユーザー提供データを正規化してハッシュ化する方法を示します。

Java

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

  return result.toString();
}

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

C#

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

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

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

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

PHP

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

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

Python

def normalize_and_hash_email_address(email_address):
    """Returns the result of normalizing and hashing an email address.

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

    Args:
        email_address: An email address to normalize.

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

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

    return normalize_and_hash(normalized_email)


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

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

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

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

Ruby

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

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

Perl

sub normalize_and_hash {
  my $value = shift;

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

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

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

ClickConversion オブジェクトにデータを入力する

UploadClickConversionRequestClickConversion オブジェクトのコレクションは、インポートするコンバージョンのセットを表します。ClickConversion オブジェクトを作成する際は、次の点に注意してください。

gclid

GCLID は、ユーザーが広告をクリックしてウェブサイトにアクセスしたときに URL パラメータから取得されるクリック ID です。

user_identifiers

リードの拡張コンバージョンを使用する場合は、user_identifiers フィールドに、正規化されハッシュ化されたユーザー提供データを入力する必要があります。使用可能なユーザー ID が複数ある場合は、それぞれに個別の UserIdentifier を作成します(最大 5 つの ID)。

conversion_date_time

コンバージョンの日時。

値にはタイムゾーンを指定し、形式は yyyy-mm-dd HH:mm:ss+|-HH:mm にする必要があります(例: 2022-01-01 19:32:45-05:00(夏時間は無視))。

タイムゾーンには任意の有効な値を指定できます。アカウントのタイムゾーンと一致する必要はありません。ただし、インポートしたコンバージョン データと Google 広告の管理画面のコンバージョン データを比較する場合は、コンバージョン数が一致するように、Google 広告アカウントと同じタイムゾーンを使用することをおすすめします。詳細と例については、ヘルプセンターをご覧ください。また、有効なタイムゾーン ID の一覧については、コードと形式をご覧ください。

conversion_action

オフライン コンバージョンの ConversionAction のリソース名。

コンバージョン アクションの typeUPLOAD_CLICKS にする必要があります。また、クリックに関連付けられている Google 広告アカウントの Google 広告コンバージョン カスタマーに存在している必要があります。

conversion_value

コンバージョンの価値。

currency_code

conversion_value通貨コード

consent

ClickConversion オブジェクトの consent フィールドに値を入力することを強くおすすめします。設定されていない場合、コンバージョンの割り当てが行われない可能性があります。

order_id

コンバージョンのトランザクション ID とも呼ばれます。このフィールドは省略可能ですが、調整を行う際にインポートしたコンバージョンを参照しやすくなるため、使用することを強くおすすめします。インポート時に設定した場合は、調整に使用する必要があります。トランザクション ID を使用して重複コンバージョンを最小限に抑える方法について詳しくは、こちらのヘルプセンター記事をご覧ください。

custom_variables

カスタム コンバージョン変数の値。

Google 広告では、wbraid または gbraid と組み合わせたカスタム コンバージョン変数はサポートされていません。

conversion_environment

このコンバージョンが記録された環境を示します。たとえば、APPWEB です。

session_attributes_encodedsession_attributes_key_value_pairs

セッション属性は、コンバージョン アトリビューションに使用される集約された ID を表します。これらは、クリック ID(GCLID や GBRAID など)やユーザー提供データ(リードの拡張コンバージョンの中心となるデータ)に加えて機能します。セッション属性をインポートする方法は 2 つあります。ブラウザで JavaScript コードによって生成されたエンコードされたトークンを指定する方法と、各 ID に個別の Key-Value ペアを指定する方法です。

キャンペーンのパフォーマンスを最大化するには、可能であれば、すべてのコンバージョンでクリック ID、ユーザー提供データ、セッション属性をインポートすることをおすすめします。

Java

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

C#

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

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

PHP

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

Python

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

Ruby

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

Perl

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

サンプルコード

この例では、正規化されハッシュ化されたユーザー提供データを ClickConversion オブジェクトに設定する方法を示します。

Java

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

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

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

ImmutableMap.Builder<String, String> rawRecordBuilder =
    ImmutableMap.<String, String>builder()
        .put("email", "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
];

// 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_email = normalize_and_hash_email_address(
    raw_record["email"]
)
# Adds the user identifier to the conversion.
click_conversion.user_identifiers.append(email_identifier)

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

Ruby

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

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

raw_record = {
  # Email address that includes a period (.) before the Gmail domain.
  "email" => "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::V19::Services::ConversionUploadService::ClickConversion
  ->new({});

# Extract user email and phone from the raw data, normalize and hash it,
# then wrap it in UserIdentifier objects. Create a separate UserIdentifier
# object for each.
# The data in this example is hardcoded, but in your application
# you might read the raw data from an input file.
#
# IMPORTANT: Since the identifier attribute of UserIdentifier
# (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier)
# is a oneof
# (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set
# only ONE of hashed_email, hashed_phone_number, mobile_id, third_party_user_id,
# or address-info. Setting more than one of these attributes on the same UserIdentifier
# will clear all the other members of the oneof. For example, the following code is
# INCORRECT and will result in a UserIdentifier with ONLY a hashed_phone_number:
#
# my $incorrect_user_identifier = Google::Ads::GoogleAds::V19::Common::UserIdentifier->new({
#   hashedEmail => '...',
#   hashedPhoneNumber => '...',
# });
my $raw_record = {
  # Email address that includes a period (.) before the Gmail domain.
  email => '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::V19::Common::UserIdentifier->new({
      hashedEmail => $hashed_email,
      # Optional: Specify the user identifier source.
      userIdentifierSource => FIRST_PARTY
    }));

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

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

この例では、ClickConversion オブジェクトに必要な他のフィールドを設定する方法を示します。

Java

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

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

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

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

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

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

C#

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

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

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

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

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

      

PHP

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

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

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

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

Python

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

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

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

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

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

Ruby

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

unless order_id.nil?
  cc.order_id = order_id
end

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

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

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

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

Perl

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

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

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

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

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

リクエストを作成する

ClickConversion オブジェクトを構成して UploadClickConversionRequest オブジェクトの conversions フィールドに追加したら、次のフィールドを設定し、ConversionUploadServiceUploadClickConversions メソッドにリクエストを渡します。

customer_id
クリックの参照元となるアカウントの Google 広告コンバージョン カスタマーに設定します。どのアカウントが正しいかわからない場合は、スタートガイド のセクションの例のクエリの customer.conversion_tracking_setting.google_ads_conversion_customer フィールドを参照してください。
job_id

オフライン データの診断で、インポート リクエストをジョブごとの情報に関連付けるメカニズムを提供します。

このフィールドを設定しない場合は、Google Ads API が各リクエストに [2^31, 2^63) の範囲内の一意の値を割り当てます。複数のリクエストを 1 つの論理ジョブにグループ化する場合、このフィールドをジョブ内のすべてのリクエストで [0, 2^31) の範囲内の同じ値に設定します。

レスポンスjob_id には、値を指定したかどうかにかかわらず、リクエストのジョブ ID が含まれます。

partial_failure

コンバージョンをインポートする場合は、このフィールドを true に設定する必要があります。レスポンスを処理する際は、部分的な失敗のガイドラインに沿って対応します。

リクエストをインポートする

ClickConversion オブジェクトにデータを入力し、リクエストを作成したら、インポートを送信できます。

Java

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

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

C#

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

      

PHP

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

Python

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

Ruby

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

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

Perl

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

インポートを確認する

リードの拡張コンバージョンの診断レポートを使用して、最近のインポートの全体的な状態を確認します。

インポートされたコンバージョンは、インポート リクエストの日付や ClickConversionconversion_date_time の日付ではなく、元のクリックのインプレッションの日付のレポートに反映されます。

インポートしたコンバージョン データが、ラストクリック アトリビューションの Google 広告アカウントに表示されるまでには、最長で 3 時間ほどかかります。他の検索アトリビューション モデルでは、3 時間以上かかることがあります。詳しくは、データの更新頻度に関するガイドをご覧ください。

キャンペーンのコンバージョン指標をレポートする場合は、ユーザー インターフェース指標のマッピングを参照して、Google 広告管理画面の指標と Google Ads API レポート フィールドを関連付けてください。conversion_action リソースをクエリして、特定のコンバージョン アクションの合計コンバージョン数と合計コンバージョン値を確認することもできます。

ベスト プラクティス

見込み顧客向けの拡張コンバージョンを実装する際は、次のベスト プラクティスに留意してください。

完全性に関わらずすべてのコンバージョン データを送信する

コンバージョン レポートを完全かつ正確に作成するには、Google 広告以外で発生した可能性のあるコンバージョン イベントも含め、利用可能なすべてのオフライン コンバージョン イベントをインポートしてください。ユーザー提供データのみを含むコンバージョンも有用であり、Google 広告キャンペーンの最適化に役立ちます。

コンバージョンに order_id を割り当てる場合は、含めることをおすすめします。コンバージョンの GCLID がある場合は、パフォーマンスを改善するために user_identifiers に加えて送信することをおすすめします。さらに、コンバージョンに複数の UserIdentifier がある場合は、一致する可能性を高めるために、それらをすべて ClickConversion オブジェクトに含めます。

1 つのリクエストで複数のコンバージョンを一括処理する

インポートするコンバージョンが複数ある場合は、コンバージョンごとにインポート リクエストを送信するのではなく、コンバージョンを 1 つの UploadClickConversionsRequest にまとめて送信してください。

リクエストあたりのコンバージョン数の上限については、割り当てのガイドをご覧ください。

オフライン データ診断で、同じ論理ジョブにリクエストのセットをグループ化する場合、すべてのリクエストの job_id を同じ値に設定します。これは、複数のリクエストを使用して大量のコンバージョンをインポートする単一のジョブまたはプロセスがある場合に便利です。各リクエストの job_id を同じ値に設定すると、job_summaries からジョブのエントリを 1 つ取得できます。代わりに、Google 広告 API が各リクエストの job_id にシステム生成値を割り当てるようにすると、job_summaries にはリクエストごとに個別のエントリが含まれるため、ジョブの全体的な健全性を分析するのが難しくなる可能性があります。

外部アトリビューション データを使用しない

リードの拡張コンバージョンを使用する場合は、ClickConversionexternal_attribution_data を設定したり、外部アトリビューション モデルを使用する conversion_action を指定したりすることはありません。Google 広告では、ユーザー提供データを使用してインポートされたコンバージョンについて、外部で貢献度が割り当てられたコンバージョンをサポートしていません。

トラブルシューティング

オフライン データの診断は、インポートの全体的な健全性を継続的に確認するための単一のリソースです。ただし、実装中は、このセクションの情報を使用して、レスポンスの partial_failure_error フィールドで報告されたエラーを調査できます。

コンバージョン アクションのインポート時によく発生するエラーには、USER_PERMISSION_DENIED などの認可エラーがあります。リクエストのカスタマー ID が、コンバージョン アクションを所有する Google 広告のコンバージョン カスタマーに設定されていることを再度確認します。詳しくは、認可ガイドをご覧ください。これらのエラーをデバッグする方法については、一般的なエラーのガイドをご覧ください。

一般的なエラーをデバッグする

エラー
NO_CONVERSION_ACTION_FOUND

指定されたコンバージョン アクションが有効になっていないか、リクエストの client_id フィールドで指定されたクライアント アカウントからアクセスできません。アップロード内のコンバージョン アクションが有効であり、アップロード リクエストを送信したお客様が所有していることを確認します。

このエラーは、リクエスト内の GCLID が、リクエストで指定されたコンバージョン アクションにアクセス権のないクライアント アカウントに属している場合にも発生することがあります。GCLID がクライアント アカウントに属しているかどうかを確認するには、click_view リソースを使用して、click_view.gclidsegments.date でフィルタするクエリを送信します。日付はクリックが発生した日付です。

INVALID_CONVERSION_ACTION_TYPE 指定されたコンバージョン アクションのタイプは、リードの拡張コンバージョンでは無効です。アップロード リクエストで指定された ConversionAction のタイプが UPLOAD_CLICKS であることを確認します。
CUSTOMER_NOT_ENABLED_ENHANCED_CONVERSIONS_FOR_LEADS コンバージョン設定でリードの拡張コンバージョンが有効になっていることを確認してください。手順については、前提条件ガイドをご覧ください。
DUPLICATE_ORDER_ID インポートされたイベントに同じオーダー ID の複数のコンバージョンが含まれているため、イベントが処理されませんでした。 オーダー ID が一意であることを確認してから、もう一度お試しください。
CLICK_NOT_FOUND 指定されたユーザー ID と一致するクリックは見つかりませんでした。Google 広告 API からこのエラーが返されるのは、UploadClickConversionsRequestdebug_enabledtrue の場合のみです。

コンバージョンでこの警告が発生した場合、Google Ads API はオフライン データ診断successful_event_count にそのデータを含めます。Google Ads API の alerts コレクションには CLICK_NOT_FOUND のエントリが含まれているため、この警告の頻度をモニタリングできます。

このエラーは、クリックが Google 広告の広告キャンペーンからのものではない場合に発生します。たとえば、SA360DV360 から取得できます。考えられるその他の原因は次のとおりです。

アップロードしたお客様が Google 広告のコンバージョン クライアントと異なる場合、このエラーは、アップロードしたお客様がカスタマー データ利用規約に同意しているが、配信先のお客様が同意していないことを意味することがあります。

アカウントが顧客データに関する規約に同意しているかどうかを確認するには、customer リソースに対してクエリを実行し、customer.offline_conversion_tracking_info.accepted_customer_data_terms フィールドを確認します。