github.com/prebid/prebid-server@v0.275.0/adapters/engagebdr/engagebdr.go (about) 1 package engagebdr 2 3 import ( 4 "encoding/json" 5 "net/http" 6 7 "github.com/prebid/openrtb/v19/openrtb2" 8 "github.com/prebid/prebid-server/config" 9 "github.com/prebid/prebid-server/openrtb_ext" 10 11 "fmt" 12 13 "github.com/prebid/prebid-server/adapters" 14 "github.com/prebid/prebid-server/errortypes" 15 ) 16 17 type EngageBDRAdapter struct { 18 URI string 19 } 20 21 func (adapter *EngageBDRAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 22 23 errors := make([]error, 0, len(request.Imp)) 24 25 if request.Imp == nil || len(request.Imp) == 0 { 26 errors = append(errors, &errortypes.BadInput{ 27 Message: fmt.Sprintf("Invalid BidRequest. No valid imp."), 28 }) 29 return nil, errors 30 } 31 32 // EngageBDR uses different sspid parameters for banner and video. 33 sspidImps := make(map[string][]openrtb2.Imp) 34 for _, imp := range request.Imp { 35 36 if imp.Audio != nil { 37 errors = append(errors, &errortypes.BadInput{ 38 Message: fmt.Sprintf("Ignoring imp id=%s, invalid MediaType. EngageBDR only supports Banner, Video and Native.", imp.ID), 39 }) 40 continue 41 } 42 43 var bidderExt adapters.ExtImpBidder 44 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 45 errors = append(errors, &errortypes.BadInput{ 46 Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s.", imp.ID, err), 47 }) 48 continue 49 } 50 impExt := openrtb_ext.ExtImpEngageBDR{} 51 err := json.Unmarshal(bidderExt.Bidder, &impExt) 52 if err != nil { 53 errors = append(errors, &errortypes.BadInput{ 54 Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s.", imp.ID, err), 55 }) 56 continue 57 } 58 if impExt.Sspid == "" { 59 errors = append(errors, &errortypes.BadInput{ 60 Message: fmt.Sprintf("Ignoring imp id=%s, no sspid present.", imp.ID), 61 }) 62 continue 63 } 64 sspidImps[impExt.Sspid] = append(sspidImps[impExt.Sspid], imp) 65 } 66 67 var adapterRequests []*adapters.RequestData 68 69 headers := http.Header{} 70 headers.Add("Content-Type", "application/json;charset=utf-8") 71 72 for sspid, imps := range sspidImps { 73 if len(imps) > 0 { 74 // Make a copy as we don't want to change the original request 75 reqCopy := *request 76 reqCopy.Imp = imps 77 reqJSON, err := json.Marshal(reqCopy) 78 if err != nil { 79 errors = append(errors, err) 80 return nil, errors 81 } 82 adapterReq := adapters.RequestData{ 83 Method: "POST", 84 Uri: adapter.URI + "?zoneid=" + sspid, 85 Body: reqJSON, 86 Headers: headers, 87 } 88 adapterRequests = append(adapterRequests, &adapterReq) 89 } 90 } 91 92 return adapterRequests, errors 93 } 94 95 func (adapter *EngageBDRAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 96 if response.StatusCode == http.StatusNoContent { 97 return nil, nil 98 } 99 100 if response.StatusCode == http.StatusBadRequest { 101 return nil, []error{&errortypes.BadInput{ 102 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 103 }} 104 } 105 106 if response.StatusCode != http.StatusOK { 107 return nil, []error{&errortypes.BadServerResponse{ 108 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 109 }} 110 } 111 112 var bidResp openrtb2.BidResponse 113 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 114 return nil, []error{err} 115 } 116 117 bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) 118 119 for _, sb := range bidResp.SeatBid { 120 for i := range sb.Bid { 121 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 122 Bid: &sb.Bid[i], 123 BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp), 124 }) 125 } 126 } 127 return bidResponse, nil 128 } 129 130 func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType { 131 mediaType := openrtb_ext.BidTypeBanner 132 for _, imp := range imps { 133 if imp.ID == impId { 134 if imp.Video != nil { 135 mediaType = openrtb_ext.BidTypeVideo 136 } else if imp.Native != nil { 137 mediaType = openrtb_ext.BidTypeNative 138 } 139 return mediaType 140 } 141 } 142 return mediaType 143 } 144 145 // Builder builds a new instance of the EngageBDR adapter for the given bidder with the given config. 146 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 147 bidder := &EngageBDRAdapter{ 148 URI: config.Endpoint, 149 } 150 return bidder, nil 151 }