github.com/prebid/prebid-server/v2@v2.18.0/adapters/yieldone/yieldone.go (about) 1 package yieldone 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/prebid/openrtb/v20/openrtb2" 9 "github.com/prebid/prebid-server/v2/adapters" 10 "github.com/prebid/prebid-server/v2/config" 11 "github.com/prebid/prebid-server/v2/errortypes" 12 "github.com/prebid/prebid-server/v2/openrtb_ext" 13 ) 14 15 type YieldoneAdapter struct { 16 endpoint string 17 } 18 19 // MakeRequests makes the HTTP requests which should be made to fetch bids. 20 func (a *YieldoneAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 21 var errors = make([]error, 0) 22 23 var validImps []openrtb2.Imp 24 for i := 0; i < len(request.Imp); i++ { 25 if err := preprocess(&request.Imp[i]); err == nil { 26 validImps = append(validImps, request.Imp[i]) 27 } else { 28 errors = append(errors, err) 29 } 30 } 31 32 request.Imp = validImps 33 34 reqJSON, err := json.Marshal(request) 35 if err != nil { 36 errors = append(errors, err) 37 return nil, errors 38 } 39 40 headers := http.Header{} 41 headers.Add("Content-Type", "application/json;charset=utf-8") 42 43 return []*adapters.RequestData{{ 44 Method: "POST", 45 Uri: a.endpoint, 46 Body: reqJSON, 47 Headers: headers, 48 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 49 }}, errors 50 } 51 52 // MakeBids unpacks the server's response into Bids. 53 func (a *YieldoneAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 54 if response.StatusCode == http.StatusNoContent { 55 return nil, nil 56 } 57 58 if response.StatusCode == http.StatusBadRequest { 59 return nil, []error{&errortypes.BadInput{ 60 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 61 }} 62 } 63 64 if response.StatusCode != http.StatusOK { 65 return nil, []error{&errortypes.BadServerResponse{ 66 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 67 }} 68 } 69 70 var bidResp openrtb2.BidResponse 71 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 72 return nil, []error{err} 73 } 74 75 bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) 76 77 for _, sb := range bidResp.SeatBid { 78 for i := range sb.Bid { 79 bidType, err := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp) 80 if err != nil { 81 return nil, []error{err} 82 } 83 84 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 85 Bid: &sb.Bid[i], 86 BidType: bidType, 87 }) 88 } 89 } 90 if bidResp.Cur != "" { 91 bidResponse.Currency = bidResp.Cur 92 } 93 return bidResponse, nil 94 95 } 96 97 // Builder builds a new instance of the Yieldone adapter for the given bidder with the given config. 98 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 99 bidder := &YieldoneAdapter{ 100 endpoint: config.Endpoint, 101 } 102 return bidder, nil 103 } 104 105 func preprocess(imp *openrtb2.Imp) error { 106 107 var ext adapters.ExtImpBidder 108 if err := json.Unmarshal(imp.Ext, &ext); err != nil { 109 return err 110 } 111 var impressionExt openrtb_ext.ExtImpYieldone 112 if err := json.Unmarshal(ext.Bidder, &impressionExt); err != nil { 113 return err 114 } 115 116 if imp.Banner != nil { 117 bannerCopy := *imp.Banner 118 if bannerCopy.W == nil && bannerCopy.H == nil && len(bannerCopy.Format) > 0 { 119 firstFormat := bannerCopy.Format[0] 120 bannerCopy.W = &(firstFormat.W) 121 bannerCopy.H = &(firstFormat.H) 122 } 123 imp.Banner = &bannerCopy 124 } 125 126 return nil 127 } 128 129 func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { 130 for _, imp := range imps { 131 if imp.ID == impID { 132 if imp.Banner != nil { 133 return openrtb_ext.BidTypeBanner, nil 134 } 135 136 if imp.Video != nil { 137 return openrtb_ext.BidTypeVideo, nil 138 } 139 140 return "", &errortypes.BadServerResponse{ 141 Message: fmt.Sprintf("Unknown impression type for ID: \"%s\"", impID), 142 } 143 } 144 } 145 146 // This shouldnt happen. Lets handle it just incase by returning an error. 147 return "", &errortypes.BadServerResponse{ 148 Message: fmt.Sprintf("Failed to find impression for ID: \"%s\"", impID), 149 } 150 }