TURTLEDOVE RTB 시뮬레이션 API

개인 정보 보호 샌드박스의 일환으로 Chrome은 광고주와 광고 기술 회사가 서드 파티 쿠키를 사용하지 않고도 관심분야 그룹 타겟팅 광고를 표시할 수 있도록 하는 브라우저 내 API인 TURTLEDOVE를 제안하여 사용자를 크로스 사이트 추적으로부터 보호했습니다. Chrome에서 TURTLEDOVE를 구현하기 전에 Google RTB팀은 RTB 파트너(Authorized Buyers 및 공개 입찰 파트너)가 API를 실험할 수 있는 서버 측 TURTLEDOVE API 시뮬레이션을 제공합니다. 이 시뮬레이션을 통해 파트너와 Google은 TURTLEDOVE 스타일 흐름의 효과에 대해 알아보고, 공개 포럼에서 잠재적인 API 개선사항에 관한 관련 의견을 제공하며, 서드 파티 쿠키를 사용하지 않고도 개인 맞춤 광고 지원으로 쉽게 전환할 수 있습니다.

시뮬레이션의 첫 번째 단계에서 입찰자는 관심분야 그룹 멤버십을 호스팅합니다. 입찰자는 API를 통해 미리 입찰 기능을 Google에 제공합니다. 제공 시간에 Google은 시뮬레이션 범위에 포함된 각 입찰 요청을 두 가지 요청, 즉 문맥 요청과 관심 기반 요청으로 분할합니다. 문맥 요청은 현재 입찰 요청과 유사하지만 사용 가능한 사용자 식별자가 없습니다(예: google_user_id,hosted_match_data 필드). 관심분야 그룹 요청에는 문맥 정보가 포함되지 않으며 사용자 식별 필드만 포함됩니다 (기존의 개인 정보 보호 설정이 적용됨). 관심분야 그룹 입찰에는 CPM 값이 포함되지 않으며, 샌드박스 환경에서 서버 측에서 실행하는 입찰 기능을 참조하는 것이 좋습니다. 입찰은 일반적으로 문맥 입찰가와 입찰 함수에서 계산된 입찰가로 실행됩니다.

시뮬레이션의 첫 번째 단계에서 Google은 관심 기반 요청에 대해 가명처리된 사용자 ID를 보냅니다. 실험을 양쪽에서 모두 구현할 수 있도록 구현 작업을 최소화하는 것이 목적입니다. 관심 기반 요청에 사용자 식별자가 있으면 기존의 개인 정보 보호 기능 및 제어 기능 (예: 사용자가 개인 맞춤 광고를 선택 해제한 경우)이 적용됩니다.

흐름

플로우 차트

  1. RTB 입찰자는 광고주와 협력하여 각 광고주의 관심분야 그룹을 만들고 유지 관리하며 해당 그룹의 사용자 멤버십을 호스팅합니다.
  2. 사용자가 게시자 웹페이지를 방문하면 사용자의 브라우저에서 Google의 광고 태그를 다운로드합니다. 사용자의 브라우저가 Google 게시자 플랫폼에서 광고를 요청합니다.
  3. RTB 입찰자는 하나 이상의 입찰 기능 (자바스크립트 함수)을 Google에 미리 제공합니다. 입찰 함수 섹션을 참고하세요.
  4. 실험 범위에 속하는 일부 요청의 경우 Google은 실험에 참여하는 각 입찰자에게 별도의 문맥 입찰 요청관심 기반 입찰 요청을 전송합니다 (입찰 요청 섹션 참고).
  5. 입찰자는 관심분야 그룹 입찰 요청에 제공된 가명처리된 사용자 ID를 사용하여 해당 관심분야 그룹에 매핑합니다. RTB 입찰자는 문맥 입찰 응답관심 기반 입찰 응답을 반환합니다 (섹션: 입찰 응답 참고).
    1. 문맥 입찰 응답은 문맥 입찰가가 0개 이상인 현재의 입찰 응답과 유사합니다. 그 밖에도 문맥 입찰 응답은 입찰 함수에 입력으로 제공되는 입찰자 맞춤 문맥 신호를 전달합니다.
    2. 관심 기반 입찰 응답은 입찰가를 지정하지 않고 입찰 함수의 이름을 지정합니다. Google은 입찰 기능을 실행하여 입찰을 가져옵니다.
  6. Google에서는 다음 후보와 함께 서버 측 입찰을 실행합니다.

    1. 문맥 응답의 입찰가입니다.
    2. 입찰 기능을 실행하여 계산된 입찰가로 관심분야 그룹 응답의 입찰가입니다.
    3. 다른 입찰자의 일반 입찰가

    이는 현재와 동일한 입찰 방식입니다.

  7. Google은 낙찰된 광고를 사용자의 브라우저에 반환하고, 정상적으로 렌더링됩니다.

입찰 함수

입찰 함수는 특정 관심 그룹 기반 광고 및 광고 슬롯의 입찰가를 반환하는 입찰자가 제공하는 함수입니다 . 원래의 TURTLEDOVE 제안서에서 이 함수는 사용자의 브라우저에 저장됩니다. 이 시뮬레이션에서 입찰자는 광고 게재 전에 API를 사용하여 입찰 함수를 Google에 업로드합니다. 광고 게재 중에 관심분야 그룹 응답에서 입찰 함수 이름을 지정합니다. Google은 샌드박스 환경에서 입찰 기능을 실행하여 입찰가를 가져옵니다. 이 관심기반 입찰가 값은 문맥 입찰가와 동일한 입찰에 참여하게 됩니다.

입찰 함수 인터페이스

입찰 함수는 거래소에서 제공하는 샌드박스에서 실행되는 순수한 부수 효과 없는 자바스크립트 함수여야 합니다. 입찰 함수는 네트워크, 저장소 또는 기타 형태의 I/O에 액세스할 수 없으며 다양한 입찰 요청에 대한 호출 간의 상태를 유지할 수 없습니다. 입찰 함수는 문맥 데이터와 관심분야 그룹 데이터의 조합을 기반으로 알고리즘을 통해 특정 광고 조합에 대한 입찰가 CPM을 계산하고 반환합니다.

입찰 함수는 빈 객체를 수락하고 입력 매개변수로 실행해야 합니다. 일회성 초기화 중에 입찰 함수에 빈 입력이 제공됩니다. 초기화 시 입찰 기능의 스냅샷을 만들고 몇 번 호출하여 JIT (적시) 컴파일러가 코드의 핫스팟을 최적화하도록 합니다.

/**
 * Returns a bid price CPM for a given ad candidate.
 *
 * @param {Object} inputs an object with the
 *                 following named fields:
 *                   - openrtbContextualBidRequest or googleContextualBidRequest
 *                   - customContextualSignal
 *                   - interestBasedBidData
 */
function biddingFunction(inputs) {
  ...
  return inputs.interestBasedBidData.cpm
      * inputs.customContextualSignals.placementMultiplier;
}

inputs 객체 인수의 이름이 지정된 필드에는 실험이 포함됩니다 (실험이 진행됨에 따라 변경될 수 있음).

openrtbContextualBidRequest (JS 객체) OpenRTB 프로토콜의 문맥 입찰 요청 Authorized Buyers RTB 프로토콜을 사용하는 입찰자는 이 입력을 무시해야 하며, 입찰 함수에서 이 정보를 사용해서는 안 됩니다.
googleContextualBidRequest (JS 객체) Google Authorized Buyers 프로토콜의 문맥 입찰 요청 OpenRTB 프로토콜을 사용하는 입찰자는 이 입력을 무시해야 하며, 입찰 함수에서 이를 사용해서는 안 됩니다.
customContextualSignal (JS 객체) 문맥 입찰 응답에서 입찰자가 제공한 맞춤 데이터 입찰자가 형식을 결정합니다.
interestBasedBidData (JS 객체) 입찰자가 관심분야 그룹 입찰 응답에서 제공한 맞춤 데이터입니다. 입찰자가 형식을 결정합니다.

API를 통한 입찰 함수 관리

이 실험용 API 리소스를 사용하면 입찰자가 Google에 입찰 함수를 업로드하고 이러한 함수를 관리할 수 있습니다.

기본 서비스 엔드포인트: https://realtimebidding.googleapis.com

리소스: 입찰 함수

{
  "name": string,
  "biddingFunction": string
}

name 필드는 입찰 함수의 이름을 나타내며 bidders/{bidderAccountId}/biddingFunctions/{biddingFunctionName} 형식을 따라야 합니다. 여기서 biddingFunctionName는 입찰자에 의해 선택됩니다.

biddingFunction 필드는 다음 요구사항을 충족하는 입찰 함수의 자바스크립트 소스 코드입니다.

  • 크기는 5MiB 미만입니다.
  • 입찰 함수 인터페이스의 요구사항을 준수합니다.
  • 샌드박스에서 최초 생성하는 동안 입력 없이 실행을 지원해야 합니다(MUST).

예:

{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;})"
}

입찰 함수 만들기

CreateBiddingFunction API가 호출된 후 약 1시간 이내에 관심분야 그룹 응답에서 입찰 기능을 사용할 수 있습니다.

POST https://realtimebidding.googleapis.com/v1alpha/{parent=bidders/*}/biddingFunctions
경로 매개변수
parent bidders/{bidderAccountId} 형식의 문자열
본문: 만들 입찰 함수
{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;})"
}
응답 (입찰 기능)
{
  "name": "bidders/1234567678/biddingFunctions/my_bidding_function_name",
  "biddingFunction": "(function(inputs) {return 1.23;};)"
}

기존 입찰 함수 나열

GET https://realtimebidding.googleapis.com/v1alpha/bidders/{bidderAccountId}/biddingFunctions
경로 매개변수
parent bidders/{bidderAccountId} 형식의 문자열입니다.
쿼리 매개변수
pageToken 서버에서 반환해야 하는 결과 페이지를 식별하는 문자열 토큰입니다. 결과가 한 페이지에 맞지 않는 경우 이 값은 이전 ListBiddingFunctions 호출 응답에서 수신됩니다.
응답
{
  "biddingFunctions": [
    {
      object (BiddingFunction)
    }
  ],
  "nextPageToken": string
}
호출 예
GET https://realtimebidding.googleapis.com/v1alpha/bidders/123456789/biddingFunctions

TURTLEDOVE 시뮬레이션 RTB 프로토콜 변경사항

Authorized Buyers RTB 프로토콜

입찰 요청

실험에서 문맥 입찰 요청은 기존 입찰 요청과 모양이 비슷하지만 가명처리된 사용자 식별자가 수정됩니다.

// All fields will be filled unless otherwise specified.
message BidRequest {
  // Fields below would not be populated in the experiment
  optional string google_user_id = ...;
  optional uint32 cookie_version = ...;
  optional int32 cookie_age_seconds = ...;
  optional bytes hosted_match_data = ...;
  optional string session_id = ...;

  // Contextual fields below will be populated
  optional string publisher_id = ...;
  optional string url = ...;
  ...
  message Mobile {
    // Device advertising identifiers below would not be populated
    // in the contextual requests in the experiment
    optional bytes encrypted_advertising_id = ...;
    optional bytes advertising_id = ...;
    ...
    optional bytes encrypted_hashed_idfa = ...;
    optional bytes hashed_idfa = ...;
    ...
  }
  ...
  message AdSlot {
    message MatchingAdData {
      repeated int64 billing_id = ...;
      ...
    }
    ...
  }
  repeated AdSlot adslot = ...;
  ...
}

예를 들면 다음과 같습니다.

{
  id: "_\321\326\000\n\301\207\n\323\n\227",
  ip: "S\030\347",
  user_agent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
  publisher_country: "RU",
  geo_criteria_id: 9061060,
   adslot: [{
    id: 1,
    ad_block_key: 3613182520,
    width:   [240,200,120],
    height:   [400,200,240],
    matching_ad_data:   [{
      billing_id:     [923487589],
      minimum_cpm_micros: 850000
    }]
  }]
}

실험의 관심 기반 요청에는 기존의 모든 개인 정보 보호 기능 및 관리 설정이 적용되는 기존 가명처리된 사용자 식별자가 포함되지만 문맥 정보 (페이지 URL, 게시자 ID 등)는 포함되지 않습니다.

// Most fields would not be populated in the experiment unless otherwise specified.
message BidRequest {
   // Will be provided, subject to the existing privacy controls.
  optional string google_user_id = ...;
  optional uint32 cookie_version = ...;
  optional int32 cookie_age_seconds = ...;
  optional bytes hosted_match_data = ...;

  message AdSlot {
    // Will be filled.
    repeated int32 width = ...;
    repeated int32 height = ...;
    optional ConsentedProvidersSettings consented_providers_settings = ...;
    optional bool regs_gdpr = ...;
    optional bool regs_lgpd = ...;

    message MatchingAdData {
      // Will be filled.
      repeated int64 billing_id = ...;
      ...
    }
    ...
  }
  repeated AdSlot adslot = ...;
  ...
}

예를 들면 다음과 같습니다.

id: "_\322\207\000\003\320\n\031\177C\307\215\035"
adslot {
  id: 1
  width: 1200
  height: 60
  consented_providers_settings {
    consented_providers: 292
    tcf_consent_string: "CO-eDrRO-eDrREkAAAAAAAAeYwf95y3p-wzhheMCY70-vv__7v3ff_3g"
  }
  regs_gdpr: true
  matching_ad_data {
    billing_id: 9833784997
  }
}
google_user_id: "ABCDEF1"
hosted_match_data: "ABCABCABC2"

입찰 응답

문맥 입찰 응답에는 나중에 입찰 함수에 전달되는 임의의 형식의 맞춤 입찰자별 문맥 데이터가 포함될 수 있습니다.

message BidResponse {
  message Ad {
    message AdSlot {
      required int64 max_cpm_micros = ...;
      ...
    }
    repeated AdSlot adslot = ...;
    ...
  }
  repeated Ad ad = ...;
  // Contains contextual signals that will be passed to the bidding function.
  // This can be any JSON value. For example:
  // {"foo": "bar", "base": [1, 2, 3]}
  optional google.protobuf.Value custom_contextual_signal = ...;

  ...
}

예를 들면 다음과 같습니다.

ad {
  html_snippet: "<iframe src=\"http://example.com/something" width=\"300\" height=\"250\" scrolling=\"no\" frameBorder=\"0\" ></iframe>"
  adslot {
    id: 1
    max_cpm_micros: 100000
    billing_id: 1234567890
  }
  click_through_url: "https://www.example.com.pl"
  attribute: 47
  buyer_creative_id: "FFI399F3HI9HFH"
  width: 300
  height: 250
  impression_tracking_url: "http://example.com/impression"
}
custom_contextual_signal {
 struct_value {
   fields {
     name: "string_data_name"
     value {
       string_value: "string_value_1"
     }
   }
   fields {
     name: "bool_data_name"
     value {
       bool_value: true
     }
   }
 }
}
processing_time_ms: 1

관심분야 그룹 기반 입찰가

관심분야 그룹 입찰 응답의 각 입찰가에는 입찰 함수에 대한 참조가 포함되어 있습니다. 입찰 함수는 입찰자가 미리 제공합니다.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
message BidResponse {
  // Ad HTML code that will be rendered normally upon winning.
  optional string html_snippet = ...;

  message Ad {
    message AdSlot {
      // Should not be populated for interest group-based bids.
      required int64 max_cpm_micros = ...;
      ...
    }
    repeated AdSlot adslot = ...;

    // Will be filled.
    // This is the bidding function name that references a bidding function
    // that is provided ahead of time through Bidding functions API resource.
    optional string bidding_function_name = ...;

    // Contains interest group-related data that will be passed
    // to the bidding function. This can be any JSON value.
    optional google.protobuf.Value interest_group_data = ...;
    ...
  }
  repeated Ad ad = ...;
  ...
}

예를 들면 다음과 같습니다.

ad {
  html_snippet: "<iframe src=\"http://example.com/something" width=\"300\" height=\"250\" scrolling=\"no\" frameBorder=\"0\" ></iframe>"
  adslot {
    id: 1
    max_cpm_micros: 0
    billing_id: 1234567890
    bidding_function_name: "bidders/123/biddingFunctions/my_bidding_function_1"
    interest_group_data {
      struct_value {
        fields {
          name: "string_data_name"
          value {
            string_value: "string_value_1"
          }
        }
        fields {
          name: "bool_data_name"
          value {
            bool_value: true
          }
        }
      }
    }
  }
  click_through_url: "https://www.example.com.pl"
  attribute: 47
  buyer_creative_id: "FFI399F3HI9HFH"
  width: 300
  height: 250
  impression_tracking_url: "http://example.com/impression"
}
processing_time_ms: 1

OpenRTB

입찰 요청

컨텍스트 요청 (JSON)
// All fields will be filled unless otherwise specified.
{
  // Fields below would not be populated in the experiment
  "user": {...}

  "device": {
    // Fields below would not be populated in the experiment
    "ifa": ...
    "dpidsha1": ...
    "dpidmd5": ...


    // Other fields will not be affected by the experiment
    ...
  }

  // Other fields will not be affected by the experiment
  ...
}
관심 기반 요청 (JSON 형식)
// Most fields would not be populated in the experiment unless otherwise specified.
{
  // Will be provided, subject to the existing privacy controls.
  "user": {
    "id": "BFEUKH3"
    "buyeruid": "FEI3F3I29"
    "ext": {
      "consented_providers": [ 292 ]
      "tcf_consent_string": "CO-eDrRO-eDrREkAAilsbO2dYGD9Pn8HT3ZCY70-vv__7v3ff_3g"
    }
  }

  "imp": {
    // Will be provided, subject to the existing privacy controls.
    "banner": {
      "w": ...
      "h": ...
    }

    "ext": {
      // Will be provided, subject to the existing privacy controls.
      "billing_id": [...]

      // Other fields will not be provided by the experiment
      ...
    }
  }
}

입찰 응답

문맥 입찰 응답에는 나중에 입찰 기능에 전달될 맞춤 입찰자별 문맥 데이터가 포함될 수 있습니다.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
{
  ...
  "seatbid": [{
     "bid": [...],
     ...
  }],
  ...
  "ext": {
    // Contains contextual signals that will be passed to the bidding function.
    // This signal can be any JSON blob. For example:
    // {"foo", "bar", "base": [1, 2, 3]}
    "custom_contextual_signal": ...
  }
}

관심분야 그룹 기반 입찰 응답

관심분야 그룹 입찰 응답의 각 입찰가에는 입찰 함수에 대한 참조가 포함되어 있습니다. 입찰 함수는 입찰자가 미리 제공합니다.

// All fields should be filled by a bidder as discussed in
// https://developers.google.com/authorized-buyers/rtb/response-guide
// unless otherwise specified.
{
  "bid": [{
       "id": ...
       ...
       "ext": {
         // This is the bidding function name that references a bidding function
         // that is provided ahead of time through Bidding functions API resource.
         "bidding_function_name": ...

         // Contains interest group related data that will be passed to the
         // bidding function.
         // This signal can be any JSON blob. For example:
         // {"foo", "bar", "base": [1, 2, 3]}
         "interest_group_data": ...
       }
    }
    ...
  ]
}