github.com/prebid/prebid-server/v2@v2.18.0/adapters/sovrnXsp/sovrnXsp.go (about) 1 package sovrnXsp 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 8 "github.com/prebid/prebid-server/v2/adapters" 9 "github.com/prebid/prebid-server/v2/config" 10 "github.com/prebid/prebid-server/v2/errortypes" 11 "github.com/prebid/prebid-server/v2/openrtb_ext" 12 13 "github.com/prebid/openrtb/v20/openrtb2" 14 ) 15 16 type adapter struct { 17 Endpoint string 18 } 19 20 // bidExt.CreativeType values. 21 const ( 22 creativeTypeBanner int = 0 23 creativeTypeVideo int = 1 24 creativeTypeNative int = 2 25 creativeTypeAudio int = 3 26 ) 27 28 // Bid response extension from XSP. 29 type bidExt struct { 30 CreativeType int `json:"creative_type"` 31 } 32 33 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 34 appCopy := *request.App 35 if appCopy.Publisher == nil { 36 appCopy.Publisher = &openrtb2.Publisher{} 37 } else { 38 publisherCopy := *appCopy.Publisher 39 appCopy.Publisher = &publisherCopy 40 } 41 request.App = &appCopy 42 43 var errors []error 44 var imps []openrtb2.Imp 45 46 for idx, imp := range request.Imp { 47 if imp.Banner == nil && imp.Video == nil && imp.Native == nil { 48 continue 49 } 50 51 var bidderExt adapters.ExtImpBidder 52 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 53 err = &errortypes.BadInput{ 54 Message: fmt.Sprintf("imp #%d: ext.bidder not provided", idx), 55 } 56 errors = append(errors, err) 57 continue 58 } 59 60 var xspExt openrtb_ext.ExtImpSovrnXsp 61 if err := json.Unmarshal(bidderExt.Bidder, &xspExt); err != nil { 62 err = &errortypes.BadInput{ 63 Message: fmt.Sprintf("imp #%d: %s", idx, err.Error()), 64 } 65 errors = append(errors, err) 66 continue 67 } 68 69 request.App.Publisher.ID = xspExt.PubID 70 if xspExt.MedID != "" { 71 request.App.ID = xspExt.MedID 72 } 73 if xspExt.ZoneID != "" { 74 imp.TagID = xspExt.ZoneID 75 } 76 imps = append(imps, imp) 77 } 78 79 if len(imps) == 0 { 80 return nil, append(errors, &errortypes.BadInput{ 81 Message: "no matching impression with ad format", 82 }) 83 } 84 85 request.Imp = imps 86 requestJson, err := json.Marshal(request) 87 if err != nil { 88 return nil, append(errors, err) 89 } 90 91 headers := http.Header{} 92 headers.Add("Content-Type", "application/json;charset=utf-8") 93 headers.Add("Accept", "application/json") 94 headers.Add("x-openrtb-version", "2.5") 95 96 return []*adapters.RequestData{{ 97 Method: "POST", 98 Uri: a.Endpoint, 99 Body: requestJson, 100 Headers: headers, 101 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 102 }}, errors 103 } 104 105 func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 106 if adapters.IsResponseStatusCodeNoContent(responseData) { 107 return nil, nil 108 } 109 if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil { 110 return nil, []error{err} 111 } 112 113 var response openrtb2.BidResponse 114 if err := json.Unmarshal(responseData.Body, &response); err != nil { 115 return nil, []error{err} 116 } 117 118 var errors []error 119 result := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) 120 121 for _, seatBid := range response.SeatBid { 122 for _, bid := range seatBid.Bid { 123 bid := bid 124 var ext bidExt 125 if err := json.Unmarshal(bid.Ext, &ext); err != nil { 126 errors = append(errors, err) 127 continue 128 } 129 130 var bidType openrtb_ext.BidType 131 var mkupType openrtb2.MarkupType 132 switch ext.CreativeType { 133 case creativeTypeBanner: 134 bidType = openrtb_ext.BidTypeBanner 135 mkupType = openrtb2.MarkupBanner 136 case creativeTypeVideo: 137 bidType = openrtb_ext.BidTypeVideo 138 mkupType = openrtb2.MarkupVideo 139 case creativeTypeNative: 140 bidType = openrtb_ext.BidTypeNative 141 mkupType = openrtb2.MarkupNative 142 default: 143 errors = append(errors, &errortypes.BadServerResponse{ 144 Message: fmt.Sprintf("Unsupported creative type: %d", ext.CreativeType), 145 }) 146 continue 147 } 148 149 if bid.MType == 0 { 150 bid.MType = mkupType 151 } 152 153 result.Bids = append(result.Bids, &adapters.TypedBid{ 154 Bid: &bid, 155 BidType: bidType, 156 }) 157 } 158 } 159 160 if len(result.Bids) == 0 { 161 // it's possible an empty seat array was sent as a response 162 return nil, errors 163 } 164 return result, errors 165 } 166 167 // Builder builds a new instance of the SovrnXSP adapter for the given bidder with the given config. 168 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 169 bidder := &adapter{ 170 Endpoint: config.Endpoint, 171 } 172 return bidder, nil 173 }