Fazer o upload das conversões

Este guia fornece instruções detalhadas para upload de conversões off-line usando o serviço Conversions da API DCM/DFA Reporting and Trafficking. Antes de continuar, consulte a Visão geral para saber mais sobre as conversões off-line e os conceitos analisados neste guia.

Configurar recursos de conversão

A primeira etapa no processo de upload de conversões é criar um ou mais objetos de recurso Conversion. Cada um desses objetos representa um único evento de conversão e contém alguns campos obrigatórios:

Campo Descrição
floodlightActivityId É a atividade do Floodlight que será associada a essa conversão.
floodlightConfigurationId É a configuração do Floodlight usada pela atividade especificada.
ordinal Contém um valor usado para controlar como eliminar a duplicação de conversões do mesmo dispositivo ou usuário no mesmo dia. Consulte as Perguntas frequentes para mais informações.
timestampMicros É o carimbo de data/hora da conversão em microssegundos desde a Era Unix.

Além disso, cada objeto precisa conter um dos seguintes campos:

Campo Descrição
encryptedUserId Contém um único ID do usuário criptografado, extraído da macro de correspondência %m ou daTransferência de dados.
encryptedUserIdCandidates[] É uma lista de IDs de usuário criptografados, extraída da macro de correspondência %m ou da Transferência de dados. Será usado o primeiro ID que tiver uma exposição do Floodlight registrada antes do timestampMicros especificado. Se nenhum deles corresponder a uma exposição existente, o resultado será um erro.
gclid É um identificador de clique do Google gerado pelo Google Ads ou pelo Search Ads 360.
mobileDeviceId Contém um código de dispositivo móvel sem criptografia no formato IDFA ou AdID.

Os campos opcionais são descritos na documentação de referência. Apesar de ser opcional, o campo de quantidade precisa ter um valor mínimo de 1 para que a conversão seja incluída em certas métricas (como "Total de conversões") ao gerar relatórios.

O exemplo abaixo ilustra a criação de um objeto de recurso de conversão simples:

C#

// Generate a timestamp in milliseconds since Unix epoch.
TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1);
long currentTimeInMilliseconds = (long) timeSpan.TotalMilliseconds;

// Find the Floodlight configuration ID based on the provided activity ID.
FloodlightActivity floodlightActivity =
    service.FloodlightActivities.Get(profileId, floodlightActivityId).Execute();
long floodlightConfigurationId = (long) floodlightActivity.FloodlightConfigurationId;

// Create the conversion.
Conversion conversion = new Conversion();
conversion.EncryptedUserId = conversionUserId;
conversion.FloodlightActivityId = floodlightActivityId;
conversion.FloodlightConfigurationId = floodlightConfigurationId;
conversion.Ordinal = currentTimeInMilliseconds.ToString();
conversion.TimestampMicros = currentTimeInMilliseconds * 1000;

Java

long currentTimeInMilliseconds = System.currentTimeMillis();

// Find Floodlight configuration ID based on the provided activity ID.
FloodlightActivity floodlightActivity = reporting.floodlightActivities()
    .get(profileId, floodlightActivityId).execute();
long floodlightConfigurationId = floodlightActivity.getFloodlightConfigurationId();

Conversion conversion = new Conversion();
conversion.setEncryptedUserId(encryptedUserId);
conversion.setFloodlightActivityId(floodlightActivityId);
conversion.setFloodlightConfigurationId(floodlightConfigurationId);
conversion.setOrdinal(String.valueOf(currentTimeInMilliseconds));
conversion.setTimestampMicros(currentTimeInMilliseconds * 1000);

PHP

$currentTimeInMicros = time() * 1000 * 1000;

// Find Floodlight configuration ID based on provided activity ID.
$activity = $this->service->floodlightActivities->get(
    $values['user_profile_id'],
    $values['floodlight_activity_id']
);
$floodlightConfigId = $activity->getFloodlightConfigurationId();

$conversion = new Google_Service_Dfareporting_Conversion();
$conversion->setEncryptedUserId($values['encrypted_user_id']);
$conversion->setFloodlightActivityId($values['floodlight_activity_id']);
$conversion->setFloodlightConfigurationId($floodlightConfigId);
$conversion->setOrdinal($currentTimeInMicros);
$conversion->setTimestampMicros($currentTimeInMicros);

Python

# Look up the Floodlight configuration ID based on activity ID.
floodlight_activity = service.floodlightActivities().get(
    profileId=profile_id, id=floodlight_activity_id).execute()
floodlight_config_id = floodlight_activity['floodlightConfigurationId']

current_time_in_micros = int(time.time() * 1000000)

# Construct the conversion.
conversion = {
    'encryptedUserId': encrypted_user_id,
    'floodlightActivityId': floodlight_activity_id,
    'floodlightConfigurationId': floodlight_config_id,
    'ordinal': current_time_in_micros,
    'timestampMicros': current_time_in_micros
}

Ruby

# Look up the Floodlight configuration ID based on activity ID.
floodlight_activity = service.get_floodlight_activity(profile_id,
  floodlight_activity_id)
floodlight_config_id = floodlight_activity.floodlight_configuration_id

current_time_in_micros = DateTime.now.strftime('%Q').to_i * 1000

# Construct the conversion.
conversion = DfareportingUtils::API_NAMESPACE::Conversion.new(
  encrypted_user_id: encrypted_user_id,
  floodlight_activity_id: floodlight_activity_id,
  floodlight_configuration_id: floodlight_config_id,
  ordinal: current_time_in_micros,
  timestamp_micros: current_time_in_micros
)

Especificar informações de criptografia

Caso você pretenda atribuir conversões off-line a códigos de usuário criptografados, como no exemplo anterior, será necessário fornecer alguns detalhes sobre a criptografia na solicitação de inserção. Estes são os dados específicos:

  1. A fonte de criptografia, que descreve a origem de um lote de códigos criptografados. Os valores aceitáveis são AD_SERVING para códigos da macro de correspondência %m ou DATA_TRANSFER para aqueles vindos de arquivos da Transferência de dados.

  2. A entidade de criptografia, que é um conjunto exclusivo de valores usado para criptografar códigos de usuário. Esses valores normalmente estão relacionados a uma conta do Campaign Manager, quando a fonte é a Transferência de dados, ou a um anunciante do Campaign Manager, quando a fonte é a macro %m, mas esse nem sempre é o caso. Se não tiver certeza, entre em contato com o representante da sua conta ou com o suporte do Campaign Manager para saber mais.

Quando necessário, a segunda etapa do processo de upload de conversões é criar um objeto EncryptionInfo para especificar esses valores:

C#

// Create the encryption info.
EncryptionInfo encryptionInfo = new EncryptionInfo();
encryptionInfo.EncryptionEntityId = encryptionEntityId;
encryptionInfo.EncryptionEntityType = encryptionEntityType;
encryptionInfo.EncryptionSource = encryptionSource;

Java

// Create the encryption info.
EncryptionInfo encryptionInfo = new EncryptionInfo();
encryptionInfo.setEncryptionEntityId(encryptionEntityId);
encryptionInfo.setEncryptionEntityType(encryptionEntityType);
encryptionInfo.setEncryptionSource(encryptionSource);

PHP

$encryptionInfo = new Google_Service_Dfareporting_EncryptionInfo();
$encryptionInfo->setEncryptionEntityId($values['encryption_entity_id']);
$encryptionInfo->setEncryptionEntityType($values['encryption_entity_type']);
$encryptionInfo->setEncryptionSource($values['encryption_source']);

Python

# Construct the encryption info.
encryption_info = {
    'encryptionEntityId': encryption_entity_id,
    'encryptionEntityType': encryption_entity_type,
    'encryptionSource': encryption_source
}

Ruby

# Construct the encryption info.
encryption_info = DfareportingUtils::API_NAMESPACE::EncryptionInfo.new(
  encryption_entity_id: encryption[:entity_id],
  encryption_entity_type: encryption[:entity_type],
  encryption_source: encryption[:source]
)

Cada solicitação de inserção só pode conter um objeto EncryptionInfo. Isso significa que todas as conversões incluídas em uma determinada solicitação precisam vir da mesma origem e usar a mesma entidade de criptografia.

Gerar uma solicitação de inserção

A etapa final do processo é fazer upload das conversões com uma chamada para batchinsert. Esse método aceita um objeto ConversionsBatchInsertRequest, que une o conjunto de conversões que serão enviadas com as informações de criptografia associadas (quando necessário):

C#

// Insert the conversion.
ConversionsBatchInsertRequest request = new ConversionsBatchInsertRequest();
request.Conversions = new List<Conversion>() { conversion };
request.EncryptionInfo = encryptionInfo;

ConversionsBatchInsertResponse response =
    service.Conversions.Batchinsert(request, profileId).Execute();

Java

ConversionsBatchInsertRequest request = new ConversionsBatchInsertRequest();
request.setConversions(ImmutableList.of(conversion));
request.setEncryptionInfo(encryptionInfo);

ConversionsBatchInsertResponse response = reporting.conversions()
    .batchinsert(profileId, request).execute();

PHP

$batch = new Google_Service_Dfareporting_ConversionsBatchInsertRequest();
$batch->setConversions([$conversion]);
$batch->setEncryptionInfo($encryptionInfo);

$result = $this->service->conversions->batchinsert(
    $values['user_profile_id'],
    $batch
);

Python

# Insert the conversion.
request_body = {
    'conversions': [conversion],
    'encryptionInfo': encryption_info
}
request = service.conversions().batchinsert(profileId=profile_id,
                                            body=request_body)
response = request.execute()

Ruby

# Construct the batch insert request.
batch_insert_request =
  DfareportingUtils::API_NAMESPACE::ConversionsBatchInsertRequest.new(
    conversions: [conversion],
    encryption_info: encryption_info
  )

# Insert the conversion.
result = service.batchinsert_conversion(profile_id, batch_insert_request)

O Campaign Manager tenta inserir cada conversão na solicitação da melhor forma possível, em vez de inserir todo o lote como uma transação "tudo ou nada". Se ocorrer falha na inserção de algumas conversões em um lote, outras ainda poderão ser inseridas. Portanto, é recomendável inspecionar o ConversionsBatchInsertResponse retornado para determinar o status de cada conversão:

C#

// Handle the batchinsert response.
if (!response.HasFailures.Value) {
  Console.WriteLine("Successfully inserted conversion for encrypted user ID {0}.",
      conversionUserId);
} else {
  Console.WriteLine("Error(s) inserting conversion for encrypted user ID {0}:",
      conversionUserId);

  ConversionStatus status = response.Status[0];
  foreach(ConversionError error in status.Errors) {
    Console.WriteLine("\t[{0}]: {1}", error.Code, error.Message);
  }
}

Java

if (!response.getHasFailures()) {
  System.out.printf("Successfully inserted conversion for encrypted user ID %s.%n",
      encryptedUserId);
} else {
  System.out.printf("Error(s) inserting conversion for encrypted user ID %s:%n",
      encryptedUserId);

  // Retrieve the conversion status and report any errors found. If multiple conversions
  // were included in the original request, the response would contain a status for each.
  ConversionStatus status = response.getStatus().get(0);
  for (ConversionError error : status.getErrors()) {
    System.out.printf("\t[%s]: %s.%n", error.getCode(), error.getMessage());
  }
}

PHP

if (!$result->getHasFailures()) {
    printf(
        'Successfully inserted conversion for encrypted user ID %s.',
        $values['encrypted_user_id']
    );
} else {
    printf(
        'Error(s) inserting conversion for encrypted user ID %s:<br><br>',
        $values['encrypted_user_id']
    );

    $status = $result->getStatus()[0];
    foreach ($status->getErrors() as $error) {
        printf('[%s] %s<br>', $error->getCode(), $error->getMessage());
    }
}

Python

if not response['hasFailures']:
  print ('Successfully inserted conversion for encrypted user ID %s.'
         % encrypted_user_id)
else:
  print ('Error(s) inserting conversion for encrypted user ID %s.'
         % encrypted_user_id)

  status = response['status'][0]
  for error in status['errors']:
    print '\t[%s]: %s' % (error['code'], error['message'])

Ruby

if result.has_failures
  puts format('Error(s) inserting conversion for encrypted user ID %s.',
    encrypted_user_id)

  status = result.status[0]
  status.errors.each do |error|
    puts format("\t[%s]: %s", error.code, error.message)
  end
else
  puts format('Successfully inserted conversion for encrypted user ID %s.',
    encrypted_user_id)
end

O campo status da resposta, como visto acima, terá um objeto ConversionStatus para cada conversão incluída na solicitação original. Se você só tiver interesse nas conversões que não foram inseridas, use o campo hasFailures para determinar rapidamente se alguma conversão do lote fornecido teve falha.

Verificar se as conversões foram processadas

Geralmente, as conversões enviadas serão processadas e estarão disponíveis para relatórios em até 24 horas. Para verificar se as conversões enviadas foram processadas, é recomendável gerar um relatório Impressões do Floodlight. Ao contrário de outros relatórios de atribuição, por padrão, esse retornará as conversões atribuídas, associadas a um anúncio, e as não atribuídas. Por isso, esse tipo é ideal para verificar rapidamente se as conversões enviadas chegaram ao Campaign Manager.