Skip to content

Commit 9c96622

Browse files
committed
Better fix for bad exchanges
1 parent 491cb5c commit 9c96622

File tree

6 files changed

+158
-56
lines changed

6 files changed

+158
-56
lines changed

bid.go

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,33 @@ var (
1616
// Cid can be used to block ads that were previously identified as inappropriate.
1717
// Substitution macros may allow a bidder to use a static notice URL for all of its bids.
1818
type Bid struct {
19-
ID string `json:"id"`
20-
ImpID string `json:"impid"` // Required string ID of the impression object to which this bid applies.
21-
Price float64 `json:"price"` // Bid price in CPM. Suggests using integer math for accounting to avoid rounding errors.
22-
AdID string `json:"adid,omitempty"` // References the ad to be served if the bid wins.
23-
NURL string `json:"nurl,omitempty"` // Win notice URL.
24-
BURL string `json:"burl,omitempty"` // Billing notice URL.
25-
LURL string `json:"lurl,omitempty"` // Loss notice URL.
26-
AdMarkup string `json:"adm,omitempty"` // Actual ad markup. XHTML if a response to a banner object, or VAST XML if a response to a video object.
27-
AdvDomain []string `json:"adomain,omitempty"` // Advertiser’s primary or top-level domain for advertiser checking; or multiple if imp rotating.
28-
Bundle string `json:"bundle,omitempty"` // A platform-specific application identifier intended to be unique to the app and independent of the exchange.
29-
IURL string `json:"iurl,omitempty"` // Sample image URL.
30-
CampaignID string `json:"cid,omitempty"` // Campaign ID that appears with the Ad markup.
31-
CreativeID string `json:"crid,omitempty"` // Creative ID for reporting content issues or defects. This could also be used as a reference to a creative ID that is posted with an exchange.
32-
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.
33-
Cat []string `json:"cat,omitempty"` // IAB content categories of the creative. Refer to List 5.1
34-
Attr []int `json:"attr,omitempty"` // Array of creative attributes.
35-
API int `json:"api,omitempty"` // API required by the markup if applicable
36-
Protocol int `json:"protocol,omitempty"` // Video response protocol of the markup if applicable
37-
QAGMediaRating int `json:"qagmediarating,omitempty"` // Creative media rating per IQG guidelines.
38-
Language string `json:"language,omitempty"` // Language of the creative using ISO-639-1-alpha-2.
39-
DealID string `json:"dealid,omitempty"` // DealID extension of private marketplace deals
40-
H int `json:"h,omitempty"` // Height of the ad in pixels.
41-
W int `json:"w,omitempty"` // Width of the ad in pixels.
42-
WRatio int `json:"wratio,omitempty"` // Relative width of the creative when expressing size as a ratio.
43-
HRatio int `json:"hratio,omitempty"` // Relative height of the creative when expressing size as a ratio.
44-
Exp int `json:"exp,omitempty"` // Advisory as to the number of seconds the bidder is willing to wait between the auction and the actual impression.
45-
Ext Extension `json:"ext,omitempty"`
19+
ID string `json:"id"`
20+
ImpID string `json:"impid"` // Required string ID of the impression object to which this bid applies.
21+
Price float64 `json:"price"` // Bid price in CPM. Suggests using integer math for accounting to avoid rounding errors.
22+
AdID string `json:"adid,omitempty"` // References the ad to be served if the bid wins.
23+
NURL string `json:"nurl,omitempty"` // Win notice URL.
24+
BURL string `json:"burl,omitempty"` // Billing notice URL.
25+
LURL string `json:"lurl,omitempty"` // Loss notice URL.
26+
AdMarkup string `json:"adm,omitempty"` // Actual ad markup. XHTML if a response to a banner object, or VAST XML if a response to a video object.
27+
AdvDomain []string `json:"adomain,omitempty"` // Advertiser’s primary or top-level domain for advertiser checking; or multiple if imp rotating.
28+
Bundle string `json:"bundle,omitempty"` // A platform-specific application identifier intended to be unique to the app and independent of the exchange.
29+
IURL string `json:"iurl,omitempty"` // Sample image URL.
30+
CampaignID StringOrNumber `json:"cid,omitempty"` // Campaign ID that appears with the Ad markup.
31+
CreativeID string `json:"crid,omitempty"` // Creative ID for reporting content issues or defects. This could also be used as a reference to a creative ID that is posted with an exchange.
32+
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.
33+
Cat []string `json:"cat,omitempty"` // IAB content categories of the creative. Refer to List 5.1
34+
Attr []int `json:"attr,omitempty"` // Array of creative attributes.
35+
API int `json:"api,omitempty"` // API required by the markup if applicable
36+
Protocol int `json:"protocol,omitempty"` // Video response protocol of the markup if applicable
37+
QAGMediaRating int `json:"qagmediarating,omitempty"` // Creative media rating per IQG guidelines.
38+
Language string `json:"language,omitempty"` // Language of the creative using ISO-639-1-alpha-2.
39+
DealID string `json:"dealid,omitempty"` // DealID extension of private marketplace deals
40+
H int `json:"h,omitempty"` // Height of the ad in pixels.
41+
W int `json:"w,omitempty"` // Width of the ad in pixels.
42+
WRatio int `json:"wratio,omitempty"` // Relative width of the creative when expressing size as a ratio.
43+
HRatio int `json:"hratio,omitempty"` // Relative height of the creative when expressing size as a ratio.
44+
Exp int `json:"exp,omitempty"` // Advisory as to the number of seconds the bidder is willing to wait between the auction and the actual impression.
45+
Ext Extension `json:"ext,omitempty"`
4646
}
4747

4848
// Validate required attributes

bidrequest_test.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package openrtb
22

33
import (
4-
"encoding/json"
5-
64
. "github.com/onsi/ginkgo"
75
. "github.com/onsi/gomega"
86
)
@@ -30,7 +28,7 @@ var _ = Describe("BidRequest", func() {
3028
Imp: []Impression{
3129
{
3230
ID: "1",
33-
Secure: json.Number("1"),
31+
Secure: 1,
3432
Banner: &Banner{W: 300, H: 250, Pos: AdPosAboveFold, BAttr: []int{CreativeAttributeUserInitiated}},
3533
},
3634
},

impression.go

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package openrtb
22

3-
import (
4-
"encoding/json"
5-
"errors"
6-
)
3+
import "errors"
74

85
// Validation errors
96
var (
@@ -19,22 +16,22 @@ var (
1916
// The presence of Banner, Video, and/or Native objects
2017
// subordinate to the Imp object indicates the type of impression being offered.
2118
type Impression struct {
22-
ID string `json:"id"` // A unique identifier for this impression
23-
Banner *Banner `json:"banner,omitempty"`
24-
Video *Video `json:"video,omitempty"`
25-
Audio *Audio `json:"audio,omitempty"`
26-
Native *Native `json:"native,omitempty"`
27-
Pmp *Pmp `json:"pmp,omitempty"` // A reference to the PMP object containing any Deals eligible for the impression object.
28-
DisplayManager string `json:"displaymanager,omitempty"` // Name of ad mediation partner, SDK technology, etc
29-
DisplayManagerVer string `json:"displaymanagerver,omitempty"` // Version of the above
30-
Instl int `json:"instl,omitempty"` // Interstitial, Default: 0 ("1": Interstitial, "0": Something else)
31-
TagID string `json:"tagid,omitempty"` // IDentifier for specific ad placement or ad tag
32-
BidFloor float64 `json:"bidfloor,omitempty"` // Bid floor for this impression in CPM
33-
BidFloorCurrency string `json:"bidfloorcur,omitempty"` // Currency of bid floor
34-
Secure json.Number `json:"secure,omitempty"` // Flag to indicate whether the impression requires secure HTTPS URL creative assets and markup.
35-
Exp int `json:"exp,omitempty"` // Advisory as to the number of seconds that may elapse between the auction and the actual impression.
36-
IFrameBuster []string `json:"iframebuster,omitempty"` // Array of names for supportediframe busters.
37-
Ext Extension `json:"ext,omitempty"`
19+
ID string `json:"id"` // A unique identifier for this impression
20+
Banner *Banner `json:"banner,omitempty"`
21+
Video *Video `json:"video,omitempty"`
22+
Audio *Audio `json:"audio,omitempty"`
23+
Native *Native `json:"native,omitempty"`
24+
Pmp *Pmp `json:"pmp,omitempty"` // A reference to the PMP object containing any Deals eligible for the impression object.
25+
DisplayManager string `json:"displaymanager,omitempty"` // Name of ad mediation partner, SDK technology, etc
26+
DisplayManagerVer string `json:"displaymanagerver,omitempty"` // Version of the above
27+
Instl int `json:"instl,omitempty"` // Interstitial, Default: 0 ("1": Interstitial, "0": Something else)
28+
TagID string `json:"tagid,omitempty"` // IDentifier for specific ad placement or ad tag
29+
BidFloor float64 `json:"bidfloor,omitempty"` // Bid floor for this impression in CPM
30+
BidFloorCurrency string `json:"bidfloorcur,omitempty"` // Currency of bid floor
31+
Secure NumberOrString `json:"secure,omitempty"` // Flag to indicate whether the impression requires secure HTTPS URL creative assets and markup.
32+
Exp int `json:"exp,omitempty"` // Advisory as to the number of seconds that may elapse between the auction and the actual impression.
33+
IFrameBuster []string `json:"iframebuster,omitempty"` // Array of names for supportediframe busters.
34+
Ext Extension `json:"ext,omitempty"`
3835
}
3936

4037
func (imp *Impression) assetCount() int {

native/response/response.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import "github.com/bsm/openrtb"
44

55
// The native object is the top level JSON object which identifies a native response
66
type Response struct {
7-
Ver string `json:"ver,omitempty"` // Version of the Native Markup
8-
Assets []Asset `json:"assets"` // An array of Asset Objects
9-
Link Link `json:"link"` // Destination Link. This is default link object for the ad
10-
ImpTrackers []string `json:"imptrackers,omitempty"` // Array of impression tracking URLs, expected to return a 1x1 image or 204 response
11-
JSTracker string `json:"jstracker,omitempty"` // 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
12-
Ext openrtb.Extension `json:"ext,omitempty"`
7+
Ver openrtb.StringOrNumber `json:"ver,omitempty"` // Version of the Native Markup
8+
Assets []Asset `json:"assets"` // An array of Asset Objects
9+
Link Link `json:"link"` // Destination Link. This is default link object for the ad
10+
ImpTrackers []string `json:"imptrackers,omitempty"` // Array of impression tracking URLs, expected to return a 1x1 image or 204 response
11+
JSTracker string `json:"jstracker,omitempty"` // 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
12+
Ext openrtb.Extension `json:"ext,omitempty"`
1313
}

numbers.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package openrtb
2+
3+
import (
4+
"encoding/json"
5+
"strconv"
6+
)
7+
8+
// NumberOrString attempts to fix OpenRTB incompatibilities
9+
// of exchanges. On decoding, it can handle numbers and strings.
10+
// On encoding, it will generate a number, as intended by the
11+
// standard.
12+
type NumberOrString int
13+
14+
// UnmarshalJSON implements json.Unmarshaler
15+
func (n *NumberOrString) UnmarshalJSON(data []byte) (err error) {
16+
var v int
17+
18+
if len(data) > 2 && data[0] == '"' && data[len(data)-1] == '"' {
19+
err = json.Unmarshal(data[1:len(data)-1], &v)
20+
} else {
21+
err = json.Unmarshal(data, &v)
22+
}
23+
if err != nil {
24+
return err
25+
}
26+
27+
*n = NumberOrString(v)
28+
return nil
29+
}
30+
31+
// StringOrNumber attempts to fix OpenRTB incompatibilities
32+
// of exchanges. On decoding, it can handle numbers and strings.
33+
// On encoding, it will generate a string, as intended by the
34+
// standard.
35+
type StringOrNumber string
36+
37+
// UnmarshalJSON implements json.Unmarshaler
38+
func (n *StringOrNumber) UnmarshalJSON(data []byte) error {
39+
if len(data) > 2 && data[0] == '"' && data[len(data)-1] == '"' {
40+
var v string
41+
if err := json.Unmarshal(data, &v); err != nil {
42+
return err
43+
}
44+
*n = StringOrNumber(v)
45+
} else {
46+
var v int
47+
if err := json.Unmarshal(data, &v); err != nil {
48+
return err
49+
}
50+
*n = StringOrNumber(strconv.Itoa(v))
51+
}
52+
return nil
53+
}

numbers_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package openrtb
2+
3+
import (
4+
"encoding/json"
5+
6+
. "github.com/onsi/ginkgo"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
var _ = Describe("NumberOrString", func() {
11+
12+
It("should decode numbers", func() {
13+
var n NumberOrString
14+
Expect(json.Unmarshal([]byte(`33`), &n)).To(Succeed())
15+
Expect(n).To(Equal(NumberOrString(33)))
16+
})
17+
18+
It("should decode strings", func() {
19+
var n NumberOrString
20+
Expect(json.Unmarshal([]byte(`"33"`), &n)).To(Succeed())
21+
Expect(n).To(Equal(NumberOrString(33)))
22+
})
23+
24+
It("should encode to numbers", func() {
25+
var n NumberOrString = 33
26+
bin, err := json.Marshal(n)
27+
Expect(err).NotTo(HaveOccurred())
28+
Expect(string(bin)).To(Equal(`33`))
29+
})
30+
31+
})
32+
33+
var _ = Describe("StringOrNumber", func() {
34+
35+
It("should decode numbers", func() {
36+
var n StringOrNumber
37+
Expect(json.Unmarshal([]byte(`33`), &n)).To(Succeed())
38+
Expect(n).To(Equal(StringOrNumber("33")))
39+
})
40+
41+
It("should decode strings", func() {
42+
var n StringOrNumber
43+
Expect(json.Unmarshal([]byte(`"33"`), &n)).To(Succeed())
44+
Expect(n).To(Equal(StringOrNumber("33")))
45+
})
46+
47+
It("should encode to strings", func() {
48+
var n StringOrNumber = "33"
49+
bin, err := json.Marshal(n)
50+
Expect(err).NotTo(HaveOccurred())
51+
Expect(string(bin)).To(Equal(`"33"`))
52+
})
53+
54+
})

0 commit comments

Comments
 (0)