github.com/prebid/prebid-server@v0.275.0/adapters/smarthub/smarthub.go (about) 1 package smarthub 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "text/template" 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/errortypes" 13 "github.com/prebid/prebid-server/macros" 14 "github.com/prebid/prebid-server/openrtb_ext" 15 ) 16 17 const ( 18 ADAPTER_VER = "1.0.0" 19 ) 20 21 type adapter struct { 22 endpoint *template.Template 23 } 24 25 type bidExt struct { 26 MediaType string `json:"mediaType"` 27 } 28 29 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 30 template, err := template.New("endpointTemplate").Parse(config.Endpoint) 31 if err != nil { 32 return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) 33 } 34 35 bidder := &adapter{ 36 endpoint: template, 37 } 38 39 return bidder, nil 40 } 41 42 func (a *adapter) getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtSmartHub, error) { 43 var bidderExt adapters.ExtImpBidder 44 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 45 return nil, &errortypes.BadInput{ 46 Message: "Bidder extension not provided or can't be unmarshalled", 47 } 48 } 49 50 var smarthubExt openrtb_ext.ExtSmartHub 51 if err := json.Unmarshal(bidderExt.Bidder, &smarthubExt); err != nil { 52 return nil, &errortypes.BadInput{ 53 Message: "Error while unmarshaling bidder extension", 54 } 55 } 56 57 return &smarthubExt, nil 58 } 59 60 func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtSmartHub) (string, error) { 61 endpointParams := macros.EndpointTemplateParams{ 62 Host: params.PartnerName, 63 AccountID: params.Seat, 64 SourceId: params.Token, 65 } 66 return macros.ResolveMacros(a.endpoint, endpointParams) 67 } 68 69 func (a *adapter) MakeRequests( 70 openRTBRequest *openrtb2.BidRequest, 71 reqInfo *adapters.ExtraRequestInfo, 72 ) ( 73 []*adapters.RequestData, 74 []error, 75 ) { 76 var smarthubExt *openrtb_ext.ExtSmartHub 77 smarthubExt, err := a.getImpressionExt(&(openRTBRequest.Imp[0])) 78 if err != nil { 79 return nil, []error{err} 80 } 81 82 url, err := a.buildEndpointURL(smarthubExt) 83 if err != nil { 84 return nil, []error{err} 85 } 86 87 reqJSON, err := json.Marshal(openRTBRequest) 88 if err != nil { 89 return nil, []error{err} 90 } 91 92 headers := http.Header{} 93 headers.Add("Content-Type", "application/json;charset=utf-8") 94 headers.Add("Accept", "application/json") 95 headers.Add("Prebid-Adapter-Ver", ADAPTER_VER) 96 97 return []*adapters.RequestData{{ 98 Method: http.MethodPost, 99 Body: reqJSON, 100 Uri: url, 101 Headers: headers, 102 }}, nil 103 } 104 105 func (a *adapter) MakeBids( 106 openRTBRequest *openrtb2.BidRequest, 107 requestToBidder *adapters.RequestData, 108 bidderRawResponse *adapters.ResponseData, 109 ) ( 110 *adapters.BidderResponse, 111 []error, 112 ) { 113 if bidderRawResponse.StatusCode == http.StatusNoContent { 114 return nil, nil 115 } 116 117 if bidderRawResponse.StatusCode == http.StatusBadRequest { 118 return nil, []error{&errortypes.BadInput{ 119 Message: fmt.Sprintf("Bad Request. %s", string(bidderRawResponse.Body)), 120 }} 121 } 122 123 if bidderRawResponse.StatusCode == http.StatusServiceUnavailable { 124 return nil, []error{&errortypes.BadInput{ 125 Message: "Bidder unavailable. Please contact the bidder support.", 126 }} 127 } 128 129 if bidderRawResponse.StatusCode != http.StatusOK { 130 return nil, []error{&errortypes.BadServerResponse{ 131 Message: fmt.Sprintf("Status Code: [ %d ] %s", bidderRawResponse.StatusCode, string(bidderRawResponse.Body)), 132 }} 133 } 134 135 responseBody := bidderRawResponse.Body 136 var bidResp openrtb2.BidResponse 137 if err := json.Unmarshal(responseBody, &bidResp); err != nil { 138 return nil, []error{err} 139 } 140 141 if len(bidResp.SeatBid) == 0 { 142 return nil, []error{&errortypes.BadServerResponse{ 143 Message: "Array SeatBid cannot be empty", 144 }} 145 } 146 147 bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) 148 149 bids := bidResp.SeatBid[0].Bid 150 151 if len(bids) == 0 { 152 return nil, []error{&errortypes.BadServerResponse{ 153 Message: "Array SeatBid[0].Bid cannot be empty", 154 }} 155 } 156 157 bid := bids[0] 158 159 var bidExt bidExt 160 var bidType openrtb_ext.BidType 161 162 if err := json.Unmarshal(bid.Ext, &bidExt); err != nil { 163 return nil, []error{&errortypes.BadServerResponse{ 164 Message: "Field BidExt is required", 165 }} 166 } 167 168 bidType, err := getBidType(bidExt) 169 170 if err != nil { 171 return nil, []error{err} 172 } 173 174 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 175 Bid: &bid, 176 BidType: bidType, 177 }) 178 return bidResponse, nil 179 } 180 181 func getBidType(ext bidExt) (openrtb_ext.BidType, error) { 182 return openrtb_ext.ParseBidType(ext.MediaType) 183 }