openrtb3: less overengineering; split types into multiple files
This commit is contained in:
Родитель
9e40292b67
Коммит
8f645da46b
|
@ -1,3 +1,3 @@
|
|||
# openrtb3
|
||||
|
||||
[OpenRTB](https://github.com/InteractiveAdvertisingBureau/openrtb) [v3.0 BETA](https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%203.0%20BETA.md) types for Go programming language (Golang)
|
||||
[OpenRTB](https://github.com/InteractiveAdvertisingBureau/openrtb) [v3.0](https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%20v3.0%20FINAL.md) types for Go programming language (Golang)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package openrtb
|
||||
|
||||
// AuctionType defines an auction type.
|
||||
type AuctionType int64
|
||||
|
||||
// AuctionType values.
|
||||
const (
|
||||
FirstPrice AuctionType = 1
|
||||
SecondPricePlus = 2
|
||||
DealPrice = 3 // the value passed in flr is the agreed upon deal price
|
||||
|
||||
// Values greater than 500 can be used for exchange-specific auction types.
|
||||
)
|
|
@ -0,0 +1,128 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Bid is an OpenRTB bid object.
|
||||
// A Seatbid object contains one or more Bid objects, each of which relates to a specific item in the bid request offer via the “item” attribute and constitutes an offer to buy that item for a given price.
|
||||
type Bid struct {
|
||||
// Attribute:
|
||||
// id
|
||||
// Type:
|
||||
// string; recommended
|
||||
// Definition:
|
||||
// Bidder generated bid ID to assist with logging/tracking.
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// item
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// ID of the item object in the related bid request; specifically item.id.
|
||||
Item string `json:"item,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// price
|
||||
// Type:
|
||||
// float; required
|
||||
// Definition:
|
||||
// Bid price expressed as CPM although the actual transaction is for a unit item only
|
||||
// Note that while the type indicates float, integer math is highly recommended when handling currencies (e.g., BigDecimal in Java).
|
||||
Price float64 `json:"price,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// deal
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Reference to a deal from the bid request if this bid pertains to a private marketplace deal; specifically deal.id.
|
||||
Deal string `json:"deal,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// cid
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Campaign ID or other similar grouping of brand-related ads
|
||||
// Typically used to increase the efficiency of audit processes.
|
||||
CID string `json:"cid,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// tactic
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Tactic ID to enable buyers to label bids for reporting to the exchange the tactic through which their bid was submitted
|
||||
// The specific usage and meaning of the tactic ID should be communicated between buyer and exchanges a priori.
|
||||
Tactic string `json:"tactic,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// purl
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Pending notice URL called by the exchange when a bid has been declared the winner within the scope of an OpenRTB compliant supply chain (i.e., there may still be non-compliant decisioning such as header bidding)
|
||||
// Substitution macros may be included.
|
||||
PURL string `json:"purl,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// burl
|
||||
// Type:
|
||||
// string; recommended
|
||||
// Definition:
|
||||
// Billing notice URL called by the exchange when a winning bid becomes billable based on exchange-specific business policy (e.g., markup rendered)
|
||||
// Substitution macros may be included.
|
||||
BURL string `json:"burl,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// lurl
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Loss notice URL called by the exchange when a bid is known to have been lost
|
||||
// Substitution macros may be included
|
||||
// Exchange-specific policy may preclude support for loss notices or the disclosure of winning clearing prices resulting in ${OPENRTB_PRICE} macros being removed (i.e., replaced with a zero-length string).
|
||||
LURL string `json:"lurl,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// exp
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Advisory as to the number of seconds the buyer is willing to wait between auction and fulfilment.
|
||||
Exp int64 `json:"exp,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// mid
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// ID to enable media to be specified by reference if previously uploaded to the exchange rather than including it by value in the domain objects.
|
||||
MID string `json:"mid,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// macro
|
||||
// Type:
|
||||
// object array
|
||||
// Definition:
|
||||
// Array of Macro objects that enable bid specific values to be substituted into markup; especially useful for previously uploaded media referenced via the mid attribute
|
||||
// Refer to Object: Macro.
|
||||
Macro []Macro `json:"macro,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// media
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Layer-4 domain object structure that specifies the media to be presented if the bid is won conforming to the specification and version referenced in openrtb.domainspec and openrtb.domainver
|
||||
// For AdCOM v1.x, the objects allowed here are “Ad” and any objects subordinate thereto as specified by AdCOM.
|
||||
Media json.RawMessage `json:"media,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional demand source specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package openrtb
|
||||
|
||||
// Body is a top-level wrapper for OpenRTB requests.
|
||||
type Body struct {
|
||||
OpenRTB OpenRTB `json:"openrtb"`
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package openrtb3
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
// Bool is a bool type wrapper.
|
||||
type Bool bool
|
||||
|
||||
// Val is a nil-safe value getter.
|
||||
func (b *Bool) Val(defaultValue bool) bool {
|
||||
if b == nil {
|
||||
return defaultValue
|
||||
}
|
||||
return (bool)(*b)
|
||||
}
|
||||
|
||||
// Ptr is a value-copying pointer shortcut.
|
||||
//
|
||||
// Intended usage:
|
||||
//
|
||||
// req := Request {
|
||||
// WSeat: Bool(true).Ptr(),
|
||||
// }
|
||||
//
|
||||
func (b Bool) Ptr() *Bool {
|
||||
return &b
|
||||
}
|
||||
|
||||
// MarshalJSON marshals Bool as JSON.
|
||||
func (b Bool) MarshalJSON() (bb []byte, err error) {
|
||||
if b {
|
||||
bb = []byte("1")
|
||||
} else {
|
||||
bb = []byte("0")
|
||||
}
|
||||
return bb, err
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals Bool from JSON.
|
||||
func (b *Bool) UnmarshalJSON(bb []byte) error {
|
||||
if bytes.Equal(bb, []byte("1")) {
|
||||
*b = true
|
||||
} else {
|
||||
*b = false
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Deal object constitutes a specific deal that was struck a priori between a seller and a buyer.
|
||||
// Its presence indicates that this item is available under the terms of that deal.
|
||||
type Deal struct {
|
||||
// Attribute:
|
||||
// id
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// A unique identifier for the deal.
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// flr
|
||||
// Type:
|
||||
// float
|
||||
// Definition:
|
||||
// Minimum deal price for this item expressed in CPM.
|
||||
Flr float64 `json:"flr,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// flrcur
|
||||
// Type:
|
||||
// string; default "USD"
|
||||
// Definition:
|
||||
// Currency of the flr attribute specified using ISO-4217 alpha codes.
|
||||
FlrCur string `json:"flrcur,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// at
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Optional override of the overall auction type of the request, where 1 = First Price, 2 = Second Price Plus, 3 = the value passed in flr is the agreed upon deal price.
|
||||
// Additional auction types can be defined by the exchange using 500+ values.
|
||||
AT AuctionType `json:"at,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// wseat
|
||||
// Type:
|
||||
// string array
|
||||
// Definition:
|
||||
// Whitelist of buyer seats allowed to bid on this deal.
|
||||
// IDs of seats and the buyer’s customers to which they refer must be coordinated between bidders and the exchange a priori.
|
||||
// Omission implies no restrictions.
|
||||
WSeat []string `json:"wseat,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// wadomain
|
||||
// Type:
|
||||
// string array
|
||||
// Definition:
|
||||
// Array of advertiser domains (e.g., advertiser.com) allowed to bid on this deal.
|
||||
// Omission implies no restrictions.
|
||||
WADomain []string `json:"wadomain,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional exchange-specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Item object represents a unit of goods being offered for sale either on the open market or in relation to a private marketplace deal.
|
||||
// The id attribute is required since there may be multiple items being offered in the same bid request and bids must reference the specific item of interest.
|
||||
// This object interfaces to Layer-4 domain objects for deeper specification of the item being offered (e.g., an impression).
|
||||
type Item struct {
|
||||
// Attribute:
|
||||
// id
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// A unique identifier for this item within the context of the offer (typically starts with “1” and increments).
|
||||
ID string `json:"id"`
|
||||
|
||||
// Attribute:
|
||||
// qty
|
||||
// Type:
|
||||
// integer; default 1
|
||||
// Definition:
|
||||
// The number of instances (i.e., “quantity”) of this item being offered (e.g., multiple identical impressions in a digital out-of-home scenario).
|
||||
Qty int `json:"qty,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// seq
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// If multiple items are offered in the same bid request, the sequence number allows for the coordinated delivery.
|
||||
Seq int `json:"seq,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// flr
|
||||
// Type:
|
||||
// float
|
||||
// Definition:
|
||||
// Minimum bid price for this item expressed in CPM.
|
||||
Flr float64 `json:"flr,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// flrcur
|
||||
// Type:
|
||||
// string; default “USD”
|
||||
// Definition:
|
||||
// Currency of the flr attribute specified using ISO-4217 alpha codes.
|
||||
FlrCur string `json:"flrcur,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// exp
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Advisory as to the number of seconds that may elapse between auction and fulfilment.
|
||||
Exp int64 `json:"exp,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// dt
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Timestamp when the item is expected to be fulfilled (e.g
|
||||
// when a DOOH impression will be displayed) in Unix format (i.e., milliseconds since the epoch).
|
||||
DT int64 `json:"dt,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// dlvy
|
||||
// Type:
|
||||
// integer; default 0
|
||||
// Definition:
|
||||
// Item (e.g., an Ad object) delivery method required, where 0 = either method, 1 = the item must be sent as part of the transaction (e.g., by value in the bid itself, fetched by URL included in the bid), and 2 = an item previously uploaded to the exchange must be referenced by its ID.
|
||||
// Note that if an exchange does not supported prior upload, then the default of 0 is effectively the same as 1 since there can be no items to reference.
|
||||
Dlvy int8 `json:"dlvy,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// metric
|
||||
// Type:
|
||||
// object array
|
||||
// Definition:
|
||||
// An array of Metric objects.
|
||||
// Refer to Object: Metric.
|
||||
Metric []Metric `json:"metric,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// deal
|
||||
// Type:
|
||||
// object array
|
||||
// Definition:
|
||||
// Array of Deal objects that convey special terms applicable to this item.
|
||||
// Refer to Object: Deal.
|
||||
Deal []Deal `json:"deal,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// private
|
||||
// Type:
|
||||
// integer; default 0
|
||||
// Definition:
|
||||
// Indicator of auction eligibility to seats named in Deal objects, where 0 = all bids are accepted, 1 = bids are restricted to the deals specified and the terms thereof.
|
||||
Private int8 `json:"private,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// spec
|
||||
// Type:
|
||||
// object; required
|
||||
// Definition:
|
||||
// Layer-4 domain object structure that provides specifies the item being offered conforming to the specification and version referenced in openrtb.domainspec and openrtb.domainver.
|
||||
// For AdCOM v1.x, the objects allowed here are Placement and any objects subordinate to these as specified by AdCOM.
|
||||
Spec json.RawMessage `json:"spec"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional exchange-specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package openrtb
|
||||
|
||||
// LossReason represents OpenRTB Loss Reason Code enumeration.
|
||||
//
|
||||
// It lists the options for an exchange to inform a bidder as to the reason why they did not win an item.
|
||||
type LossReason int64
|
||||
|
||||
// LossReason options.
|
||||
//
|
||||
// Values of 500+ are exchange specific values; should be communicated with buyers a priori.
|
||||
const (
|
||||
LossWon LossReason = 0 // Bid Won
|
||||
LossInternalError LossReason = 1 // Internal Error
|
||||
LossExpired LossReason = 2 // Impression Opportunity Expired
|
||||
LossInvalidResponse LossReason = 3 // Invalid Bid Response
|
||||
LossInvalidDealID LossReason = 4 // Invalid Deal ID
|
||||
LossInvalidAuctionID LossReason = 5 // Invalid Auction ID
|
||||
LossInvalidAdvertiserDomain LossReason = 6 // Invalid Advertiser Domain
|
||||
LossMissingMarkup LossReason = 7 // Missing Markup
|
||||
LossMissingCreativeID LossReason = 8 // Missing Creative ID
|
||||
LossMissingBidPrice LossReason = 9 // Missing Bid Price
|
||||
LossMissingApproval LossReason = 10 // Missing Minimum Creative Approval Data
|
||||
LossBelowAuctionFloor LossReason = 100 // Bid was Below Auction Floor
|
||||
LossBelowDealFloor LossReason = 101 // Bid was Below Deal Floor
|
||||
LossLostToHigherBid LossReason = 102 // Lost to Higher Bid
|
||||
LossLostToDealBid LossReason = 103 // Lost to a Bid for a Deal
|
||||
LossSeatBlocked LossReason = 104 // Buyer Seat Blocked
|
||||
LossCreativeFiltered LossReason = 200 // Creative Filtered - General; Reason Unknown
|
||||
LossPendingProcessing LossReason = 201 // Creative Filtered - Pending Processing by Exchange (e.g., approval, transcoding, etc.)
|
||||
LossDisapproved LossReason = 202 // Creative Filtered - Disapproved by Exchange
|
||||
LossSizeNotAllowed LossReason = 203 // Creative Filtered - Size Not Allowed
|
||||
LossIncorrectFormat LossReason = 204 // Creative Filtered - Incorrect Creative Format
|
||||
LossAdvertiserExclusions LossReason = 205 // Creative Filtered - Advertiser Exclusions
|
||||
LossNotSecure LossReason = 206 // Creative Filtered - Not Secure
|
||||
LossLanguageExclusions LossReason = 207 // Creative Filtered - Language Exclusions
|
||||
LossCategoryExclusions LossReason = 208 // Creative Filtered - Category Exclusions
|
||||
LossAttributeExclusions LossReason = 209 // Creative Filtered - Creative Attribute Exclusions
|
||||
LossAdTypeExclusions LossReason = 210 // Creative Filtered - Ad Type Exclusions
|
||||
LossAnimationTooLong LossReason = 211 // Creative Filtered - Animation Too Long
|
||||
LossNotAllowedInDeal LossReason = 212 // Creative Filtered - Not Allowed in Deal
|
||||
)
|
|
@ -1,39 +0,0 @@
|
|||
package openrtb3
|
||||
|
||||
// LossReasonCode defines the options for an exchange to inform a bidder as to the reason why they did not win an item.
|
||||
type LossReasonCode int64
|
||||
|
||||
// The following LossReasonCode constants list the options for an exchange to inform a bidder as to the reason why they did not win an item.
|
||||
const (
|
||||
LossBidWon LossReasonCode = 0 // Bid Won
|
||||
LossInternalError LossReasonCode = 1 // Internal Error
|
||||
LossImpressionOpportunityExpired LossReasonCode = 2 // Impression Opportunity Expired
|
||||
LossInvalidBidResponse LossReasonCode = 3 // Invalid Bid Response
|
||||
LossInvalidDealID LossReasonCode = 4 // Invalid Deal ID
|
||||
LossInvalidAuctionID LossReasonCode = 5 // Invalid Auction ID
|
||||
LossInvalidAdvertiserDomain LossReasonCode = 6 // Invalid Advertiser Domain
|
||||
LossMissingMarkup LossReasonCode = 7 // Missing Markup
|
||||
LossMissingCreativeID LossReasonCode = 8 // Missing Creative ID
|
||||
LossMissingBidPrice LossReasonCode = 9 // Missing Bid Price
|
||||
LossMissingMininumCreativeApprovalData LossReasonCode = 10 // Missing Minimum Creative Approval Data
|
||||
LossBidBelowAuctionFloor LossReasonCode = 100 // Bid was Below Auction Floor
|
||||
LossBidBelowDealFloor LossReasonCode = 101 // Bid was Below Deal Floor
|
||||
LossLostHigherBid LossReasonCode = 102 // Lost to Higher Bid
|
||||
LossLostBidDeal LossReasonCode = 103 // Lost to a Bid for a Deal
|
||||
LossBuyerSeatBlocked LossReasonCode = 104 // Buyer Seat Blocked
|
||||
LossCreativeFilteredGeneralUnknown LossReasonCode = 200 // Creative Filtered - General; Reason Unknown
|
||||
LossCreativeFilteredPendingProcessingExchange LossReasonCode = 201 // Creative Filtered - Pending Processing by Exchange (e.g., approval, transcoding, etc.)
|
||||
LossCreativeFilteredDisapprovedExchange LossReasonCode = 202 // Creative Filtered - Disapproved by Exchange
|
||||
LossCreativeFilteredSizeNotAllowed LossReasonCode = 203 // Creative Filtered - Size Not Allowed
|
||||
LossCreativeFilteredIncorrectCreativeFormat LossReasonCode = 204 // Creative Filtered - Incorrect Creative Format
|
||||
LossCreativeFilteredAdvertiserExclusions LossReasonCode = 205 // Creative Filtered - Advertiser Exclusions
|
||||
LossCreativeFilteredNotSecure LossReasonCode = 206 // Creative Filtered - Not Secure
|
||||
LossCreativeFilteredLanguageExclusions LossReasonCode = 207 // Creative Filtered - Language Exclusions
|
||||
LossCreativeFilteredCategoryExclusions LossReasonCode = 208 // Creative Filtered - Category Exclusions
|
||||
LossCreativeFilteredCreativeAttributeExclusions LossReasonCode = 209 // Creative Filtered - Creative Attribute Exclusions
|
||||
LossCreativeFilteredAdTypeExclusions LossReasonCode = 210 // Creative Filtered - Ad Type Exclusions
|
||||
LossCreativeFilteredAnimationTooLong LossReasonCode = 211 // Creative Filtered - Animation Too Long
|
||||
LossCreativeFilteredNotAllowedDeal LossReasonCode = 212 // Creative Filtered - Not Allowed in Deal
|
||||
|
||||
// 500+ Exchange specific values; should be communicated with buyers a priori.
|
||||
)
|
|
@ -0,0 +1,33 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Macro object constitutes a buyer defined key/value pair used to inject dynamic values into media markup
|
||||
// While they apply to any media markup irrespective of how it is conveyed, the principle use case is for media that was uploaded to the exchange prior to the transaction (e.g., pre-registered for creative quality review) and referenced in bid
|
||||
// The full form of the macro to be substituted at runtime is ${CUSTOM_KEY}, where “KEY” is the name supplied in the key attribute
|
||||
// This ensures no conflict with standard OpenRTB macros.
|
||||
type Macro struct {
|
||||
// Attribute:
|
||||
// key
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// Name of a buyer specific macro.
|
||||
Key string `json:"key"`
|
||||
|
||||
// Attribute:
|
||||
// value
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Value to substitute for each instance of the macro found in markup.
|
||||
Value string `json:"value,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional demand source specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Metric object is associated with an item as an array of metrics.
|
||||
// These metrics can offer insight to assist with decisioning such as average recent viewability, click-through rate, etc.
|
||||
// Each metric is identified by its type, reports the value of the metric, and optionally identifies the source or vendor measuring the value.
|
||||
type Metric struct {
|
||||
// Attribute:
|
||||
// type
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// Type of metric being presented using exchange curated string names which should be published to bidders a priori.
|
||||
Type string `json:"type"`
|
||||
|
||||
// Attribute:
|
||||
// value
|
||||
// Type:
|
||||
// float; required
|
||||
// Definition:
|
||||
// Number representing the value of the metric.
|
||||
// Probabilities must be in the range 0.0 – 1.0.
|
||||
Value float64 `json:"value,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// vendor
|
||||
// Type:
|
||||
// string; recommended
|
||||
// Definition:
|
||||
// Source of the value using exchange curated string names which should be published to bidders a priori.
|
||||
// If the exchange itself is the source versus a third party, “EXCHANGE” is recommended.
|
||||
Vendor string `json:"vendor,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional exchange-specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package openrtb
|
||||
|
||||
// NoBidReason represents OpenRTB No-Bid Reason Code enumeration.
|
||||
//
|
||||
// It lists the options for a bidder to signal the exchange as to why it did not offer a bid for the item.
|
||||
type NoBidReason int64
|
||||
|
||||
// NoBidReason options.
|
||||
//
|
||||
// Values of 500+ are exchange specific values; should be communicated with buyers a priori.
|
||||
const (
|
||||
NoBidUnknownError NoBidReason = 0 // Unknown Error
|
||||
NoBidTechnicalError NoBidReason = 1 // Technical Error
|
||||
NoBidInvalidRequest NoBidReason = 2 // Invalid Request
|
||||
NoBidCrawler NoBidReason = 3 // Known Web Crawler
|
||||
NoBidNonHuman NoBidReason = 4 // Suspected Non-Human Traffic
|
||||
NoBidProxy NoBidReason = 5 // Cloud, Data Center, or Proxy IP
|
||||
NoBidUnsupportedDevice NoBidReason = 6 // Unsupported Device
|
||||
NoBidBlockedPublisher NoBidReason = 7 // Blocked Publisher or Site
|
||||
NoBidUnmatchedUser NoBidReason = 8 // Unmatched User
|
||||
NoBidDailyUserCap NoBidReason = 9 // Daily User Cap Met
|
||||
NoBidDailyDomainCap NoBidReason = 10 // Daily Domain Cap Met
|
||||
NoBidAuthorizationUnavailable NoBidReason = 11 // Ads.txt Authorization Unavailable
|
||||
NoBidAuthorizationViolation NoBidReason = 12 // Ads.txt Authorization Violation
|
||||
NoBidAuthenticationUnavailable NoBidReason = 13 // Ads.cert Authentication Unavailable
|
||||
NoBidAuthenticationViolation NoBidReason = 14 // Ads.cert Authentication Violation
|
||||
NoBidInsufficientTime NoBidReason = 15 // Insufficient Auction Time
|
||||
)
|
|
@ -1,26 +0,0 @@
|
|||
package openrtb3
|
||||
|
||||
// NoBidReasonCode defines the options for a bidder to signal the exchange as to why it did not offer a bid for the item.
|
||||
type NoBidReasonCode int64
|
||||
|
||||
// The following NoBidReasonCode constants list the options for a bidder to signal the exchange as to why it did not offer a bid for the item.
|
||||
const (
|
||||
NoBidUnknownError NoBidReasonCode = 0 // Unknown Error
|
||||
NoBidTechnicalError NoBidReasonCode = 1 // Technical Error
|
||||
NoBidInvalidRequest NoBidReasonCode = 2 // Invalid Request
|
||||
NoBidKnownWebCrawler NoBidReasonCode = 3 // Known Web Crawler
|
||||
NoBidSuspectedNonHumanTraffic NoBidReasonCode = 4 // Suspected Non-Human Traffic
|
||||
NoBidCloudDataCenterProxyIP NoBidReasonCode = 5 // Cloud, Data Center, or Proxy IP
|
||||
NoBidUnsupportedDevice NoBidReasonCode = 6 // Unsupported Device
|
||||
NoBidBlockedPublisherSite NoBidReasonCode = 7 // Blocked Publisher or Site
|
||||
NoBidUnmatchedUser NoBidReasonCode = 8 // Unmatched User
|
||||
NoBidDailyUserCapMet NoBidReasonCode = 9 // Daily User Cap Met
|
||||
NoBidDailyDomainCapMet NoBidReasonCode = 10 // Daily Domain Cap Met
|
||||
NoBidAdsTxtAuthorizationUnavailable NoBidReasonCode = 11 // Ads.txt Authorization Unavailable
|
||||
NoBidAdsTxtAuthorizationViolation NoBidReasonCode = 12 // Ads.txt Authorization Violation
|
||||
NoBidAdsCertAuthenticationUnavailable NoBidReasonCode = 13 // Ads.cert Authentication Unavailable
|
||||
NoBidAdsCertAuthenticationViolation NoBidReasonCode = 14 // Ads.cert Authentication Violation
|
||||
NoBidInsufficientAuctionTime NoBidReasonCode = 15 // Insufficient Auction Time
|
||||
|
||||
// 500+ Exchange specific values; should be communicated with buyers a priori.
|
||||
)
|
|
@ -0,0 +1,60 @@
|
|||
// Package openrtb implements types for OpenRTB Specification v3.0
|
||||
// https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%20v3.0%20FINAL.md
|
||||
package openrtb
|
||||
|
||||
// OpenRTB top-level object is the root for both request and response payloads.
|
||||
// It includes versioning information and references to the Layer-4 domain model on which transactions are based.
|
||||
// By default, the domain model used by OpenRTB is the Advertising Common Object Model (AdCOM).
|
||||
//
|
||||
// Some of these attributes are optional.
|
||||
// The ver attribute, for example, indicates the OpenRTB specification version to which this payload conforms.
|
||||
// This is also conveyed in Layer-1 via an HTTP header.
|
||||
// Its utility here is more to assist in diagnostics by making the payload more self-documenting outside the context of a runtime transaction.
|
||||
//
|
||||
// The domainver attribute, however, does have runtime utility since the structures of Layer-4 objects may vary over time based on their specification versions.
|
||||
// This attribute can assist in invoking the correct domain object parser or unmarshalling code.
|
||||
type OpenRTB struct {
|
||||
// Attribute:
|
||||
// ver
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Version of the Layer-3 OpenRTB specification (e.g., "3.0").
|
||||
Ver string `json:"ver,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// domainspec
|
||||
// Type:
|
||||
// string; default “adcom”
|
||||
// Definition:
|
||||
// Identifier of the Layer-4 domain model used to define items for sale, media associated with bids, etc.
|
||||
DomainSpec string `json:"domainspec,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// domainver
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// Specification version of the Layer-4 domain model referenced in the domainspec attribute.
|
||||
DomainVer string `json:"domainver"`
|
||||
|
||||
// Attribute:
|
||||
// request
|
||||
// Type:
|
||||
// object; required *
|
||||
// Definition:
|
||||
// Bid request container.
|
||||
// * Required only for request payloads.
|
||||
// Refer to Object: Request.
|
||||
Request *Request `json:"request,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// response
|
||||
// Type:
|
||||
// object; required *
|
||||
// Definition:
|
||||
// Bid response container.
|
||||
// * Required only for response payloads.
|
||||
// Refer to Object: Response.
|
||||
Response *Response `json:"response,omitempty"`
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
// Package openrtb3 holds OpenRTB 3.0 types implementation
|
||||
// (https://github.com/InteractiveAdvertisingBureau/openrtb)
|
||||
package openrtb3
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Body is a top-level wrapper for OpenRTB requests.
|
||||
type Body struct {
|
||||
OpenRTB OpenRTB `json:"openrtb"`
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// OpenRTB is the top-level object is the root for both request and response payloads.
|
||||
// It includes versioning information and references to the Layer-4 domain model on which transactions are based.
|
||||
// By default, the domain model used by OpenRTB is the Advertising Common Object Model (AdCOM).
|
||||
type OpenRTB struct {
|
||||
Ver string `json:"ver,omitempty"` // Version of the Layer-3 OpenRTB specification (e.g., "3.0").
|
||||
DomainSpec string `json:"domainspec,omitempty"` // Default: "adcom" (const DefaultOpenRTBDomainSpec). Identifier of the Layer-4 domain model used to define items for sale, media associated with bids, etc.
|
||||
DomainVer string `json:"domainver"` // Required. Specification version of the Layer-4 domain model referenced in the “domainspec” attribute.
|
||||
Request *Request `json:"request,omitempty"` // Required only for request payloads. Bid request container.
|
||||
Response *Response `json:"response,omitempty"` // Required only for response payloads. Bid response container.
|
||||
|
||||
// Some of these attributes are optional.
|
||||
// The "ver" attribute, for example, indicates the OpenRTB specification version to which this payload conforms.
|
||||
// This is also conveyed in Layer-1 via an HTTP header.
|
||||
// Its utility here is more to assist in diagnostics by making the payload more self-documenting outside the context of a runtime transaction.
|
||||
//
|
||||
// The "domainver" attribute, however, does have runtime utility since the structures of Layer-4 objects may vary over time based on their specification versions.
|
||||
// This attribute can assist in invoking the correct domain object parser or unmarshalling code.
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Request object contains a globally unique bid request ID.
|
||||
// This "id" attribute is required as is an Item array with at least one object (i.e., at least one item for sale).
|
||||
// Other attributes establish rules and restrictions that apply to all items being offered.
|
||||
// This object also interfaces to Layer-4 domain objects for context such as the user, device, site or app, etc.
|
||||
type Request struct {
|
||||
ID string `json:"id"` // Required. Unique ID of the bid request; provided by the exchange.
|
||||
Test Bool `json:"test,omitempty"` // Default: 0 (false). Indicator of test mode in which auctions are not billable, where 0 (false) = live mode, 1 (true) = test mode.
|
||||
TMax int64 `json:"tmax,omitempty"` // Maximum time in milliseconds the exchange allows for bids to be received including Internet latency to avoid timeout. This value supersedes any a priori guidance from the exchange. If an exchange acts as an intermediary, it should decrease the outbound "tmax" value from what it received to account for its latency and the additional internet hop.
|
||||
AT int8 `json:"at,omitempty"` // Default: 2. Auction type, where 1 = First Price, 2 = Second Price Plus. Values greater than 500 can be used for exchange-specific auction types.
|
||||
Cur []string `json:"cur,omitempty"` // Default: ["USD"]. Array of accepted currencies for bids on this bid request using ISO-4217 alpha codes. Recommended if the exchange accepts multiple currencies. If omitted, the single currency of "USD" is assumed.
|
||||
Seat []string `json:"seat,omitempty"` // Restriction list of buyer seats for bidding on this item. Knowledge of buyer’s customers and their seat IDs must be coordinated between parties a priori. Omission implies no restrictions.
|
||||
WSeat *Bool `json:"wseat,omitempty"` // Default: 1 (true). Flag that determines the restriction interpretation of the “seat” array, where 0 (false) = block list, 1 (true) = whitelist.
|
||||
CData string `json:"cdata,omitempty"` // Allows bidder to retrieve data set on its behalf in the exchange’s cookie (refer to “cdata” in Object: Response) if supported by the exchange. The string must be in base85 cookie-safe characters.
|
||||
Source *Source `json:"source,omitempty"` // A Source object that provides data about the inventory source and which entity makes the final decision.
|
||||
Item []Item `json:"item"` // Required. Array of Item objects (at least one) that constitute the set of goods being offered for sale.
|
||||
Package Bool `json:"package,omitempty"` // Flag to indicate if the Exchange can verify that the items offered represent all of the items available in context (e.g., all impressions on a web page, all video spots such as pre/mid/post roll) to support road-blocking, where 0 = no, 1 = yes.
|
||||
Context json.RawMessage `json:"context,omitempty"` // Recommended. Layer-4 domain object structure that provides context for the items being offered conforming to the specification and version referenced in “openrtb.domainspec” and “openrtb.domainver”. For AdCOM v1.x, the objects allowed here all of which are optional are one of the “DistributionChannel” subtypes (i.e., “Site”, “App”, or “Dooh”), “User”, “Device”, “Regs”, and any objects subordinate to these as specified by AdCOM.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional exchange-specific extensions.
|
||||
}
|
||||
|
||||
// Source object carries data about the source of the transaction including the unique ID of the transaction itself, source authentication information, and the chain of custody.
|
||||
type Source struct {
|
||||
TID string `json:"tid,omitempty"` // Recommended. Transaction ID that must be common across all participants throughout the entire supply chain of this transaction. This also applies across all participating exchanges in a header bidding or similar publisher-centric broadcast scenario.
|
||||
DS string `json:"ds,omitempty"` // Recommended. Digital signature used to authenticate this request computed by the publisher or its trusted agent from the transaction digest string "tid:digest", where ‘tid’ matches the "tid" attribute and ‘digest’ is a string composed of an immutable portion of domain objects as defined in the domain specification used for this request. Refer to Section “Inventory Authentication” for more details.
|
||||
DSGVer int8 `json:"dsgver,omitempty"` // Recommended. Format version of the digest string that was digitally signed to produce “ds”. Refer to Section “Inventory Authentication” for more details.
|
||||
Digest string `json:"digest,omitempty"` // The full transaction digest string that was signed to produce the digital signature. Refer to Section “Inventory Authentication” for more details. NOTE: This is only intended for debugging purposes as needed. It is not intended for normal Production traffic due to the bandwidth impact.
|
||||
Cert string `json:"cert,omitempty"` // Recommended. File name of the certificate (i.e., the public key) used to generate the digital signature in “ds” attribute. Refer to Section “Inventory Authentication” for more details.
|
||||
PChain string `json:"pchain,omitempty"` // Payment ID chain string containing embedded syntax described in the TAG Payment ID Protocol. NOTE that the authentication features in this Source object combined with the “ads.txt” specification may lead to the future deprecation of this attribute.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional exchange-specific extensions.
|
||||
}
|
||||
|
||||
// Item object represents a unit of goods being offered for sale either on the open market or in relation to a private marketplace deal.
|
||||
// The id attribute is required since there may be multiple items being offered in the same bid request and bids must reference the specific item of interest.
|
||||
// This object interfaces to Layer-4 domain objects for deeper specification of the item being offered (e.g., an impression).
|
||||
type Item struct {
|
||||
ID string `json:"id"` // Required. A unique identifier for this item within the context of the offer (typically starts with 1 and increments).
|
||||
Qty int `json:"qty,omitempty"` // Default: 1. The number of instances (i.e., "quantity") of this item being offered (e.g., multiple identical impressions in a digital out-of-home scenario).
|
||||
Seq *int `json:"seq,omitempty"` // If multiple items are offered in the same bid request, the sequence number allows for the coordinated delivery.
|
||||
Flr float64 `json:"flr,omitempty"` // Minimum bid price for this item expressed in CPM.
|
||||
FlrCur string `json:"flrcur,omitempty"` // Default: "USD". Currency of the “flr” attribute specified using ISO-4217 alpha codes.
|
||||
Exp int64 `json:"exp,omitempty"` // Advisory as to the number of seconds that may elapse between auction and fulfilment.
|
||||
DT string `json:"dt,omitempty"` // Date/time when the item is expected to be fulfilled (e.g. when a DOOH impression will be displayed) using the W3C-defined ISO-8601 format.
|
||||
Dlvy int8 `json:"dlvy,omitempty"` // Default: 0. Item (e.g., an Ad object) delivery method required, where 0 = either method, 1 = the item must be sent as part of the transaction (e.g., by value in the bid itself, fetched by URL included in the bid), and 2 = an item previously uploaded to the exchange must be referenced by its ID. Note that if an exchange does not supported prior upload, then the default of 0 is effectively the same as 1 since there can be no items to reference.
|
||||
Metric []Metric `json:"metric,omitempty"` // An array of “Metric” objects.
|
||||
Deal []Deal `json:"deal,omitempty"` // Array of “Deal” objects that convey special terms applicable to this item.
|
||||
Private Bool `json:"private,omitempty"` // Default: 0 (false). Indicator of auction eligibility to seats named in “Deal” objects, where 0 (false) = all bids are accepted, 1 (true) = bids are restricted to the deals specified and the terms thereof.
|
||||
Spec json.RawMessage `json:"spec"` // Required. Layer-4 domain object structure that provides specifies the item being offered conforming to the specification and version referenced in “openrtb.domainspec” and “openrtb.domainver”. For AdCOM v1.x, the objects allowed here are “Placement” and any objects subordinate to these as specified by AdCOM.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional exchange-specific extensions.
|
||||
}
|
||||
|
||||
// Deal object constitutes a specific deal that was struck a priori between a seller and a buyer. Its presence indicates that this item is available under the terms of that deal.
|
||||
type Deal struct {
|
||||
ID string `json:"id"` // Required. A unique identifier for the deal.
|
||||
Flr float64 `json:"flr,omitempty"` // Minimum deal price for this item expressed in CPM.
|
||||
FlrCur string `json:"flrcur,omitempty"` // Default: "USD". Currency of the “flr” attribute specified using ISO-4217 alpha codes.
|
||||
AT int8 `json:"at,omitempty"` // Optional override of the overall auction type of the request, where 1 = First Price, 2 = Second Price Plus, 3 = the value passed in “flr” is the agreed upon deal price. Additional auction types can be defined by the exchange using 500+ values.
|
||||
WSeat []string `json:"wseat,omitempty"` // Whitelist of buyer seats allowed to bid on this deal. IDs of seats and the buyer’s customers to which they refer must be coordinated between bidders and the exchange a priori. Omission implies no restrictions.
|
||||
WADomain []string `json:"wadomain,omitempty"` // Array of advertiser domains (e.g., advertiser.com) allowed to bid on this deal. Omission implies no restrictions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional exchange-specific extensions.
|
||||
}
|
||||
|
||||
// Metric object is associated with an item as an array of metrics. These metrics can offer insight to assist with decisioning such as average recent viewability, click-through rate, etc. Each metric is identified by its type, reports the value of the metric, and optionally identifies the source or vendor measuring the value.
|
||||
type Metric struct {
|
||||
Type string `json:"type"` // Required. Type of metric being presented using exchange curated string names which should be published to bidders a priori.
|
||||
Value float64 `json:"value"` // Required. Number representing the value of the metric. Probabilities must be in the range 0.0 – 1.0.
|
||||
Vendor string `json:"vendor,omitempty"` // Recommended. Source of the value using exchange curated string names which should be published to bidders a priori. If the exchange itself is the source versus a third party, "EXCHANGE" is recommended.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional exchange-specific extensions.
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Response object is the bid response object under the Openrtb root.
|
||||
// Its id attribute is a reflection of the bid request ID.
|
||||
// The bidid attribute is an optional response tracking ID for bidders.
|
||||
// If specified, it will be available for use in substitution macros placed in markup and notification URLs.
|
||||
// At least one Seatbid object is required, which contains at least one Bid for an item.
|
||||
// Other attributes are optional.
|
||||
//
|
||||
// To express a "no-bid", the most compact option is simply to return an empty response with HTTP 204.
|
||||
// However, if the bidder wishes to convey a reason for not bidding, a Response object can be returned with just a reason code in the nbr attribute.
|
||||
type Response struct {
|
||||
ID string `json:"id"` // Required. ID of the bid request to which this is a response; must match the "request.id" attribute.
|
||||
BidID string `json:"bidid,omitempty"` // Bidder generated response ID to assist with logging/tracking.
|
||||
NBR NoBidReasonCode `json:"nbr,omitempty"` // Reason for not bidding if applicable (see List: No-Bid Reason Codes). Note that while many exchanges prefer a simple HTTP 204 response to indicate a no-bid, responses indicating a reason code can be useful in debugging scenarios.
|
||||
Cur string `json:"cur,omitempty"` // Default: "USD". Bid currency using ISO-4217 alpha codes.
|
||||
CData string `json:"cdata,omitempty"` // Allows bidder to set data in the exchange’s cookie, which can be retrieved on bid requests (refer to “cdata” in Object: Request) if supported by the exchange. The string must be in base85 cookie-safe characters.
|
||||
SeatBid []SeatBid `json:"seatbid,omitempty"` // Array of “Seatbid” objects; 1+ required if a bid is to be made.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional demand source specific extensions.
|
||||
}
|
||||
|
||||
// SeatBid object.
|
||||
//
|
||||
// A bid response can contain multiple Seatbid objects, each on behalf of a different buyer seat and each containing one or more individual bids.
|
||||
// If multiple items are presented in the request offer, the package attribute can be used to specify if a seat is willing to accept any impressions that it can win (default) or if it is interested in winning any only if it can win them all as a group.
|
||||
type SeatBid struct {
|
||||
Seat string `json:"seat,omitempty"` // Recommended. ID of the buyer seat on whose behalf this bid is made.
|
||||
Package int8 `json:"package,omitempty"` // Default: 0. For offers with multiple items, this flag Indicates if the bidder is willing to accept wins on a subset of bids or requires the full group as a package, where 0 = individual wins accepted; 1 = package win or loss only.
|
||||
Bid []Bid `json:"bid"` // Required. Array of 1+ "Bid" objects each related to an item. Multiple bids can relate to the same item.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional demand source specific extensions.
|
||||
}
|
||||
|
||||
// Bid object.
|
||||
//
|
||||
// A Seatbid object contains one or more Bid objects, each of which relates to a specific item in the bid request offer via the “item” attribute and constitutes an offer to buy that item for a given price.
|
||||
type Bid struct {
|
||||
ID string `json:"id,omitempty"` // Recommended. Bidder generated bid ID to assist with logging/tracking.
|
||||
Item string `json:"item"` // Required. ID of the item object in the related bid request; specifically "item.id".
|
||||
Price float64 `json:"price"` // Required. Bid price expressed as CPM although the actual transaction is for a unit item only. Note that while the type indicates float, integer math is highly recommended when handling currencies (e.g., BigDecimal in Java).
|
||||
Deal string `json:"deal,omitempty"` // Reference to a deal from the bid request if this bid pertains to a private marketplace deal; specifically “deal.id”.
|
||||
CID string `json:"cid,omitempty"` // Campaign ID or other similar grouping of brand-related ads. Typically used to increase the efficiency of audit processes.
|
||||
Tactic string `json:"tactic,omitempty"` // Tactic ID to enable buyers to label bids for reporting to the exchange the tactic through which their bid was submitted. The specific usage and meaning of the tactic ID should be communicated between buyer and exchanges a priori.
|
||||
PURL string `json:"purl,omitempty"` // Pending notice URL called by the exchange when a bid has been declared the winner within the scope of an OpenRTB compliant supply chain (i.e., there may still be non-compliant decisioning such as header bidding). Substitution macros may be included.
|
||||
BURL string `json:"burl,omitempty"` // Recommended. Billing notice URL called by the exchange when a winning bid becomes billable based on exchange-specific business policy (e.g., markup rendered). Substitution macros may be included.
|
||||
LURL string `json:"lurl,omitempty"` // Loss notice URL called by the exchange when a bid is known to have been lost. Substitution macros may be included. Exchange-specific policy may preclude support for loss notices or the disclosure of winning clearing prices resulting in ${OPENRTB_PRICE} macros being removed (i.e., replaced with a zero-length string).
|
||||
Exp int64 `json:"exp,omitempty"` // Advisory as to the number of seconds the buyer is willing to wait between auction and fulfilment.
|
||||
MID string `json:"mid,omitempty"` // ID to enable media to be specified by reference if previously uploaded to the exchange rather than including it by value in the domain objects.
|
||||
Macro []Macro `json:"macro,omitempty"` // Array of “Macro” objects that enable bid specific values to be substituted into markup; especially useful for previously uploaded media referenced via the “mid” attribute. Refer to Object: Macro.
|
||||
Media json.RawMessage `json:"media,omitempty"` // Layer-4 domain object structure that specifies the media to be presented if the bid is won conforming to the specification and version referenced in “openrtb.domainspec” and “openrtb.domainver”. For AdCOM v1.x, the objects allowed here are “Ad” and any objects subordinate thereto as specified by AdCOM.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional demand source specific extensions.
|
||||
}
|
||||
|
||||
// Macro object constitutes a buyer defined key/value pair used to inject dynamic values into media markup.
|
||||
// While they apply to any media markup irrespective of how it is conveyed, the principle use case is for media that was uploaded to the exchange prior to the transaction (e.g., pre-registered for creative quality review) and referenced in bid.
|
||||
type Macro struct {
|
||||
Key string `json:"key"` // Required. Name of a buyer specific macro.
|
||||
Value string `json:"value,omitempty"` // Value to substitute for each instance of the macro found in markup.
|
||||
Ext json.RawMessage `json:"ext,omitempty"` // Optional demand source specific extensions.
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package openrtb3_test
|
||||
package openrtb_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package openrtb3_test
|
||||
package openrtb_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
|
@ -1,28 +0,0 @@
|
|||
package openrtb3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// timeFormats holds possible ISO-8601 date/time formats (https://en.wikipedia.org/wiki/ISO_8601).
|
||||
var timeFormats = []string{
|
||||
time.RFC3339,
|
||||
"2006-01-02",
|
||||
"2006-01-02T15:04:05+00:00",
|
||||
"2006-01-02T15:04:05Z",
|
||||
"20060102T150405Z",
|
||||
}
|
||||
|
||||
// ParseTime parses a date/time string.
|
||||
func ParseTime(s string) (time.Time, error) {
|
||||
var err error
|
||||
for _, f := range timeFormats {
|
||||
if t, e := time.Parse(f, s); e == nil {
|
||||
return t, nil
|
||||
} else {
|
||||
err = e
|
||||
}
|
||||
}
|
||||
return time.Time{}, fmt.Errorf("openrtb3: ParseTime(%q) failed: %s", s, err)
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
package openrtb3_test
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
. "github.com/mxmCherry/openrtb/openrtb3"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/extensions/table"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("ParseTime", func() {
|
||||
|
||||
DescribeTable(
|
||||
"different date/time formats",
|
||||
func(input string, expected time.Time) {
|
||||
Expect(ParseTime(input)).To(Equal(expected))
|
||||
},
|
||||
|
||||
Entry(
|
||||
"RFC3339 UTC",
|
||||
"2018-10-14T08:45:16+00:00",
|
||||
time.Date(2018, 10, 14, 8, 45, 16, 0, time.FixedZone("", 0)), // zone parsed as "nameless"
|
||||
),
|
||||
Entry(
|
||||
"RFC3339 GMT+00:12",
|
||||
"2018-10-14T08:45:16+00:12",
|
||||
time.Date(2018, 10, 14, 8, 45, 16, 0, time.FixedZone("", 12*60)), // zone parsed as "nameless"
|
||||
),
|
||||
Entry(
|
||||
"RFC3339 GMT-00:12",
|
||||
"2018-10-14T08:45:16-00:12",
|
||||
time.Date(2018, 10, 14, 8, 45, 16, 0, time.FixedZone("", -12*60)), // zone parsed as "nameless"
|
||||
),
|
||||
|
||||
// https://en.wikipedia.org/wiki/ISO_8601
|
||||
Entry(
|
||||
"Date",
|
||||
"2018-10-14",
|
||||
time.Date(2018, 10, 14, 0, 0, 0, 0, time.UTC),
|
||||
),
|
||||
Entry(
|
||||
"Combined date and time in UTC 1",
|
||||
"2018-10-14T08:45:16+00:00",
|
||||
time.Date(2018, 10, 14, 8, 45, 16, 0, time.FixedZone("", 0)), // zone parsed as "nameless"
|
||||
),
|
||||
Entry(
|
||||
"Combined date and time in UTC 2",
|
||||
"2018-10-14T08:45:16Z",
|
||||
time.Date(2018, 10, 14, 8, 45, 16, 0, time.UTC),
|
||||
),
|
||||
Entry(
|
||||
"Combined date and time in UTC 3",
|
||||
"20181014T084516Z",
|
||||
time.Date(2018, 10, 14, 8, 45, 16, 0, time.UTC),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
// ----------------------------------------------------------------------------
|
|
@ -0,0 +1,124 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Request object contains a globally unique bid request ID.
|
||||
// This id attribute is required as is an Item array with at least one object (i.e., at least one item for sale).
|
||||
// Other attributes establish rules and restrictions that apply to all items being offered.
|
||||
// This object also interfaces to Layer-4 domain objects for context such as the user, device, site or app, etc.
|
||||
type Request struct {
|
||||
// Attribute:
|
||||
// id
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// Unique ID of the bid request; provided by the exchange.
|
||||
ID string `json:"id"`
|
||||
|
||||
// Attribute:
|
||||
// test
|
||||
// Type:
|
||||
// integer; default 0
|
||||
// Definition:
|
||||
// Indicator of test mode in which auctions are not billable, where 0 = live mode, 1 = test mode.
|
||||
Test int8 `json:"test,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// tmax
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Maximum time in milliseconds the exchange allows for bids to be received including Internet latency to avoid timeout.
|
||||
// This value supersedes any a priori guidance from the exchange.
|
||||
// If an exchange acts as an intermediary, it should decrease the outbound tmax value from what it received to account for its latency and the additional internet hop.
|
||||
TMax int64 `json:"tmax,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// at
|
||||
// Type:
|
||||
// integer; default 2
|
||||
// Definition:
|
||||
// Auction type, where 1 = First Price, 2 = Second Price Plus.
|
||||
// Values greater than 500 can be used for exchange-specific auction types.
|
||||
AT AuctionType `json:"at,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// cur
|
||||
// Type:
|
||||
// string array; default [“USD”]
|
||||
// Definition:
|
||||
// Array of accepted currencies for bids on this bid request using ISO-4217 alpha codes.
|
||||
// Recommended if the exchange accepts multiple currencies.
|
||||
// If omitted, the single currency of “USD” is assumed.
|
||||
Cur []string `json:"cur,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// seat
|
||||
// Type:
|
||||
// string array
|
||||
// Definition:
|
||||
// Restriction list of buyer seats for bidding on this item.
|
||||
// Knowledge of buyer’s customers and their seat IDs must be coordinated between parties a priori.
|
||||
// Omission implies no restrictions.
|
||||
Seat []string `json:"seat,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// wseat
|
||||
// Type:
|
||||
// integer; default 1
|
||||
// Definition:
|
||||
// Flag that determines the restriction interpretation of the seat array, where 0 = block list, 1 = whitelist.
|
||||
WSeat int8 `json:"wseat,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// cdata
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Allows bidder to retrieve data set on its behalf in the exchange’s cookie (refer to cdata in Object: Response) if supported by the exchange.
|
||||
// The string must be in base85 cookie-safe characters.
|
||||
CData string `json:"cdata,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// source
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// A Source object that provides data about the inventory source and which entity makes the final decision
|
||||
// Refer to Object: Source.
|
||||
Source *Source `json:"source,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// item
|
||||
// Type:
|
||||
// object array; required
|
||||
// Definition:
|
||||
// Array of Item objects (at least one) that constitute the set of goods being offered for sale.
|
||||
// Refer to Object: Item.
|
||||
Item []Item `json:"item"`
|
||||
|
||||
// Attribute:
|
||||
// package
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Flag to indicate if the Exchange can verify that the items offered represent all of the items available in context (e.g., all impressions on a web page, all video spots such as pre/mid/post roll) to support road-blocking, where 0 = no, 1 = yes.
|
||||
Package int8 `json:"package,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// context
|
||||
// Type:
|
||||
// object; recommended
|
||||
// Definition:
|
||||
// Layer-4 domain object structure that provides context for the items being offered conforming to the specification and version referenced in openrtb.domainspec and openrtb.domainver.
|
||||
// For AdCOM v1.x, the objects allowed here all of which are optional are one of the DistributionChannel subtypes (i.e., Site, App, or Dooh), User, Device, Regs, Restrictions, and any objects subordinate to these as specified by AdCOM.
|
||||
Context json.RawMessage `json:"context,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional exchange-specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Response object is the bid response object under the Openrtb root.
|
||||
// Its id attribute is a reflection of the bid request ID.
|
||||
// The bidid attribute is an optional response tracking ID for bidders.
|
||||
// If specified, it will be available for use in substitution macros placed in markup and notification URLs.
|
||||
// At least one Seatbid object is required, which contains at least one Bid for an item.
|
||||
// Other attributes are optional.
|
||||
//
|
||||
// To express a “no-bid”, the most compact option is simply to return an empty response with HTTP 204.
|
||||
// However, if the bidder wishes to convey a reason for not bidding, a Response object can be returned with just a reason code in the nbr attribute.
|
||||
type Response struct {
|
||||
// Attribute:
|
||||
// id
|
||||
// Type:
|
||||
// string; required
|
||||
// Definition:
|
||||
// ID of the bid request to which this is a response; must match the request.id attribute.
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// bidid
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Bidder generated response ID to assist with logging/tracking.
|
||||
BidID string `json:"bidid,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// nbr
|
||||
// Type:
|
||||
// integer
|
||||
// Definition:
|
||||
// Reason for not bidding if applicable (see List: No-Bid Reason Codes).
|
||||
// Note that while many exchanges prefer a simple HTTP 204 response to indicate a no-bid, responses indicating a reason code can be useful in debugging scenarios.
|
||||
NBR NoBidReason `json:"nbr,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// cur
|
||||
// Type:
|
||||
// string; default “USD”
|
||||
// Definition:
|
||||
// Bid currency using ISO-4217 alpha codes.
|
||||
Cur string `json:"cur,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// cdata
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Allows bidder to set data in the exchange’s cookie, which can be retrieved on bid requests (refer to cdata in Object: Request) if supported by the exchange.
|
||||
// The string must be in base85 cookie-safe characters.
|
||||
CData string `json:"cdata,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// seatbid
|
||||
// Type:
|
||||
// object array
|
||||
// Definition:
|
||||
// Array of Seatbid objects; 1+ required if a bid is to be made.
|
||||
// Refer to Object: Seatbid.
|
||||
SeatBid []SeatBid `json:"seatbid,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional demand source specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// SeatBid is an OpenRTB seatbid object.
|
||||
// A bid response can contain multiple Seatbid objects, each on behalf of a different buyer seat and each containing one or more individual bids.
|
||||
// If multiple items are presented in the request offer, the package attribute can be used to specify if a seat is willing to accept any impressions that it can win (default) or if it is interested in winning any only if it can win them all as a group.
|
||||
type SeatBid struct {
|
||||
// Attribute:
|
||||
// seat
|
||||
// Type:
|
||||
// string, recommended
|
||||
// Definition:
|
||||
// ID of the buyer seat on whose behalf this bid is made.
|
||||
Seat string `json:"seat,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// package
|
||||
// Type:
|
||||
// integer; default 0
|
||||
// Definition:
|
||||
// For offers with multiple items, this flag Indicates if the bidder is willing to accept wins on a subset of bids or requires the full group as a package, where 0 = individual wins accepted; 1 = package win or loss only.
|
||||
Package int8 `json:"package,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// bid
|
||||
// Type:
|
||||
// object array; required
|
||||
// Definition:
|
||||
// Array of 1+ Bid objects each related to an item.
|
||||
// Multiple bids can relate to the same item.
|
||||
// Refer to Object: Bid.
|
||||
Bid []Bid `json:"bid,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional demand source specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package openrtb
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// Source object carries data about the source of the transaction including the unique ID of the transaction itself, source authentication information, and the chain of custody.
|
||||
//
|
||||
// NOTE: Attributes ds, dsmap, cert, and digest support digitally signed bid requests as defined by the Ads.cert: Signed Bid Requests specification.
|
||||
// As the Ads.cert specification is still in its BETA state, these attributes should be considered to be in a similar state.
|
||||
type Source struct {
|
||||
// Attribute:
|
||||
// tid
|
||||
// Type:
|
||||
// string; recommended
|
||||
// Definition:
|
||||
// Transaction ID that must be common across all participants throughout the entire supply chain of this transaction.
|
||||
// This also applies across all participating exchanges in a header bidding or similar publisher-centric broadcast scenario.
|
||||
TID string `json:"tid,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ts
|
||||
// Type:
|
||||
// integer; recommended
|
||||
// Definition:
|
||||
// Timestamp when the request originated at the beginning of the supply chain in Unix format (i.e., milliseconds since the epoch).
|
||||
// This value must be held as immutable throughout subsequent intermediaries.
|
||||
TS int64 `json:"ts,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ds
|
||||
// Type:
|
||||
// string; recommended
|
||||
// Definition:
|
||||
// Digital signature used to authenticate the origin of this request computed by the publisher or its trusted agent from a digest string composed of a set of immutable attributes found in the bid request.
|
||||
// Refer to Section “Inventory Authentication” for more details.
|
||||
DS string `json:"ds,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// dsmap
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// An ordered list of identifiers that indicates the attributes used to create the digest.
|
||||
// This map provides the essential instructions for recreating the digest from the bid request, which is a necessary step in validating the digital signature in the ds attribute.
|
||||
// Refer to Section “Inventory Authentication” for more details.
|
||||
DSMap string `json:"dsmap,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// cert
|
||||
// Type:
|
||||
// string; recommended
|
||||
// Definition:
|
||||
// File name of the certificate (i.e., the public key) used to generate the digital signature in the ds attribute.
|
||||
// Refer to Section “Inventory Authentication” for more details.
|
||||
Cert string `json:"cert,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// digest
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// The full digest string that was signed to produce the digital signature.
|
||||
// Refer to Section “Inventory Authentication” for more details.
|
||||
// NOTE: This is only intended for debugging purposes as needed.
|
||||
// It is not intended for normal Production traffic due to the bandwidth impact.
|
||||
Digest string `json:"digest,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// pchain
|
||||
// Type:
|
||||
// string
|
||||
// Definition:
|
||||
// Payment ID chain string containing embedded syntax described in the TAG Payment ID Protocol.
|
||||
// NOTE: Authentication features in this Source object combined with the “ads.txt” specification may lead to the deprecation of this attribute.
|
||||
PChain string `json:"pchain,omitempty"`
|
||||
|
||||
// Attribute:
|
||||
// ext
|
||||
// Type:
|
||||
// object
|
||||
// Definition:
|
||||
// Optional exchange-specific extensions.
|
||||
Ext json.RawMessage `json:"ext,omitempty"`
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
# testdata
|
||||
|
||||
Examples copied from [OpenRTB](https://github.com/InteractiveAdvertisingBureau/openrtb) [3.0 BETA](https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%203.0%20BETA.md) spec.
|
||||
Examples copied from [OpenRTB](https://github.com/InteractiveAdvertisingBureau/openrtb) [3.0](https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/OpenRTB%20v3.0%20FINAL.md) spec.
|
||||
|
|
|
@ -1,35 +1,58 @@
|
|||
{
|
||||
"openrtb": {
|
||||
"ver": "3.0",
|
||||
"domainspec": "adcom",
|
||||
"domainver": "1.0",
|
||||
"request": {
|
||||
"id": "0123456789ABCDEF",
|
||||
"tmax": 150,
|
||||
"at": 2,
|
||||
"cur": [
|
||||
"USD",
|
||||
"EUR"
|
||||
],
|
||||
"source": {
|
||||
"ds": "AE23865DF890100BECCD76579DD4769DBBA9812CEE8ED90BF",
|
||||
"tid": "FEDCBA9876543210",
|
||||
"pchain": "..."
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"id": "1",
|
||||
"qty": 1,
|
||||
"deal": [
|
||||
{
|
||||
"id": "1234",
|
||||
"flr": 1.5
|
||||
}
|
||||
],
|
||||
"spec": {}
|
||||
}
|
||||
],
|
||||
"context": {}
|
||||
}
|
||||
}
|
||||
"openrtb": {
|
||||
"ver": "3.0",
|
||||
"domainspec": "adcom",
|
||||
"domainver": "1.0",
|
||||
"request": {
|
||||
"id": "0123456789ABCDEF",
|
||||
"tmax": 150,
|
||||
"at": 2,
|
||||
"cur": [
|
||||
"USD",
|
||||
"EUR"
|
||||
],
|
||||
"source": {
|
||||
"tid": "FEDCBA9876543210",
|
||||
"ts": 1541796182157,
|
||||
"ds": "AE23865DF890100BECCD76579DD4769DBBA9812CEE8ED90BF",
|
||||
"dsmap": "...",
|
||||
"cert": "ads-cert.1.txt",
|
||||
"pchain": "..."
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"id": "1",
|
||||
"qty": 1,
|
||||
"deal": [
|
||||
{
|
||||
"id": "1234",
|
||||
"flr": 1.5
|
||||
}
|
||||
],
|
||||
"spec": {
|
||||
"placement": {
|
||||
"dummy": "dummy"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"context": {
|
||||
"site": {
|
||||
"dummy": "dummy"
|
||||
},
|
||||
"user": {
|
||||
"dummy": "dummy"
|
||||
},
|
||||
"device": {
|
||||
"dummy": "dummy"
|
||||
},
|
||||
"regs": {
|
||||
"dummy": "dummy"
|
||||
},
|
||||
"restrictions": {
|
||||
"dummy": "dummy"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,44 @@
|
|||
{
|
||||
"openrtb": {
|
||||
"ver": "3.0",
|
||||
"domainspec": "adcom",
|
||||
"domainver": "1.0",
|
||||
"response": {
|
||||
"id": "0123456789ABCDEF",
|
||||
"bidid": "0011223344AABBCC",
|
||||
"seatbid": [
|
||||
{
|
||||
"seat": "XYZ",
|
||||
"bid": [
|
||||
{
|
||||
"id": "yaddayadda",
|
||||
"item": "1",
|
||||
"deal": "1234",
|
||||
"price": 1.5,
|
||||
"tactic": "...",
|
||||
"purl": "...",
|
||||
"burl": "...",
|
||||
"lurl": "...",
|
||||
"mid": "...",
|
||||
"macro": [
|
||||
{
|
||||
"key": "TIMESTAMP",
|
||||
"value": "1127987134"
|
||||
},
|
||||
{
|
||||
"key": "CLICKTOKEN",
|
||||
"value": "A7D800F2716DB"
|
||||
}
|
||||
],
|
||||
"media": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"openrtb": {
|
||||
"ver": "3.0",
|
||||
"domainspec": "adcom",
|
||||
"domainver": "1.0",
|
||||
"response": {
|
||||
"id": "0123456789ABCDEF",
|
||||
"bidid": "0011223344AABBCC",
|
||||
"seatbid": [
|
||||
{
|
||||
"seat": "XYZ",
|
||||
"bid": [
|
||||
{
|
||||
"id": "yaddayadda",
|
||||
"item": "1",
|
||||
"deal": "1234",
|
||||
"price": 1.5,
|
||||
"tactic": "...",
|
||||
"purl": "...",
|
||||
"burl": "...",
|
||||
"lurl": "...",
|
||||
"mid": "...",
|
||||
"macro": [
|
||||
{
|
||||
"key": "TIMESTAMP",
|
||||
"value": "1127987134"
|
||||
},
|
||||
{
|
||||
"key": "CLICKTOKEN",
|
||||
"value": "A7D800F2716DB"
|
||||
}
|
||||
],
|
||||
"media": {
|
||||
"ad": {
|
||||
"dummy": "dummy"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче