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

Commit d1d7bf6

Browse files
authored
New: InMobi Prebid Server Adapter (prebid#1489)
* Adding InMobi adapter * code review feedback, also explicitly working with Imp[0], as we don't support multiple impressions * less tolerant bidder params due to sneaky 1.13 -> 1.14+ change
1 parent fb45a9c commit d1d7bf6

File tree

19 files changed

+701
-0
lines changed

19 files changed

+701
-0
lines changed

adapters/inmobi/inmobi.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package inmobi
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/mxmCherry/openrtb"
7+
"github.com/prebid/prebid-server/adapters"
8+
"github.com/prebid/prebid-server/errortypes"
9+
"github.com/prebid/prebid-server/openrtb_ext"
10+
"net/http"
11+
)
12+
13+
type InMobiAdapter struct {
14+
endPoint string
15+
}
16+
17+
func NewInMobiAdapter(endpoint string) *InMobiAdapter {
18+
return &InMobiAdapter{
19+
endPoint: endpoint,
20+
}
21+
}
22+
23+
func (a *InMobiAdapter) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
24+
var errs []error
25+
26+
if len(request.Imp) == 0 {
27+
return nil, []error{&errortypes.BadInput{
28+
Message: "No impression in the request",
29+
}}
30+
}
31+
32+
if err := preprocess(&request.Imp[0]); err != nil {
33+
errs = append(errs, err)
34+
return nil, errs
35+
}
36+
37+
reqJson, err := json.Marshal(request)
38+
if err != nil {
39+
errs = append(errs, err)
40+
return nil, errs
41+
}
42+
43+
headers := http.Header{}
44+
headers.Add("Content-Type", "application/json;charset=utf-8")
45+
headers.Add("Accept", "application/json")
46+
47+
return []*adapters.RequestData{{
48+
Method: "POST",
49+
Uri: a.endPoint,
50+
Body: reqJson,
51+
Headers: headers,
52+
}}, errs
53+
}
54+
55+
func (a *InMobiAdapter) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
56+
if response.StatusCode == http.StatusNoContent {
57+
return nil, nil
58+
}
59+
60+
if response.StatusCode != http.StatusOK {
61+
return nil, []error{&errortypes.BadServerResponse{
62+
Message: fmt.Sprintf("Unexpected http status code: %d", response.StatusCode),
63+
}}
64+
}
65+
66+
var serverBidResponse openrtb.BidResponse
67+
if err := json.Unmarshal(response.Body, &serverBidResponse); err != nil {
68+
return nil, []error{err}
69+
}
70+
71+
bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)
72+
73+
for _, sb := range serverBidResponse.SeatBid {
74+
for i := range sb.Bid {
75+
mediaType := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp)
76+
bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
77+
Bid: &sb.Bid[i],
78+
BidType: mediaType,
79+
})
80+
}
81+
}
82+
83+
return bidResponse, nil
84+
}
85+
86+
func preprocess(imp *openrtb.Imp) error {
87+
var bidderExt adapters.ExtImpBidder
88+
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
89+
return &errortypes.BadInput{
90+
Message: err.Error(),
91+
}
92+
}
93+
94+
var inMobiExt openrtb_ext.ExtImpInMobi
95+
if err := json.Unmarshal(bidderExt.Bidder, &inMobiExt); err != nil {
96+
return &errortypes.BadInput{Message: "bad InMobi bidder ext"}
97+
}
98+
99+
if len(inMobiExt.Plc) == 0 {
100+
return &errortypes.BadInput{Message: "'plc' is a required attribute for InMobi's bidder ext"}
101+
}
102+
103+
if imp.Banner != nil {
104+
banner := *imp.Banner
105+
imp.Banner = &banner
106+
if (banner.W == nil || banner.H == nil || *banner.W == 0 || *banner.H == 0) && len(banner.Format) > 0 {
107+
format := banner.Format[0]
108+
banner.W = &format.W
109+
banner.H = &format.H
110+
}
111+
}
112+
113+
return nil
114+
}
115+
116+
func getMediaTypeForImp(impId string, imps []openrtb.Imp) openrtb_ext.BidType {
117+
mediaType := openrtb_ext.BidTypeBanner
118+
for _, imp := range imps {
119+
if imp.ID == impId {
120+
if imp.Video != nil {
121+
mediaType = openrtb_ext.BidTypeVideo
122+
}
123+
break
124+
}
125+
}
126+
return mediaType
127+
}

adapters/inmobi/inmobi_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package inmobi
2+
3+
import (
4+
"github.com/prebid/prebid-server/adapters/adapterstest"
5+
"testing"
6+
)
7+
8+
func TestJsonSamples(t *testing.T) {
9+
adapterstest.RunJSONBidderTest(t, "inmobitest", NewInMobiAdapter("https://api.w.inmobi.com/showad/openrtb/bidder/prebid"))
10+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"mockBidRequest": {
3+
"app": {
4+
"bundle": "com.example.app"
5+
},
6+
"id": "req-id",
7+
"device": {
8+
"ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d",
9+
"ip": "1.1.1.1",
10+
"ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36"
11+
},
12+
"imp": [
13+
{
14+
"ext": {
15+
"bidder": {
16+
"plc": "1596825400965"
17+
}
18+
},
19+
"banner": {
20+
"w": 320,
21+
"h": 50
22+
},
23+
"id": "imp-id"
24+
}
25+
]
26+
},
27+
"httpCalls": [{
28+
"expectedRequest": {
29+
"uri": "https://api.w.inmobi.com/showad/openrtb/bidder/prebid",
30+
"body": {
31+
"app": {
32+
"bundle": "com.example.app"
33+
},
34+
"id": "req-id",
35+
"device": {
36+
"ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d",
37+
"ip": "1.1.1.1",
38+
"ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36"
39+
},
40+
"imp": [
41+
{
42+
"ext": {
43+
"bidder": {
44+
"plc": "1596825400965"
45+
}
46+
},
47+
"banner": {
48+
"w": 320,
49+
"h": 50
50+
},
51+
"id": "imp-id"
52+
}
53+
]
54+
}
55+
},
56+
"mockResponse": {
57+
"status": 200,
58+
"body": {
59+
"id": "req-id",
60+
"seatbid": [
61+
{
62+
"bid": [
63+
{
64+
"ext": {
65+
"prebid": {
66+
"meta": {
67+
"networkName": "inmobi"
68+
}
69+
}
70+
},
71+
"nurl": "https://some.event.url/params",
72+
"crid": "123456789",
73+
"adomain": [],
74+
"price": 2.0,
75+
"id": "1234",
76+
"adm": "bannerhtml",
77+
"impid": "imp-id"
78+
}
79+
]
80+
}
81+
]
82+
}
83+
}
84+
}],
85+
86+
"expectedBidResponses": [{
87+
"currency": "USD",
88+
"bids": [{
89+
"bid": {
90+
"id": "1234",
91+
"impid": "imp-id",
92+
"price": 2.0,
93+
"adm": "bannerhtml",
94+
"crid": "123456789",
95+
"nurl": "https://some.event.url/params",
96+
"ext": {
97+
"prebid": {
98+
"meta": {
99+
"networkName": "inmobi"
100+
}
101+
}
102+
}
103+
},
104+
"type": "banner"
105+
}]
106+
}]
107+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
{
2+
"mockBidRequest": {
3+
"app": {
4+
"bundle": "com.example.app"
5+
},
6+
"id": "req-id",
7+
"device": {
8+
"ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d",
9+
"ip": "1.1.1.1",
10+
"ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36"
11+
},
12+
"imp": [
13+
{
14+
"ext": {
15+
"bidder": {
16+
"plc": "1598991608990"
17+
}
18+
},
19+
"video": {
20+
"w": 640,
21+
"h": 360,
22+
"mimes": ["video/mp4"]
23+
},
24+
"id": "imp-id"
25+
}
26+
]
27+
},
28+
"httpCalls": [{
29+
"expectedRequest": {
30+
"uri": "https://api.w.inmobi.com/showad/openrtb/bidder/prebid",
31+
"body": {
32+
"app": {
33+
"bundle": "com.example.app"
34+
},
35+
"id": "req-id",
36+
"device": {
37+
"ifa": "9d8fe0a9-c0dd-4482-b16b-5709b00c608d",
38+
"ip": "1.1.1.1",
39+
"ua": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.84 Mobile Safari/537.36"
40+
},
41+
"imp": [
42+
{
43+
"ext": {
44+
"bidder": {
45+
"plc": "1598991608990"
46+
}
47+
},
48+
"video": {
49+
"w": 640,
50+
"h": 360,
51+
"mimes": ["video/mp4"]
52+
},
53+
"id": "imp-id"
54+
}
55+
]
56+
}
57+
},
58+
"mockResponse": {
59+
"status": 200,
60+
"body": {
61+
"id": "req-id",
62+
"seatbid": [
63+
{
64+
"bid": [
65+
{
66+
"ext": {
67+
"prebid": {
68+
"meta": {
69+
"networkName": "inmobi"
70+
}
71+
}
72+
},
73+
"nurl": "https://some.event.url/params",
74+
"crid": "123456789",
75+
"adomain": [],
76+
"price": 2.0,
77+
"id": "1234",
78+
"adm": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <VAST version=\"3.0\"></VAST>",
79+
"impid": "imp-id"
80+
}
81+
]
82+
}
83+
]
84+
}
85+
}
86+
}],
87+
88+
"expectedBidResponses": [{
89+
"currency": "USD",
90+
"bids": [{
91+
"bid": {
92+
"id": "1234",
93+
"impid": "imp-id",
94+
"price": 2.0,
95+
"adm": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <VAST version=\"3.0\"></VAST>",
96+
"crid": "123456789",
97+
"nurl": "https://some.event.url/params",
98+
"ext": {
99+
"prebid": {
100+
"meta": {
101+
"networkName": "inmobi"
102+
}
103+
}
104+
}
105+
},
106+
"type": "video"
107+
}]
108+
}]
109+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plc": "1596825400965"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plc": "1598991608990"
3+
}

0 commit comments

Comments
 (0)