Skip to content
This repository was archived by the owner on Dec 22, 2022. It is now read-only.

Commit e1134e2

Browse files
vladi-mmgSyntaxNode
authored andcommitted
Marsmedia - add new bidder (prebid#1118)
1 parent 8dd39cd commit e1134e2

File tree

22 files changed

+696
-1
lines changed

22 files changed

+696
-1
lines changed

adapters/marsmedia/marsmedia.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package marsmedia
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"strconv"
8+
9+
"github.com/mxmCherry/openrtb"
10+
"github.com/prebid/prebid-server/adapters"
11+
"github.com/prebid/prebid-server/errortypes"
12+
"github.com/prebid/prebid-server/openrtb_ext"
13+
)
14+
15+
type MarsmediaAdapter struct {
16+
URI string
17+
}
18+
19+
func (a *MarsmediaAdapter) MakeRequests(requestIn *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
20+
21+
request := *requestIn
22+
23+
if len(request.Imp) == 0 {
24+
return nil, []error{&errortypes.BadInput{
25+
Message: "No impression in the bid request",
26+
}}
27+
}
28+
29+
var bidderExt adapters.ExtImpBidder
30+
if err := json.Unmarshal(request.Imp[0].Ext, &bidderExt); err != nil {
31+
return nil, []error{&errortypes.BadInput{
32+
Message: "ext.bidder not provided",
33+
}}
34+
}
35+
36+
var marsmediaExt openrtb_ext.ExtImpMarsmedia
37+
if err := json.Unmarshal(bidderExt.Bidder, &marsmediaExt); err != nil {
38+
return nil, []error{&errortypes.BadInput{
39+
Message: "ext.bidder.zone not provided",
40+
}}
41+
}
42+
43+
if marsmediaExt.ZoneID == "" {
44+
return nil, []error{&errortypes.BadInput{
45+
Message: "Zone is empty",
46+
}}
47+
}
48+
49+
validImpExists := false
50+
for i := 0; i < len(request.Imp); i++ {
51+
if request.Imp[i].Banner != nil {
52+
bannerCopy := *requestIn.Imp[i].Banner
53+
if len(bannerCopy.Format) > 0 {
54+
firstFormat := bannerCopy.Format[0]
55+
bannerCopy.W = &(firstFormat.W)
56+
bannerCopy.H = &(firstFormat.H)
57+
request.Imp[i].Banner = &bannerCopy
58+
validImpExists = true
59+
} else if bannerCopy.W != nil && bannerCopy.H != nil {
60+
validImpExists = true
61+
} else {
62+
return nil, []error{&errortypes.BadInput{
63+
Message: "No valid banner format in the bid request",
64+
}}
65+
}
66+
} else if request.Imp[i].Video != nil {
67+
validImpExists = true
68+
}
69+
}
70+
if !validImpExists {
71+
return nil, []error{&errortypes.BadInput{
72+
Message: "No valid impression in the bid request",
73+
}}
74+
}
75+
76+
request.AT = 1 //Defaulting to first price auction for all prebid requests
77+
78+
reqJSON, err := json.Marshal(request)
79+
if err != nil {
80+
return nil, []error{&errortypes.BadInput{
81+
Message: fmt.Sprintf("Json not encoded. err: %s", err),
82+
}}
83+
}
84+
85+
uri := a.URI + "&zone=" + marsmediaExt.ZoneID
86+
headers := http.Header{}
87+
headers.Add("Content-Type", "application/json;charset=utf-8")
88+
headers.Add("Accept", "application/json")
89+
headers.Add("x-openrtb-version", "2.5")
90+
91+
if request.Device != nil {
92+
addHeaderIfNonEmpty(headers, "User-Agent", request.Device.UA)
93+
addHeaderIfNonEmpty(headers, "X-Forwarded-For", request.Device.IP)
94+
addHeaderIfNonEmpty(headers, "Accept-Language", request.Device.Language)
95+
if request.Device.DNT != nil {
96+
addHeaderIfNonEmpty(headers, "DNT", strconv.Itoa(int(*request.Device.DNT)))
97+
}
98+
}
99+
100+
return []*adapters.RequestData{{
101+
Method: "POST",
102+
Uri: uri,
103+
Body: reqJSON,
104+
Headers: headers,
105+
}}, []error{}
106+
}
107+
108+
func (a *MarsmediaAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
109+
110+
if response.StatusCode == http.StatusNoContent {
111+
return nil, nil
112+
}
113+
114+
if response.StatusCode == http.StatusBadRequest {
115+
return nil, []error{&errortypes.BadInput{
116+
Message: fmt.Sprintf("Unexpected status code: %d. ", response.StatusCode),
117+
}}
118+
}
119+
120+
if response.StatusCode != http.StatusOK {
121+
return nil, []error{&errortypes.BadServerResponse{
122+
Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
123+
}}
124+
}
125+
126+
var bidResp openrtb.BidResponse
127+
if err := json.Unmarshal(response.Body, &bidResp); err != nil {
128+
return nil, []error{&errortypes.BadServerResponse{
129+
Message: fmt.Sprintf("Bad server response: %d. ", err),
130+
}}
131+
}
132+
133+
bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid))
134+
sb := bidResp.SeatBid[0]
135+
for i := 0; i < len(sb.Bid); i++ {
136+
bid := sb.Bid[i]
137+
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
138+
Bid: &bid,
139+
BidType: getMediaTypeForImp(bid.ImpID, internalRequest.Imp),
140+
})
141+
}
142+
return bidResponse, nil
143+
}
144+
145+
func addHeaderIfNonEmpty(headers http.Header, headerName string, headerValue string) {
146+
if len(headerValue) > 0 {
147+
headers.Add(headerName, headerValue)
148+
}
149+
}
150+
151+
// getMediaTypeForImp figures out which media type this bid is for.
152+
func getMediaTypeForImp(impId string, imps []openrtb.Imp) openrtb_ext.BidType {
153+
mediaType := openrtb_ext.BidTypeBanner //default type
154+
for _, imp := range imps {
155+
if imp.ID == impId {
156+
if imp.Video != nil {
157+
mediaType = openrtb_ext.BidTypeVideo
158+
}
159+
return mediaType
160+
}
161+
}
162+
return mediaType
163+
}
164+
165+
func NewMarsmediaBidder(endpoint string) *MarsmediaAdapter {
166+
return &MarsmediaAdapter{
167+
URI: endpoint,
168+
}
169+
}

adapters/marsmedia/marsmedia_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package marsmedia
2+
3+
import (
4+
"testing"
5+
6+
"github.com/prebid/prebid-server/adapters/adapterstest"
7+
)
8+
9+
func TestJsonSamples(t *testing.T) {
10+
adapterstest.RunJSONBidderTest(t, "marsmediatest", NewMarsmediaBidder("http://bid306.rtbsrv.com/bidder/?bid=f3xtet"))
11+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
{
2+
"mockBidRequest": {
3+
"id": "test-request-id",
4+
"imp": [
5+
{
6+
"id": "test-imp-id",
7+
"at" : 1,
8+
"banner": {
9+
"format": [
10+
{
11+
"w": 300,
12+
"h": 250
13+
}
14+
]
15+
},
16+
"ext": {
17+
"bidder": {
18+
"zone": "9999"
19+
}
20+
}
21+
}
22+
]
23+
},
24+
25+
"httpCalls": [
26+
{
27+
"expectedRequest": {
28+
"uri": "http://bid306.rtbsrv.com/bidder/?bid=f3xtet&zone=9999",
29+
"body": {
30+
"id": "test-request-id",
31+
"at" : 1,
32+
"imp": [
33+
{
34+
"id": "test-imp-id",
35+
"banner": {
36+
"format": [
37+
{
38+
"w": 300,
39+
"h": 250
40+
}
41+
],
42+
"w": 300,
43+
"h": 250
44+
},
45+
"ext": {
46+
"bidder": {
47+
"zone": "9999"
48+
}
49+
}
50+
}
51+
]
52+
}
53+
},
54+
"mockResponse": {
55+
"status": 200,
56+
"body": {
57+
"id": "test-request-id",
58+
"seatbid": [
59+
{
60+
"seat": "marsmedia",
61+
"bid": [{
62+
"id": "1",
63+
"impid": "test-imp-id",
64+
"price": 1.1,
65+
"adid": "17586",
66+
"adm": "some-test-ad",
67+
"nurl" : "some-test-nurl",
68+
"iurl" : "some-test-iurl",
69+
"adomain": ["wooga.com"],
70+
"cid": "17586",
71+
"crid": "17586",
72+
"h": 250,
73+
"w": 300
74+
}]
75+
}
76+
],
77+
"bidid": "5778926625248726496",
78+
"cur": "USD"
79+
}
80+
}
81+
}
82+
],
83+
84+
"expectedBids": [
85+
{
86+
"bid": {
87+
"id": "7706636740145184841",
88+
"impid": "test-imp-id",
89+
"price": 0.5,
90+
"adm": "some-test-ad",
91+
"adid": "29681110",
92+
"adomain": ["yahoo.com"],
93+
"cid": "958",
94+
"crid": "29681110",
95+
"h": 250,
96+
"w": 300
97+
},
98+
"ext": {
99+
"prebid": {
100+
"type": "banner"
101+
}
102+
}
103+
}
104+
]
105+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
{
2+
"mockBidRequest": {
3+
"id": "test-request-id",
4+
"imp": [
5+
{
6+
"id": "test-imp-id",
7+
"video": {
8+
"mimes": ["video/mp4"],
9+
"protocols": [2, 5],
10+
"w": 1024,
11+
"h": 576
12+
},
13+
"ext":{
14+
"bidder":{
15+
"zone": "9999"
16+
}
17+
}
18+
}
19+
]
20+
},
21+
22+
"httpCalls": [
23+
{
24+
"expectedRequest": {
25+
"uri": "http://bid306.rtbsrv.com/bidder/?bid=f3xtet&zone=9999",
26+
"body": {
27+
"id": "test-request-id",
28+
"at":1,
29+
"imp": [
30+
{
31+
"id": "test-imp-id",
32+
"video": {
33+
"mimes": ["video/mp4"],
34+
"protocols": [2, 5],
35+
"w": 1024,
36+
"h": 576
37+
},
38+
"ext": {
39+
"bidder": {
40+
"zone": "9999"
41+
}
42+
}
43+
}
44+
]
45+
}
46+
},
47+
"mockResponse": {
48+
"status": 200,
49+
"body": {
50+
"id": "test-request-id",
51+
"cur": "USD",
52+
"seatbid": [
53+
{
54+
"seat": "Marsmedia",
55+
"bid": [{
56+
"id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
57+
"impid": "test-imp-id",
58+
"price": 0.500000,
59+
"adm": "some-test-ad",
60+
"crid": "crid_10",
61+
"w": 1024,
62+
"h": 576
63+
}]
64+
}
65+
]
66+
}
67+
}
68+
}
69+
],
70+
71+
"expectedBids": [
72+
{
73+
"bid": {
74+
"id": "8ee514f1-b2b8-4abb-89fd-084437d1e800",
75+
"impid": "test-imp-id",
76+
"price": 0.5,
77+
"adm": "some-test-ad",
78+
"crid": "crid_10",
79+
"w": 1024,
80+
"h": 576
81+
},
82+
"type": "video"
83+
}
84+
]
85+
}

0 commit comments

Comments
 (0)