对转换进行修改

本指南详细介绍了如何使用 Campaign Manager 360 API Conversions 服务修改转化数据。在继续操作之前,建议您先查看概览,了解线下转化,并熟悉本指南中讨论的概念。

准备工作

通过此修改工作流程,您可以修改现有线上和线下转化的 quantity 和 value。为此,您需要提供可唯一标识要修改的转化的值。根据您要修改的转化类型,您可以通过不同的方式获取这些值:

成功修改任一类型的转化后,ConversionsBatchUpdateResponse 将包含执行后续修改所需的值。

配置转化资源

修改工作流的第一步是创建一个或多个 Conversion 资源对象。

以下字段用于标识要修改的转化。这些字段是必填字段,且必须与现有转化完全一致。

字段 说明

encryptedUserId、gclid、dclid、matchid 或 mobileDeviceId

生成相应转化事件的经过加密的用户 ID、Google 点击 ID、展示广告点击 ID、匹配 ID 或移动设备 ID。
floodlightActivityId 转化归因到的 Floodlight 活动。
floodlightConfigurationId 指定活动使用的 Floodlight 配置。
ordinal 与转化关联的重复信息删除标识符。
timestampMicros 转化时间戳,采用 Unix 格式(即自 Unix 纪元以来的微秒数)。

可修改的字段如下所示。

这些字段为必填字段,您提供的值将覆盖所修改转化中任何预先存在的值。

字段 说明
quantity 与转化关联的商品数量。
value 转化带来的收入金额。

这些字段是可选字段。如果未设置,该值将保持不变。

字段 说明
customVariables 转化的自定义 Floodlight 变量。如果设置了变量,则会更新或插入值。如果未设置,则变量的值保持不变。

参考文档中提及的所有其他字段均不受支持,无法修改。在修改请求中包含不受支持的字段会导致错误。如果正在修改的转化包含任何不受支持字段的预先存在的值,这些值将自动保留。

以下示例展示了如何创建要修改的简单转化资源对象:

C#

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

// Construct the conversion object with values that identify the conversion to update.
Conversion conversion = new Conversion();
conversion.EncryptedUserId = conversionUserId;
conversion.FloodlightActivityId = floodlightActivityId;
conversion.FloodlightConfigurationId = floodlightConfigurationId;
conversion.Ordinal = conversionOrdinal;
conversion.TimestampMicros = conversionTimestamp;

// Set the fields to be updated. These fields are required; to preserve a value from the
// existing conversion, it must be copied over manually.
conversion.Quantity = newQuantity;
conversion.Value = newValue;

Java

// Create a conversion object populated with values that identify the conversion to update.
Conversion conversion = new Conversion();
conversion.setEncryptedUserId(encryptedUserId);
conversion.setFloodlightActivityId(floodlightActivityId);
conversion.setFloodlightConfigurationId(floodlightConfigurationId);
conversion.setOrdinal(ordinal);
conversion.setTimestampMicros(timestampMicros);

// Set the fields to be updated. These fields are required; to preserve a value from the
// existing conversion, it must be copied over manually.
conversion.setQuantity(newQuantity);
conversion.setValue(newValue);

PHP

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

// Create a conversion object with values that identify the conversion to
// update.
$conversion = new Google_Service_Dfareporting_Conversion();
$conversion->setEncryptedUserId($values['encrypted_user_id']);
$conversion->setFloodlightActivityId($values['floodlight_activity_id']);
$conversion->setFloodlightConfigurationId($floodlightConfigId);
$conversion->setOrdinal($values['ordinal']);
$conversion->setTimestampMicros($values['timestamp']);

// Set the fields to be updated. These fields are required; to preserve a
// value from the existing conversion, it must be copied over manually.
$conversion->setQuantity($values['new_quantity']);
$conversion->setValue($values['new_value']);

Python

# Construct the conversion object with values that identify the conversion
# to update.
conversion = {
    'encryptedUserId': encrypted_user_id,
    'floodlightActivityId': floodlight_activity_id,
    'floodlightConfigurationId': floodlight_config_id,
    'ordinal': ordinal,
    'timestampMicros': timestamp
}

# Set the fields to be updated. These fields are required; to preserve a
# value from the existing conversion, it must be copied over manually.
conversion['quantity'] = new_quantity
conversion['value'] = new_value

Ruby

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

# Construct the conversion with values that identify the conversion to
# update.
conversion = DfareportingUtils::API_NAMESPACE::Conversion.new(
  encrypted_user_id: existing_conversion[:encrypted_user_id],
  floodlight_activity_id: existing_conversion[:floodlight_activity_id],
  floodlight_configuration_id: floodlight_config_id,
  ordinal: existing_conversion[:ordinal],
  timestamp_micros: existing_conversion[:timestamp]
)

# Set the fields to be updated. These fields are required; to preserve a
# value from the existing conversion, it must be copied over manually.
conversion.quantity = new_quantity
conversion.value = new_value

指定加密信息

如果要修改的转化与加密的用户 ID 相关联,您需要在修改请求中提供有关这些 ID 的加密方式的详细信息。如需了解详情,请参阅上传转化数据指南。

必要时,创建指定这些值的 EncryptionInfo 对象是修改工作流中的第二步:

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]
)

生成更新请求

此流程的最后一步是通过调用 batchupdate 来修改转化。此方法接受一个 ConversionsBatchUpdateRequest 对象,该对象将要修改的转化集与其关联的加密信息(必要时)组合在一起:

C#

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

ConversionsBatchUpdateResponse response =
    service.Conversions.Batchupdate(request, profileId).Execute();

Java

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

ConversionsBatchUpdateResponse response = reporting.conversions()
    .batchupdate(profileId, request).execute();

PHP

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

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

Python

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

Ruby

# Construct the batch update request.
batch_update_request =
  DfareportingUtils::API_NAMESPACE::ConversionsBatchUpdateRequest.new(
    conversions: [conversion],
    encryption_info: encryption_info
  )

# Update the conversion.
result = service.batchupdate_conversion(profile_id, batch_update_request)

请注意,Campaign Manager 360 会尽力修改请求中的每项转化,而不是将整个批次作为全有或全无事务进行更新。如果一批转化中有部分转化未能更新,其他转化可能仍会成功更新。因此,建议您检查返回的 ConversionsBatchUpdateResponse,以确定每次转化的状态:

C#

// Handle the batchinsert response.
if (!response.HasFailures.Value) {
  Console.WriteLine("Successfully updated conversion for encrypted user ID {0}.",
      conversionUserId);
} else {
  Console.WriteLine("Error(s) updating 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 updated conversion for encrypted user ID %s.%n",
      encryptedUserId);
} else {
  System.out.printf("Error(s) updating 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 updated conversion for encrypted user ID %s.',
        $values['encrypted_user_id']
    );
} else {
    printf(
        'Error(s) updating 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 updated conversion for encrypted user ID %s.' %
        encrypted_user_id)
else:
  print('Error(s) updating 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) updating conversion for encrypted user ID %s.',
    existing_conversion[: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 updated conversion for encrypted user ID %s.',
    existing_conversion[:encrypted_user_id])
end

如前所述,响应的 status 字段将包含原始请求中每个转化的 ConversionStatus 对象。如果您只对未能更新的转化感兴趣,可以使用 hasFailures 字段快速确定所提供批次中的任何转化是否失败。如需了解如何处理每个错误代码以及要重试哪些失败的转化(INTERNAL 和 NOT_FOUND),请参阅常见问题解答。