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

Commit 40d1f06

Browse files
IncSWSyntaxNode
authored andcommitted
Add Applogy adapter (prebid#1151)
1 parent e1134e2 commit 40d1f06

File tree

17 files changed

+1004
-0
lines changed

17 files changed

+1004
-0
lines changed

adapters/applogy/applogy.go

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package applogy
2+
3+
import (
4+
"encoding/json"
5+
"errors"
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 ApplogyAdapter struct {
16+
endpoint string
17+
}
18+
19+
func (a *ApplogyAdapter) MakeRequests(request *openrtb.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
20+
headers := http.Header{}
21+
headers.Add("Content-Type", "application/json;charset=utf-8")
22+
headers.Add("Accept", "application/json")
23+
impressions := request.Imp
24+
result := make([]*adapters.RequestData, 0, len(impressions))
25+
errs := make([]error, 0, len(impressions))
26+
27+
for i, impression := range impressions {
28+
if impression.Banner == nil && impression.Video == nil && impression.Native == nil {
29+
errs = append(errs, &errortypes.BadInput{
30+
Message: "Applogy only supports banner, video or native ads",
31+
})
32+
continue
33+
}
34+
if impression.Banner != nil {
35+
banner := impression.Banner
36+
if banner.W == nil || banner.H == nil || *banner.W == 0 || *banner.H == 0 {
37+
if len(banner.Format) == 0 {
38+
errs = append(errs, &errortypes.BadInput{
39+
Message: "banner size information missing",
40+
})
41+
continue
42+
}
43+
format := banner.Format[0]
44+
banner.W = &format.W
45+
banner.H = &format.H
46+
}
47+
}
48+
if len(impression.Ext) == 0 {
49+
errs = append(errs, errors.New("impression extensions required"))
50+
continue
51+
}
52+
var bidderExt adapters.ExtImpBidder
53+
err := json.Unmarshal(impression.Ext, &bidderExt)
54+
if err != nil {
55+
errs = append(errs, err)
56+
continue
57+
}
58+
if len(bidderExt.Bidder) == 0 {
59+
errs = append(errs, errors.New("bidder required"))
60+
continue
61+
}
62+
var impressionExt openrtb_ext.ExtImpApplogy
63+
err = json.Unmarshal(bidderExt.Bidder, &impressionExt)
64+
if err != nil {
65+
errs = append(errs, err)
66+
continue
67+
}
68+
if impressionExt.Token == "" {
69+
errs = append(errs, errors.New("Applogy token required"))
70+
continue
71+
}
72+
request.Imp = impressions[i : i+1]
73+
body, err := json.Marshal(request)
74+
if err != nil {
75+
errs = append(errs, err)
76+
continue
77+
}
78+
result = append(result, &adapters.RequestData{
79+
Method: "POST",
80+
Uri: a.endpoint + "/" + impressionExt.Token,
81+
Body: body,
82+
Headers: headers,
83+
})
84+
}
85+
86+
request.Imp = impressions
87+
88+
if len(result) == 0 {
89+
return nil, errs
90+
}
91+
return result, errs
92+
}
93+
94+
func (a *ApplogyAdapter) MakeBids(request *openrtb.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
95+
var errs []error
96+
97+
switch responseData.StatusCode {
98+
case http.StatusNoContent:
99+
return nil, nil
100+
case http.StatusBadRequest:
101+
return nil, []error{&errortypes.BadInput{
102+
Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode),
103+
}}
104+
case http.StatusOK:
105+
break
106+
default:
107+
return nil, []error{&errortypes.BadServerResponse{
108+
Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode),
109+
}}
110+
}
111+
112+
var bidResponse openrtb.BidResponse
113+
err := json.Unmarshal(responseData.Body, &bidResponse)
114+
if err != nil {
115+
return nil, []error{&errortypes.BadServerResponse{
116+
Message: err.Error(),
117+
}}
118+
}
119+
120+
response := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
121+
122+
for _, seatBid := range bidResponse.SeatBid {
123+
for _, bid := range seatBid.Bid {
124+
bid := bid // pin https://github.com/kyoh86/scopelint#whats-this
125+
var bidType openrtb_ext.BidType
126+
for _, impression := range request.Imp {
127+
if impression.ID != bid.ImpID {
128+
continue
129+
}
130+
switch {
131+
case impression.Banner != nil:
132+
bidType = openrtb_ext.BidTypeBanner
133+
case impression.Video != nil:
134+
bidType = openrtb_ext.BidTypeVideo
135+
case impression.Native != nil:
136+
bidType = openrtb_ext.BidTypeNative
137+
}
138+
break
139+
}
140+
if bidType == "" {
141+
errs = append(errs, &errortypes.BadServerResponse{
142+
Message: "ignoring bid id=" + bid.ID + ", request doesn't contain any valid impression with id=" + bid.ImpID,
143+
})
144+
continue
145+
}
146+
response.Bids = append(response.Bids, &adapters.TypedBid{
147+
Bid: &bid,
148+
BidType: bidType,
149+
})
150+
}
151+
}
152+
153+
return response, errs
154+
}
155+
156+
func NewApplogyBidder(endpoint string) *ApplogyAdapter {
157+
return &ApplogyAdapter{
158+
endpoint: endpoint,
159+
}
160+
}

adapters/applogy/applogy_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package applogy
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, "applogytest", NewApplogyBidder("http://example.com/prebid"))
11+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
{
2+
"mockBidRequest": {
3+
"id": "test-request-id",
4+
"imp": [{
5+
"id": "test-impression-id-1",
6+
"banner": {
7+
"format": [{
8+
"h": 250,
9+
"w": 300
10+
}]
11+
},
12+
"ext": {
13+
"bidder": {
14+
"token": "test-token-1"
15+
}
16+
}
17+
}, {
18+
"id": "test-impression-id-2",
19+
"banner": {
20+
"w": 300,
21+
"h": 250
22+
},
23+
"ext": {
24+
"bidder": {
25+
"token": "test-token-1"
26+
}
27+
}
28+
}, {
29+
"id": "test-impression-id-3",
30+
"banner": {
31+
"w": 300,
32+
"h": 250
33+
},
34+
"ext": {
35+
"bidder": {
36+
"token": "test-token-2"
37+
}
38+
}
39+
}]
40+
},
41+
"httpCalls": [{
42+
"expectedRequest": {
43+
"uri": "http://example.com/prebid/test-token-1",
44+
"body": {
45+
"id": "test-request-id",
46+
"imp": [{
47+
"id": "test-impression-id-1",
48+
"banner": {
49+
"format": [{
50+
"h": 250,
51+
"w": 300
52+
}],
53+
"h": 250,
54+
"w": 300
55+
},
56+
"ext": {
57+
"bidder": {
58+
"token": "test-token-1"
59+
}
60+
}
61+
}]
62+
}
63+
},
64+
"mockResponse": {
65+
"status": 200,
66+
"body": {
67+
"id": "test-response-id",
68+
"seatbid": [{
69+
"bid": [{
70+
"id": "test-bid-id-1",
71+
"impid": "test-impression-id-1",
72+
"price": 1
73+
}]
74+
}]
75+
}
76+
}
77+
}, {
78+
"expectedRequest": {
79+
"uri": "http://example.com/prebid/test-token-1",
80+
"body": {
81+
"id": "test-request-id",
82+
"imp": [{
83+
"id": "test-impression-id-2",
84+
"banner": {
85+
"h": 250,
86+
"w": 300
87+
},
88+
"ext": {
89+
"bidder": {
90+
"token": "test-token-1"
91+
}
92+
}
93+
}]
94+
}
95+
},
96+
"mockResponse": {
97+
"status": 200,
98+
"body": {
99+
"id": "test-response-id-2",
100+
"seatbid": [{
101+
"bid": [{
102+
"id": "test-bid-id-2",
103+
"impid": "test-impression-id-2",
104+
"price": 2
105+
}]
106+
}]
107+
}
108+
}
109+
}, {
110+
"expectedRequest": {
111+
"uri": "http://example.com/prebid/test-token-2",
112+
"body": {
113+
"id": "test-request-id",
114+
"imp": [{
115+
"id": "test-impression-id-3",
116+
"banner": {
117+
"h": 250,
118+
"w": 300
119+
},
120+
"ext": {
121+
"bidder": {
122+
"token": "test-token-2"
123+
}
124+
}
125+
}]
126+
}
127+
},
128+
"mockResponse": {
129+
"status": 200,
130+
"body": {
131+
"id": "test-response-id-3",
132+
"seatbid": [{
133+
"bid": [{
134+
"id": "test-bid-id-3",
135+
"impid": "test-impression-id-3",
136+
"price": 3
137+
}]
138+
}]
139+
}
140+
}
141+
}],
142+
"expectedBidResponses": [{
143+
"bids": [{
144+
"bid": {
145+
"id": "test-bid-id-1",
146+
"impid": "test-impression-id-1",
147+
"price": 1
148+
},
149+
"type": "banner"
150+
}]
151+
}, {
152+
"bids": [{
153+
"bid": {
154+
"id": "test-bid-id-2",
155+
"impid": "test-impression-id-2",
156+
"price": 2
157+
},
158+
"type": "banner"
159+
}]
160+
}, {
161+
"bids": [{
162+
"bid": {
163+
"id": "test-bid-id-3",
164+
"impid": "test-impression-id-3",
165+
"price": 3
166+
},
167+
"type": "banner"
168+
}]
169+
}]
170+
}

0 commit comments

Comments
 (0)