전환 업로드

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

전환 리소스 구성

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

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

또한 각 객체는 다음 필드 중 하나를 포함해야 합니다.

필드 설명
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 또는 AdID 형식의 암호화되지 않은 모바일 ID 또는 지원되는 CTV 기기 플랫폼 (Roku, Fire TV, Android TV, Apple TV, Xbox, Samsung, Vizio)의 광고용 커넥티드 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);

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에 도착했는지 빠르게 확인하는 데 적합합니다.