Google Ads API를 사용하여 오프라인 통화 전환을 Google Ads로 가져와 광고가 전화 통화로 이어지는 때와 이러한 전화 통화가 가치 있는 고객 액션으로 이어지는 때를 추적할 수 있습니다.
Google Ads UI에 매핑하면 업로드 전환 소스를 사용한 다음 전화 전환을 선택하는 것과 같습니다.
통화 전환 만들기
CallConversion
를 만들 때 다음 사항에 유의하세요.
CallConversion
객체의consent
필드를 채워야 합니다.UploadCallConversionsRequest
의partial_failure
속성은 항상true
로 설정해야 합니다. 유효한 작업과 실패한 작업을 동시에 처리할 때는 부분 실패 가이드라인을 따르세요.전환수 가져오기 요청에 대한
TOO_RECENT_CONVERSION_ACTION
또는TOO_RECENT_CALL
응답 메시지가 표시되면 실패한 행을 다시 시도하기 전에 각각 6시간 또는 12시간을 기다리세요.가져온 전환 통계가 Google Ads 계정에 표시되기까지 최대 3시간이 걸립니다.
- 단일 요청에 동일한 전환에 대한 여러 작업이 포함된 경우
DUPLICATE_CALL_CONVERSION_IN_REQUEST
오류가 반환됩니다.
- 단일 요청에 동일한 전환에 대한 여러 작업이 포함된 경우
사용자가 Google 착신 전화번호를 수동으로 복사하여 전화를 걸면 전환이 기록되지 않습니다.
통화 전환 가져오기
오프라인 통화 전환을 전환 액션과 연결하려면 발신자 ID (전화번호), 전환 날짜 및 시간, 전환 액션 리소스 이름이 필요하며, 선택적으로 전환 가치 및 통화가 ConversionUploadService
에 필요합니다.
다양한 입력에 대한 자세한 내용은 고객센터 도움말을 참고하세요. 코드 예시에서는 다양한 입력의 형식도 설명합니다.
요구사항
CallConversion
을 가져올 때는 다음 요구사항을 충족해야 합니다.
ConversionUploadError.INVALID_CONVERSION_ACTION
오류를 방지하려면 conversion_action
속성이 다음을 충족하는 ConversionAction
를 참조해야 합니다.
ConversionActionType
은UPLOAD_CALLS
입니다.ConversionAction
의status
은ENABLED
입니다. 그렇지 않으면NO_CONVERSION_ACTION_FOUND
오류와 함께 작업이 실패합니다.ConversionAction
이 클릭의 Google Ads 계정의 Google Ads 전환 고객에 있습니다.
ConversionAction.category
도 전환을 가장 잘 나타내는 카테고리로 설정하는 것이 좋습니다.
또한 다음 조건을 충족해야 합니다.
통화 시점에 통화의 Google Ads 계정의 Google Ads 전환 고객에서 전환 추적이 사용 설정되어 있었습니다.
UploadCallConversionsRequest
의customer_id
는 통화의 Google Ads 계정의 Google Ads 전환 고객의 고객 ID여야 합니다. 그렇지 않으면 전환 가져오기에서ConversionUploadError.INVALID_CUSTOMER_FOR_CALL
오류가 발생합니다.conversion_value
는 0 이상이어야 합니다.conversion_date_time
에는 시간대가 지정되어야 하며 형식은yyyy-mm-dd HH:mm:ss+|-HH:mm
입니다(예:2022-01-01 19:32:45-05:00
(일광 절약 시간 무시)). 시간대는 유효한 값일 수 있으며 계정의 시간대와 일치하지 않아도 됩니다. 하지만 가져온 전환 데이터를 Google Ads UI의 데이터와 비교하려면 전환 수가 일치하도록 Google Ads 계정과 동일한 시간대를 사용하는 것이 좋습니다.
코드 예
자바
private void runExample( GoogleAdsClient googleAdsClient, long customerId, String conversionActionId, String callerId, String callStartDateTime, double conversionValue, Long conversionCustomVariableId, String conversionCustomVariableValue, ConsentStatus adUserDataConsent) { // Create a call conversion by specifying currency as USD. CallConversion.Builder conversionBuilder = CallConversion.newBuilder() .setConversionAction(conversionActionId) .setCallerId(callerId) .setCallStartDateTime(callStartDateTime) .setConversionValue(conversionValue) .setCurrencyCode("USD"); if (conversionCustomVariableId != null && conversionCustomVariableValue != null) { conversionBuilder.addCustomVariables( CustomVariable.newBuilder() .setConversionCustomVariable( ResourceNames.conversionCustomVariable(customerId, conversionCustomVariableId)) .setValue(conversionCustomVariableValue)); } // 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. conversionBuilder.setConsent(Consent.newBuilder().setAdUserData(adUserDataConsent)); } CallConversion conversion = conversionBuilder.build(); // Uploads the call conversion to the API. try (ConversionUploadServiceClient conversionUploadServiceClient = googleAdsClient.getLatestVersion().createConversionUploadServiceClient()) { // Partial failure MUST be enabled for this request. // 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 UploadCallConversionsResponse response = conversionUploadServiceClient.uploadCallConversions( UploadCallConversionsRequest.newBuilder() .setCustomerId(String.valueOf(customerId)) .setCustomerId(Long.toString(customerId)) .addConversions(conversion) .setPartialFailure(true) .build()); // Prints any partial failure errors returned. if (response.hasPartialFailureError()) { GoogleAdsFailure googleAdsFailure = ErrorUtils.getInstance().getGoogleAdsFailure(response.getPartialFailureError()); googleAdsFailure .getErrorsList() .forEach(e -> System.out.println("Partial failure occurred: " + e.getMessage())); throw new RuntimeException( "Partial failure occurred " + response.getPartialFailureError().getMessage()); } // Prints the result if valid. CallConversionResult result = response.getResults(0); System.out.printf( "Uploaded call conversion that occurred at '%' for caller ID '%' to the conversion" + " action with resource name '%'.%n", result.getCallStartDateTime(), result.getCallerId(), result.getConversionAction()); } }
C#
public void Run(GoogleAdsClient client, long customerId, long conversionActionId, string callerId, string callStartTime, string conversionTime, double conversionValue, long? conversionCustomVariableId, string conversionCustomVariableValue, ConsentStatus? adUserDataConsent) { // Get the ConversionUploadService. ConversionUploadServiceClient conversionUploadService = client.GetService(Services.V21.ConversionUploadService); // Create a call conversion by specifying currency as USD. CallConversion callConversion = new CallConversion() { ConversionAction = ResourceNames.ConversionAction(customerId, conversionActionId), CallerId = callerId, CallStartDateTime = callStartTime, ConversionDateTime = conversionTime, ConversionValue = conversionValue, CurrencyCode = "USD", }; 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. callConversion.Consent = new Consent() { AdUserData = (ConsentStatus)adUserDataConsent }; } if (conversionCustomVariableId != null && !string.IsNullOrEmpty(conversionCustomVariableValue)) { callConversion.CustomVariables.Add(new CustomVariable() { ConversionCustomVariable = ResourceNames.ConversionCustomVariable( customerId, conversionCustomVariableId.Value), Value = conversionCustomVariableValue }); } UploadCallConversionsRequest request = new UploadCallConversionsRequest() { CustomerId = customerId.ToString(), Conversions = { callConversion }, PartialFailure = true }; try { // Issues a request to upload the call conversion. The partialFailure parameter // is set to true, and validateOnly parameter to false as required by this method // call. // 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 UploadCallConversionsResponse response = conversionUploadService.UploadCallConversions(request); // Since we set partialFailure = true, we can retrieve error messages (if any) from // the operation response. if (response.PartialFailureError != null) { Console.WriteLine("Call conversion upload failed."); // Retrieves the errors from the partial failure and prints them. List<GoogleAdsError> errors = response.PartialFailure.GetErrorsByOperationIndex(0); foreach (GoogleAdsError error in errors) { Console.WriteLine($"Operation failed with error: {error}."); } } else { // Prints the result. CallConversionResult uploadedCallConversion = response.Results[0]; Console.WriteLine($"Uploaded call conversion that occurred at " + $"'{uploadedCallConversion.CallStartDateTime}' for caller ID " + $"'{uploadedCallConversion.CallerId}' to the conversion action with " + $"resource name '{uploadedCallConversion.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 $callerId, string $callStartDateTime, string $conversionDateTime, float $conversionValue, ?string $conversionCustomVariableId, ?string $conversionCustomVariableValue, ?int $adUserDataConsent ) { // Creates a call conversion by specifying currency as USD. $callConversion = new CallConversion([ 'conversion_action' => ResourceNames::forConversionAction($customerId, $conversionActionId), 'caller_id' => $callerId, 'call_start_date_time' => $callStartDateTime, 'conversion_date_time' => $conversionDateTime, 'conversion_value' => $conversionValue, 'currency_code' => 'USD' ]); if (!is_null($conversionCustomVariableId) && !is_null($conversionCustomVariableValue)) { $callConversion->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. $callConversion->setConsent(new Consent(['ad_user_data' => $adUserDataConsent])); } // Issues a request to upload the call 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->uploadCallConversions( // Partial failure MUST be enabled for this request. UploadCallConversionsRequest::build($customerId, [$callConversion], 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 CallConversionResult $uploadedCallConversion */ $uploadedCallConversion = $response->getResults()[0]; printf( "Uploaded call conversion that occurred at '%s' for caller ID '%s' to the " . "conversion action with resource name '%s'.%s", $uploadedCallConversion->getCallStartDateTime(), $uploadedCallConversion->getCallerId(), $uploadedCallConversion->getConversionAction(), PHP_EOL ); } }
Python
def main( client: GoogleAdsClient, customer_id: str, conversion_action_id: str, caller_id: str, call_start_date_time: str, conversion_date_time: str, conversion_value: float, conversion_custom_variable_id: Optional[str], conversion_custom_variable_value: Optional[str], ad_user_data_consent: Optional[str], ): """Imports offline call conversion values for calls related to your ads. 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. caller_id: The caller ID from which this call was placed. Caller ID is expected to be in E.164 format with preceding '+' sign, e.g. '+18005550100'. call_start_date_time: The date and time at which the call occurred. The format is 'yyyy-mm-dd hh:mm:ss+|-hh:mm', e.g. '2021-01-01 12:32:45-08:00'. 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. ad_user_data_consent: The consent status for ad user data for all members in the job. """ # Get the ConversionUploadService client. conversion_upload_service: ConversionUploadServiceClient = ( client.get_service("ConversionUploadService") ) # Create a call conversion in USD currency. call_conversion: CallConversion = client.get_type("CallConversion") call_conversion.conversion_action = client.get_service( "ConversionActionService" ).conversion_action_path(customer_id, conversion_action_id) call_conversion.caller_id = caller_id call_conversion.call_start_date_time = call_start_date_time call_conversion.conversion_date_time = conversion_date_time call_conversion.conversion_value = conversion_value call_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_custom_variable_id ) conversion_custom_variable.value = conversion_custom_variable_value call_conversion.custom_variables.append(conversion_custom_variable) # 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 ad_user_data_consent: call_conversion.consent.ad_user_data = client.enums.ConsentStatusEnum[ ad_user_data_consent ] # Issue a request to upload the call conversion. # Partial failure MUST be enabled for this request. request: UploadCallConversionsRequest = client.get_type( "UploadCallConversionsRequest" ) request.customer_id = customer_id request.conversions = [call_conversion] request.partial_failure = 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 upload_call_conversions_response: UploadCallConversionsResponse = ( conversion_upload_service.upload_call_conversions(request=request) ) # Print any partial errors returned. if upload_call_conversions_response.partial_failure_error: print( "Partial error occurred: " f"'{upload_call_conversions_response.partial_failure_error.message}'" ) # Print the result if valid. uploaded_call_conversion: CallConversionResult = ( upload_call_conversions_response.results[0] ) if uploaded_call_conversion.call_start_date_time: print( "Uploaded call conversion that occurred at " f"'{uploaded_call_conversion.call_start_date_time}' " f"for caller ID '{uploaded_call_conversion.caller_id}' " "to the conversion action with resource name " f"'{uploaded_call_conversion.conversion_action}'." )
Ruby
def upload_call_conversion( customer_id, conversion_action_id, caller_id, call_start_date_time, 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 # Create a call conversion by specifying currency as USD. call_conversion = client.resource.call_conversion do |c| c.conversion_action = client.path.conversion_action( customer_id, conversion_action_id) c.caller_id = caller_id c.call_start_date_time = call_start_date_time c.conversion_date_time = conversion_date_time c.conversion_value = conversion_value c.currency_code = "USD" if conversion_custom_variable_id && conversion_custom_variable_value c.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 unless ad_user_data_consent.nil? c.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 # Issues a request to upload the call conversion. response = client.service.conversion_upload.upload_call_conversions( customer_id: customer_id, # 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 conversions: [call_conversion], partial_failure: true ) # Prints errors if any partial failure error is returned. if response.partial_failure_error failures = client.decode_partial_failure_error(response.partial_failure_error) failures.each do |failure| failure.errors.each do |error| human_readable_error_path = error .location .field_path_elements .map { |location_info| if location_info.index "#{location_info.field_name}[#{location_info.index}]" else "#{location_info.field_name}" end }.join(" > ") errmsg = "error occured while adding operations " \ "#{human_readable_error_path}" \ " with value: #{error.trigger.string_value}" \ " because #{error.message.downcase}" puts errmsg end end else # Print the result if valid. uploaded_call_conversion = response.results.first puts "Uploaded call conversion that occurred at " \ "#{uploaded_call_conversion.call_start_date_time} " \ "for caller ID " \ "#{uploaded_call_conversion.caller_id} " \ "to the conversion action with resource name " \ "#{uploaded_call_conversion.conversion_action}" end end
Perl
sub upload_call_conversion { my ( $api_client, $customer_id, $conversion_action_id, $caller_id, $call_start_date_time, $conversion_date_time, $conversion_value, $conversion_custom_variable_id, $conversion_custom_variable_value, $ad_user_data_consent ) = @_; # Create a call conversion by specifying currency as USD. my $call_conversion = Google::Ads::GoogleAds::V21::Services::ConversionUploadService::CallConversion ->new({ conversionAction => Google::Ads::GoogleAds::V21::Utils::ResourceNames::conversion_action( $customer_id, $conversion_action_id ), callerId => $caller_id, callStartDateTime => $call_start_date_time, conversionDateTime => $conversion_date_time, conversionValue => $conversion_value, currencyCode => "USD" }); if ($conversion_custom_variable_id && $conversion_custom_variable_value) { $call_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 })]; } # 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. $call_conversion->{consent} = Google::Ads::GoogleAds::V21::Common::Consent->new({ adUserData => $ad_user_data_consent }); } # Issue a request to upload the call conversion. # 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_call_conversions_response = $api_client->ConversionUploadService()->upload_call_conversions({ customerId => $customer_id, conversions => [$call_conversion], partialFailure => "true" }); # Print any partial errors returned. if ($upload_call_conversions_response->{partialFailureError}) { printf "Partial error encountered: '%s'.\n", $upload_call_conversions_response->{partialFailureError}{message}; } # Print the result if valid. my $uploaded_call_conversion = $upload_call_conversions_response->{results}[0]; if (%$uploaded_call_conversion) { printf "Uploaded call conversion that occurred at '%s' " . "for caller ID '%s' to the conversion action with resource name '%s'.\n", $uploaded_call_conversion->{callStartDateTime}, $uploaded_call_conversion->{callerId}, $uploaded_call_conversion->{conversionAction}; } return 1; }
curl
# This code example uploads a call 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. # CALLER_ID: The caller id from which this call was placed. Caller id is # expected to be in E.164 format with preceding '+' sign, for example, # "+18005550100". # CALL_START_DATE_TIME: The date time at which the call occurred. The format # is "yyyy-mm-dd hh:mm:ss+|-hh:mm", for example, # "2019-01-01 12:32:45-08:00". # 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". # CONVERSION_VALUE: The value of the conversion for the advertiser. # 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. curl -f --request POST \ "https://googleads.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}:uploadCallConversions" \ --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}", "callerId": "${CALLER_ID}", "callStartDateTime": "${CALL_START_DATE_TIME}", "conversionDateTime": "${CONVERSION_DATE_TIME}", "conversionValue": ${CONVERSION_VALUE}, "currencyCode": "${CURRENCY_CODE}", "customVariables": [ { "conversionCustomVariable": "${CONVERSION_CUSTOM_VARIABLE}", "value": "${CONVERSION_CUSTOM_VARIABLE_VALUE}" } ], "consent": { "adUserData": "GRANTED" } } ] } EOF