전환 업로드

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

전환 리소스 구성

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

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

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

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

마지막으로 각 전환에는 다음 두 가지 측정항목이 있습니다.

필드 설명
quantity 필수 항목입니다. 전환과 관련된 항목 수입니다. 전환이 총 전환수와 같은 특정 측정항목에 포함되려면 1 이상이어야 합니다.
value 전환과 관련된 달러 금액입니다. 플러드라이트 구성 소유 광고주 통화로 해석됩니다.

선택적 필드는 참조 문서에 설명되어 있습니다.

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

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

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
)

암호화 정보 지정

이전 예와 같이 암호화된 사용자 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);

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

각 삽입 요청에는 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();

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)

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

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

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

전환이 처리되었는지 확인

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