Skip to content

Commit 804334a

Browse files
authored
New Adapter: MetaX (#3712)
1 parent e8e2848 commit 804334a

30 files changed

+2782
-0
lines changed

adapters/metax/metax.go

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
package metax
2+
3+
import (
4+
"encoding/json"
5+
"errors"
6+
"fmt"
7+
"net/http"
8+
"strconv"
9+
"text/template"
10+
11+
"github.com/prebid/openrtb/v20/openrtb2"
12+
"github.com/prebid/prebid-server/v2/adapters"
13+
"github.com/prebid/prebid-server/v2/config"
14+
"github.com/prebid/prebid-server/v2/errortypes"
15+
"github.com/prebid/prebid-server/v2/macros"
16+
"github.com/prebid/prebid-server/v2/openrtb_ext"
17+
"github.com/prebid/prebid-server/v2/util/ptrutil"
18+
)
19+
20+
type adapter struct {
21+
template *template.Template
22+
}
23+
24+
func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
25+
errs := make([]error, 0, len(request.Imp))
26+
27+
// split impressions
28+
reqDatas := make([]*adapters.RequestData, 0, len(request.Imp))
29+
for _, imp := range request.Imp {
30+
metaxExt, err := parseBidderExt(&imp)
31+
if err != nil {
32+
errs = append(errs, err)
33+
continue
34+
}
35+
36+
if err := preprocessImp(&imp); err != nil {
37+
errs = append(errs, err)
38+
continue
39+
}
40+
41+
endpoint, err := a.getEndpoint(metaxExt)
42+
if err != nil {
43+
errs = append(errs, err)
44+
continue
45+
}
46+
47+
requestCopy := *request
48+
requestCopy.Imp = []openrtb2.Imp{imp}
49+
reqJSON, err := json.Marshal(requestCopy)
50+
if err != nil {
51+
errs = append(errs, err)
52+
return nil, errs
53+
}
54+
55+
headers := http.Header{}
56+
headers.Add("Content-Type", "application/json;charset=utf-8")
57+
headers.Add("Accept", "application/json")
58+
reqDatas = append(reqDatas, &adapters.RequestData{
59+
Method: "POST",
60+
Uri: endpoint,
61+
Body: reqJSON,
62+
Headers: headers,
63+
ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp),
64+
})
65+
}
66+
67+
return reqDatas, errs
68+
}
69+
70+
func (a *adapter) MakeBids(bidReq *openrtb2.BidRequest, reqData *adapters.RequestData, respData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
71+
if adapters.IsResponseStatusCodeNoContent(respData) {
72+
return nil, nil
73+
}
74+
75+
if err := adapters.CheckResponseStatusCodeForErrors(respData); err != nil {
76+
return nil, []error{err}
77+
}
78+
79+
var bidResp openrtb2.BidResponse
80+
if err := json.Unmarshal(respData.Body, &bidResp); err != nil {
81+
return nil, []error{err}
82+
}
83+
84+
// additional no content check
85+
if len(bidResp.SeatBid) == 0 || len(bidResp.SeatBid[0].Bid) == 0 {
86+
return nil, nil
87+
}
88+
89+
resp := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid))
90+
if len(bidResp.Cur) != 0 {
91+
resp.Currency = bidResp.Cur
92+
}
93+
for _, sb := range bidResp.SeatBid {
94+
for i := range sb.Bid {
95+
bid := &sb.Bid[i]
96+
bidType, err := getBidType(bid)
97+
if err != nil {
98+
return nil, []error{err}
99+
}
100+
resp.Bids = append(resp.Bids, &adapters.TypedBid{
101+
Bid: bid,
102+
BidType: bidType,
103+
})
104+
}
105+
}
106+
return resp, nil
107+
}
108+
109+
func (a *adapter) getEndpoint(ext *openrtb_ext.ExtImpMetaX) (string, error) {
110+
params := macros.EndpointTemplateParams{
111+
PublisherID: strconv.Itoa(ext.PublisherID),
112+
AdUnit: strconv.Itoa(ext.Adunit),
113+
}
114+
return macros.ResolveMacros(a.template, params)
115+
}
116+
117+
func parseBidderExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpMetaX, error) {
118+
var bidderExt adapters.ExtImpBidder
119+
if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
120+
return nil, err
121+
}
122+
123+
var metaxExt openrtb_ext.ExtImpMetaX
124+
if err := json.Unmarshal(bidderExt.Bidder, &metaxExt); err != nil {
125+
return nil, errors.New("Wrong MetaX bidder ext")
126+
}
127+
128+
return &metaxExt, nil
129+
}
130+
131+
func preprocessImp(imp *openrtb2.Imp) error {
132+
if imp == nil {
133+
return errors.New("imp is nil")
134+
}
135+
136+
if imp.Banner != nil {
137+
imp.Banner = assignBannerSize(imp.Banner)
138+
}
139+
140+
return nil
141+
}
142+
143+
func assignBannerSize(banner *openrtb2.Banner) *openrtb2.Banner {
144+
if banner.W != nil && banner.H != nil {
145+
return banner
146+
}
147+
148+
if len(banner.Format) == 0 {
149+
return banner
150+
}
151+
152+
return assignBannerWidthAndHeight(banner, banner.Format[0].W, banner.Format[0].H)
153+
}
154+
155+
func assignBannerWidthAndHeight(banner *openrtb2.Banner, w, h int64) *openrtb2.Banner {
156+
bannerCopy := *banner
157+
bannerCopy.W = ptrutil.ToPtr(w)
158+
bannerCopy.H = ptrutil.ToPtr(h)
159+
return &bannerCopy
160+
}
161+
162+
func getBidType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) {
163+
switch bid.MType {
164+
case openrtb2.MarkupBanner:
165+
return openrtb_ext.BidTypeBanner, nil
166+
case openrtb2.MarkupVideo:
167+
return openrtb_ext.BidTypeVideo, nil
168+
case openrtb2.MarkupNative:
169+
return openrtb_ext.BidTypeNative, nil
170+
case openrtb2.MarkupAudio:
171+
return openrtb_ext.BidTypeAudio, nil
172+
default:
173+
return "", &errortypes.BadServerResponse{
174+
Message: fmt.Sprintf("Unsupported MType %d", bid.MType),
175+
}
176+
}
177+
}
178+
179+
// Builder builds a new instance of the MetaX adapter for the given bidder with the given config.
180+
func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
181+
if config.Endpoint == "" {
182+
return nil, errors.New("endpoint is empty")
183+
}
184+
185+
templ, err := template.New("endpointTemplate").Parse(config.Endpoint)
186+
if err != nil {
187+
return nil, fmt.Errorf("unable to parse endpoint: %v", err)
188+
}
189+
190+
bidder := &adapter{
191+
template: templ,
192+
}
193+
return bidder, nil
194+
}

0 commit comments

Comments
 (0)