github.com/prebid/prebid-server@v0.275.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/v19/openrtb2" 11 "github.com/prebid/prebid-server/adapters" 12 "github.com/prebid/prebid-server/config" 13 "github.com/prebid/prebid-server/errortypes" 14 "github.com/prebid/prebid-server/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 } 88 requestsToBidder = append(requestsToBidder, requestToBidder) 89 90 return requestsToBidder, errs 91 } 92 93 const unexpectedStatusCodeFormat = "" + 94 "Unexpected status code: %d. Run with request.debug = 1 for more info" 95 96 func (a *adapter) MakeBids( 97 openRTBRequest *openrtb2.BidRequest, 98 requestToBidder *adapters.RequestData, 99 bidderRawResponse *adapters.ResponseData, 100 ) ( 101 bidderResponse *adapters.BidderResponse, 102 errs []error, 103 ) { 104 switch bidderRawResponse.StatusCode { 105 case http.StatusOK: 106 break 107 case http.StatusNoContent: 108 return nil, nil 109 case http.StatusBadRequest: 110 err := &errortypes.BadInput{ 111 Message: fmt.Sprintf(unexpectedStatusCodeFormat, bidderRawResponse.StatusCode), 112 } 113 return nil, []error{err} 114 default: 115 err := &errortypes.BadServerResponse{ 116 Message: fmt.Sprintf(unexpectedStatusCodeFormat, bidderRawResponse.StatusCode), 117 } 118 return nil, []error{err} 119 } 120 121 var openRTBBidderResponse openrtb2.BidResponse 122 if err := json.Unmarshal(bidderRawResponse.Body, &openRTBBidderResponse); err != nil { 123 return nil, []error{err} 124 } 125 126 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(openRTBRequest.Imp)) 127 bidResponse.Currency = "USD" 128 129 for _, seatBid := range openRTBBidderResponse.SeatBid { 130 for idx := range seatBid.Bid { 131 b := &adapters.TypedBid{ 132 Bid: &seatBid.Bid[idx], 133 BidType: getMediaTypeForImp(seatBid.Bid[idx].ImpID, openRTBRequest.Imp), 134 } 135 bidResponse.Bids = append(bidResponse.Bids, b) 136 } 137 } 138 return bidResponse, nil 139 } 140 141 // getMediaTypeForBid determines which type of bid. 142 func getMediaTypeForImp(impID string, imps []openrtb2.Imp) openrtb_ext.BidType { 143 mediaType := openrtb_ext.BidTypeBanner 144 for _, imp := range imps { 145 if imp.ID == impID { 146 if imp.Banner == nil && imp.Video != nil { 147 mediaType = openrtb_ext.BidTypeVideo 148 } else if imp.Banner == nil && imp.Native != nil { 149 mediaType = openrtb_ext.BidTypeNative 150 } 151 } 152 } 153 154 return mediaType 155 }