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