github.com/prebid/prebid-server/v2@v2.18.0/adapters/adyoulike/adyoulike.go (about) 1 package adyoulike 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/buger/jsonparser" 10 "github.com/prebid/openrtb/v20/openrtb2" 11 "github.com/prebid/prebid-server/v2/adapters" 12 "github.com/prebid/prebid-server/v2/config" 13 "github.com/prebid/prebid-server/v2/errortypes" 14 "github.com/prebid/prebid-server/v2/openrtb_ext" 15 ) 16 17 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 18 return &adapter{ 19 endpoint: config.Endpoint, 20 }, nil 21 } 22 23 type adapter struct { 24 endpoint string 25 } 26 27 func (a *adapter) MakeRequests( 28 openRTBRequest *openrtb2.BidRequest, 29 reqInfo *adapters.ExtraRequestInfo, 30 ) ( 31 requestsToBidder []*adapters.RequestData, 32 errs []error, 33 ) { 34 var err error 35 var tagID string 36 37 reqCopy := *openRTBRequest 38 reqCopy.Imp = []openrtb2.Imp{} 39 for ind, imp := range openRTBRequest.Imp { 40 41 // Check if imp comes with bid floor amount defined in a foreign currency 42 if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" { 43 // Convert to US dollars 44 convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD") 45 if err != nil { 46 return nil, []error{err} 47 } 48 // Update after conversion. All imp elements inside request.Imp are shallow copies 49 // therefore, their non-pointer values are not shared memory and are safe to modify. 50 imp.BidFloorCur = "USD" 51 imp.BidFloor = convertedValue 52 } 53 54 // Set the CUR of bid to USD after converting all floors 55 reqCopy.Cur = []string{"USD"} 56 57 reqCopy.Imp = append(reqCopy.Imp, imp) 58 59 tagID, err = jsonparser.GetString(reqCopy.Imp[ind].Ext, "bidder", "placement") 60 if err != nil { 61 errs = append(errs, err) 62 continue 63 } 64 65 reqCopy.Imp[ind].TagID = tagID 66 } 67 68 openRTBRequestJSON, err := json.Marshal(reqCopy) 69 if err != nil { 70 errs = append(errs, err) 71 } 72 73 if len(errs) > 0 { 74 return nil, errs 75 } 76 77 headers := http.Header{} 78 headers.Add("Content-Type", "application/json;charset=utf-8") 79 headers.Add("Accept", "application/json") 80 headers.Add("x-openrtb-version", "2.5") 81 82 requestToBidder := &adapters.RequestData{ 83 Method: "POST", 84 Uri: a.endpoint, 85 Body: openRTBRequestJSON, 86 Headers: headers, 87 ImpIDs: openrtb_ext.GetImpIDs(reqCopy.Imp), 88 } 89 requestsToBidder = append(requestsToBidder, requestToBidder) 90 91 return requestsToBidder, errs 92 } 93 94 const unexpectedStatusCodeFormat = "" + 95 "Unexpected status code: %d. Run with request.debug = 1 for more info" 96 97 func (a *adapter) MakeBids( 98 openRTBRequest *openrtb2.BidRequest, 99 requestToBidder *adapters.RequestData, 100 bidderRawResponse *adapters.ResponseData, 101 ) ( 102 bidderResponse *adapters.BidderResponse, 103 errs []error, 104 ) { 105 switch bidderRawResponse.StatusCode { 106 case http.StatusOK: 107 break 108 case http.StatusNoContent: 109 return nil, nil 110 case http.StatusBadRequest: 111 err := &errortypes.BadInput{ 112 Message: fmt.Sprintf(unexpectedStatusCodeFormat, bidderRawResponse.StatusCode), 113 } 114 return nil, []error{err} 115 default: 116 err := &errortypes.BadServerResponse{ 117 Message: fmt.Sprintf(unexpectedStatusCodeFormat, bidderRawResponse.StatusCode), 118 } 119 return nil, []error{err} 120 } 121 122 var openRTBBidderResponse openrtb2.BidResponse 123 if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { 124 return nil, []error{err} 125 } 126 127 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(openRTBRequest.Imp)) 128 bidResponse.Currency = "USD" 129 130 for _, seatBid := range openRTBBidderResponse.SeatBid { 131 for idx := range seatBid.Bid { 132 b := &adapters.TypedBid{ 133 Bid: &seatBid.Bid[idx], 134 BidType: getMediaTypeForImp(seatBid.Bid[idx].ImpID, openRTBRequest.Imp), 135 } 136 bidResponse.Bids = append(bidResponse.Bids, b) 137 } 138 } 139 return bidResponse, nil 140 } 141 142 // getMediaTypeForBid determines which type of bid. 143 func getMediaTypeForImp(impID string, imps []openrtb2.Imp) openrtb_ext.BidType { 144 mediaType := openrtb_ext.BidTypeBanner 145 for _, imp := range imps { 146 if imp.ID == impID { 147 if imp.Banner == nil && imp.Video != nil { 148 mediaType = openrtb_ext.BidTypeVideo 149 } else if imp.Banner == nil && imp.Native != nil { 150 mediaType = openrtb_ext.BidTypeNative 151 } 152 } 153 } 154 155 return mediaType 156 }