github.com/prebid/prebid-server/v2@v2.18.0/adapters/aidem/aidem.go (about) 1 package aidem 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "text/template" 8 9 "github.com/prebid/openrtb/v20/openrtb2" 10 "github.com/prebid/prebid-server/v2/adapters" 11 "github.com/prebid/prebid-server/v2/config" 12 "github.com/prebid/prebid-server/v2/errortypes" 13 "github.com/prebid/prebid-server/v2/macros" 14 "github.com/prebid/prebid-server/v2/openrtb_ext" 15 ) 16 17 type adapter struct { 18 EndpointTemplate *template.Template 19 } 20 21 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 22 23 reqJson, err := json.Marshal(request) 24 if err != nil { 25 return nil, []error{err} 26 } 27 28 impExt, err := getImpressionExt(&request.Imp[0]) 29 if err != nil { 30 return nil, []error{err} 31 } 32 33 url, err := a.buildEndpointURL(impExt) 34 if err != nil { 35 return nil, []error{err} 36 } 37 38 headers := http.Header{} 39 headers.Add("Content-Type", "application/json;charset=utf-8") 40 41 return []*adapters.RequestData{{ 42 Method: "POST", 43 Uri: url, 44 Body: reqJson, 45 Headers: headers, 46 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 47 }}, nil 48 } 49 50 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 51 var errs []error 52 53 if adapters.IsResponseStatusCodeNoContent(response) { 54 return nil, nil 55 } 56 57 if err := adapters.CheckResponseStatusCodeForErrors(response); err != nil { 58 return nil, []error{&errortypes.BadInput{ 59 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 60 }} 61 } 62 63 var bidResp openrtb2.BidResponse 64 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 65 return nil, []error{&errortypes.BadServerResponse{ 66 Message: fmt.Sprintf("JSON parsing error: %v", err), 67 }} 68 } 69 70 if len(bidResp.SeatBid) == 0 { 71 return nil, []error{&errortypes.BadServerResponse{ 72 Message: "Empty SeatBid array", 73 }} 74 } 75 76 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(bidResp.SeatBid[0].Bid)) 77 78 for _, seatBid := range bidResp.SeatBid { 79 for i := range seatBid.Bid { 80 bidType, err := getMediaTypeForBid(seatBid.Bid[i]) 81 if err != nil { 82 errs = append(errs, err) 83 } else { 84 b := &adapters.TypedBid{ 85 Bid: &seatBid.Bid[i], 86 BidType: bidType, 87 } 88 bidResponse.Bids = append(bidResponse.Bids, b) 89 } 90 } 91 } 92 return bidResponse, errs 93 } 94 95 // Builder builds a new instance of the AIDEM adapter for the given bidder with the given config. 96 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 97 urlTemplate, err := template.New("endpointTemplate").Parse(config.Endpoint) 98 if err != nil { 99 return nil, fmt.Errorf("unable to parse endpoint url template: %v", err) 100 } 101 102 bidder := &adapter{ 103 EndpointTemplate: urlTemplate, 104 } 105 return bidder, nil 106 } 107 108 func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { 109 switch bid.MType { 110 case openrtb2.MarkupBanner: 111 return openrtb_ext.BidTypeBanner, nil 112 case openrtb2.MarkupVideo: 113 return openrtb_ext.BidTypeVideo, nil 114 case openrtb2.MarkupAudio: 115 return openrtb_ext.BidTypeAudio, nil 116 case openrtb2.MarkupNative: 117 return openrtb_ext.BidTypeNative, nil 118 default: 119 return "", fmt.Errorf("Unable to fetch mediaType in multi-format: %s", bid.ImpID) 120 } 121 } 122 123 func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpAidem, error) { 124 var bidderExt adapters.ExtImpBidder 125 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 126 return nil, &errortypes.BadInput{ 127 Message: err.Error(), 128 } 129 } 130 var AIDEMExt openrtb_ext.ExtImpAidem 131 if err := json.Unmarshal(bidderExt.Bidder, &AIDEMExt); err != nil { 132 return nil, &errortypes.BadInput{ 133 Message: err.Error(), 134 } 135 } 136 return &AIDEMExt, nil 137 } 138 139 // Builds enpoint url based on adapter-specific pub settings from imp.ext 140 func (a *adapter) buildEndpointURL(params *openrtb_ext.ExtImpAidem) (string, error) { 141 endpointParams := macros.EndpointTemplateParams{PublisherID: params.PublisherId} 142 return macros.ResolveMacros(a.EndpointTemplate, endpointParams) 143 }