クリック コンバージョンのアップロード

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

セットアップ

オフライン コンバージョンを正しく設定するには、いくつかの前提条件があります。実装に進む前に、すべての前提条件が満たされていることを確認します。

  1. Google 広告のコンバージョン クライアントでコンバージョン トラッキングを有効にします。

  2. タグ設定を設定し、クリック ID を保存します。

1. Google 広告のコンバージョン カスタマーでコンバージョン トラッキングを有効にする

コンバージョンのスタートガイドを完了し、コンバージョン トラッキングを有効にしている場合は、ステップ 2: タグ設定を構成するに進んでください。

コンバージョン トラッキングの設定に関する情報を取得する

アカウントのコンバージョン トラッキングの設定を確認して、コンバージョン トラッキングが有効になっていることを確認するには、ConversionTrackingSettingCustomer リソースをクエリします。GoogleAdsService.SearchStream を使用して次のクエリを実行します。

SELECT
  customer.conversion_tracking_setting.google_ads_conversion_customer,
  customer.conversion_tracking_setting.conversion_tracking_status,
  customer.conversion_tracking_setting.conversion_tracking_id,
  customer.conversion_tracking_setting.cross_account_conversion_tracking_id
FROM customer

google_ads_conversion_customer フィールドには、このお客様のコンバージョンを作成して管理する Google 広告アカウントが示されます。クロスアカウント コンバージョン トラッキングを使用している場合は、MCC アカウントの ID です。コンバージョンを作成、管理するには、Google Ads API リクエストで Google 広告コンバージョンの顧客 ID を customer_id として指定する必要があります。コンバージョン トラッキングが有効になっていない場合でも、このフィールドには値が入力されます。

conversion_tracking_status フィールドには、コンバージョン トラッキングが有効になっているかどうかと、アカウントでクロスアカウント コンバージョン トラッキングを使用しているかどうかが表示されます。

Google 広告のコンバージョン カスタマーでコンバージョン アクションを作成する

conversion_tracking_status の値が NOT_CONVERSION_TRACKED の場合、アカウントでコンバージョン トラッキングが有効になっていません。次の例のように、Google 広告コンバージョン アカウントで 1 つ以上の ConversionAction を作成して、コンバージョン トラッキングを有効にします。または、有効にするコンバージョン タイプに関するヘルプセンターの手順に沿って、UI でコンバージョン アクションを作成することもできます。

拡張コンバージョンは、Google Ads API 経由で送信されると自動的に有効になりますが、Google 広告の管理画面で無効にできます。

サンプルコード

JavaC#PHPPythonRubyPerl
private void runExample(GoogleAdsClient googleAdsClient, long customerId) {

  // Creates a ConversionAction.
  ConversionAction conversionAction =
      ConversionAction.newBuilder()
          // Note that conversion action names must be unique. If a conversion action already
          // exists with the specified conversion_action_name the create operation will fail with
          // a ConversionActionError.DUPLICATE_NAME error.
          .setName("Earth to Mars Cruises Conversion #" + getPrintableDateTime())
          .setCategory(ConversionActionCategory.DEFAULT)
          .setType(ConversionActionType.WEBPAGE)
          .setStatus(ConversionActionStatus.ENABLED)
          .setViewThroughLookbackWindowDays(15L)
          .setValueSettings(
              ValueSettings.newBuilder()
                  .setDefaultValue(23.41)
                  .setAlwaysUseDefaultValue(true)
                  .build())
          .build();

  // Creates the operation.
  ConversionActionOperation operation =
      ConversionActionOperation.newBuilder().setCreate(conversionAction).build();

  try (ConversionActionServiceClient conversionActionServiceClient =
      googleAdsClient.getLatestVersion().createConversionActionServiceClient()) {
    MutateConversionActionsResponse response =
        conversionActionServiceClient.mutateConversionActions(
            Long.toString(customerId), Collections.singletonList(operation));
    System.out.printf("Added %d conversion actions:%n", response.getResultsCount());
    for (MutateConversionActionResult result : response.getResultsList()) {
      System.out.printf(
          "New conversion action added with resource name: '%s'%n", result.getResourceName());
    }
  }
}
      
public void Run(GoogleAdsClient client, long customerId)
{
    // Get the ConversionActionService.
    ConversionActionServiceClient conversionActionService =
        client.GetService(Services.V19.ConversionActionService);

    // Note that conversion action names must be unique.
    // If a conversion action already exists with the specified name the create operation
    // will fail with a ConversionAction.DUPLICATE_NAME error.
    string ConversionActionName = "Earth to Mars Cruises Conversion #"
        + ExampleUtilities.GetRandomString();

    // Add a conversion action.
    ConversionAction conversionAction = new ConversionAction()
    {
        Name = ConversionActionName,
        Category = ConversionActionCategory.Default,
        Type = ConversionActionType.Webpage,
        Status = ConversionActionStatus.Enabled,
        ViewThroughLookbackWindowDays = 15,
        ValueSettings = new ConversionAction.Types.ValueSettings()
        {
            DefaultValue = 23.41,
            AlwaysUseDefaultValue = true
        }
    };

    // Create the operation.
    ConversionActionOperation operation = new ConversionActionOperation()
    {
        Create = conversionAction
    };

    try
    {
        // Create the conversion action.
        MutateConversionActionsResponse response =
            conversionActionService.MutateConversionActions(customerId.ToString(),
                    new ConversionActionOperation[] { operation });

        // Display the results.
        foreach (MutateConversionActionResult newConversionAction in response.Results)
        {
            Console.WriteLine($"New conversion action with resource name = " +
                $"'{newConversionAction.ResourceName}' was added.");
        }
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
        throw;
    }
}
      
public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
{
    // Creates a conversion action.
    $conversionAction = new ConversionAction([
        // Note that conversion action names must be unique.
        // If a conversion action already exists with the specified conversion_action_name
        // the create operation will fail with a ConversionActionError.DUPLICATE_NAME error.
        'name' => 'Earth to Mars Cruises Conversion #' . Helper::getPrintableDatetime(),
        'category' => ConversionActionCategory::PBDEFAULT,
        'type' => ConversionActionType::WEBPAGE,
        'status' => ConversionActionStatus::ENABLED,
        'view_through_lookback_window_days' => 15,
        'value_settings' => new ValueSettings([
            'default_value' => 23.41,
            'always_use_default_value' => true
        ])
    ]);

    // Creates a conversion action operation.
    $conversionActionOperation = new ConversionActionOperation();
    $conversionActionOperation->setCreate($conversionAction);

    // Issues a mutate request to add the conversion action.
    $conversionActionServiceClient = $googleAdsClient->getConversionActionServiceClient();
    $response = $conversionActionServiceClient->mutateConversionActions(
        MutateConversionActionsRequest::build($customerId, [$conversionActionOperation])
    );

    printf("Added %d conversion actions:%s", $response->getResults()->count(), PHP_EOL);

    foreach ($response->getResults() as $addedConversionAction) {
        /** @var ConversionAction $addedConversionAction */
        printf(
            "New conversion action added with resource name: '%s'%s",
            $addedConversionAction->getResourceName(),
            PHP_EOL
        );
    }
}
      
def main(client, customer_id):
    conversion_action_service = client.get_service("ConversionActionService")

    # Create the operation.
    conversion_action_operation = client.get_type("ConversionActionOperation")

    # Create conversion action.
    conversion_action = conversion_action_operation.create

    # Note that conversion action names must be unique. If a conversion action
    # already exists with the specified conversion_action_name, the create
    # operation will fail with a ConversionActionError.DUPLICATE_NAME error.
    conversion_action.name = f"Earth to Mars Cruises Conversion {uuid.uuid4()}"
    conversion_action.type_ = (
        client.enums.ConversionActionTypeEnum.UPLOAD_CLICKS
    )
    conversion_action.category = (
        client.enums.ConversionActionCategoryEnum.DEFAULT
    )
    conversion_action.status = client.enums.ConversionActionStatusEnum.ENABLED
    conversion_action.view_through_lookback_window_days = 15

    # Create a value settings object.
    value_settings = conversion_action.value_settings
    value_settings.default_value = 15.0
    value_settings.always_use_default_value = True

    # Add the conversion action.
    conversion_action_response = (
        conversion_action_service.mutate_conversion_actions(
            customer_id=customer_id,
            operations=[conversion_action_operation],
        )
    )

    print(
        "Created conversion action "
        f'"{conversion_action_response.results[0].resource_name}".'
    )
      
def add_conversion_action(customer_id)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new


  # Add a conversion action.
  conversion_action = client.resource.conversion_action do |ca|
    ca.name = "Earth to Mars Cruises Conversion #{(Time.new.to_f * 100).to_i}"
    ca.type = :UPLOAD_CLICKS
    ca.category = :DEFAULT
    ca.status = :ENABLED
    ca.view_through_lookback_window_days = 15

    # Create a value settings object.
    ca.value_settings = client.resource.value_settings do |vs|
      vs.default_value = 15
      vs.always_use_default_value = true
    end
  end

  # Create the operation.
  conversion_action_operation = client.operation.create_resource.conversion_action(conversion_action)

  # Add the ad group ad.
  response = client.service.conversion_action.mutate_conversion_actions(
    customer_id: customer_id,
    operations: [conversion_action_operation],
  )

  puts "New conversion action with resource name = #{response.results.first.resource_name}."
end
      
sub add_conversion_action {
  my ($api_client, $customer_id) = @_;

  # Note that conversion action names must be unique.
  # If a conversion action already exists with the specified conversion_action_name,
  # the create operation fails with error ConversionActionError.DUPLICATE_NAME.
  my $conversion_action_name = "Earth to Mars Cruises Conversion #" . uniqid();

  # Create a conversion action.
  my $conversion_action =
    Google::Ads::GoogleAds::V19::Resources::ConversionAction->new({
      name                          => $conversion_action_name,
      category                      => DEFAULT,
      type                          => WEBPAGE,
      status                        => ENABLED,
      viewThroughLookbackWindowDays => 15,
      valueSettings                 =>
        Google::Ads::GoogleAds::V19::Resources::ValueSettings->new({
          defaultValue          => 23.41,
          alwaysUseDefaultValue => "true"
        })});

  # Create a conversion action operation.
  my $conversion_action_operation =
    Google::Ads::GoogleAds::V19::Services::ConversionActionService::ConversionActionOperation
    ->new({create => $conversion_action});

  # Add the conversion action.
  my $conversion_actions_response =
    $api_client->ConversionActionService()->mutate({
      customerId => $customer_id,
      operations => [$conversion_action_operation]});

  printf "New conversion action added with resource name: '%s'.\n",
    $conversion_actions_response->{results}[0]{resourceName};

  return 1;
}
      

conversion_action_type が正しい ConversionActionType 値に設定されていることを確認します。Google Ads API でコンバージョン アクションを作成する方法について詳しくは、コンバージョン アクションを作成するをご覧ください。

既存のコンバージョン アクションを取得する

既存のコンバージョン アクションの詳細を取得するには、次のクエリを実行します。リクエストのお客様 ID が、上記で特定した Google 広告のコンバージョン カスタマーに設定されていること、コンバージョン アクションのタイプが正しい ConversionActionType 値に設定されていることを確認します。

SELECT
  conversion_action.resource_name,
  conversion_action.name,
  conversion_action.status
FROM conversion_action
WHERE conversion_action.type = 'INSERT_CONVERSION_ACTION_TYPE'

2. タグ設定とストアクリック ID を構成する

手順に沿って、自動タグ設定が有効になっていることを確認します。Google 広告アカウント、ウェブサイト、見込み顧客管理システムを設定して、広告の各インプレッションとクリックの GCLID、GBRAID、または WBRAID を取得して保存します。自動タグ設定は、アカウントを新規に作成するとデフォルトで有効になります。

リクエストを作成する

以下のガイダンスに沿って UploadClickConversionsRequest を作成し、フィールドに適切な値を設定します。

customer_id

アップロードした Google 広告アカウントを識別します。クリックの参照元となるアカウントの Google 広告コンバージョン カスタマーに設定します。

job_id

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

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

レスポンスjob_id には、値を指定した場合でも、Google 広告 API に値を割り当てた場合でも、リクエストのジョブ ID が含まれます。

partial_failure_enabled

Google Ads API がオペレーションのエラーを処理する方法を決定します。

このフィールドは true に設定する必要があります。レスポンスを処理する際は、部分的な失敗に関するガイドラインに沿って対応してください。

debug_enabled

リードの拡張コンバージョンのアップロードのエラー レポートの動作を決定します。Google Ads API は、gclidgbraidwbraid を使用してクリック コンバージョンのアップロードを処理する際に、このフィールドを無視します。

クリック コンバージョン オペレーションを作成する

UploadClickConversionRequestClickConversion オブジェクトのコレクションは、アップロードするコンバージョンのセットを定義します。以下のガイダンスに沿って各 ClickConversion を作成し、フィールドを適切な値に設定します。

各コンバージョン オペレーションの必須フィールドを設定する

以下の手順に沿って、ClickConversion の必須フィールドに適切な値を設定します。

gclidgbraidwbraid
コンバージョンのクリックまたはインプレッションのクリック時に取得した識別子。これらのフィールドは1 つだけ設定してください。
conversion_date_time

コンバージョンの日時。

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

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

user_identifiers

クリック ID のみを使用してコンバージョンをアップロードする場合は、このフィールドを設定しないでください。このフィールドが設定されている場合、アップロード オペレーションはリードの拡張コンバージョンのアップロードとして扱われます。

conversion_action

クリック コンバージョンの ConversionAction のリソース名。

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

conversion_value

コンバージョンの価値。

currency_code

conversion_value通貨コード

各コンバージョン オペレーションのオプション フィールドを設定する

以下の省略可フィールドの一覧を確認し、必要に応じて ClickConversion に設定します。

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

サードパーティのツールや独自のソリューションを使用してコンバージョンをトラッキングしている場合は、コンバージョンのクレジットを Google 広告に一部のみ割り当てるか、コンバージョンのクレジットを複数のクリックに分散することをおすすめします。外部アトリビューションによるコンバージョンのインポートを使用すると、各クリックに割り当てられたコンバージョンの貢献度の一部をアップロードできます。

小数点以下のクレジットをアップロードするには、このフィールドを ExternalAttributionData オブジェクトに設定し、external_attribution_modelexternal_attribution_credit の値を設定します。

custom_variables

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

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

cart_data

ClickConversionショッピング カート データは、cart_data フィールドに含めることができます。このフィールドは次の属性で構成されます。

  • merchant_id: 関連付けられている Merchant Center アカウントの ID。
  • feed_country_code: Merchant Center フィードの ISO 3166 2 文字の地域コード
  • feed_language_code: Merchant Center フィードの ISO 639-1 言語コード
  • local_transaction_cost: すべてのトランザクション単位の割引の合計(ClickConversioncurrency_code 内)。
  • items: ショッピング カート内の商品。

items の各アイテムは、次の属性で構成されます。

  • product_id: 商品の ID(オファー ID または商品 ID とも呼ばれる)。
  • quantity: アイテムの数量。
  • unit_price: 商品の単価。

conversion_environment

このコンバージョンが記録された環境を示します。(例: アプリ、ウェブ)。

サンプルコード

JavaC#PHPPythonRubyPerl
private void runExample(
    GoogleAdsClient googleAdsClient,
    long customerId,
    long conversionActionId,
    String gclid,
    String gbraid,
    String wbraid,
    String conversionDateTime,
    Double conversionValue,
    Long conversionCustomVariableId,
    String conversionCustomVariableValue,
    String orderId,
    ConsentStatus adUserDataConsent)
    throws InvalidProtocolBufferException {
  // Verifies that exactly one of gclid, gbraid, and wbraid is specified, as required.
  // See https://developers.google.com/google-ads/api/docs/conversions/upload-clicks for details.
  long numberOfIdsSpecified =
      Arrays.asList(gclid, gbraid, wbraid).stream().filter(idField -> idField != null).count();
  if (numberOfIdsSpecified != 1) {
    throw new IllegalArgumentException(
        "Exactly 1 of gclid, gbraid, or wbraid is required, but "
            + numberOfIdsSpecified
            + " ID values were provided");
  }

  // Constructs the conversion action resource name from the customer and conversion action IDs.
  String conversionActionResourceName =
      ResourceNames.conversionAction(customerId, conversionActionId);

  // Creates the click conversion.
  ClickConversion.Builder clickConversionBuilder =
      ClickConversion.newBuilder()
          .setConversionAction(conversionActionResourceName)
          .setConversionDateTime(conversionDateTime)
          .setConversionValue(conversionValue)
          .setCurrencyCode("USD");

  // Sets the single specified ID field.
  if (gclid != null) {
    clickConversionBuilder.setGclid(gclid);
  } else if (gbraid != null) {
    clickConversionBuilder.setGbraid(gbraid);
  } else {
    clickConversionBuilder.setWbraid(wbraid);
  }

  if (conversionCustomVariableId != null && conversionCustomVariableValue != null) {
    // Sets the custom variable and value, if provided.
    clickConversionBuilder.addCustomVariables(
        CustomVariable.newBuilder()
            .setConversionCustomVariable(
                ResourceNames.conversionCustomVariable(customerId, conversionCustomVariableId))
            .setValue(conversionCustomVariableValue));
  }

  if (orderId != null) {
    // Sets the order ID (unique transaction ID), if provided.
    clickConversionBuilder.setOrderId(orderId);
  }

  // Sets the consent information, if provided.
  if (adUserDataConsent != null) {
    // Specifies whether user consent was obtained for the data you are uploading. See
    // https://www.google.com/about/company/user-consent-policy for details.
    clickConversionBuilder.setConsent(Consent.newBuilder().setAdUserData(adUserDataConsent));
  }
  ClickConversion clickConversion = clickConversionBuilder.build();

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

    // Prints any partial errors returned.
    if (response.hasPartialFailureError()) {
      GoogleAdsFailure googleAdsFailure =
          ErrorUtils.getInstance().getGoogleAdsFailure(response.getPartialFailureError());
      // Constructs a protocol buffer printer that will print error details in a concise format.
      Printer errorPrinter = JsonFormat.printer().omittingInsignificantWhitespace();
      for (int operationIndex = 0;
          operationIndex < response.getResultsCount();
          operationIndex++) {
        ClickConversionResult conversionResult = response.getResults(operationIndex);
        if (ErrorUtils.getInstance().isPartialFailureResult(conversionResult)) {
          // Prints the errors for the failed operation.
          System.out.printf("Operation %d failed with the following errors:%n", operationIndex);
          for (GoogleAdsError resultError :
              ErrorUtils.getInstance().getGoogleAdsErrors(operationIndex, googleAdsFailure)) {
            // Prints the error with newlines and extra spaces removed.
            System.out.printf("  %s%n", errorPrinter.print(resultError));
          }
        } else {
          // Prints the information about the successful operation.
          StringBuilder clickInfoBuilder =
              new StringBuilder("conversion that occurred at ")
                  .append(String.format("'%s' ", conversionResult.getConversionDateTime()))
                  .append("with ");
          if (conversionResult.hasGclid()) {
            clickInfoBuilder.append(String.format("gclid '%s'", conversionResult.getGclid()));
          } else if (!conversionResult.getGbraid().isEmpty()) {
            clickInfoBuilder.append(String.format("gbraid '%s'", conversionResult.getGbraid()));
          } else if (!conversionResult.getWbraid().isEmpty()) {
            clickInfoBuilder.append(String.format("wbraid '%s'", conversionResult.getWbraid()));
          } else {
            clickInfoBuilder.append("no click ID");
          }
          System.out.printf("Operation %d for %s succeeded.%n", operationIndex, clickInfoBuilder);
        }
      }
    }
  }
}
      
public void Run(GoogleAdsClient client, long customerId, long conversionActionId,
    string gclid, string gbraid, string wbraid, string conversionTime,
    double conversionValue, ConsentStatus? adUserDataConsent)
{
    // Get the ConversionActionService.
    ConversionUploadServiceClient conversionUploadService =
        client.GetService(Services.V19.ConversionUploadService);

    // Creates a click conversion by specifying currency as USD.
    ClickConversion clickConversion = new ClickConversion()
    {
        ConversionAction = ResourceNames.ConversionAction(customerId, conversionActionId),
        ConversionValue = conversionValue,
        ConversionDateTime = conversionTime,
        CurrencyCode = "USD",
    };

    // Sets the consent information, if provided.
    if (adUserDataConsent != null)
    {
        // Specifies whether user consent was obtained for the data you are uploading. See
        // https://www.google.com/about/company/user-consent-policy
        // for details.
        clickConversion.Consent = new Consent()
        {
            AdUserData = (ConsentStatus)adUserDataConsent
        };
    }

    // Verifies that exactly one of gclid, gbraid, and wbraid is specified, as required.
    // See https://developers.google.com/google-ads/api/docs/conversions/upload-clicks
    // for details.
    string[] ids = { gclid, gbraid, wbraid };
    int idCount = ids.Where(id => !string.IsNullOrEmpty(id)).Count();

    if (idCount != 1)
    {
        throw new ArgumentException($"Exactly 1 of gclid, gbraid, or wbraid is " +
            $"required, but {idCount} ID values were provided");
    }

    // Sets the single specified ID field.
    if (!string.IsNullOrEmpty(gclid))
    {
        clickConversion.Gclid = gclid;
    }
    else if (!string.IsNullOrEmpty(wbraid))
    {
        clickConversion.Wbraid = wbraid;
    }
    else if (!string.IsNullOrEmpty(gbraid))
    {
        clickConversion.Gbraid = gbraid;
    }

    try
    {
        // Issues a request to upload the click conversion.
        UploadClickConversionsResponse response =
            conversionUploadService.UploadClickConversions(
                new UploadClickConversionsRequest()
                {
                    CustomerId = customerId.ToString(),
                    Conversions = { clickConversion },
                    PartialFailure = true,
                    ValidateOnly = false
                });

        // Prints the result.
        ClickConversionResult uploadedClickConversion = response.Results[0];
        Console.WriteLine($"Uploaded conversion that occurred at " +
            $"'{uploadedClickConversion.ConversionDateTime}' from Google " +
            $"Click ID '{uploadedClickConversion.Gclid}' to " +
            $"'{uploadedClickConversion.ConversionAction}'.");
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
        throw;
    }
}
      
public static function runExample(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    int $conversionActionId,
    ?string $gclid,
    ?string $gbraid,
    ?string $wbraid,
    ?string $orderId,
    string $conversionDateTime,
    float $conversionValue,
    ?string $conversionCustomVariableId,
    ?string $conversionCustomVariableValue,
    ?int $adUserDataConsent
) {
    // Verifies that exactly one of gclid, gbraid, and wbraid is specified, as required.
    // See https://developers.google.com/google-ads/api/docs/conversions/upload-clicks for details.
    $nonNullFields = array_filter(
        [$gclid, $gbraid, $wbraid],
        function ($field) {
            return !is_null($field);
        }
    );
    if (count($nonNullFields) !== 1) {
        throw new \UnexpectedValueException(
            sprintf(
                "Exactly 1 of gclid, gbraid or wbraid is required, but %d ID values were "
                . "provided",
                count($nonNullFields)
            )
        );
    }

    // Creates a click conversion by specifying currency as USD.
    $clickConversion = new ClickConversion([
        'conversion_action' =>
            ResourceNames::forConversionAction($customerId, $conversionActionId),
        'conversion_value' => $conversionValue,
        'conversion_date_time' => $conversionDateTime,
        'currency_code' => 'USD'
    ]);
    // Sets the single specified ID field.
    if (!is_null($gclid)) {
        $clickConversion->setGclid($gclid);
    } elseif (!is_null($gbraid)) {
        $clickConversion->setGbraid($gbraid);
    } else {
        $clickConversion->setWbraid($wbraid);
    }

    if (!is_null($conversionCustomVariableId) && !is_null($conversionCustomVariableValue)) {
        $clickConversion->setCustomVariables([new CustomVariable([
            'conversion_custom_variable' => ResourceNames::forConversionCustomVariable(
                $customerId,
                $conversionCustomVariableId
            ),
            'value' => $conversionCustomVariableValue
        ])]);
    }
    // Sets the consent information, if provided.
    if (!empty($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' => $adUserDataConsent]));
    }

    if (!empty($orderId)) {
        // Sets the order ID (unique transaction ID), if provided.
        $clickConversion->setOrderId($orderId);
    }

    // Issues a request to upload the click conversion.
    $conversionUploadServiceClient = $googleAdsClient->getConversionUploadServiceClient();
    /** @var UploadClickConversionsResponse $response */
    // 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(
        // Uploads the click conversion. Partial failure should always be set to true.
        UploadClickConversionsRequest::build($customerId, [$clickConversion], true)
    );

    // Prints the status message if any partial failure error is returned.
    // Note: The details of each partial failure error are not printed here, you can refer to
    // the example HandlePartialFailure.php to learn more.
    if ($response->hasPartialFailureError()) {
        printf(
            "Partial failures occurred: '%s'.%s",
            $response->getPartialFailureError()->getMessage(),
            PHP_EOL
        );
    } else {
        // Prints the result if exists.
        /** @var ClickConversionResult $uploadedClickConversion */
        $uploadedClickConversion = $response->getResults()[0];
        printf(
            "Uploaded click conversion that occurred at '%s' from Google Click ID '%s' " .
            "to '%s'.%s",
            $uploadedClickConversion->getConversionDateTime(),
            $uploadedClickConversion->getGclid(),
            $uploadedClickConversion->getConversionAction(),
            PHP_EOL
        );
    }
}
      
def main(
    client,
    customer_id,
    conversion_action_id,
    gclid,
    conversion_date_time,
    conversion_value,
    conversion_custom_variable_id,
    conversion_custom_variable_value,
    gbraid,
    wbraid,
    order_id,
    ad_user_data_consent,
):
    """Creates a click conversion with a default currency of USD.

    Args:
        client: An initialized GoogleAdsClient instance.
        customer_id: The client customer ID string.
        conversion_action_id: The ID of the conversion action to upload to.
        gclid: The Google Click Identifier ID. If set, the wbraid and gbraid
            parameters must be None.
        conversion_date_time: The the date and time of the conversion (should be
            after the click time). The format is 'yyyy-mm-dd hh:mm:ss+|-hh:mm',
            e.g. '2021-01-01 12:32:45-08:00'.
        conversion_value: The conversion value in the desired currency.
        conversion_custom_variable_id: The ID of the conversion custom
            variable to associate with the upload.
        conversion_custom_variable_value: The str value of the conversion custom
            variable to associate with the upload.
        gbraid: The GBRAID for the iOS app conversion. If set, the gclid and
            wbraid parameters must be None.
        wbraid: The WBRAID for the iOS app conversion. If set, the gclid and
            gbraid parameters must be None.
        order_id: The order ID for the click conversion.
        ad_user_data_consent: The ad user data consent for the click.
    """
    click_conversion = client.get_type("ClickConversion")
    conversion_upload_service = client.get_service("ConversionUploadService")
    conversion_action_service = client.get_service("ConversionActionService")
    click_conversion.conversion_action = (
        conversion_action_service.conversion_action_path(
            customer_id, conversion_action_id
        )
    )

    # Sets the single specified ID field.
    if gclid:
        click_conversion.gclid = gclid
    elif gbraid:
        click_conversion.gbraid = gbraid
    else:
        click_conversion.wbraid = wbraid

    click_conversion.conversion_value = float(conversion_value)
    click_conversion.conversion_date_time = conversion_date_time
    click_conversion.currency_code = "USD"

    if conversion_custom_variable_id and conversion_custom_variable_value:
        conversion_custom_variable = client.get_type("CustomVariable")
        conversion_custom_variable.conversion_custom_variable = (
            conversion_upload_service.conversion_custom_variable_path(
                customer_id, conversion_custom_variable_id
            )
        )
        conversion_custom_variable.value = conversion_custom_variable_value
        click_conversion.custom_variables.append(conversion_custom_variable)

    if order_id:
        click_conversion.order_id = order_id

    # Sets the consent information, if provided.
    if ad_user_data_consent:
        # 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
        click_conversion.consent.ad_user_data = client.enums.ConsentStatusEnum[
            ad_user_data_consent
        ]

    # Uploads the click conversion. Partial failure must be set to True here.
    #
    # 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
    request = client.get_type("UploadClickConversionsRequest")
    request.customer_id = customer_id
    request.conversions.append(click_conversion)
    request.partial_failure = True
    conversion_upload_response = (
        conversion_upload_service.upload_click_conversions(
            request=request,
        )
    )
    uploaded_click_conversion = conversion_upload_response.results[0]
    print(
        f"Uploaded conversion that occurred at "
        f'"{uploaded_click_conversion.conversion_date_time}" from '
        f'Google Click ID "{uploaded_click_conversion.gclid}" '
        f'to "{uploaded_click_conversion.conversion_action}"'
    )
      
def upload_offline_conversion(
  customer_id,
  conversion_action_id,
  gclid,
  gbraid,
  wbraid,
  conversion_date_time,
  conversion_value,
  conversion_custom_variable_id,
  conversion_custom_variable_value,
  ad_user_data_consent)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  # Verifies that exactly one of gclid, gbraid, and wbraid is specified, as required.
  # See https://developers.google.com/google-ads/api/docs/conversions/upload-clicks for details.
  identifiers_specified = [gclid, gbraid, wbraid].reject {|v| v.nil?}.count
  if identifiers_specified != 1
    raise "Must specify exactly one of GCLID, GBRAID, and WBRAID. " \
      "#{identifiers_specified} values were provided."
  end

  click_conversion = client.resource.click_conversion do |cc|
    cc.conversion_action = client.path.conversion_action(customer_id, conversion_action_id)
    # Sets the single specified ID field.
    if !gclid.nil?
      cc.gclid = gclid
    elsif !gbraid.nil?
      cc.gbraid = gbraid
    else
      cc.wbraid = wbraid
    end
    cc.conversion_value = conversion_value.to_f
    cc.conversion_date_time = conversion_date_time
    cc.currency_code = 'USD'
    if conversion_custom_variable_id && conversion_custom_variable_value
      cc.custom_variables << client.resource.custom_variable do |cv|
        cv.conversion_custom_variable = client.path.conversion_custom_variable(
          customer_id, conversion_custom_variable_id)
        cv.value = conversion_custom_variable_value
      end
    end
    # Sets the consent information, if provided.
    unless ad_user_data_consent.nil?
      cc.consent = client.resource.consent do |c|
        # 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
        c.ad_user_data = ad_user_data_consent
      end
    end
  end

  response = client.service.conversion_upload.upload_click_conversions(
    customer_id: customer_id,
    # 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
    conversions: [click_conversion],
    partial_failure: true,
  )
  if response.partial_failure_error.nil?
    result = response.results.first
    puts "Uploaded conversion that occurred at #{result.conversion_date_time} " \
      "from Google Click ID #{result.gclid} to #{result.conversion_action}."
  else
    failures = client.decode_partial_failure_error(response.partial_failure_error)
    puts "Request failed. Failure details:"
    failures.each do |failure|
      failure.errors.each do |error|
        puts "\t#{error.error_code.error_code}: #{error.message}"
      end
    end
  end
end
      
sub upload_offline_conversion {
  my (
    $api_client,                    $customer_id,
    $conversion_action_id,          $gclid,
    $gbraid,                        $wbraid,
    $conversion_date_time,          $conversion_value,
    $conversion_custom_variable_id, $conversion_custom_variable_value,
    $order_id,                      $ad_user_data_consent
  ) = @_;

  # Verify that exactly one of gclid, gbraid, and wbraid is specified, as required.
  # See https://developers.google.com/google-ads/api/docs/conversions/upload-clicks for details.
  my $number_of_ids_specified = grep { defined $_ } ($gclid, $gbraid, $wbraid);
  if ($number_of_ids_specified != 1) {
    die sprintf "Exactly 1 of gclid, gbraid, or wbraid is required, " .
      "but %d ID values were provided.\n",
      $number_of_ids_specified;
  }

  # Create a click conversion by specifying currency as USD.
  my $click_conversion =
    Google::Ads::GoogleAds::V19::Services::ConversionUploadService::ClickConversion
    ->new({
      conversionAction =>
        Google::Ads::GoogleAds::V19::Utils::ResourceNames::conversion_action(
        $customer_id, $conversion_action_id
        ),
      conversionDateTime => $conversion_date_time,
      conversionValue    => $conversion_value,
      currencyCode       => "USD"
    });

  # Set the single specified ID field.
  if (defined $gclid) {
    $click_conversion->{gclid} = $gclid;
  } elsif (defined $gbraid) {
    $click_conversion->{gbraid} = $gbraid;
  } else {
    $click_conversion->{wbraid} = $wbraid;
  }

  if ($conversion_custom_variable_id && $conversion_custom_variable_value) {
    $click_conversion->{customVariables} = [
      Google::Ads::GoogleAds::V19::Services::ConversionUploadService::CustomVariable
        ->new({
          conversionCustomVariable =>
            Google::Ads::GoogleAds::V19::Utils::ResourceNames::conversion_custom_variable(
            $customer_id, $conversion_custom_variable_id
            ),
          value => $conversion_custom_variable_value
        })];
  }

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

  # Set the consent information, if provided.
  if ($ad_user_data_consent) {
    # Specify whether user consent was obtained for the data you are uploading.
    # See https://www.google.com/about/company/user-consent-policy for details.
    $click_conversion->{consent} =
      Google::Ads::GoogleAds::V19::Common::Consent->new({
        adUserData => $ad_user_data_consent
      });
  }

  # Issue a request to 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 $upload_click_conversions_response =
    $api_client->ConversionUploadService()->upload_click_conversions({
      customerId     => $customer_id,
      conversions    => [$click_conversion],
      partialFailure => "true"
    });

  # Print any partial errors returned.
  if ($upload_click_conversions_response->{partialFailureError}) {
    printf "Partial error encountered: '%s'.\n",
      $upload_click_conversions_response->{partialFailureError}{message};
  }

  # Print the result if valid.
  my $uploaded_click_conversion =
    $upload_click_conversions_response->{results}[0];
  if (%$uploaded_click_conversion) {
    printf
      "Uploaded conversion that occurred at '%s' from Google Click ID '%s' " .
      "to the conversion action with resource name '%s'.\n",
      $uploaded_click_conversion->{conversionDateTime},
      $uploaded_click_conversion->{gclid},
      $uploaded_click_conversion->{conversionAction};
  }

  return 1;
}
      

トラブルシューティング

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

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

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

エラー
ConversionUploadError.INVALID_CONVERSION_ACTION_TYPE 指定されたコンバージョン アクションのタイプは、クリック コンバージョンのアップロードには有効ではありません。アップロード リクエストで指定した ConversionAction のタイプが UPLOAD_CLICKS であることを確認します。
ConversionUploadError.NO_CONVERSION_ACTION_FOUND 指定されたコンバージョン アクションが有効になっていないか、アップロード中の customer_id 内に見つかりません。コンバージョン設定に関する情報を取得して、アップロード内のコンバージョン アクションが有効であり、アップロード リクエストの customer_id によって所有されていることを確認します。
ConversionUploadError.TOO_RECENT_CONVERSION_ACTION コンバージョン アクションが新規に作成された場合、アクションの作成後、少なくとも 6 時間待ってから、失敗したコンバージョンを再試行してください。
ConversionUploadError.INVALID_CUSTOMER_FOR_CLICK リクエストの customer_id が、クリック時の Google Ads API コンバージョン アカウントのお客様 ID と一致していません。リクエストの customer_id を正しいお客様に更新します。
ConversionUploadError.EVENT_NOT_FOUND Google 広告で、クリック ID と customer_id の組み合わせが見つかりません。customer_id の要件を確認し、正しい Google 広告アカウントを使用してアップロードしていることを確認します。
ConversionUploadError.DUPLICATE_CLICK_CONVERSION_IN_REQUEST リクエスト内の複数のコンバージョンのクリック ID、conversion_date_timeconversion_action の組み合わせが同じである。リクエストから重複するコンバージョンを削除します。
ConversionUploadError.CLICK_CONVERSION_ALREADY_EXISTS クリック ID、conversion_date_timeconversion_action の組み合わせが同じコンバージョンが以前にアップロードされています。アップロードを再試行していて、この変換が以前に成功した場合は、このエラーを無視してください。以前にアップロードしたコンバージョンに加えて、別のコンバージョンを追加する場合は、ClickConversionconversion_date_time を調整して、以前にアップロードしたコンバージョンが重複しないようにします。
ConversionUploadError.EVENT_NOT_FOUND Google 広告で、クリック ID と customer_id の組み合わせが見つかりません。customer_id の要件を確認し、正しい Google 広告アカウントを使用してアップロードしていることを確認します。
ConversionUploadError.EXPIRED_EVENT インポートされたクリックは、click_through_lookback_window_days フィールドで指定された期間より前に発生しています。click_through_lookback_window_days の変更は変更後に記録されたクリックにのみ影響します。そのため、ルックバック ウィンドウを変更しても、特定のクリックに関するこのエラーは解決されません。必要に応じて、conversion_action を、ルックバック ウィンドウが長い別のアクションに変更します。
ConversionUploadError.CONVERSION_PRECEDES_EVENT conversion_date_time はクリックの日時より前です。conversion_date_time を新しい値に更新します。
ConversionUploadError.GBRAID_WBRAID_BOTH_SET ClickConversion には、gbraidwbraid の両方に値が設定されています。1 つのクリック ID のみを使用するようにコンバージョンを更新し、複数のクリックを同じコンバージョンにまとめないようにします。各クリックには 1 つのクリック ID のみが割り当てられます。
FieldError.VALUE_MUST_BE_UNSET GoogleAdsErrorlocation を確認して、次のいずれの問題がエラーの原因となっているかを確認します。
  • ClickConversion には、gclid の値と、gbraid または wbraid の少なくとも 1 つの値が設定されています。1 つのクリック ID のみを使用するようにコンバージョンを更新し、複数のクリックを同じコンバージョンにまとめないようにします。各クリックには 1 つのクリック ID のみが割り当てられます。
  • ClickConversion には gbraid または wbraid の値が設定され、custom_variables の値が設定されています。Google 広告では、gbraid または wbraid のクリック ID を持つコンバージョンのカスタム変数はサポートされていません。コンバージョンの custom_variables フィールドを設定解除します。

レポートのコンバージョン

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

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