Skip to content

Commit 20b516b

Browse files
committed
Merge pull request #6 from applift/2_3
Add Native support from OpenRTB 2.3 specifications
2 parents 20dca94 + 6732010 commit 20b516b

File tree

11 files changed

+552
-4
lines changed

11 files changed

+552
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Go OpenRTB 2.2
1+
# Go OpenRTB 2.3
22

33
[![Build Status](https://travis-ci.org/bsm/openrtb.svg?branch=master)](https://travis-ci.org/bsm/openrtb)
44

asset.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package openrtb
2+
3+
// TODO: Add description, use cases and other details
4+
type Asset struct {
5+
Id *int `json:"id"` // Unique asset ID, assigned by exchange
6+
Required *int `json:"required,omitempty"` // Set to 1 if asset is required
7+
Title *Title `json:"title,omitempty"` // Title object for title assets
8+
Img *Image `json:"img,omitempty"` // Image object for image assets
9+
Video *NativeVideo `json:"video,omitempty"` // Video object for video assets
10+
Data *NativeData `json:"data,omitempty"` // Data object for ratings, price, etc.
11+
Ext Extensions `json:"ext,omitempty"`
12+
}
13+
14+
type Title struct {
15+
Len *int `json:"len"` // Maximum length of the text in the title element
16+
Ext Extensions `json:"ext,omitempty"`
17+
}
18+
19+
type Image struct {
20+
Type *int `json:"type,omitempty"` // Type ID of the image element supported by the publisher
21+
W *int `json:"w,omitempty"` // Width
22+
H *int `json:"h,omitempty"` // Height
23+
Wmax *int `json:"wmax,omitempty"` // Width maximum
24+
Hmax *int `json:"hmax,omitempty"` // Height maximum
25+
Wmin *int `json:"wmin,omitempty"` // Width minimum
26+
Hmin *int `json:"hmin,omitempty"` // Height minimum
27+
Mimes []string `json:"mimes,omitempty"` // Whitelist of content MIME types supported
28+
Ext Extensions `json:"ext,omitempty"`
29+
}
30+
31+
type NativeData struct {
32+
Type *int `json:"type"` // Type ID of the image element supported by the publisher
33+
Len *int `json:"len,omitempty"` // Maximum length of the text in the element’s response
34+
Ext Extensions `json:"ext,omitempty"`
35+
}
36+
37+
// Applies defaults
38+
func (a *Asset) WithDefaults() *Asset {
39+
if a.Required == nil {
40+
a.Required = new(int)
41+
*a.Required = 0
42+
}
43+
return a
44+
}

asset_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package openrtb
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/gomega"
6+
)
7+
8+
var _ = Describe("Asset", func() {
9+
var subject *Asset
10+
11+
BeforeEach(func() {
12+
subject = new(Asset)
13+
})
14+
15+
It("should have defaults", func() {
16+
subject.WithDefaults()
17+
Expect(*subject.Required).To(Equal(0))
18+
})
19+
})

fixtures_test.go

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
package openrtb
22

3+
var sptr = func(s string) *string { return &s }
4+
var iptr = func(i int) *int { return &i }
5+
36
var testFixtures = struct {
4-
simpleBanner []byte
5-
expandableCreative []byte
6-
simpleResponse []byte
7+
simpleBanner []byte
8+
expandableCreative []byte
9+
simpleResponse []byte
10+
simpleNativeResponse []byte
11+
simpleLink Link
12+
simpleImg ResponseImg
13+
simpleTitle ResponseTitle
14+
simpleData ResponseData
15+
installData ResponseData
16+
fullLink Link
717
}{
818
simpleBanner: []byte(`
919
{
@@ -160,4 +170,63 @@ var testFixtures = struct {
160170
"cur": "USD"
161171
}
162172
`),
173+
simpleNativeResponse: []byte(`
174+
{
175+
"native": {
176+
"ver": "1",
177+
"link": {
178+
"url": "deeplink://deeplink/url/into/app",
179+
"fallback": "http: //i.am.a/URL",
180+
"clicktrackers": [
181+
"http: //a.com/a",
182+
"http: //b.com/b"
183+
]
184+
},
185+
"imptrackers": [
186+
"http: //a.com/a",
187+
"http: //b.com/b"
188+
],
189+
"assets": [
190+
{
191+
"id": 1,
192+
"title": {
193+
"text": "InstallBOA"
194+
},
195+
"link": {
196+
"url": "http: //i.am.a/URL"
197+
}
198+
},
199+
{
200+
"id": 2,
201+
"data": {
202+
"value": "5"
203+
}
204+
},
205+
{
206+
"id": 3,
207+
"img": {
208+
"url": "http: //cdn.mobad.com/ad.png",
209+
"w": 64,
210+
"h": 64
211+
}
212+
},
213+
{
214+
"id": 4,
215+
"data": {
216+
"value": "Install"
217+
},
218+
"link": {
219+
"url": "http: //i.am.a/URL"
220+
}
221+
}
222+
]
223+
}
224+
}
225+
`),
226+
simpleLink: Link{Url: sptr("http: //i.am.a/URL")},
227+
simpleImg: ResponseImg{Url: sptr("http: //cdn.mobad.com/ad.png"), W: iptr(64), H: iptr(64)},
228+
simpleTitle: ResponseTitle{Text: sptr("InstallBOA")},
229+
simpleData: ResponseData{Value: sptr("5")},
230+
installData: ResponseData{Value: sptr("Install")},
231+
fullLink: Link{Url: sptr("deeplink://deeplink/url/into/app"), Clicktrackers: []string{"http: //a.com/a", "http: //b.com/b"}, Fallback: sptr("http: //i.am.a/URL")},
163232
}

impression.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type Impression struct {
1313
Id *string `json:"id"` // A unique identifier for this impression
1414
Banner *Banner `json:"banner,omitempty"`
1515
Video *Video `json:"video,omitempty"`
16+
Native *Native `json:"native,omitempty"`
1617
Displaymanager *string `json:"displaymanager,omitempty"` // Name of ad mediation partner, SDK technology, etc
1718
Displaymanagerver *string `json:"displaymanagerver,omitempty"` // Version of the above
1819
Instl *int `json:"instl,omitempty"` // Interstitial, Default: 0 ("1": Interstitial, "0": Something else)

native.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package openrtb
2+
3+
// TODO: Add description, use cases and other details
4+
type Native struct {
5+
Ver *string `json:"ver,omitempty"` // Version of the Native Markup version in use
6+
Layout *int `json:"layout,omitempty"` // Layout ID of the native ad unit
7+
Adunit *int `json:"adunit,omitempty"` // Ad unit ID of the native ad unit
8+
Plcmtcnt *int `json:"plcmtcnt,omitempty"` // Number of identical placements in this Layout
9+
Seq *int `json:"seq,omitempty"` // This is not the sequence number of the content in the stream
10+
Assets []Asset `json:"assets"` // Array of Asset Objects
11+
Ext Extensions `json:"ext,omitempty"`
12+
}
13+
14+
// Applies defaults
15+
func (n *Native) WithDefaults() *Native {
16+
if n.Ver == nil {
17+
n.Ver = new(string)
18+
*n.Ver = "1"
19+
}
20+
if n.Plcmtcnt == nil {
21+
n.Plcmtcnt = new(int)
22+
*n.Plcmtcnt = 1
23+
}
24+
if n.Seq == nil {
25+
n.Seq = new(int)
26+
*n.Seq = 0
27+
}
28+
return n
29+
}

native_response.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package openrtb
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
)
7+
8+
type NativeAdm struct {
9+
Native *NativeResponse
10+
}
11+
12+
type NativeResponse struct {
13+
Ver *string `json:"ver,omitempty"` // Version of the Native Markup version in use
14+
Assets []ResponseAsset `json:"assets"` // Array of Asset Objects
15+
Link *Link `json:"link"`
16+
Imptrackers []string `json:"imptrackers,omitempty"`
17+
Jstracker *string `json:"jstracker, omitempty"`
18+
Ext Extensions `json:"ext,omitempty"`
19+
}
20+
21+
type ResponseAsset struct {
22+
Id *int `json:"id"` // Unique asset ID, assigned by exchange
23+
Required *int `json:"required,omitempty"` // Set to 1 if asset is required
24+
Title *ResponseTitle `json:"title,omitempty"` // Title object for title assets
25+
Img *ResponseImg `json:"img,omitempty"` // Image object for image assets
26+
Video *ResponseVideo `json:"video,omitempty"` // Video object for video assets
27+
Data *ResponseData `json:"data,omitempty"` // Data object for ratings, price, etc.
28+
Link *Link `json:"link"`
29+
Ext Extensions `json:"ext,omitempty"`
30+
}
31+
32+
type Link struct {
33+
Url *string `json:"url"`
34+
Clicktrackers []string `json:"clicktrackers,omitempty"`
35+
Fallback *string `json:"fallback,omitempty"`
36+
Ext Extensions `json:"ext,omitempty"`
37+
}
38+
39+
type ResponseTitle struct {
40+
Text *string `json:"text"`
41+
Ext Extensions `json:"ext,omitempty"`
42+
}
43+
44+
type ResponseImg struct {
45+
Url *string `json:"url"`
46+
W *int `json:"w,omitempty"` // Width
47+
H *int `json:"h,omitempty"` // Height
48+
Ext Extensions `json:"ext,omitempty"`
49+
}
50+
51+
type ResponseData struct {
52+
Label *string `json:"label,omitempty"`
53+
Value *string `json:"value"`
54+
Ext Extensions `json:"ext,omitempty"`
55+
}
56+
57+
type ResponseVideo struct {
58+
Vasttag *string `json:"vasttag"`
59+
}
60+
61+
// Set the Asset
62+
func (nativeResponse *NativeResponse) SetAssets(a *ResponseAsset) *NativeResponse {
63+
nativeResponse.Assets = append(nativeResponse.Assets, *a)
64+
return nativeResponse
65+
}
66+
67+
//Parses an OpenRTB Native Response from an io.Reader
68+
func ParseNativeAdm(reader io.Reader) (adm *NativeAdm, err error) {
69+
dec := json.NewDecoder(reader)
70+
if err = dec.Decode(&adm); err != nil {
71+
return nil, err
72+
}
73+
adm.Native = adm.Native.WithDefaults()
74+
return adm, nil
75+
}
76+
77+
//Parses an OpenRTB Native Response from bytes
78+
func ParseNativeAdmBytes(data []byte) (adm *NativeAdm, err error) {
79+
if err = json.Unmarshal(data, &adm); err != nil {
80+
return nil, err
81+
}
82+
adm.Native = adm.Native.WithDefaults()
83+
return adm, nil
84+
}
85+
86+
// Applies NativeResponse defaults
87+
func (resp *NativeResponse) WithDefaults() *NativeResponse {
88+
if resp.Ver == nil {
89+
resp.Ver = new(string)
90+
*resp.Ver = "1"
91+
}
92+
for id, asset := range resp.Assets {
93+
resp.Assets[id] = *asset.WithDefaults()
94+
}
95+
return resp
96+
}
97+
98+
// Applies ResponseAsset defaults
99+
func (asset *ResponseAsset) WithDefaults() *ResponseAsset {
100+
if asset.Required == nil {
101+
asset.Required = new(int)
102+
*asset.Required = 0
103+
}
104+
return asset
105+
}

native_response_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package openrtb
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/gomega"
6+
)
7+
8+
var _ = Describe("NativeResponse", func() {
9+
var sptr = func(s string) *string { return &s }
10+
var iptr = func(i int) *int { return &i }
11+
12+
var subject *NativeResponse
13+
14+
BeforeEach(func() {
15+
subject = new(NativeResponse)
16+
})
17+
18+
It("should have defaults", func() {
19+
subject.SetAssets(&ResponseAsset{})
20+
subject.WithDefaults()
21+
22+
Expect(*subject.Ver).To(Equal("1"))
23+
Expect(*subject.Assets[0].Required).To(Equal(0))
24+
})
25+
26+
It("should parse native adm", func() {
27+
resp, err := ParseNativeAdmBytes(testFixtures.simpleNativeResponse)
28+
29+
Expect(err).NotTo(HaveOccurred())
30+
nativeAdm := NativeAdm{
31+
&NativeResponse{
32+
Ver: sptr("1"),
33+
Assets: []ResponseAsset{
34+
ResponseAsset{
35+
Id: iptr(1),
36+
Required: iptr(0),
37+
Title: &testFixtures.simpleTitle,
38+
Link: &testFixtures.simpleLink,
39+
},
40+
ResponseAsset{
41+
Id: iptr(2),
42+
Required: iptr(0),
43+
Data: &testFixtures.simpleData,
44+
},
45+
ResponseAsset{
46+
Id: iptr(3),
47+
Required: iptr(0),
48+
Img: &testFixtures.simpleImg,
49+
},
50+
ResponseAsset{
51+
Id: iptr(4),
52+
Required: iptr(0),
53+
Data: &testFixtures.installData,
54+
Link: &testFixtures.simpleLink,
55+
},
56+
},
57+
Link: &testFixtures.fullLink,
58+
Imptrackers: []string{"http: //a.com/a", "http: //b.com/b"},
59+
},
60+
}
61+
62+
Expect(resp).To(Equal(&nativeAdm))
63+
})
64+
})

native_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package openrtb
2+
3+
import (
4+
. "github.com/onsi/ginkgo"
5+
. "github.com/onsi/gomega"
6+
)
7+
8+
var _ = Describe("Native", func() {
9+
var subject *Native
10+
11+
BeforeEach(func() {
12+
subject = new(Native)
13+
})
14+
15+
It("should have defaults", func() {
16+
subject.WithDefaults()
17+
Expect(*subject.Ver).To(Equal("1"))
18+
Expect(*subject.Plcmtcnt).To(Equal(1))
19+
Expect(*subject.Seq).To(Equal(0))
20+
})
21+
})

0 commit comments

Comments
 (0)