github.com/prebid/prebid-server/v2@v2.18.0/adapters/bidscube/bidscube.go (about) 1 package bidscube 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "net/http" 8 "strconv" 9 10 "github.com/buger/jsonparser" 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/openrtb_ext" 16 ) 17 18 type adapter struct { 19 endpoint string 20 } 21 22 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, _ *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 23 headers := http.Header{} 24 headers.Add("Content-Type", "application/json;charset=utf-8") 25 headers.Add("Accept", "application/json") 26 impressions := request.Imp 27 result := make([]*adapters.RequestData, 0, len(impressions)) 28 var errs []error 29 30 for _, impression := range impressions { 31 var impExt map[string]json.RawMessage 32 if err := json.Unmarshal(impression.Ext, &impExt); err != nil { 33 errs = append(errs, err) 34 continue 35 } 36 37 bidderExt, bidderExtExists := impExt["bidder"] 38 if !bidderExtExists || len(bidderExt) == 0 { 39 errs = append(errs, errors.New("bidder parameters required")) 40 continue 41 } 42 43 impression.Ext = bidderExt 44 request.Imp = []openrtb2.Imp{impression} 45 body, err := json.Marshal(request) 46 if err != nil { 47 errs = append(errs, err) 48 continue 49 } 50 result = append(result, &adapters.RequestData{ 51 Method: "POST", 52 Uri: a.endpoint, 53 Body: body, 54 Headers: headers, 55 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 56 }) 57 } 58 59 request.Imp = impressions 60 return result, errs 61 } 62 63 func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 64 var errs []error 65 66 switch responseData.StatusCode { 67 case http.StatusNoContent: 68 return nil, nil 69 case http.StatusBadRequest: 70 return nil, []error{&errortypes.BadInput{ 71 Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode), 72 }} 73 case http.StatusOK: 74 break 75 default: 76 return nil, []error{&errortypes.BadServerResponse{ 77 Message: "unexpected status code: " + strconv.Itoa(responseData.StatusCode), 78 }} 79 } 80 81 var bidResponse openrtb2.BidResponse 82 err := json.Unmarshal(responseData.Body, &bidResponse) 83 if err != nil { 84 return nil, []error{&errortypes.BadServerResponse{ 85 Message: err.Error(), 86 }} 87 } 88 89 response := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) 90 91 for _, seatBid := range bidResponse.SeatBid { 92 for i := range seatBid.Bid { 93 bidType, err := jsonparser.GetString(seatBid.Bid[i].Ext, "prebid", "type") 94 if err != nil { 95 errs = append(errs, fmt.Errorf("unable to read bid.ext.prebid.type: %v", err)) 96 continue 97 } 98 response.Bids = append(response.Bids, &adapters.TypedBid{ 99 Bid: &seatBid.Bid[i], 100 BidType: getMediaTypeForImp(bidType), 101 }) 102 } 103 } 104 105 return response, errs 106 } 107 108 func getMediaTypeForImp(bidType string) openrtb_ext.BidType { 109 switch bidType { 110 case "banner": 111 return openrtb_ext.BidTypeBanner 112 case "video": 113 return openrtb_ext.BidTypeVideo 114 case "native": 115 return openrtb_ext.BidTypeNative 116 } 117 return openrtb_ext.BidTypeBanner 118 } 119 120 // Builder builds a new instance of the BidsCube adapter for the given bidder with the given config. 121 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 122 bidder := &adapter{ 123 endpoint: config.Endpoint, 124 } 125 return bidder, nil 126 }