github.com/prebid/prebid-server@v0.275.0/adapters/cpmstar/cpmstar.go (about) 1 package cpmstar 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/prebid/openrtb/v19/openrtb2" 9 "github.com/prebid/prebid-server/adapters" 10 "github.com/prebid/prebid-server/config" 11 "github.com/prebid/prebid-server/errortypes" 12 "github.com/prebid/prebid-server/openrtb_ext" 13 ) 14 15 type Adapter struct { 16 endpoint string 17 } 18 19 func (a *Adapter) MakeRequests(request *openrtb2.BidRequest, unused *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 20 var errs []error 21 var adapterRequests []*adapters.RequestData 22 23 if err := preprocess(request); err != nil { 24 errs = append(errs, err) 25 return nil, errs 26 } 27 28 adapterReq, err := a.makeRequest(request) 29 if err != nil { 30 errs = append(errs, err) 31 return nil, errs 32 } 33 34 adapterRequests = append(adapterRequests, adapterReq) 35 36 return adapterRequests, errs 37 } 38 39 func (a *Adapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, error) { 40 var err error 41 42 jsonBody, err := json.Marshal(request) 43 if err != nil { 44 return nil, err 45 } 46 47 headers := http.Header{} 48 headers.Add("Content-Type", "application/json;charset=utf-8") 49 50 return &adapters.RequestData{ 51 Method: "POST", 52 Uri: a.endpoint, 53 Body: jsonBody, 54 Headers: headers, 55 }, nil 56 } 57 58 func preprocess(request *openrtb2.BidRequest) error { 59 if len(request.Imp) == 0 { 60 return &errortypes.BadInput{ 61 Message: "No Imps in Bid Request", 62 } 63 } 64 for i := 0; i < len(request.Imp); i++ { 65 var imp = &request.Imp[i] 66 var bidderExt adapters.ExtImpBidder 67 68 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 69 return &errortypes.BadInput{ 70 Message: err.Error(), 71 } 72 } 73 74 if err := validateImp(imp); err != nil { 75 return err 76 } 77 78 var extImp openrtb_ext.ExtImpCpmstar 79 if err := json.Unmarshal(bidderExt.Bidder, &extImp); err != nil { 80 return &errortypes.BadInput{ 81 Message: err.Error(), 82 } 83 } 84 85 imp.Ext = bidderExt.Bidder 86 } 87 88 return nil 89 } 90 91 func validateImp(imp *openrtb2.Imp) error { 92 if imp.Banner == nil && imp.Video == nil { 93 return &errortypes.BadInput{ 94 Message: "Only Banner and Video bid-types are supported at this time", 95 } 96 } 97 return nil 98 } 99 100 // MakeBids based on cpmstar server response 101 func (a *Adapter) MakeBids(bidRequest *openrtb2.BidRequest, unused *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 102 if responseData.StatusCode == http.StatusNoContent { 103 return nil, nil 104 } 105 106 if responseData.StatusCode != http.StatusOK { 107 return nil, []error{&errortypes.BadServerResponse{ 108 Message: fmt.Sprintf("Unexpected HTTP status code: %d. Run with request.debug = 1 for more info", responseData.StatusCode), 109 }} 110 } 111 112 var bidResponse openrtb2.BidResponse 113 114 if err := json.Unmarshal(responseData.Body, &bidResponse); err != nil { 115 return nil, []error{&errortypes.BadServerResponse{ 116 Message: err.Error(), 117 }} 118 } 119 120 if len(bidResponse.SeatBid) == 0 { 121 return nil, nil 122 } 123 124 rv := adapters.NewBidderResponseWithBidsCapacity(len(bidResponse.SeatBid[0].Bid)) 125 var errors []error 126 127 for _, seatbid := range bidResponse.SeatBid { 128 for _, bid := range seatbid.Bid { 129 foundMatchingBid := false 130 bidType := openrtb_ext.BidTypeBanner 131 for _, imp := range bidRequest.Imp { 132 if imp.ID == bid.ImpID { 133 foundMatchingBid = true 134 if imp.Banner != nil { 135 bidType = openrtb_ext.BidTypeBanner 136 } else if imp.Video != nil { 137 bidType = openrtb_ext.BidTypeVideo 138 } 139 break 140 } 141 } 142 143 if foundMatchingBid { 144 rv.Bids = append(rv.Bids, &adapters.TypedBid{ 145 Bid: &bid, 146 BidType: bidType, 147 }) 148 } else { 149 errors = append(errors, &errortypes.BadServerResponse{ 150 Message: fmt.Sprintf("bid id='%s' could not find valid impid='%s'", bid.ID, bid.ImpID), 151 }) 152 } 153 } 154 } 155 return rv, errors 156 } 157 158 // Builder builds a new instance of the Cpmstar adapter for the given bidder with the given config. 159 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 160 bidder := &Adapter{ 161 endpoint: config.Endpoint, 162 } 163 return bidder, nil 164 }