github.com/prebid/prebid-server/v2@v2.18.0/adapters/brave/brave.go (about) 1 package brave 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "text/template" 8 9 "github.com/prebid/openrtb/v20/openrtb2" 10 "github.com/prebid/prebid-server/v2/adapters" 11 "github.com/prebid/prebid-server/v2/config" 12 "github.com/prebid/prebid-server/v2/errortypes" 13 "github.com/prebid/prebid-server/v2/macros" 14 "github.com/prebid/prebid-server/v2/openrtb_ext" 15 ) 16 17 type adapter struct { 18 endpoint *template.Template 19 } 20 21 // Builder builds a new instance of the Brave adapter for the given bidder with the given config. 22 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 23 uri, err := template.New("endpointTemplate").Parse(config.Endpoint) 24 if err != nil { 25 return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) 26 } 27 28 bidder := &adapter{ 29 endpoint: uri, 30 } 31 return bidder, nil 32 } 33 34 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 35 var braveExt *openrtb_ext.ExtImpBrave 36 var err error 37 38 braveExt, err = a.getImpressionExt(&request.Imp[0]) 39 if err != nil { 40 return nil, []error{err} 41 } 42 43 request.Imp[0].Ext = nil 44 45 reqJSON, err := json.Marshal(request) 46 if err != nil { 47 return nil, []error{err} 48 } 49 50 headers := http.Header{} 51 headers.Add("Content-Type", "application/json;charset=utf-8") 52 headers.Add("Accept", "application/json") 53 54 url, err := a.buildEndpointURL(braveExt) 55 if err != nil { 56 return nil, []error{err} 57 } 58 59 return []*adapters.RequestData{{ 60 Method: http.MethodPost, 61 Body: reqJSON, 62 Uri: url, 63 Headers: headers, 64 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 65 }}, nil 66 } 67 68 func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpBrave, error) { 69 var bidderExt adapters.ExtImpBidder 70 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 71 return nil, &errortypes.BadInput{ 72 Message: "ext.bidder not provided", 73 } 74 } 75 var braveExt openrtb_ext.ExtImpBrave 76 if err := json.Unmarshal(bidderExt.Bidder, &braveExt); err != nil { 77 return nil, &errortypes.BadInput{ 78 Message: "ext.bidder not provided", 79 } 80 } 81 return &braveExt, nil 82 } 83 84 func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpBrave) (string, error) { 85 endpointParams := macros.EndpointTemplateParams{PublisherID: params.PlacementID} 86 return macros.ResolveMacros(a.endpoint, endpointParams) 87 } 88 89 func (a *adapter) MakeBids( 90 receivedRequest *openrtb2.BidRequest, 91 bidderRequest *adapters.RequestData, 92 bidderResponse *adapters.ResponseData, 93 ) ( 94 *adapters.BidderResponse, 95 []error, 96 ) { 97 98 if bidderResponse.StatusCode == http.StatusNoContent { 99 return nil, []error{&errortypes.BadInput{Message: "No bid"}} 100 } 101 102 if bidderResponse.StatusCode == http.StatusBadRequest { 103 return nil, []error{&errortypes.BadInput{ 104 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", bidderResponse.StatusCode), 105 }} 106 } 107 108 if bidderResponse.StatusCode == http.StatusServiceUnavailable { 109 return nil, []error{&errortypes.BadInput{ 110 Message: fmt.Sprintf("Service Unavailable. Status Code: [ %d ] ", bidderResponse.StatusCode), 111 }} 112 } 113 114 if bidderResponse.StatusCode != http.StatusOK { 115 return nil, []error{&errortypes.BadServerResponse{ 116 Message: fmt.Sprintf("Something went wrong, please contact your Account Manager. Status Code: [ %d ] ", bidderResponse.StatusCode), 117 }} 118 } 119 120 var bidResponse openrtb2.BidResponse 121 if err := json.Unmarshal(bidderResponse.Body, &bidResponse); err != nil { 122 return nil, []error{&errortypes.BadServerResponse{ 123 Message: "Bad Server Response", 124 }} 125 } 126 127 if len(bidResponse.SeatBid) == 0 { 128 return nil, []error{&errortypes.BadServerResponse{ 129 Message: "Empty SeatBid array", 130 }} 131 } 132 133 bidResponseFinal := adapters.NewBidderResponseWithBidsCapacity(len(bidResponse.SeatBid[0].Bid)) 134 sb := bidResponse.SeatBid[0] 135 136 for _, bid := range sb.Bid { 137 bidResponseFinal.Bids = append(bidResponseFinal.Bids, &adapters.TypedBid{ 138 Bid: &bid, 139 BidType: getMediaTypeForImp(bid.ImpID, receivedRequest.Imp), 140 }) 141 } 142 return bidResponseFinal, nil 143 } 144 145 func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { 146 mediaType := openrtb_ext.BidTypeBanner 147 for _, imp := range imps { 148 if imp.ID == impId { 149 if imp.Video != nil { 150 mediaType = openrtb_ext.BidTypeVideo 151 } else if imp.Native != nil { 152 mediaType = openrtb_ext.BidTypeNative 153 } 154 return mediaType 155 } 156 } 157 return mediaType 158 }