mirror of
https://github.com/prebid/openrtb.git
synced 2026-06-15 14:36:36 +03:00
@@ -1,6 +1,11 @@
|
||||
# openrtb [](https://godoc.org/github.com/mxmCherry/openrtb) [](https://travis-ci.org/mxmCherry/openrtb)
|
||||
|
||||
[OpenRTB](//www.iab.com/guidelines/real-time-bidding-rtb-project/) [v2.5](//www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) types for Go programming language (Golang)
|
||||
[OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [v2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) types for Go programming language (Golang)
|
||||
|
||||
Also includes [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [Dynamic Native Ads API
|
||||
Specification Version 1.1](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf) types:
|
||||
- [4 Native Ad Request Markup Details](native/request/)
|
||||
- [5 Native Ad Response Markup Details](native/response/)
|
||||
|
||||
# Using
|
||||
|
||||
@@ -12,7 +17,7 @@ go get -u "github.com/mxmCherry/openrtb"
|
||||
import "github.com/mxmCherry/openrtb"
|
||||
```
|
||||
|
||||
This repo follows [semver](http://semver.org/) - see [releases](//github.com/mxmCherry/openrtb/releases).
|
||||
This repo follows [semver](http://semver.org/) - see [releases](https://github.com/mxmCherry/openrtb/releases).
|
||||
Master always contains latest code, so better use some package manager to vendor specific version.
|
||||
|
||||
# Guidelines
|
||||
@@ -25,7 +30,7 @@ Master always contains latest code, so better use some package manager to vendor
|
||||
## Types
|
||||
- Key types should be chosen according to OpenRTB specification (attribute types)
|
||||
- Numeric types:
|
||||
- `int64` - time, duration, unbound enums (like `BidRequest.at` - exchange-specific auctions types are > 500)
|
||||
- `int64` - time, duration, length, unbound enums (like `BidRequest.at` - exchange-specific auctions types are > 500)
|
||||
- `int8` - short enums (with values <= 127), boolean-like attributes (like `BidRequest.test`)
|
||||
- `uint64` - width, height, bitrate etc. (unbound positive numbers)
|
||||
- `float64` - coordinates, prices etc.
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package openrtb_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
. "github.com/mxmCherry/openrtb"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/extensions/table"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("BidRequest", func() {
|
||||
DescribeTable(
|
||||
"Marshaling",
|
||||
|
||||
func(filename string, subject interface{}) {
|
||||
expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(json.Unmarshal(expected, subject)).To(Succeed())
|
||||
|
||||
actual, err := json.Marshal(subject)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(actual).To(MatchJSON(expected))
|
||||
},
|
||||
|
||||
Entry(
|
||||
"Simple Banner",
|
||||
"bid-request/simple-banner.json",
|
||||
new(BidRequest)),
|
||||
Entry(
|
||||
"Expandable Creative",
|
||||
"bid-request/expandable-creative.json",
|
||||
new(BidRequest)),
|
||||
Entry(
|
||||
"Mobile",
|
||||
"bid-request/mobile.json",
|
||||
new(BidRequest)),
|
||||
Entry(
|
||||
"Video",
|
||||
"bid-request/video.json",
|
||||
new(BidRequest)),
|
||||
Entry(
|
||||
"PMP with Direct Deal",
|
||||
"bid-request/pmp-with-direct-deal.json",
|
||||
new(BidRequest)),
|
||||
Entry(
|
||||
"Native Ad",
|
||||
"bid-request/native-ad.json",
|
||||
new(BidRequest)),
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,48 @@
|
||||
package openrtb_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
. "github.com/mxmCherry/openrtb"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/extensions/table"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("BidResponse", func() {
|
||||
DescribeTable(
|
||||
"Marshaling",
|
||||
|
||||
func(filename string, subject interface{}) {
|
||||
expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(json.Unmarshal(expected, subject)).To(Succeed())
|
||||
|
||||
actual, err := json.Marshal(subject)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(actual).To(MatchJSON(expected))
|
||||
},
|
||||
|
||||
Entry(
|
||||
"Ad Served on Win Notice",
|
||||
"bid-response/ad-served-on-win-notice.json",
|
||||
new(BidResponse)),
|
||||
Entry(
|
||||
"VAST XML Document Returned Inline",
|
||||
"bid-response/vast-xml-document-returned-inline.json",
|
||||
new(BidResponse)),
|
||||
Entry(
|
||||
"Direct Deal Ad Served on Win Notice",
|
||||
"bid-response/direct-deal-ad-served-on-win-notice.json",
|
||||
new(BidResponse)),
|
||||
Entry(
|
||||
"Native Markup Returned Inline",
|
||||
"bid-response/native-markup-returned-inline.json",
|
||||
new(BidResponse)),
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
# native
|
||||
|
||||
[Go](https://golang.org/) implementation of [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [Dynamic Native Ads API
|
||||
Specification Version 1.1](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf) types.
|
||||
@@ -0,0 +1,4 @@
|
||||
# native/request [](https://godoc.org/github.com/mxmCherry/openrtb/native/request)
|
||||
|
||||
[Go](https://golang.org/) implementation of [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [Dynamic Native Ads API
|
||||
Specification Version 1.1](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf) section 4 Native Ad Request Markup Details types.
|
||||
@@ -0,0 +1,22 @@
|
||||
package request
|
||||
|
||||
// 7.2 Native Ad Unit IDs - To Be Deprecated
|
||||
//
|
||||
// Ad Unit ID is to be deprecated in a future version and is not suggested for new implementations.
|
||||
//
|
||||
// Below is a list of the core ad unit ids described by IAB here http://www.iab.net/media/file/IABNativeAdvertisingPlaybook120413.pdf
|
||||
//
|
||||
// In feed unit is essentially a layout, it has been removed from the list. The in feed units can be identified via the layout parameter on the request.
|
||||
//
|
||||
// An implementing exchange may not support all asset variants or introduce new ones unique to that system.
|
||||
type AdUnit int64
|
||||
|
||||
const (
|
||||
AdUnitPaidSearch AdUnit = 1 // Paid Search Units
|
||||
AdUnitRecommendationWidget AdUnit = 2 // Recommendation Widgets
|
||||
AdUnitPromotedListing AdUnit = 3 // Promoted Listings
|
||||
AdUnitInAd AdUnit = 4 // In-Ad (IAB Standard) with Native Element Units
|
||||
AdUnitCustom AdUnit = 5 // Custom /”Can’t Be Contained”
|
||||
|
||||
// 500+ Reserved for Exchange specific formats.
|
||||
)
|
||||
@@ -0,0 +1,97 @@
|
||||
package request
|
||||
|
||||
// 4.2 Asset Object
|
||||
//
|
||||
// The main container object for each asset requested or supported by Exchange on behalf of the rendering client.
|
||||
// Any object that is required is to be flagged as such.
|
||||
// Only one of the {title,img,video,data} objects should be present in each object.
|
||||
// All others should be null/absent.
|
||||
// The id is to be unique within the AssetObject array so that the response can be aligned.
|
||||
//
|
||||
// To be more explicit, it is the ID of each asset object that maps the response to the request.
|
||||
// So if a request for a title object is sent with id 1, then the response containing the title should have an id of 1.
|
||||
//
|
||||
// New in version 1.1 of the spec, there are recommended sizes/lengths/etc with some of the asset types.
|
||||
// The goal for asset requirements standardization is to facilitate adoption of native by DSPs by limiting the diverse types/sizes/requirements of assets they must have available to purchase a native ad impression.
|
||||
// While great diversity may exist in publishers, advertisers/DSPs can not be expected to provide infinite headline lengths, thumbnail aspect ratios, etc.
|
||||
// While we have not gone as far as creating a single standard, we've honed in on a few options that cover the most common cases.
|
||||
// SSPs can deviate from these standards, but should understand they may limit applicable DSP demand by doing so.
|
||||
// DSPs should feel confident that if they support these standards they'll be able to access most native inventory.
|
||||
type Asset struct {
|
||||
// Field:
|
||||
// id
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// int
|
||||
// Description:
|
||||
// Unique asset ID, assigned by exchange.
|
||||
// Typically a counter for the array.
|
||||
ID int64 `json:"id"`
|
||||
|
||||
// Field:
|
||||
// required
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// int
|
||||
// Default:
|
||||
// 0
|
||||
// Description:
|
||||
// Set to 1 if asset is required (exchange will not accept a bid without it)
|
||||
Required int8 `json:"required,omitempty"`
|
||||
|
||||
// Field:
|
||||
// title
|
||||
// Scope:
|
||||
// recommended (each asset object may contain only one of title, img, data or video)
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Title object for title assets.
|
||||
// See TitleObject definition.
|
||||
Title *Title `json:"title,omitempty"`
|
||||
|
||||
// Field:
|
||||
// img
|
||||
// Scope:
|
||||
// recommended (each asset object may contain only one of title, img, data or video)
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Image object for image assets.
|
||||
// See ImageObject definition.
|
||||
Img *Image `json:"img,omitempty"`
|
||||
|
||||
// Field:
|
||||
// video
|
||||
// Scope:
|
||||
// optional (each asset object may contain only one of title, img, data or video)
|
||||
// Type:
|
||||
// object - Video object for video assets.
|
||||
// See the Video request object definition.
|
||||
// Note that in-stream (ie preroll, etc) video ads are not part of Native.
|
||||
// Native ads may contain a video as the ad creative itself.
|
||||
Video *Video `json:"video,omitempty"`
|
||||
|
||||
// Field:
|
||||
// data
|
||||
// Scope:
|
||||
// recommended (each asset object may contain only one of title, img, data or video)
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Data object for brand name, description, ratings, prices etc.
|
||||
// See DataObject definition.
|
||||
Data *Data `json:"data,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package request
|
||||
|
||||
// 7.4 Context Sub Type IDs
|
||||
//
|
||||
// Next-level context in which the ad appears.
|
||||
// Again this reflects the primary context, and does not imply no presence of other elements.
|
||||
// For example, an article is likely to contain images but is still first and foremost an article.
|
||||
// SubType should only be combined with the primary context type as indicated (ie for a context type of 1, only context subtypes that start with 1 are valid).
|
||||
type ContextSubType int64
|
||||
|
||||
const (
|
||||
ContextSubTypeGeneral ContextSubType = 10 // General or mixed content.
|
||||
ContextSubTypeArticle ContextSubType = 11 // Primarily article content (which of course could include images, etc as part of the article)
|
||||
ContextSubTypeVideo ContextSubType = 12 // Primarily video content
|
||||
ContextSubTypeAudio ContextSubType = 13 // Primarily audio content
|
||||
ContextSubTypeImage ContextSubType = 14 // Primarily image content
|
||||
ContextSubTypeUserGenerated ContextSubType = 15 // User-generated content - forums, comments, etc
|
||||
ContextSubTypeSocial ContextSubType = 20 // General social content such as a general social network
|
||||
ContextSubTypeEmail ContextSubType = 21 // Primarily email content
|
||||
ContextSubTypeChat ContextSubType = 22 // Primarily chat/IM content
|
||||
ContextSubTypeSelling ContextSubType = 30 // Content focused on selling products, whether digital or physical
|
||||
ContextSubTypeAppStore ContextSubType = 31 // Application store/marketplace
|
||||
ContextSubTypeProductReview ContextSubType = 32 // Product reviews site primarily (which may sell product secondarily)
|
||||
|
||||
// 500+ To be defined by the exchange
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package request
|
||||
|
||||
// 7.3 Context Type IDs
|
||||
//
|
||||
// The context in which the ad appears - what type of content is surrounding the ad on the page at a high level.
|
||||
// This maps directly to the new Deep Dive on In-Feed Ad Units.
|
||||
// This denotes the primary context, but does not imply other content may not exist on the page - for example it's expected that most content platforms have some social components, etc.
|
||||
type ContextType int64
|
||||
|
||||
const (
|
||||
ContextTypeContent ContextType = 1 // Content-centric context such as newsfeed, article, image gallery, video gallery, or similar.
|
||||
ContextTypeSocial ContextType = 2 // Social-centric context such as social network feed, email, chat, or similar.
|
||||
ContextTypeProduct ContextType = 3 // Product context such as product listings, details, recommendations, reviews, or similar.
|
||||
|
||||
// 500+ To be defined by the exchange.
|
||||
)
|
||||
@@ -0,0 +1,41 @@
|
||||
package request
|
||||
|
||||
// 4.6 Data Object
|
||||
//
|
||||
// The Data Object is to be used for all non-core elements of the native unit such as Brand Name, Ratings, Review Count, Stars, Download count, descriptions etc.
|
||||
// It is also generic for future native elements not contemplated at the time of the writing of this document.
|
||||
// In some cases, additional recommendations are also included in the Data Asset Types table.
|
||||
type Data struct {
|
||||
|
||||
// Field:
|
||||
// type
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Type ID of the element supported by the publisher.
|
||||
// The publisher can display this information in an appropriate format.
|
||||
// See Data Asset Types table for commonly used examples.
|
||||
Type DataAssetType `json:"type"`
|
||||
|
||||
// Field:
|
||||
// len
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Maximum length of the text in the element’s response.
|
||||
Len int64 `json:"len,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package request
|
||||
|
||||
// 7.6 Data Asset Types
|
||||
//
|
||||
// Below is a list of common asset element types of native advertising at the time of writing this spec.
|
||||
// This list is non-exhaustive and intended to be extended by the buyers and sellers as the format evolves.
|
||||
//
|
||||
// An implementing exchange may not support all asset variants or introduce new ones unique to that system.
|
||||
type DataAssetType int64
|
||||
|
||||
const (
|
||||
// Type ID:
|
||||
// 1
|
||||
// Name:
|
||||
// sponsored
|
||||
// Description:
|
||||
// Sponsored By message where response should contain the brand name of the sponsor.
|
||||
// Format:
|
||||
// text
|
||||
// Recommendations:
|
||||
// Required. Max 25 or longer
|
||||
DataAssetTypeSponsored DataAssetType = 1
|
||||
|
||||
// Type ID:
|
||||
// 2
|
||||
// Name:
|
||||
// desc
|
||||
// Description:
|
||||
// Descriptive text associated with the product or service being advertised.
|
||||
// Longer length of text in response may be truncated or ellipsed by th exchange.
|
||||
// Format:
|
||||
// text
|
||||
// Recommendations:
|
||||
// Recommended. Max 140 or longer.
|
||||
DataAssetTypeDesc DataAssetType = 2
|
||||
|
||||
// Type ID:
|
||||
// 3
|
||||
// Name:
|
||||
// rating
|
||||
// Description:
|
||||
// Rating of the product being offered to the user.
|
||||
// For example an app’s rating in an app store from 0-5.
|
||||
// Format:
|
||||
// number formatted as string
|
||||
// Recommendations:
|
||||
// Optional. 0-5 integer formatted as string.
|
||||
DataAssetTypeRating DataAssetType = 3
|
||||
|
||||
// Type ID:
|
||||
// 4
|
||||
// Name:
|
||||
// likes
|
||||
// Description:
|
||||
// Number of social ratings or “likes” of the product being offered to the user.
|
||||
// Format:
|
||||
// number formatted as string
|
||||
DataAssetTypeLikes DataAssetType = 4
|
||||
|
||||
// Type ID:
|
||||
// 5
|
||||
// Name:
|
||||
// downloads
|
||||
// Description:
|
||||
// Number downloads/installs of this product
|
||||
// Format:
|
||||
// number formatted as string
|
||||
DataAssetTypeDownloads DataAssetType = 5
|
||||
|
||||
// Type ID:
|
||||
// 6
|
||||
// Name:
|
||||
// price
|
||||
// Description:
|
||||
// Price for product / app / in-app purchase.
|
||||
// Value should include currency symbol in localised format.
|
||||
// Format:
|
||||
// number formatted as string
|
||||
DataAssetTypePrice DataAssetType = 6
|
||||
|
||||
// Type ID:
|
||||
// 7
|
||||
// Name:
|
||||
// saleprice
|
||||
// Description:
|
||||
// Sale price that can be used together with price to indicate a discounted price compared to a regular price.
|
||||
// Value should include currency symbol in localised format.
|
||||
// Format:
|
||||
// number formatted as string
|
||||
DataAssetTypeSalePrice DataAssetType = 7
|
||||
|
||||
// Type ID:
|
||||
// 8
|
||||
// Name:
|
||||
// phone
|
||||
// Description:
|
||||
// Phone number formatted
|
||||
// Format:
|
||||
// string
|
||||
DataAssetTypePhone DataAssetType = 8
|
||||
|
||||
// Type ID:
|
||||
// 9
|
||||
// Name:
|
||||
// address
|
||||
// Description:
|
||||
// Address
|
||||
// Format:
|
||||
// text
|
||||
DataAssetTypeAddress DataAssetType = 9
|
||||
|
||||
// Type ID:
|
||||
// 10
|
||||
// Name:
|
||||
// desc2
|
||||
// Description:
|
||||
// Additional descriptive text associated with the product or service being advertised
|
||||
// Format:
|
||||
// text
|
||||
DataAssetTypeDesc2 DataAssetType = 10
|
||||
|
||||
// Type ID:
|
||||
// 11
|
||||
// Name:
|
||||
// displayurl
|
||||
// Description:
|
||||
// Display URL for the text ad.
|
||||
// To be used when sponsoring entity doesn’t own the content.
|
||||
// IE sponsored by BRAND on SITE (where SITE is transmitted in this field).
|
||||
// Format:
|
||||
// text
|
||||
DataAssetTypeDispayURL DataAssetType = 11
|
||||
|
||||
// Type ID:
|
||||
// 12
|
||||
// Name:
|
||||
// ctatext
|
||||
// Dewscription:
|
||||
// CTA description - descriptive text describing a ‘call to action’ button for the destination URL.
|
||||
// Format:
|
||||
// text
|
||||
// Recommendations:
|
||||
// Optional. Max 15 or longer.
|
||||
DataAssetTypeCTAText DataAssetType = 12
|
||||
|
||||
// Type ID:
|
||||
// 500+
|
||||
// Name:
|
||||
// XXX
|
||||
// Description:
|
||||
// Reserved for Exchange specific usage numbered above 500
|
||||
// Format:
|
||||
// Unknown
|
||||
)
|
||||
@@ -0,0 +1,92 @@
|
||||
package request
|
||||
|
||||
// 4.4 Image Object
|
||||
//
|
||||
// The Image object to be used for all image elements of the Native ad such as Icons, Main Image, etc.
|
||||
// Recommended sizes and aspect ratios are included in the Image Asset Types section.
|
||||
type Image struct {
|
||||
|
||||
// Field:
|
||||
// type
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Type ID of the image element supported by the publisher.
|
||||
// The publisher can display this information in an appropriate format.
|
||||
// See Table Image Asset Types.
|
||||
Type ImageAssetType `json:"type,omitempty"`
|
||||
|
||||
// Field:
|
||||
// w
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Width of the image in pixels.
|
||||
W uint64 `json:"w,omitempty"`
|
||||
|
||||
// Field:
|
||||
// wmin
|
||||
// Scope:
|
||||
// recommended
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// The minimum requested width of the image in pixels.
|
||||
// This option should be used for any rescaling of images by the client.
|
||||
// Either w or wmin should be transmitted.
|
||||
// If only w is included, it should be considered an exact requirement.
|
||||
WMin uint64 `json:"wmin,omitempty"`
|
||||
|
||||
// Field:
|
||||
// h
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Height of the image in pixels.
|
||||
H uint64 `json:"h,omitempty"`
|
||||
|
||||
// Field:
|
||||
// hmin
|
||||
// Scope:
|
||||
// recommended
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// The minimum requested height of the image in pixels.
|
||||
// This option should be used for any rescaling of images by the client.
|
||||
// Either h or hmin should be transmitted.
|
||||
// If only h is included, it should be considered an exact requirement.
|
||||
HMin uint64 `json:"hmin,omitempty"`
|
||||
|
||||
// Field:
|
||||
// mimes
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// array of strings
|
||||
// Default:
|
||||
// All types allowed
|
||||
// Description:
|
||||
// Whitelist of content MIME types supported.
|
||||
// Popular MIME types include, but are not limited to “image/jpg” “image/gif”.
|
||||
// Each implementing Exchange should have their own list of supported types in the integration docs.
|
||||
// See Wikipedia's MIME page for more information and links to all IETF RFCs.
|
||||
// If blank, assume all types are allowed.
|
||||
MIMEs []string `json:"mimes,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package request
|
||||
|
||||
// 7.7 Image Asset Types
|
||||
//
|
||||
// Below is a list of common image asset element types of native advertising at the time of writing this spec.
|
||||
// This list is non-exhaustive and intended to be extended by the buyers and sellers as the format evolves.
|
||||
//
|
||||
// An implementing exchange may not support all asset variants or may introduce new ones unique to that system.
|
||||
//
|
||||
// In order to facilitate adoption, recommendations are made for both minimum sizes and aspect ratios.
|
||||
// We speak here of 'minimum maximum height' or ‘max height of at least’, which means the SSP should support a max height of at least this value.
|
||||
// They are free to support larger, but the DSP knows that if they have an image of this size it will be accepted.
|
||||
// Note that SSPs will be responsible for sizing image to exact size if min-maxheight framework is used; exact size may not be available at bid request time.
|
||||
// Width is calculated from the 3 supported aspect ratios.
|
||||
// Note we are merging the prior overlapping type 1 and type 2 as just type 1 - to be used for app icon, brand logo, or similar.
|
||||
type ImageAssetType int64
|
||||
|
||||
const (
|
||||
ImageAssetTypeIcon ImageAssetType = 1 // Icon; Icon image; Optional. Max height: at least 50; aspect ratio: 1:1
|
||||
ImageAssetTypeLogo ImageAssetType = 2 // Logo; Logo image for the brand/app. To be deprecated in future version - use type 1 Icon.
|
||||
|
||||
// Main; Large image preview for the ad. At least one of 2 size variants required:
|
||||
// Small Variant:
|
||||
// max height: at least 200
|
||||
// max width: at least 200, 267, or 382
|
||||
// aspect ratio: 1:1, 4:3, or 1.91:1
|
||||
// Large Variant:
|
||||
// max height: at least 627
|
||||
// max width: at least 627, 836, or 1198
|
||||
// aspect ratio: 1:1, 4:3, or 1.91:1
|
||||
ImageAssetTypeMain ImageAssetType = 3
|
||||
|
||||
// 500+ XXX; Reserved for Exchange specific usage numbered above 500. No recommendations
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
package request
|
||||
|
||||
// 7.1 Native Layout IDs - To Be Deprecated
|
||||
//
|
||||
// Layout ID is to be deprecated in a future version and is not suggested for new implementations.
|
||||
//
|
||||
// Below is a list of the core layouts described in the introduction above.
|
||||
//
|
||||
// An implementing exchange may not support all asset variants or introduce new ones unique to that system.
|
||||
type Layout int64
|
||||
|
||||
const (
|
||||
LayoutContentWall Layout = 1 // Content Wall
|
||||
LayoutAppWall Layout = 2 // App Wall
|
||||
LayoutNewsFeed Layout = 3 // News Feed
|
||||
LayoutChatList Layout = 4 // Chat List
|
||||
LayoutCarousel Layout = 5 // Carousel
|
||||
LayoutContentStream Layout = 6 // Content Stream
|
||||
LayoutGrid Layout = 7 // Grid adjoining the content
|
||||
|
||||
// 500+ Reserved for Exchange specific layouts.
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package request
|
||||
|
||||
// 7.5 Placement Type IDs
|
||||
//
|
||||
// The FORMAT of the ad you are purchasing, separate from the surrounding context
|
||||
type PlacementType int64
|
||||
|
||||
const (
|
||||
PlacementTypeFeed = 1 // In the feed of content - for example as an item inside the organic feed/grid/listing/carousel.
|
||||
PlacementTypeAtomicContentUnit = 2 // In the atomic unit of the content - IE in the article page or single image page
|
||||
PlacementTypeOutsideCoreContent = 3 // Outside the core content - for example in the ads section on the right rail, as a banner-style placement near the content, etc.
|
||||
PlacementTypeRecommendationWidget = 4 // Recommendation widget, most commonly presented below the article content.
|
||||
|
||||
// 500+ To be defined by the exchange
|
||||
)
|
||||
@@ -0,0 +1,19 @@
|
||||
package request
|
||||
|
||||
// 5.8 Protocols (from OpenRTB spec 2.5)
|
||||
//
|
||||
// Options for the various bid response protocols that could be supported by an exchange.
|
||||
type Protocol int8
|
||||
|
||||
const (
|
||||
ProtocolVAST10 Protocol = 1 // VAST 1.0
|
||||
ProtocolVAST20 Protocol = 2 // VAST 2.0
|
||||
ProtocolVAST30 Protocol = 3 // VAST 3.0
|
||||
ProtocolVAST10Wrapper Protocol = 4 // VAST 1.0 Wrapper
|
||||
ProtocolVAST20Wrapper Protocol = 5 // VAST 2.0 Wrapper
|
||||
ProtocolVAST30Wrapper Protocol = 6 // VAST 3.0 Wrapper
|
||||
ProtocolVAST40 Protocol = 7 // VAST 4.0
|
||||
ProtocolVAST40Wrapper Protocol = 8 // VAST 4.0 Wrapper
|
||||
ProtocolDAAST10 Protocol = 9 // DAAST 1.0
|
||||
ProtocolDAAST10Wrapper Protocol = 10 // DAAST 1.0 Wrapper
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
package request
|
||||
|
||||
import "errors"
|
||||
|
||||
// RawJSON is a raw encoded JSON value.
|
||||
// It implements encoding/json.Marshaler and encoding/json.Unmarshaler and can
|
||||
// be used to delay JSON decoding or precompute a JSON encoding.
|
||||
//
|
||||
// Basically, it's just a copy of encoding/json.RawMessage type,
|
||||
// but with more convenient non-pointer encoding.
|
||||
//
|
||||
// HEADS UP: this will be replaced with json.RawMessage when Go 1.10 is out.
|
||||
type RawJSON []byte
|
||||
|
||||
// MarshalJSON returns m as the JSON encoding of m.
|
||||
func (m RawJSON) MarshalJSON() ([]byte, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets *m to a copy of data.
|
||||
func (m *RawJSON) UnmarshalJSON(data []byte) error {
|
||||
if m == nil {
|
||||
return errors.New("openrtb/native/request.RawJSON: UnmarshalJSON on nil pointer")
|
||||
}
|
||||
*m = append((*m)[0:0], data...)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package request_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
. "github.com/mxmCherry/openrtb/native/response"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("RawJSON", func() {
|
||||
|
||||
var _ json.Marshaler = (RawJSON)(nil)
|
||||
var _ json.Unmarshaler = (*RawJSON)(nil)
|
||||
|
||||
It("should encode JSON", func() {
|
||||
subject := RawJSON(`true`)
|
||||
|
||||
actual, err := subject.MarshalJSON()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(actual).To(Equal([]byte(`true`)))
|
||||
})
|
||||
|
||||
It("should decode JSON", func() {
|
||||
subject := RawJSON(nil)
|
||||
|
||||
err := subject.UnmarshalJSON([]byte(`true`))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(subject).To(Equal(RawJSON(`true`)))
|
||||
})
|
||||
|
||||
It("should decode JSON when embedded into struct", func() {
|
||||
wrapper := struct {
|
||||
Raw RawJSON `json:"raw"`
|
||||
}{
|
||||
Raw: nil,
|
||||
}
|
||||
|
||||
err := json.Unmarshal([]byte(`{"raw":true}`), &wrapper)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(wrapper.Raw).To(Equal(RawJSON(`true`)))
|
||||
})
|
||||
|
||||
It("should encode JSON when embedded into struct", func() {
|
||||
wrapper := struct {
|
||||
Raw RawJSON `json:"raw"`
|
||||
}{
|
||||
Raw: RawJSON(`true`),
|
||||
}
|
||||
|
||||
actual, err := json.Marshal(wrapper)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(actual).To(MatchJSON(`{"raw":true}`))
|
||||
})
|
||||
|
||||
})
|
||||
@@ -0,0 +1,130 @@
|
||||
// Package request provides OpenRTB Dynamic Native Ads API Specification Version 1.1
|
||||
// section 4 Native Ad Request Markup Details types:
|
||||
// https://www.iab.com/guidelines/real-time-bidding-rtb-project/
|
||||
// https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf
|
||||
package request
|
||||
|
||||
// 4.1 Native Markup Request Object
|
||||
//
|
||||
// The Native Object defines the native advertising opportunity available for bid via this bid request.
|
||||
// It will be included as a JSON-encoded string in the bid request’s imp.native field or as a direct JSON object, depending on the choice of the exchange.
|
||||
// While OpenRTB 2.3/2.4 supports only JSON-encoded strings, many exchanges have implemented a formal object.
|
||||
// Check with your integration docs.
|
||||
//
|
||||
// The Default column dictates how optional parameters should be interpreted if explicit values are not provided.
|
||||
type Request struct {
|
||||
|
||||
// Field:
|
||||
// ver
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string
|
||||
// Default:
|
||||
// 1.1
|
||||
// Description:
|
||||
// Version of the Native Markup version in use.
|
||||
Ver string `json:"ver,omitempty"`
|
||||
|
||||
// Field:
|
||||
// layout
|
||||
// Scope:
|
||||
// recommended in 1.0, to be deprecated
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// The Layout ID of the native ad unit.
|
||||
// See the Table of Layout IDs below.
|
||||
Layout Layout `json:"layout,omitempty"`
|
||||
|
||||
// Field:
|
||||
// adunit
|
||||
// Scope:
|
||||
// recommended in 1.0, to be deprecated
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// The Ad unit ID of the native ad unit.
|
||||
// See Table of Ad Unit IDs below for a list of supported core ad units.
|
||||
AdUnit AdUnit `json:"adunit,omitempty"`
|
||||
|
||||
// Field:
|
||||
// context
|
||||
// Scope:
|
||||
// recommended
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// The context in which the ad appears.
|
||||
// See Table of Context IDs below for a list of supported context types.
|
||||
Context ContextType `json:"context,omitempty"`
|
||||
|
||||
// Field:
|
||||
// contextsubtype
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// A more detailed context in which the ad appears.
|
||||
// See Table of Context SubType IDs below for a list of supported context subtypes.
|
||||
ContextSubType ContextSubType `json:"contextsubtype,omitempty"`
|
||||
|
||||
// Field:
|
||||
// plcmttype
|
||||
// Scope:
|
||||
// recommended
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// The design/format/layout of the ad unit being offered.
|
||||
// See Table of Placement Type IDs below for a list of supported placement types.
|
||||
PlcmtType PlacementType `json:"plcmttype,omitempty"`
|
||||
|
||||
// Field:
|
||||
// plcmtcnt
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Default:
|
||||
// 1
|
||||
// Description:
|
||||
// The number of identical placements in this Layout.
|
||||
// Refer Section 8.1 Multiplacement Bid Requests for further detail.
|
||||
PlcmtCnt int64 `json:"plcmtcnt,omitempty"`
|
||||
|
||||
// Field:
|
||||
// seq
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// integer
|
||||
// Default:
|
||||
// 0
|
||||
// Description:
|
||||
// 0 for the first ad, 1 for the second ad, and so on.
|
||||
// Note this would generally NOT be used in combination with plcmtcnt - either you are auctioning multiple identical placements (in which case plcmtcnt>1, seq=0) or you are holding separate auctions for distinct items in the feed (in which case plcmtcnt=1, seq=>=1)
|
||||
Seq int64 `json:"seq,omitempty"`
|
||||
|
||||
// Field:
|
||||
// assets
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// array of objects
|
||||
// Description:
|
||||
// An array of Asset Objects.
|
||||
// Any bid response must comply with the array of elements expressed in the bid request.
|
||||
Assets []Asset `json:"assets"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package request_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRequest(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Request Suite")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package request_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
. "github.com/mxmCherry/openrtb/native/request"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/extensions/table"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Request", func() {
|
||||
DescribeTable(
|
||||
"Marshaling",
|
||||
|
||||
func(filename string, subject interface{}) {
|
||||
expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(json.Unmarshal(expected, subject)).To(Succeed())
|
||||
|
||||
actual, err := json.Marshal(subject)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(actual).To(MatchJSON(expected))
|
||||
},
|
||||
|
||||
Entry(
|
||||
"Social Context",
|
||||
"social-context.json",
|
||||
new(Request)),
|
||||
Entry(
|
||||
"Content Context",
|
||||
"content-context.json",
|
||||
new(Request)),
|
||||
)
|
||||
})
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
# testdata
|
||||
|
||||
JSON examples copied from [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [Dynamic Native Ads API
|
||||
Specification Version 1.1](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf) spec - section 6 Bid Request/Response Samples.
|
||||
|
||||
Some empty/zero attributes were omited (not copied) because of [encoding/json](https://golang.org/pkg/encoding/json/) `omitempty` and [gomega.MatchJSON(...)](http://onsi.github.io/gomega/#matchjsonjson-interface).
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"ver": "1.1",
|
||||
"context": 1,
|
||||
"contextsubtype": 10,
|
||||
"plcmttype": 11,
|
||||
"plcmtcnt": 1,
|
||||
"assets": [
|
||||
{
|
||||
"id": 4,
|
||||
"video": {
|
||||
"minduration": 15,
|
||||
"maxduration": 30,
|
||||
"protocols": [
|
||||
2,
|
||||
3
|
||||
],
|
||||
"mimes": [
|
||||
"video/mp4"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 123,
|
||||
"required": 1,
|
||||
"title": {
|
||||
"len": 140
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 128,
|
||||
"img": {
|
||||
"wmin": 836,
|
||||
"hmin": 627,
|
||||
"type": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 124,
|
||||
"required": 1,
|
||||
"img": {
|
||||
"wmin": 50,
|
||||
"hmin": 50,
|
||||
"type": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"type": 1,
|
||||
"len": 25
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 127,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"type": 2,
|
||||
"len": 140
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"ver": "1.1",
|
||||
"context": 2,
|
||||
"contextsubtype": 20,
|
||||
"plcmttype": 11,
|
||||
"plcmtcnt": 1,
|
||||
"assets": [
|
||||
{
|
||||
"id": 123,
|
||||
"required": 1,
|
||||
"title": {
|
||||
"len": 140
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 128,
|
||||
"img": {
|
||||
"wmin": 836,
|
||||
"hmin": 627,
|
||||
"type": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 124,
|
||||
"required": 1,
|
||||
"img": {
|
||||
"wmin": 50,
|
||||
"hmin": 50,
|
||||
"type": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"type": 1,
|
||||
"len": 25
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 127,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"type": 2,
|
||||
"len": 140
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package request
|
||||
|
||||
// 4.3 Title Object
|
||||
//
|
||||
// The Title object is to be used for title element of the Native ad.
|
||||
type Title struct {
|
||||
// Field:
|
||||
// len
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Maximum length of the text in the title element.
|
||||
// Recommended to be 25, 90, or 140.
|
||||
Len int64 `json:"len"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package request
|
||||
|
||||
// 4.5 Video Object
|
||||
//
|
||||
// The video object to be used for all video elements supported in the Native Ad.
|
||||
// This corresponds to the Video object of OpenRTB.
|
||||
// Exchange implementers can impose their own specific restrictions.
|
||||
// Here are the required attributes of the Video Object.
|
||||
// For optional attributes please refer to OpenRTB.
|
||||
type Video struct {
|
||||
// Field:
|
||||
// mimes
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// array of string
|
||||
// Description:
|
||||
// Content MIME types supported.
|
||||
// Popular MIME types include,but are not limited to “video/x-mswmv” for Windows Media, and “video/x-flv” for Flash Video, or “video/mp4”.
|
||||
// Note that native frequently does not support flash.
|
||||
MIMEs []string `json:"mimes"`
|
||||
|
||||
// Field:
|
||||
// minduration
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Minimum video ad duration in seconds.
|
||||
MinDuration int64 `json:"minduration"`
|
||||
|
||||
// Field:
|
||||
// maxduration
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// integer
|
||||
// Description:
|
||||
// Maximum video ad duration in seconds.
|
||||
MaxDuration int64 `json:"maxduration"`
|
||||
|
||||
// Field:
|
||||
// protocols
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// array of integers
|
||||
// Description:
|
||||
// An array of video protocols the publisher can accept in the bid response.
|
||||
// See OpenRTB Table ‘Video Bid Response Protocols’ for a list of possible values.
|
||||
Protocols []Protocol `json:"protocols"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
# native/response [](https://godoc.org/github.com/mxmCherry/openrtb/native/response)
|
||||
|
||||
[Go](https://golang.org/) implementation of [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [Dynamic Native Ads API
|
||||
Specification Version 1.1](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf) section 5 Native Ad Response Markup Details types.
|
||||
@@ -0,0 +1,95 @@
|
||||
package response
|
||||
|
||||
// 5.2 Object: Asset
|
||||
//
|
||||
// Corresponds to the Asset Object in the request. The main container object for each asset
|
||||
// requested or supported by Exchange on behalf of the rendering client. Any object that is
|
||||
// required is to be flagged as such. Only one of the {title,img,video,data} objects should be
|
||||
// present in each object. All others should be null/absent. The id is to be unique within the
|
||||
// AssetObject array so that the response can be aligned.
|
||||
type Asset struct {
|
||||
// Field:
|
||||
// id
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// int
|
||||
// Description:
|
||||
// Unique asset ID, assigned by exchange, must match one of the asset IDs in request.
|
||||
ID int64 `json:"id"`
|
||||
|
||||
// Field:
|
||||
// required
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// int
|
||||
// Default:
|
||||
// 0
|
||||
// Description:
|
||||
// Set to 1 if asset is required. (bidder requires it to be displayed).
|
||||
Required int8 `json:"required,omitempty"`
|
||||
|
||||
// Field:
|
||||
// title
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Title object for title assets.
|
||||
Title *Title `json:"title,omitempty"`
|
||||
|
||||
// Field:
|
||||
// img
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Image object for image assets.
|
||||
Img *Image `json:"img,omitempty"`
|
||||
|
||||
// Field:
|
||||
// video
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Video object for video assets. See Video response object definition.
|
||||
// Note that in-stream video ads are not part of Native.
|
||||
// Native ads may contain a video as the ad creative itself.
|
||||
Video *Video `json:"video,omitempty"`
|
||||
|
||||
// Field:
|
||||
// data
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Data object for ratings, prices etc.
|
||||
Data *Data `json:"data,omitempty"`
|
||||
|
||||
// Field:
|
||||
// link
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Link object for call to actions. The link object applies if the asset item is activated (clicked).
|
||||
// If there is no link object on the asset, the parent link object on the bid response applies.
|
||||
Link *Link `json:"link,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package response
|
||||
|
||||
// 5.5 Object: Data
|
||||
//
|
||||
// Corresponds to the Data Object in the request, with the value filled in. The Data Object is to be
|
||||
// used for all miscellaneous elements of the native unit such as Brand Name, Ratings, Review
|
||||
// Count, Stars, Downloads, Price count etc. It is also generic for future native elements not
|
||||
// contemplated at the time of the writing of this document.
|
||||
type Data struct {
|
||||
// Field:
|
||||
// label
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// The optional formatted string name of the data type to be displayed.
|
||||
Label string `json:"label,omitempty"`
|
||||
|
||||
// Field:
|
||||
// value
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// The formatted string of data to be displayed.
|
||||
// Can contain a formatted value such as "5 stars" or "$10" or "3.4 stars out of 5".
|
||||
Value string `json:"value"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package response
|
||||
|
||||
// 5.4 Object: Image
|
||||
//
|
||||
// Corresponds to the Image Object in the request.
|
||||
// The Image object to be used for all image elements of the Native ad such as Icons, Main Image, etc.
|
||||
type Image struct {
|
||||
// Field:
|
||||
// url
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// URL of the image asset
|
||||
URL string `json:"url"`
|
||||
|
||||
// Field:
|
||||
// w
|
||||
// Scope:
|
||||
// recommended
|
||||
// Type:
|
||||
// int
|
||||
// Description:
|
||||
// Width of the image in pixels
|
||||
W uint64 `json:"w,omitempty"`
|
||||
|
||||
// Field:
|
||||
// h
|
||||
// Scope:
|
||||
// recommended
|
||||
// Type:
|
||||
// int
|
||||
// Description:
|
||||
// Height of the image in pixels
|
||||
H uint64 `json:"h,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package response
|
||||
|
||||
// 5.7 Object: Link
|
||||
//
|
||||
// Used for ‘call to action’ assets, or other links from the Native ad. This Object should be
|
||||
// associated to its peer object in the parent Asset Object or as the master link in the top level
|
||||
// Native Ad response object. When that peer object is activated (clicked) the action should take
|
||||
// the user to the location of the link.
|
||||
type Link struct {
|
||||
// Field:
|
||||
// url
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// Landing URL of the clickable link.
|
||||
URL string `json:"url"`
|
||||
|
||||
// Field:
|
||||
// clicktrackers
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string array
|
||||
// Description:
|
||||
// List of third-party tracker URLs to be fired on click of the URL.
|
||||
ClickTrackers []string `json:"clicktrackers,omitempty"`
|
||||
|
||||
// Field:
|
||||
// fallback
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// Fallback URL for deeplink. To be used if the URL given in url is not supported by the device.
|
||||
Fallback string `json:"fallback,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package response
|
||||
|
||||
import "errors"
|
||||
|
||||
// RawJSON is a raw encoded JSON value.
|
||||
// It implements encoding/json.Marshaler and encoding/json.Unmarshaler and can
|
||||
// be used to delay JSON decoding or precompute a JSON encoding.
|
||||
//
|
||||
// Basically, it's just a copy of encoding/json.RawMessage type,
|
||||
// but with more convenient non-pointer encoding.
|
||||
//
|
||||
// HEADS UP: this will be replaced with json.RawMessage when Go 1.10 is out.
|
||||
type RawJSON []byte
|
||||
|
||||
// MarshalJSON returns m as the JSON encoding of m.
|
||||
func (m RawJSON) MarshalJSON() ([]byte, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON sets *m to a copy of data.
|
||||
func (m *RawJSON) UnmarshalJSON(data []byte) error {
|
||||
if m == nil {
|
||||
return errors.New("openrtb/native/response.RawJSON: UnmarshalJSON on nil pointer")
|
||||
}
|
||||
*m = append((*m)[0:0], data...)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package response_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
. "github.com/mxmCherry/openrtb/native/response"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("RawJSON", func() {
|
||||
|
||||
var _ json.Marshaler = (RawJSON)(nil)
|
||||
var _ json.Unmarshaler = (*RawJSON)(nil)
|
||||
|
||||
It("should encode JSON", func() {
|
||||
subject := RawJSON(`true`)
|
||||
|
||||
actual, err := subject.MarshalJSON()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(actual).To(Equal([]byte(`true`)))
|
||||
})
|
||||
|
||||
It("should decode JSON", func() {
|
||||
subject := RawJSON(nil)
|
||||
|
||||
err := subject.UnmarshalJSON([]byte(`true`))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(subject).To(Equal(RawJSON(`true`)))
|
||||
})
|
||||
|
||||
It("should decode JSON when embedded into struct", func() {
|
||||
wrapper := struct {
|
||||
Raw RawJSON `json:"raw"`
|
||||
}{
|
||||
Raw: nil,
|
||||
}
|
||||
|
||||
err := json.Unmarshal([]byte(`{"raw":true}`), &wrapper)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(wrapper.Raw).To(Equal(RawJSON(`true`)))
|
||||
})
|
||||
|
||||
It("should encode JSON when embedded into struct", func() {
|
||||
wrapper := struct {
|
||||
Raw RawJSON `json:"raw"`
|
||||
}{
|
||||
Raw: RawJSON(`true`),
|
||||
}
|
||||
|
||||
actual, err := json.Marshal(wrapper)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(actual).To(MatchJSON(`{"raw":true}`))
|
||||
})
|
||||
|
||||
})
|
||||
@@ -0,0 +1,76 @@
|
||||
// Package response provides OpenRTB Dynamic Native Ads API Specification Version 1.1
|
||||
// section 5 Native Ad Response Markup Details types:
|
||||
// https://www.iab.com/guidelines/real-time-bidding-rtb-project/
|
||||
// https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf
|
||||
package response
|
||||
|
||||
// 5.1 Object: Response
|
||||
//
|
||||
// The native object is the top level JSON object which identifies a native response.
|
||||
type Response struct {
|
||||
// Field:
|
||||
// ver
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string
|
||||
// Default:
|
||||
// 1.1
|
||||
// Description:
|
||||
// Version of the Native Markup version in use.
|
||||
Ver string `json:"ver,omitempty"`
|
||||
|
||||
// Field:
|
||||
// assets
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// object array
|
||||
// Description:
|
||||
// List of native ad’s assets.
|
||||
Assets []Asset `json:"assets"`
|
||||
|
||||
// Field:
|
||||
// link
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// Destination Link. This is default link object for the ad.
|
||||
// Individual assets can also have a link object which applies if the asset is activated(clicked).
|
||||
// If the asset doesn’t have a link object, the parent link object applies.
|
||||
Link Link `json:"link"`
|
||||
|
||||
// Field:
|
||||
// imptrackers
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string array
|
||||
// Description:
|
||||
// Array of impression tracking URLs, expected to return a 1x1 image or 204 response - typically
|
||||
// only passed when using 3rd party trackers.
|
||||
ImpTrackers []string `json:"imptrackers,omitempty"`
|
||||
|
||||
// Field:
|
||||
// jstracker
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// Optional JavaScript impression tracker. This is a valid HTML, Javascript is already wrapped in <script> tags.
|
||||
// It should be executed at impression time where it can be supported.
|
||||
JSTracker string `json:"jstracker,omitempty"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package response_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestResponse(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Response Suite")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package response_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
|
||||
. "github.com/mxmCherry/openrtb/native/response"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/extensions/table"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Response", func() {
|
||||
DescribeTable(
|
||||
"Marshaling",
|
||||
|
||||
func(filename string, subject interface{}) {
|
||||
expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(json.Unmarshal(expected, subject)).To(Succeed())
|
||||
|
||||
actual, err := json.Marshal(subject)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(actual).To(MatchJSON(expected))
|
||||
},
|
||||
|
||||
Entry(
|
||||
"Clickout",
|
||||
"clickout.json",
|
||||
new(Response)),
|
||||
Entry(
|
||||
"Video",
|
||||
"video.json",
|
||||
new(Response)),
|
||||
)
|
||||
})
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
# testdata
|
||||
|
||||
JSON examples copied from [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [Dynamic Native Ads API
|
||||
Specification Version 1.1](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-Native-Ads-Specification-1-1_2016.pdf) spec - section 6 Bid Request/Response Samples.
|
||||
|
||||
Some empty/zero attributes were omited (not copied) because of [encoding/json](https://golang.org/pkg/encoding/json/) `omitempty` and [gomega.MatchJSON(...)](http://onsi.github.io/gomega/#matchjsonjson-interface).
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"link": {
|
||||
"url": "http: //i.am.a/URL"
|
||||
},
|
||||
"assets": [
|
||||
{
|
||||
"id": 123,
|
||||
"required": 1,
|
||||
"title": {
|
||||
"text": "Learn about this awesome thing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 124,
|
||||
"required": 1,
|
||||
"img": {
|
||||
"url": "http://www.myads.com/thumbnail1.png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 128,
|
||||
"required": 1,
|
||||
"img": {
|
||||
"url": "http://www.myads.com/largethumb1.png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"value": "My Brand"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 127,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"value": "Learn all about this awesome story of someone using my product."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"link": {
|
||||
"url": "http: //i.am.a/URL"
|
||||
},
|
||||
"assets": [
|
||||
{
|
||||
"id": 4,
|
||||
"video": {
|
||||
"vasttag": "<VAST version='2.0'></VAST>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 123,
|
||||
"required": 1,
|
||||
"title": {
|
||||
"text": "Watch this awesome thing"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 124,
|
||||
"required": 1,
|
||||
"img": {
|
||||
"url": "http://www.myads.com/thumbnail1.png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 128,
|
||||
"required": 1,
|
||||
"img": {
|
||||
"url": "http://www.myads.com/largethumb1.png"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 126,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"value": "My Brand"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 127,
|
||||
"required": 1,
|
||||
"data": {
|
||||
"value": "Watch all about this awesome story of someone using my product."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package response
|
||||
|
||||
// 5.3 Object: Title
|
||||
//
|
||||
// Corresponds to the Title Object in the request, with the value filled in.
|
||||
type Title struct {
|
||||
// Field:
|
||||
// text
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// The text associated with the text element.
|
||||
Text string `json:"text"`
|
||||
|
||||
// Field:
|
||||
// ext
|
||||
// Scope:
|
||||
// optional
|
||||
// Type:
|
||||
// object
|
||||
// Description:
|
||||
// This object is a placeholder that may contain custom JSON agreed to by the parties to support flexibility beyond the standard defined in this specification
|
||||
Ext RawJSON `json:"ext,omitempty"`
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package response
|
||||
|
||||
// 5.6 Object: Video
|
||||
//
|
||||
// Corresponds to the Video Object in the request, yet containing a value of a conforming VAST tag as a value.
|
||||
type Video struct {
|
||||
// Field:
|
||||
// vasttag
|
||||
// Scope:
|
||||
// required
|
||||
// Type:
|
||||
// string
|
||||
// Description:
|
||||
// VAST XML
|
||||
VASTTag string `json:"vasttag"`
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package openrtb_test
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOpenrtb(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Openrtb Suite")
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package openrtb_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/mxmCherry/openrtb"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/ginkgo/extensions/table"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestOpenRTB(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "OpenRTB")
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var _ = DescribeTable(
|
||||
"Marshalling",
|
||||
func(filename string, subject interface{}) {
|
||||
|
||||
expected, err := ioutil.ReadFile(filepath.Join("testdata", filename))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(json.Unmarshal(expected, subject)).To(Succeed())
|
||||
|
||||
actual, err := json.Marshal(subject)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(actual).To(MatchJSON(expected))
|
||||
},
|
||||
Entry(
|
||||
"Bid Request - Simple Banner",
|
||||
"bid-request-simple-banner.json",
|
||||
new(openrtb.BidRequest)),
|
||||
Entry(
|
||||
"Bid Request - Expandable Creative",
|
||||
"bid-request-expandable-creative.json",
|
||||
new(openrtb.BidRequest)),
|
||||
Entry(
|
||||
"Bid Request - Mobile",
|
||||
"bid-request-mobile.json",
|
||||
new(openrtb.BidRequest)),
|
||||
Entry(
|
||||
"Bid Request - Video",
|
||||
"bid-request-video.json",
|
||||
new(openrtb.BidRequest)),
|
||||
Entry(
|
||||
"Bid Request - PMP with Direct Deal",
|
||||
"bid-request-pmp-with-direct-deal.json",
|
||||
new(openrtb.BidRequest)),
|
||||
Entry(
|
||||
"Bid Request - Native Ad",
|
||||
"bid-request-native-ad.json",
|
||||
new(openrtb.BidRequest)),
|
||||
|
||||
Entry(
|
||||
"Bid Response - Ad Served on Win Notice",
|
||||
"bid-response-ad-served-on-win-notice.json",
|
||||
new(openrtb.BidResponse)),
|
||||
Entry(
|
||||
"Bid Response - VAST XML Document Returned Inline",
|
||||
"bid-response-vast-xml-document-returned-inline.json",
|
||||
new(openrtb.BidResponse)),
|
||||
Entry(
|
||||
"Bid Response - Direct Deal Ad Served on Win Notice",
|
||||
"bid-response-direct-deal-ad-served-on-win-notice.json",
|
||||
new(openrtb.BidResponse)),
|
||||
Entry(
|
||||
"Bid Response - Native Markup Returned Inline",
|
||||
"bid-response-native-markup-returned-inline.json",
|
||||
new(openrtb.BidResponse)),
|
||||
)
|
||||
@@ -8,6 +8,8 @@ import "errors"
|
||||
//
|
||||
// Basically, it's just a copy of encoding/json.RawMessage type,
|
||||
// but with more convenient non-pointer encoding.
|
||||
//
|
||||
// HEADS UP: this will be replaced with json.RawMessage when Go 1.10 is out.
|
||||
type RawJSON []byte
|
||||
|
||||
// MarshalJSON returns m as the JSON encoding of m.
|
||||
|
||||
+10
-10
@@ -3,7 +3,7 @@ package openrtb_test
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/mxmCherry/openrtb"
|
||||
. "github.com/mxmCherry/openrtb"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
|
||||
var _ = Describe("RawJSON", func() {
|
||||
|
||||
var _ json.Marshaler = (openrtb.RawJSON)(nil)
|
||||
var _ json.Unmarshaler = (*openrtb.RawJSON)(nil)
|
||||
var _ json.Marshaler = (RawJSON)(nil)
|
||||
var _ json.Unmarshaler = (*RawJSON)(nil)
|
||||
|
||||
It("should encode JSON", func() {
|
||||
subject := openrtb.RawJSON(`true`)
|
||||
subject := RawJSON(`true`)
|
||||
|
||||
actual, err := subject.MarshalJSON()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
@@ -23,30 +23,30 @@ var _ = Describe("RawJSON", func() {
|
||||
})
|
||||
|
||||
It("should decode JSON", func() {
|
||||
subject := openrtb.RawJSON(nil)
|
||||
subject := RawJSON(nil)
|
||||
|
||||
err := subject.UnmarshalJSON([]byte(`true`))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(subject).To(Equal(openrtb.RawJSON(`true`)))
|
||||
Expect(subject).To(Equal(RawJSON(`true`)))
|
||||
})
|
||||
|
||||
It("should decode JSON when embedded into struct", func() {
|
||||
wrapper := struct {
|
||||
Raw openrtb.RawJSON `json:"raw"`
|
||||
Raw RawJSON `json:"raw"`
|
||||
}{
|
||||
Raw: nil,
|
||||
}
|
||||
|
||||
err := json.Unmarshal([]byte(`{"raw":true}`), &wrapper)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(wrapper.Raw).To(Equal(openrtb.RawJSON(`true`)))
|
||||
Expect(wrapper.Raw).To(Equal(RawJSON(`true`)))
|
||||
})
|
||||
|
||||
It("should encode JSON when embedded into struct", func() {
|
||||
wrapper := struct {
|
||||
Raw openrtb.RawJSON `json:"raw"`
|
||||
Raw RawJSON `json:"raw"`
|
||||
}{
|
||||
Raw: openrtb.RawJSON(`true`),
|
||||
Raw: RawJSON(`true`),
|
||||
}
|
||||
|
||||
actual, err := json.Marshal(wrapper)
|
||||
|
||||
Vendored
+3
-3
@@ -1,5 +1,5 @@
|
||||
# Testdata
|
||||
# testdata
|
||||
|
||||
JSON examples copied from [OpenRTB](//www.iab.com/guidelines/real-time-bidding-rtb-project/) [v2.5](//www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) spec - section 6. Bid Request/Response Samples.
|
||||
JSON examples copied from [OpenRTB](https://www.iab.com/guidelines/real-time-bidding-rtb-project/) [v2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) spec - section 6. Bid Request/Response Samples.
|
||||
|
||||
Some empty/zero attributes were omited (not copied) because of [encoding/json](//golang.org/pkg/encoding/json/) `omitempty` and [gomega.MatchJSON(...)](//onsi.github.io/gomega/#matchjsonjson-interface).
|
||||
Some empty/zero attributes were omited (not copied) because of [encoding/json](https://golang.org/pkg/encoding/json/) `omitempty` and [gomega.MatchJSON(...)](http://onsi.github.io/gomega/#matchjsonjson-interface).
|
||||
|
||||
Vendored
Vendored
Reference in New Issue
Block a user