github.com/prebid/prebid-server@v0.275.0/adapters/vidoomy/vidoomy.go (about) 1 package vidoomy 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/prebid/openrtb/v19/openrtb2" 9 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/openrtb_ext" 14 ) 15 16 type adapter struct { 17 endpoint string 18 } 19 20 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 21 var errors []error 22 23 reqs := make([]*adapters.RequestData, 0, len(request.Imp)) 24 25 header := getHeaders(request) 26 for _, imp := range request.Imp { 27 28 // Split up multi-impression requests into multiple requests so that 29 // each split request is only associated to a single impression 30 reqCopy := *request 31 reqCopy.Imp = []openrtb2.Imp{imp} 32 33 if err := changeRequestForBidService(&reqCopy); err != nil { 34 errors = append(errors, err) 35 continue 36 } 37 38 reqJSON, err := json.Marshal(&reqCopy) 39 if err != nil { 40 errors = append(errors, err) 41 continue 42 } 43 44 reqs = append(reqs, &adapters.RequestData{ 45 Method: "POST", 46 Uri: a.endpoint, 47 Body: reqJSON, 48 Headers: header, 49 }) 50 } 51 52 return reqs, errors 53 } 54 55 func getHeaders(request *openrtb2.BidRequest) http.Header { 56 headers := http.Header{} 57 58 headers.Add("Content-Type", "application/json;charset=utf-8") 59 headers.Add("Accept", "application/json") 60 headers.Add("x-openrtb-version", "2.5") 61 62 if request.Device == nil { 63 return headers 64 } 65 66 if request.Device.UA != "" { 67 headers.Set("User-Agent", request.Device.UA) 68 } 69 70 if len(request.Device.IPv6) > 0 { 71 headers.Add("X-Forwarded-For", request.Device.IPv6) 72 } 73 74 if len(request.Device.IP) > 0 { 75 headers.Add("X-Forwarded-For", request.Device.IP) 76 } 77 78 return headers 79 } 80 81 func changeRequestForBidService(request *openrtb2.BidRequest) error { 82 if request.Imp[0].Banner == nil { 83 return nil 84 } 85 86 banner := *request.Imp[0].Banner 87 request.Imp[0].Banner = &banner 88 89 if banner.W != nil && banner.H != nil { 90 if *banner.W == 0 || *banner.H == 0 { 91 return fmt.Errorf("invalid sizes provided for Banner %d x %d", *banner.W, *banner.H) 92 } 93 return nil 94 } 95 96 if len(banner.Format) == 0 { 97 return fmt.Errorf("no sizes provided for Banner %v", banner.Format) 98 } 99 100 banner.W = openrtb2.Int64Ptr(banner.Format[0].W) 101 banner.H = openrtb2.Int64Ptr(banner.Format[0].H) 102 103 return nil 104 } 105 106 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 107 if response.StatusCode == http.StatusNoContent { 108 return nil, nil 109 } 110 111 if response.StatusCode != http.StatusOK { 112 return nil, []error{&errortypes.BadServerResponse{ 113 Message: fmt.Sprintf("Unexpected status code: %d.", response.StatusCode), 114 }} 115 } 116 117 var bidResp openrtb2.BidResponse 118 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 119 return nil, []error{&errortypes.BadServerResponse{ 120 Message: fmt.Sprintf("Bad server response: %d.", err), 121 }} 122 } 123 124 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(internalRequest.Imp)) 125 126 for _, sb := range bidResp.SeatBid { 127 for _, bid := range sb.Bid { 128 bid := bid 129 exists, mediaType := getImpInfo(bid.ImpID, internalRequest.Imp) 130 if !exists { 131 return nil, []error{&errortypes.BadServerResponse{ 132 Message: fmt.Sprintf("Unknown ad unit code '%s'", bid.ImpID), 133 }} 134 } 135 136 if openrtb_ext.BidTypeBanner != mediaType && 137 openrtb_ext.BidTypeVideo != mediaType { 138 //only banner and video are supported, anything else is ignored 139 continue 140 } 141 142 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 143 Bid: &bid, 144 BidType: mediaType, 145 }) 146 } 147 } 148 149 return bidResponse, nil 150 } 151 152 func getImpInfo(impId string, imps []openrtb2.Imp) (bool, openrtb_ext.BidType) { 153 var mediaType openrtb_ext.BidType 154 for _, imp := range imps { 155 if imp.ID == impId { 156 157 if imp.Video != nil { 158 mediaType = openrtb_ext.BidTypeVideo 159 } else if imp.Banner != nil { 160 mediaType = openrtb_ext.BidTypeBanner 161 } 162 163 return true, mediaType 164 } 165 } 166 return false, mediaType 167 } 168 169 // Builder builds a new instance of the Vidoomy adapter for the given bidder with the given config. 170 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 171 bidder := &adapter{ 172 endpoint: config.Endpoint, 173 } 174 return bidder, nil 175 }