Importowanie konwersji telefonicznych

Za pomocą interfejsu Google Ads API możesz importować do Google Ads konwersje telefoniczne offline, aby śledzić, kiedy reklamy generują połączenia telefoniczne i kiedy te połączenia prowadzą do wartościowych działań klientów.

W interfejsie Google Ads odpowiada to użyciu źródła konwersji Przesłane pliki, a następnie wybraniu opcji Konwersje z połączeń.

Tworzenie konwersji z połączeń

Podczas tworzenia CallConversion warto pamiętać o tych kwestiach:

  • Musisz wypełnić pole consent obiektu CallConversion.

  • Atrybut partial_failure elementu UploadCallConversionsRequest powinien mieć zawsze wartość true. Podczas obsługi prawidłowych i nieudanych operacji jednocześnie postępuj zgodnie z wytycznymi dotyczącymi częściowych błędów.

  • Jeśli w odpowiedzi na prośbę o zaimportowanie konwersji otrzymasz komunikat o błędzie TOO_RECENT_CONVERSION_ACTION lub TOO_RECENT_CALL, odczekaj odpowiednio 6 lub 12 godzin, zanim ponownie spróbujesz przesłać wiersze, których nie udało się zaimportować.

  • Statystyki zaimportowanych konwersji pojawiają się na koncie Google Ads po upływie około 3 godzin.

    • Jeśli jedno żądanie zawiera wiele operacji dotyczących tej samej konwersji, zwracany jest błąd DUPLICATE_CALL_CONVERSION_IN_REQUEST.
  • Jeśli użytkownik ręcznie skopiuje numer Google do przekazywania połączeń i zadzwoni pod ten numer, nie będzie można zarejestrować konwersji.

Importowanie konwersji telefonicznej

Aby powiązać konwersje telefoniczne offline z działaniem powodującym konwersję, potrzebujesz tych informacji: identyfikator dzwoniącego (numer telefonu), data i godzina konwersji, nazwa zasobu działania powodującego konwersję oraz opcjonalnie wartość konwersji i waluta, które należy przesłać do ConversionUploadService. Więcej informacji o różnych danych wejściowych znajdziesz w tym artykule w Centrum pomocy. W przykładzie kodu opisano też formaty różnych danych wejściowych.

Wymagania

Podczas importowania CallConversion musisz spełniać te wymagania:

Aby uniknąć błędu ConversionUploadError.INVALID_CONVERSION_ACTION, atrybut conversion_action musi odwoływać się do elementu ConversionAction, w którym:

  • Wartość ConversionActionType to UPLOAD_CALLS.

  • status ConversionAction wynosi ENABLED. W przeciwnym razie operacja nie powiedzie się i zostanie zwrócony błąd NO_CONVERSION_ACTION_FOUND.

  • ConversionAction występuje na koncie klienta Google Ads, na którym rejestrowane są konwersje z kliknięć.

Zalecamy też ustawienie parametru ConversionAction.category na kategorię, która najlepiej opisuje Twoje konwersje.

Dodatkowo muszą zostać spełnione te warunki:

  • momencie połączenia śledzenie konwersji było włączone na koncie klienta Google Ads, na którym zarejestrowano połączenie.

  • Wartość customer_id parametru UploadCallConversionsRequest musi być identyfikatorem klienta konwersji Google Ads na koncie Google Ads, z którego pochodzi połączenie. W przeciwnym razie import konwersji zakończy się ConversionUploadError.INVALID_CUSTOMER_FOR_CALLbłędem.

  • Wartość conversion_value musi być równa lub większa niż zero.

  • Wartość conversion_date_time musi mieć określoną strefę czasową, a format to yyyy-mm-dd HH:mm:ss+|-HH:mm, np. 2022-01-01 19:32:45-05:00 (z pominięciem czasu letniego). Strefa czasowa może mieć dowolną prawidłową wartość. Nie musi być zgodna ze strefą czasową konta. Jeśli jednak planujesz porównywać zaimportowane dane o konwersjach z danymi w interfejsie Google Ads, zalecamy używanie tej samej strefy czasowej co na koncie Google Ads, aby liczba konwersji była zgodna.

Przykładowy kod

Java

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.V22.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
        );
    }
}