Skip to content

Commit 83a51ab

Browse files
authored
Merge pull request #22 from dolzenko/feature/native
Feature/native
2 parents cdbda12 + 8b814bf commit 83a51ab

File tree

20 files changed

+456
-1
lines changed

20 files changed

+456
-1
lines changed

impression.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ var (
1717
// selling all ad positions on a given page as a bundle. Each "imp" object has a required ID so that
1818
// bids can reference them individually. An exchange can also conduct private auctions by
1919
// restricting involvement to specific subsets of seats within bidders.
20+
// The presence of Banner, Video, and/or Native objects
21+
// subordinate to the Imp object indicates the type of impression being offered.
2022
type Impression struct {
2123
ID string `json:"id"` // A unique identifier for this impression
2224
Banner *Banner `json:"banner,omitempty"`

native.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import "encoding/json"
1010
// banner and/or video by also including as Imp subordinates the Banner and/or Video objects,
1111
// respectively. However, any given bid for the impression must conform to one of the offered types.
1212
type Native struct {
13-
Request string `json:"request"` // Request payload complying with the Native Ad Specification.
13+
Request json.RawMessage `json:"request"` // Request payload complying with the Native Ad Specification.
1414
Ver string `json:"ver,omitempty"` // Version of the Native Ad Specification to which request complies; highly recommended for efficient parsing.
1515
API []int `json:"api,omitempty"` // List of supported API frameworks for this impression.
1616
BAttr []int `json:"battr,omitempty"` // Blocked creative attributes

native/request/asset.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package request
2+
3+
import "encoding/json"
4+
5+
// The main container object for each asset requested or supported by Exchange
6+
// on behalf of the rendering client. Only one of the {title,img,video,data}
7+
// objects should be present in each object. The id is to be unique within the
8+
// AssetObject array so that the response can be aligned.
9+
type Asset struct {
10+
ID int `json:"id"` // Unique asset ID, assigned by exchange
11+
Required int `json:"required,omitempty"` // Set to 1 if asset is required
12+
Title *Title `json:"title,omitempty"` // Title object for title assets
13+
Image *Image `json:"img,omitempty"` // Image object for image assets
14+
Video *Video `json:"video,omitempty"` // Video object for video assets
15+
Data *Data `json:"data,omitempty"` // Data object for brand name, description, ratings, prices etc.
16+
Ext json.RawMessage `json:"ext,omitempty"`
17+
}

native/request/data.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package request
2+
3+
import "encoding/json"
4+
5+
type DataTypeID int
6+
7+
const (
8+
DataTypeSponsored DataTypeID = 1 // Sponsored By message where response should contain the brand name of the sponsor
9+
DataTypeDesc DataTypeID = 2 // Descriptive text associated with the product or service being advertised
10+
DataTypeRating DataTypeID = 3 // Rating of the product being offered to the user
11+
DataTypeLikes DataTypeID = 4 // Number of social ratings or “likes” of the product being offered to the user
12+
DataTypeDownloads DataTypeID = 5 // Number downloads/installs of this product
13+
DataTypePrice DataTypeID = 6 // Price for product / app / in-app purchase. Value should include currency symbol in localised format
14+
DataTypeSalePrice DataTypeID = 7 // 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
15+
DataTypePhone DataTypeID = 8 // Phone number
16+
DataTypeAddress DataTypeID = 9 // Address
17+
DataTypeDescAdditional DataTypeID = 10 // Additional descriptive text associated with the product or service being advertised
18+
DataTypeDisplayURL DataTypeID = 11 // 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)
19+
DataTypeCTADesc DataTypeID = 12 // CTA description - descriptive text describing a ‘call to action’ button for the destination URL
20+
21+
)
22+
23+
type Data struct {
24+
TypeID DataTypeID `json:"type"` // Type ID of the element supported by the publisher. The publisher can display this information in an appropriate format
25+
Length int `json:"len"` // Maximum length of the text in the element’s response
26+
Ext json.RawMessage `json:"ext,omitempty"`
27+
}

native/request/image.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package request
2+
3+
import "encoding/json"
4+
5+
type ImageTypeID int
6+
7+
const (
8+
ImageTypeIcon ImageTypeID = 1 // Icon image
9+
ImageTypeLogo ImageTypeID = 2 // Logo image for the brand/app
10+
ImageTypeMain ImageTypeID = 3 // Large image preview for the ad
11+
)
12+
13+
type Image struct {
14+
TypeID ImageTypeID `json:"type,omitempty"` // Type ID of the image element supported by the publisher
15+
16+
Width int `json:"w,omitempty"` // Width of the image in pixels
17+
WidthMin int `json:"wmin,omitempty"` // The minimum requested width of the image in pixels
18+
Height int `json:"h,omitempty"` // Height of the image in pixels
19+
HeightMin int `json:"hmin,omitempty"` // The minimum requested height of the image in pixels
20+
// Either h/w or hmin/wmin should be transmitted. If only h/w is included, it
21+
// should be considered an exact requirement
22+
Mimes []string `json:"mimes,omitempty"` // Whitelist of content MIME types supported
23+
Ext json.RawMessage `json:"ext,omitempty"`
24+
}

native/request/request.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package request
2+
3+
import "encoding/json"
4+
5+
type LayoutID int
6+
7+
const (
8+
LayoutContentWall LayoutID = 1
9+
LayoutAppWall LayoutID = 2
10+
LayoutNewsFeed LayoutID = 3
11+
LayoutChatList LayoutID = 4
12+
LayoutCarousel LayoutID = 5
13+
LayoutContentStream LayoutID = 6
14+
LayoutGridAdjoiningContent LayoutID = 7
15+
)
16+
17+
type AdUnitID int
18+
19+
const (
20+
AdUnitPaidSearch AdUnitID = 1
21+
AdUnitRecommendationWidget AdUnitID = 2
22+
AdUnitPromotedListings AdUnitID = 3
23+
AdUnitInAdWithNativeElement AdUnitID = 4
24+
AdUnitCustom AdUnitID = 5
25+
)
26+
27+
type ContextTypeID int
28+
29+
const (
30+
ContextTypeContent ContextTypeID = 1 // newsfeed, article, image gallery, video gallery
31+
ContextTypeSocial ContextTypeID = 2 // social network feed, email, chat
32+
ContextTypeProduct ContextTypeID = 3 // product listings, details, recommendations, reviews
33+
)
34+
35+
type ContextSubTypeID int
36+
37+
const (
38+
ContextSubTypeGeneral ContextSubTypeID = 10
39+
ContextSubTypeArticle ContextSubTypeID = 11
40+
ContextSubTypeVideo ContextSubTypeID = 12
41+
ContextSubTypeAudio ContextSubTypeID = 13
42+
ContextSubTypeImage ContextSubTypeID = 14
43+
ContextSubTypeUserGenerated ContextSubTypeID = 15
44+
ContextSubTypeSocial ContextSubTypeID = 20
45+
ContextSubTypeEmail ContextSubTypeID = 21
46+
ContextSubTypeChat ContextSubTypeID = 22
47+
ContextSubTypeSelling ContextSubTypeID = 30
48+
ContextSubTypeAppStore ContextSubTypeID = 31
49+
ContextSubTypeProductReviews ContextSubTypeID = 32
50+
)
51+
52+
type PlacementTypeID int
53+
54+
const (
55+
PlacementTypeInFeed PlacementTypeID = 1 // In the feed of content - for example as an item inside the organic feed/grid/listing/carousel
56+
PlacementTypeAtomic PlacementTypeID = 2 // In the atomic unit of the content - IE in the article page or single image page
57+
PlacementTypeOutside PlacementTypeID = 3 // Outside the core content - for example in the ads section on the right rail, as a banner-style placement near the content, etc.
58+
PlacementTypeRecommendation PlacementTypeID = 4 // Recommendation widget, most commonly presented below the article content
59+
)
60+
61+
// This object represents a native type impression. Native ad units are intended to blend seamlessly into
62+
// the surrounding content (e.g., a sponsored Twitter or Facebook post). As such, the response must be
63+
// well-structured to afford the publisher fine-grained control over rendering.
64+
// The presence of a Native as a subordinate of the Imp object indicates that this impression is offered as
65+
// a native type impression. At the publisher’s discretion, that same impression may also be offered as
66+
// banner and/or video by also including as Imp subordinates the Banner and/or Video objects,
67+
// respectively. However, any given bid for the impression must conform to one of the offered types.
68+
type Request struct {
69+
Ver string `json:"ver,omitempty"` // Version of the Native Markup
70+
LayoutID LayoutID `json:"layout,omitempty"` // DEPRECATED The Layout ID of the native ad
71+
AdUnitID AdUnitID `json:"adunit,omitempty"` // DEPRECATED The Ad unit ID of the native ad
72+
ContextTypeID ContextTypeID `json:"context,omitempty"` // The context in which the ad appears
73+
ContextSubTypeID ContextSubTypeID `json:"contextsubtype,omitempty"` // A more detailed context in which the ad appears
74+
PlacementTypeID PlacementTypeID `json:"plcmttype,omitempty"` // The design/format/layout of the ad unit being offered
75+
PlacementCount int `json:"plcmtcnt,omitempty"` // The number of identical placements in this Layout
76+
Sequence int `json:"seq,omitempty"` // 0 for the first ad, 1 for the second ad, and so on
77+
Assets []Asset `json:"assets"` // An array of Asset Objects
78+
Ext json.RawMessage `json:"ext,omitempty"`
79+
}

native/request/request_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package request
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
"testing"
7+
8+
. "github.com/onsi/ginkgo"
9+
. "github.com/onsi/gomega"
10+
)
11+
12+
var _ = Describe("Request", func() {
13+
It("should parse correctly", func() {
14+
req := fixture("testdata/request1.json")
15+
Expect(req).To(Equal(&Request{
16+
Ver: "1.1",
17+
ContextTypeID: ContextTypeSocial,
18+
ContextSubTypeID: ContextSubTypeSocial,
19+
PlacementTypeID: PlacementTypeID(11),
20+
PlacementCount: 1,
21+
Sequence: 2,
22+
Assets: []Asset{
23+
{ID: 123, Required: 1, Title: &Title{Length: 140}},
24+
{ID: 128, Image: &Image{TypeID: ImageTypeMain, WidthMin: 836, HeightMin: 627, Width: 1000, Height: 800, Mimes: []string{"image/jpg"}}},
25+
{ID: 126, Required: 1, Data: &Data{TypeID: DataTypeSponsored, Length: 25}},
26+
{ID: 127, Required: 1, Data: &Data{TypeID: DataTypeDesc, Length: 140}},
27+
{ID: 4, Video: &Video{MinDuration: 15, MaxDuration: 30, Protocols: []int{2, 3}, Mimes: []string{"video/mp4"}}},
28+
},
29+
}))
30+
})
31+
})
32+
33+
func TestSuite(t *testing.T) {
34+
RegisterFailHandler(Fail)
35+
RunSpecs(t, "openrtb/native/request")
36+
}
37+
38+
func fixture(path string) *Request {
39+
var subject Request
40+
enc, err := ioutil.ReadFile(path)
41+
Expect(err).ToNot(HaveOccurred())
42+
Expect(json.Unmarshal(enc, &subject)).To(Succeed())
43+
return &subject
44+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"ver": "1.1",
3+
"context": 2,
4+
"contextsubtype": 20,
5+
"plcmttype": 11,
6+
"plcmtcnt": 1,
7+
"seq": 2,
8+
"assets": [
9+
{
10+
"id": 123,
11+
"required": 1,
12+
"title": {
13+
"len": 140
14+
}
15+
},
16+
{
17+
"id": 128,
18+
"required": 0,
19+
"img": {
20+
"w": 1000,
21+
"h": 800,
22+
"mimes": ["image/jpg"],
23+
"wmin": 836,
24+
"hmin": 627,
25+
"type": 3
26+
}
27+
},
28+
{
29+
"id": 126,
30+
"required": 1,
31+
"data": {
32+
"type": 1,
33+
"len": 25
34+
}
35+
},
36+
{
37+
"id": 127,
38+
"required": 1,
39+
"data": {
40+
"type": 2,
41+
"len": 140
42+
}
43+
},
44+
{
45+
"id": 4,
46+
"video": {
47+
"linearity": 1,
48+
"minduration": 15,
49+
"maxduration": 30,
50+
"protocols": [2, 3],
51+
"mimes": ["video/mp4"]
52+
}
53+
}
54+
]
55+
}

native/request/title.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package request
2+
3+
import "encoding/json"
4+
5+
type Title struct {
6+
Length int `json:"len"` // Maximum length of the text in the title element
7+
Ext json.RawMessage `json:"ext,omitempty"`
8+
}

native/request/video.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package request
2+
3+
import "encoding/json"
4+
5+
// TODO unclear if its the same as imp.video https://github.com/openrtb/OpenRTB/issues/26
6+
type Video struct {
7+
Mimes []string `json:"mimes,omitempty"` // Whitelist of content MIME types supported
8+
MinDuration int `json:"minduration,omitempty"` // Minimum video ad duration in seconds
9+
MaxDuration int `json:"maxduration,omitempty"` // Maximum video ad duration in seconds
10+
Protocols []int `json:"protocols,omitempty"` // Video bid response protocols
11+
Ext json.RawMessage `json:"ext,omitempty"`
12+
}

0 commit comments

Comments
 (0)