Google Ads API를 사용하여 오프라인 클릭 전환을 Google Ads에 업로드하면 전화나 영업 담당자를 통한 오프라인 판매로 이어진 광고를 추적할 수 있습니다.
설정
오프라인 전환 설정을 사용하려면 몇 가지 기본 요건이 있습니다. 구현을 진행하기 전에 모든 기본 요건이 충족되었는지 확인하세요.
Google Ads 전환 고객에서 전환 추적을 사용 설정합니다.
태그를 구성하고 클릭 ID를 저장합니다.
1. Google Ads 전환 고객에서 전환 추적 사용 설정
전환 시작 가이드를 완료하고 전환 추적을 사용 설정한 경우 2단계: 태그 구성으로 건너뛰세요.
전환 추적 설정에 관한 정보 가져오기
ConversionTrackingSetting
에 대해 Customer
리소스를 쿼리하여 계정의 전환 추적 설정을 확인하고 전환 추적이 사용 설정되어 있는지 확인할 수 있습니다.
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 Ads 계정을 나타냅니다. 교차 계정 전환 추적을 사용하는 고객의 경우 관리자 계정의 ID입니다. Google Ads 전환 고객 ID는 전환을 생성하고 관리하는 Google Ads API 요청에서 customer_id
로 제공되어야 합니다.
전환 추적이 사용 설정되지 않은 경우에도 이 필드는 채워집니다.
conversion_tracking_status
필드는 전환 추적이 사용 설정되어 있는지와 계정에서 교차 계정 전환 추적을 사용하고 있는지를 나타냅니다.
Google Ads 전환 고객에서 전환 액션 만들기
conversion_tracking_status
값이 NOT_CONVERSION_TRACKED
이면 계정에 전환 추적이 사용 설정되어 있지 않습니다. 다음 예와 같이 Google Ads 전환 계정에서 하나 이상의 ConversionAction
을 만들어 전환 추적을 사용 설정합니다. 또는 사용 설정하려는 전환 유형에 대한 고객센터의 안내에 따라 UI에서 전환 액션을 만들 수 있습니다.
Google Ads API를 통해 전송되는 경우 향상된 전환이 자동으로 사용 설정되지만 Google Ads UI를 통해 사용 중지할 수 있습니다.
코드 예
자바
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()); } } }
C#
public void Run(GoogleAdsClient client, long customerId) { // Get the ConversionActionService. ConversionActionServiceClient conversionActionService = client.GetService(Services.V21.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; } }
PHP
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 ); } }
Python
def main(client: GoogleAdsClient, customer_id: str) -> None: conversion_action_service: ConversionActionServiceClient = ( client.get_service("ConversionActionService") ) # Create the operation. conversion_action_operation: ConversionActionOperation = client.get_type( "ConversionActionOperation" ) # Create conversion action. conversion_action: ConversionAction = 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: ConversionAction.ValueSettings = ( conversion_action.value_settings ) value_settings.default_value = 15.0 value_settings.always_use_default_value = True # Add the conversion action. conversion_action_response: MutateConversionActionsResponse = ( 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}".' )
Ruby
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
Perl
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::V21::Resources::ConversionAction->new({ name => $conversion_action_name, category => DEFAULT, type => WEBPAGE, status => ENABLED, viewThroughLookbackWindowDays => 15, valueSettings => Google::Ads::GoogleAds::V21::Resources::ValueSettings->new({ defaultValue => 23.41, alwaysUseDefaultValue => "true" })}); # Create a conversion action operation. my $conversion_action_operation = Google::Ads::GoogleAds::V21::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 Ads 전환 고객으로 설정되어 있고 전환 액션 유형이 올바른 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 Ads 계정, 웹사이트, 리드 추적 시스템을 설정하여 광고의 각 노출 및 클릭에 대한 GCLID, GBRAID 또는 WBRAID를 캡처하고 저장합니다. 새 계정의 경우 자동 태그 추가 기능이 기본적으로 사용 설정됩니다.
요청 구성
이 안내에 따라 UploadClickConversionsRequest
을 구성하고 필드를 적절한 값으로 설정하세요.
customer_id
업로드의 Google Ads 계정을 식별합니다. 클릭의 소스인 계정의 Google Ads 전환 고객으로 설정합니다.
job_id
업로드 요청을 오프라인 데이터 진단의 작업별 정보와 연결하는 메커니즘을 제공합니다.
이 필드를 설정하지 않으면 Google Ads API에서 각 요청에
[2^31, 2^63)
범위의 고유한 값을 할당합니다. 여러 요청을 단일 논리 작업으로 그룹화하려면 작업의 모든 요청에서 이 필드를[0, 2^31)
범위의 동일한 값으로 설정하세요.response의
job_id
에는 값을 지정했는지 아니면 Google Ads API가 값을 할당하도록 했는지와 관계없이 요청의 작업 ID가 포함됩니다.partial_failure_enabled
Google Ads API가 작업에서 발생하는 오류를 처리하는 방법을 결정합니다.
이 필드는
true
로 설정해야 합니다. 응답을 처리할 때는 부분 실패 가이드라인을 따르세요.debug_enabled
리드 확보용 향상된 전환 업로드의 오류 보고 동작을 결정합니다. Google Ads API는
gclid
,gbraid
또는wbraid
를 사용하여 클릭 전환 업로드를 처리할 때 이 필드를 무시합니다.
클릭 전환 작업 만들기
UploadClickConversionRequest
의 ClickConversion
객체 컬렉션은 업로드할 전환 세트를 정의합니다. 이 안내에 따라 각 ClickConversion
를 구성하고 필드를 적절한 값으로 설정하세요.
각 전환 작업의 필수 필드 설정
다음 안내에 따라 ClickConversion
의 필수 필드를 적절한 값으로 설정합니다.
gclid
,gbraid
,wbraid
- 전환의 클릭 또는 노출에 대해 클릭 시 캡처한 식별자입니다. 이 필드 중 하나만 설정하세요.
conversion_date_time
전환 날짜 및 시간입니다.
값에 시간대가 지정되어야 하며 형식은
yyyy-mm-dd HH:mm:ss+|-HH:mm
이어야 합니다(예:2022-01-01 19:32:45-05:00
(일광 절약 시간 무시)).시간대는 유효한 값일 수 있으며 계정의 시간대와 일치하지 않아도 됩니다. 하지만 업로드된 전환 데이터를 Google Ads UI의 데이터와 비교할 계획이라면 전환 수가 일치하도록 Google Ads 계정과 동일한 시간대를 사용하는 것이 좋습니다. 자세한 내용과 예시는 고객센터에서 확인하고 코드 및 형식에서 유효한 시간대 ID 목록을 확인하세요.
user_identifiers
클릭 ID만 사용하여 전환을 업로드하는 경우에는 이 필드를 설정하지 마세요. 이 필드가 설정되면 Google Ads에서 업로드 작업을 리드 확보용 향상된 전환을 위한 업로드로 취급합니다.
conversion_action
클릭 전환의
ConversionAction
리소스 이름입니다.전환 액션의
type
이UPLOAD_CLICKS
이어야 하며 클릭과 연결된 Google Ads 계정의 Google Ads 전환 고객에 있어야 합니다.conversion_value
전환의 가치입니다.
currency_code
conversion_value
의 통화 코드입니다.
각 전환 작업의 선택적 필드 설정
다음 선택적 필드 목록을 검토하고 필요에 따라 ClickConversion
에서 설정합니다.
order_id
- 전환의 거래 ID입니다. 이 필드는 선택사항이지만 적극 권장됩니다. 업로드 중에 설정한 경우 전환에 적용되는 조정에 이 값을 사용해야 합니다. 거래 ID를 사용하여 중복 전환을 최소화하는 방법을 자세히 알아보려면 이 고객센터 도움말을 참고하세요.
external_attribution_data
서드 파티 도구 또는 자체 솔루션을 사용하여 전환을 추적하는 경우 Google Ads에 전환 기여도의 일부만 부여하거나 전환 기여도를 여러 클릭에 분배할 수 있습니다. 외부 기여 전환 가져오기를 사용하면 각 클릭에 할당된 세분화된 기여도를 포함하여 전환을 업로드할 수 있습니다.
소수점 이하의 크레딧을 업로드하려면 이 필드를
external_attribution_model
및external_attribution_credit
값이 있는ExternalAttributionData
객체로 설정합니다.custom_variables
맞춤 전환 변수의 값입니다.
Google Ads에서는
wbraid
또는gbraid
와 함께 맞춤 전환 변수를 지원하지 않습니다.
cart_data
cart_data
필드에 ClickConversion
의 장바구니 데이터를 포함할 수 있습니다. 장바구니 데이터는 다음 속성으로 구성됩니다.
merchant_id
: 연결된 판매자 센터 계정의 ID입니다.feed_country_code
: 판매자 센터 피드의 ISO 3166 2자리 지역 코드입니다.feed_language_code
: 판매자 센터 피드의 ISO 639-1 언어 코드입니다.local_transaction_cost
:ClickConversion
의currency_code
에 있는 모든 거래 수준 할인 금액의 합계입니다.items
: 장바구니에 있는 상품입니다.items
의 각 항목은 다음 속성으로 구성됩니다.product_id
: 제품의 ID입니다. 쿠폰 ID 또는 상품 ID라고도 합니다.quantity
: 상품의 수량입니다.unit_price
: 상품의 단가입니다.
conversion_environment
이 전환이 기록된 환경을 나타냅니다. 예를 들어 앱 또는 웹입니다.
코드 예
자바
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); } } } } }
C#
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.V21.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; } }
PHP
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 ); } }
Python
def main( client: GoogleAdsClient, customer_id: str, conversion_action_id: str, gclid: Optional[str], conversion_date_time: str, conversion_value: str, conversion_custom_variable_id: Optional[str], conversion_custom_variable_value: Optional[str], gbraid: Optional[str], wbraid: Optional[str], order_id: Optional[str], ad_user_data_consent: Optional[str], ) -> None: """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: ClickConversion = client.get_type("ClickConversion") conversion_upload_service: ConversionUploadServiceClient = ( client.get_service("ConversionUploadService") ) conversion_action_service: ConversionActionServiceClient = ( 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: CustomVariable = 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: UploadClickConversionsRequest = client.get_type( "UploadClickConversionsRequest" ) request.customer_id = customer_id request.conversions.append(click_conversion) request.partial_failure = True conversion_upload_response: UploadClickConversionsResponse = ( conversion_upload_service.upload_click_conversions( request=request, ) ) uploaded_click_conversion: ClickConversionResult = ( 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}"' )
Ruby
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
Perl
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::V21::Services::ConversionUploadService::ClickConversion ->new({ conversionAction => Google::Ads::GoogleAds::V21::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::V21::Services::ConversionUploadService::CustomVariable ->new({ conversionCustomVariable => Google::Ads::GoogleAds::V21::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::V21::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; }
curl
# This code example uploads a click conversion. # # Variables: # API_VERSION, # CUSTOMER_ID, # DEVELOPER_TOKEN, # MANAGER_CUSTOMER_ID, # OAUTH2_ACCESS_TOKEN: # See https://developers.google.com/google-ads/api/rest/auth#request_headers # for details. # # CONVERSION_ACTION_RESOURCE_NAME: Resource name of the conversion action # associated with this conversion. # GCLID: The Google click ID (gclid) associated with this conversion. # CONVERSION_VALUE: The value of the conversion for the advertiser. # CONVERSION_DATE_TIME: The date time at which the conversion occurred. The # format is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, # "2019-01-01 12:32:45-08:00". # CURRENCY_CODE: The currency code of the conversion value. This is the # ISO 4217 3-character currency code. For example: USD, EUR. # CONVERSION_CUSTOM_VARIABLE: The name of the conversion custom variable. # CONVERSION_CUSTOM_VARIABLE_VALUE: The value of the conversion custom # variable. # ORDER_ID: The order ID of the conversion. curl -f --request POST \ "https://googleads.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}:uploadClickConversions" \ --header "Content-Type: application/json" \ --header "developer-token: ${DEVELOPER_TOKEN}" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --data @- <<EOF { "conversions": [ { "conversionAction": "${CONVERSION_ACTION_RESOURCE_NAME}", "gclid": "${GCLID}", "conversionValue": ${CONVERSION_VALUE}, "conversionDateTime": "${CONVERSION_DATE_TIME}", "currencyCode": "${CURRENCY_CODE}", "customVariables": [ { "conversionCustomVariable": "${CONVERSION_CUSTOM_VARIABLE}", "value": "${CONVERSION_CUSTOM_VARIABLE_VALUE}" } ], "orderId": "${ORDER_ID}", "consent": { "adUserData": "GRANTED" } } ], "partialFailure": true } EOF
문제 해결
오프라인 데이터 진단은 업로드의 전반적인 상태를 지속적으로 검토할 수 있는 단일 리소스를 제공합니다. 하지만 구현 중에 이 섹션의 정보를 사용하여 응답의 partial_failure_error
필드에 보고된 오류를 조사할 수 있습니다.
전환 액션을 업로드할 때 가장 일반적인 오류는 USER_PERMISSION_DENIED
와 같은 승인 오류입니다. 요청의 고객 ID가 전환 액션을 소유한 Google Ads 전환 고객으로 설정되어 있는지 다시 확인합니다. 자세한 내용은 승인 가이드를 참고하고, 다양한 오류를 디버깅하는 방법에 관한 팁은 일반적인 오류 가이드를 참고하세요.
일반적인 오류 디버그
오류 | |
---|---|
INVALID_CONVERSION_ACTION_TYPE
|
지정된 전환 액션의 유형이 클릭 전환 업로드에 유효하지 않습니다. 업로드 요청에 지정된 ConversionAction 의 유형이 UPLOAD_CLICKS 인지 확인합니다.
|
NO_CONVERSION_ACTION_FOUND
|
지정된 전환 액션이 사용 설정되지 않았거나 업로드 customer_id 내에서 찾을 수 없습니다. 전환 설정에 관한 정보를 가져와 업로드의 전환 액션이 사용 설정되어 있고 업로드 요청의 customer_id 소유인지 확인합니다.
|
TOO_RECENT_CONVERSION_ACTION
|
전환 액션이 새로 생성되었습니다. 작업이 생성된 후 최소 6시간이 지난 후에 실패한 전환을 다시 시도하세요. |
INVALID_CUSTOMER_FOR_CLICK
|
요청의 customer_id 이 클릭 시 Google Ads API 전환 계정이었던 고객 ID와 동일하지 않습니다. 요청의 customer_id 을 올바른 고객으로 업데이트합니다.
|
EVENT_NOT_FOUND
|
Google Ads에서 클릭 ID와 customer_id 의 조합을 찾을 수 없습니다. customer_id 요구사항을 검토하고 올바른 Google Ads 계정을 사용하여 업로드하고 있는지 확인합니다.
|
DUPLICATE_CLICK_CONVERSION_IN_REQUEST
|
요청에 포함된 여러 전환의 클릭 ID, conversion_date_time , conversion_action 조합이 동일합니다. 요청에서 중복 전환을 삭제합니다.
|
CLICK_CONVERSION_ALREADY_EXISTS
|
클릭 ID, conversion_date_time , conversion_action 의 조합이 동일한 전환이 이전에 업로드되었습니다. 업로드를 다시 시도하고 이 변환이 이전에 성공한 경우 이 오류를 무시하세요. 이전에 업로드한 전환 외에 다른 전환을 추가하려면 이전에 업로드한 전환이 중복되지 않도록 ClickConversion 의 conversion_date_time 를 조정하세요.
|
EVENT_NOT_FOUND
|
Google Ads에서 클릭 ID와 customer_id 의 조합을 찾을 수 없습니다. customer_id 요구사항을 검토하고 올바른 Google Ads 계정을 사용하여 업로드하고 있는지 확인합니다.
|
EXPIRED_EVENT
|
가져온 클릭이 click_through_lookback_window_days 필드에 지정된 기간 전에 발생했습니다. click_through_lookback_window_days 변경은 변경 후 기록된 클릭에만 영향을 미치므로 전환 확인 기간을 변경해도 특정 클릭의 오류가 해결되지 않습니다. 필요한 경우 conversion_action 을 전환 확인 기간이 더 긴 다른 작업으로 변경합니다. |
CONVERSION_PRECEDES_EVENT
|
conversion_date_time 이 클릭 날짜 및 시간보다 이전입니다. conversion_date_time 를 더 늦은 값으로 업데이트합니다.
|
GBRAID_WBRAID_BOTH_SET
|
ClickConversion 에는 gbraid 및 wbraid 모두에 설정된 값이 있습니다. 하나의 클릭 ID만 사용하도록 전환을 업데이트하고 여러 클릭을 동일한 전환으로 결합하지 않도록 합니다. 각 클릭에는 클릭 ID가 하나만 있습니다.
|
VALUE_MUST_BE_UNSET
|
GoogleAdsError 의 location 을 확인하여 다음 문제 중 어떤 문제가 오류를 일으켰는지 확인합니다.
|
보고서의 전환
업로드된 전환은 업로드 요청 날짜나 ClickConversion
의 conversion_date_time
날짜가 아니라 원래 클릭의 노출 날짜의 보고서에 반영됩니다.
가져온 전환 통계가 마지막 클릭 기여 분석에 대해 Google Ads 계정에 표시되는 데 최대 3시간이 걸립니다. 다른 검색 기여 분석 모델의 경우 3시간 이상 걸릴 수 있습니다. 자세한 내용은 데이터 업데이트 가이드를 참고하세요.