github.com/prebid/prebid-server@v0.275.0/adapters/tpmn/tpmn.go (about) 1 package tpmn 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/prebid/openrtb/v19/openrtb2" 10 "github.com/prebid/prebid-server/adapters" 11 "github.com/prebid/prebid-server/config" 12 "github.com/prebid/prebid-server/openrtb_ext" 13 ) 14 15 // TpmnAdapter struct 16 type adapter struct { 17 uri string 18 } 19 20 // MakeRequests makes the HTTP requests which should be made to fetch bids from TpmnBidder. 21 func (rcv *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 22 validImps, errs := getValidImpressions(request, reqInfo) 23 if len(validImps) == 0 { 24 return nil, errs 25 } 26 27 request.Imp = validImps 28 29 requestBodyJSON, err := json.Marshal(request) 30 if err != nil { 31 errs = append(errs, err) 32 return nil, errs 33 } 34 35 headers := http.Header{} 36 headers.Add("Content-Type", "application/json;charset=utf-8") 37 headers.Add("Accept", "application/json") 38 39 return []*adapters.RequestData{{ 40 Method: http.MethodPost, 41 Uri: rcv.uri, 42 Body: requestBodyJSON, 43 Headers: headers, 44 }}, errs 45 } 46 47 // getValidImpressions validate imps and check for bid floor currency. Convert to EUR if necessary 48 func getValidImpressions(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]openrtb2.Imp, []error) { 49 var errs []error 50 var validImps []openrtb2.Imp 51 52 for _, imp := range request.Imp { 53 if err := preprocessBidFloorCurrency(&imp, reqInfo); err != nil { 54 errs = append(errs, err) 55 continue 56 } 57 validImps = append(validImps, imp) 58 } 59 return validImps, errs 60 } 61 62 func preprocessBidFloorCurrency(imp *openrtb2.Imp, reqInfo *adapters.ExtraRequestInfo) error { 63 // we expect every currency related data to be EUR 64 if imp.BidFloor > 0 && strings.ToUpper(imp.BidFloorCur) != "USD" && imp.BidFloorCur != "" { 65 if convertedValue, err := reqInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD"); err != nil { 66 return err 67 } else { 68 imp.BidFloor = convertedValue 69 } 70 } 71 imp.BidFloorCur = "USD" 72 return nil 73 } 74 75 func (a *adapter) MakeBids(request *openrtb2.BidRequest, _ *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 76 if adapters.IsResponseStatusCodeNoContent(responseData) { 77 return nil, nil 78 } 79 80 if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { 81 return nil, []error{err} 82 } 83 84 var response openrtb2.BidResponse 85 if err := json.Unmarshal(responseData.Body, &response); err != nil { 86 return nil, []error{fmt.Errorf("bid response unmarshal: %v", err)} 87 } 88 89 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) 90 bidResponse.Currency = response.Cur 91 for _, seatBid := range response.SeatBid { 92 for i, bid := range seatBid.Bid { 93 bidType, err := getMediaTypeForImp(bid) 94 if err != nil { 95 return nil, []error{err} 96 } 97 b := &adapters.TypedBid{ 98 Bid: &seatBid.Bid[i], 99 BidType: bidType, 100 } 101 bidResponse.Bids = append(bidResponse.Bids, b) 102 } 103 } 104 return bidResponse, nil 105 } 106 107 func getMediaTypeForImp(bid openrtb2.Bid) (openrtb_ext.BidType, error) { 108 switch bid.MType { 109 case openrtb2.MarkupBanner: 110 return openrtb_ext.BidTypeBanner, nil 111 case openrtb2.MarkupVideo: 112 return openrtb_ext.BidTypeVideo, nil 113 case openrtb2.MarkupNative: 114 return openrtb_ext.BidTypeNative, nil 115 default: 116 return "", fmt.Errorf("unsupported MType %d", bid.MType) 117 } 118 } 119 120 // Builder builds a new instance of the TpmnBidder adapter for the given bidder with the given config. 121 func Builder(_ openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 122 bidder := &adapter{ 123 uri: config.Endpoint, 124 } 125 return bidder, nil 126 }