전환 업로드

이 가이드에서는 Campaign Manager 360 API Conversions 서비스를 사용하여 오프라인 전환을 업로드하는 방법을 자세히 안내합니다. 계속하기 전에 오프라인 전환을 소개하는 개요를 참고하고 이 가이드에서 설명하는 개념을 숙지하는 것이 좋습니다.

전환 리소스 구성

전환 업로드 프로세스의 첫 번째 단계는 Conversion 리소스 객체를 하나 이상 만드는 것입니다. 이러한 각 객체는 단일 전환 이벤트를 나타내며 몇 가지 필수 필드를 포함합니다.

필드 설명
floodlightActivityId 이 전환과 연결될 플러드라이트 활동입니다.
floodlightConfigurationId 지정된 활동에서 사용하는 플러드라이트 구성입니다.
ordinal 같은 날 동일한 기기나 사용자로부터 발생한 전환의 중복을 제거하는 방식을 제어하는 데 사용되는 값입니다. 자세한 내용은 FAQ를 참고하세요.
timestampMicros Unix 에포크 이후 마이크로초 단위의 전환 타임스탬프입니다.

또한 각 객체에는 다음 필드 중 하나가 포함되어야 합니다.

필드 설명
encryptedUserId %m 일치 매크로 또는 데이터 전송에서 가져온 단일 암호화된 사용자 ID입니다.
encryptedUserIdCandidates[] %m 일치 매크로 또는 데이터 전송에서 가져온 암호화된 사용자 ID 목록입니다. 지정된 timestampMicros 이전에 플러드라이트 노출이 기록된 첫 번째 ID가 사용됩니다. 기존 종합 노출과 일치하는 ID가 없는 경우 오류가 발생합니다.
dclid Campaign Manager 360 또는 Display & Video 360에서 생성한 디스플레이 클릭 식별자
gclid Google Ads 또는 Search Ads 360에서 생성된 Google 클릭 식별자
matchId 플러드라이트 태그를 통해 Campaign Manager 360으로 전달된 고유한 광고주 생성 식별자입니다.
mobileDeviceId 지원되는 CTV 기기 플랫폼 (Roku, Fire TV, Android TV, Apple TV, Xbox, Samsung, Vizio)의 IDFA 또는 AdID 형식의 암호화되지 않은 모바일 ID 또는 광고용 커넥티드 TV 식별자 (IFA)입니다. Google은 YouTube 커넥티드 TV IFA를 지원하지 않습니다.

선택사항 필드는 참조 문서에 나와 있습니다. 선택사항이지만 보고서를 실행할 때 전환수가 특정 측정항목 (예: 총 전환수)에 반영되려면 수량 필드가 1 이상이어야 합니다.

아래 예는 간단한 전환 리소스 객체를 만드는 방법을 보여줍니다.

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;

자바

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

2,399필리핀

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

암호화 정보 지정

이전 예에서와 같이 암호화된 사용자 ID가 오프라인 전환에 기인한다는 점은 삽입 요청의 일부로 암호화된 방식에 대한 세부정보를 제공해야 합니다. 특히 다음 사항을 알아야 합니다.

  1. 암호화된 ID 배치가 어디에서 발생했는지 설명하는 암호화 소스 %m 일치 매크로에서 가져온 ID에는 AD_SERVING, 데이터 전송 파일에서 가져온 ID에는 DATA_TRANSFER 값이 허용됩니다.

  2. 암호화 항목: 사용자 ID를 암호화하는 데 사용되는 고유한 값 집합입니다. 이러한 값은 일반적으로 소스가 데이터 전송인 경우 Campaign Manager 360 계정과 연결되며, 소스가 %m 매크로인 경우에는 Campaign Manager 360 광고주와 연결됩니다. 단, 항상 그런 것은 아닙니다. 확실히 알지 못하는 경우 Campaign Manager 360 계정 담당자 또는 Campaign Manager 360 지원팀에 문의하세요.

필요한 경우 이러한 값을 지정하는 EncryptionInfo 객체를 만드는 것이 전환 업로드 프로세스의 두 번째 단계입니다.

C#

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

자바

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

2,399필리핀

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

각 삽입 요청에는 EncryptionInfo 객체가 하나만 포함될 수 있습니다. 즉, 지정된 요청에 포함된 모든 전환은 동일한 소스에서 시작되어야 하며 동일한 암호화 항목을 사용해야 합니다.

삽입 요청 생성

이 과정의 마지막 단계는 batchinsert를 호출하여 전환을 업로드하는 것입니다. 이 메서드는 업로드할 암호화 세트를 연결된 암호화 정보와 결합하는 ConversionsBatchInsertRequest 객체를 허용합니다 (필요한 경우).

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

자바

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

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

2,399필리핀

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

Campaign Manager 360은 전체 배치를 '전부 아니면 전무' 방식의 트랜잭션으로 삽입하는 것이 아니라 최선을 다해 요청에 각 전환을 삽입하려고 시도합니다. 일괄 변환의 일부 전환이 삽입되지 않더라도 다른 전환은 성공적으로 삽입될 수 있습니다. 따라서 반환된 ConversionsBatchInsertResponse를 검사하여 각 전환의 상태를 확인하는 것이 좋습니다.

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

자바

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

2,399필리핀

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

위와 같이 응답의 status 필드에는 원래 요청에 포함된 모든 전환에 대한 ConversionStatus 객체가 포함됩니다. 삽입에 실패한 변환에만 관심이 있는 경우 hasFailures 필드를 사용하여 제공된 배치의 모든 변환이 실패했는지 빠르게 확인할 수 있습니다.

전환이 처리되었는지 확인

업로드된 전환은 일반적으로 24시간 이내에 처리되어 보고할 수 있습니다. 업로드한 전환이 처리되었는지 확인하려면 플러드라이트 노출 보고서를 실행하는 것이 좋습니다. 다른 기여도 보고서와 달리, 기여 분석 (광고에 연결됨) 및 비기여 전환 모두 기본적으로 반환됩니다. 따라서 전송한 전환이 Campaign Manager 360에 도달했는지 신속하게 확인하는 데 적합합니다.