github.com/prebid/prebid-server@v0.275.0/adapters/aax/aax.go (about) 1 package aax 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/url" 8 9 "github.com/prebid/openrtb/v19/openrtb2" 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 type aaxResponseBidExt struct { 21 AdCodeType string `json:"adCodeType"` 22 } 23 24 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 25 var errs []error 26 27 reqJson, err := json.Marshal(request) 28 if err != nil { 29 errs = append(errs, err) 30 return nil, errs 31 } 32 33 headers := http.Header{} 34 headers.Add("Content-Type", "application/json;charset=utf-8") 35 36 return []*adapters.RequestData{{ 37 Method: "POST", 38 Uri: a.endpoint, 39 Body: reqJson, 40 Headers: headers, 41 }}, errs 42 } 43 44 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 45 var errs []error 46 47 if response.StatusCode == http.StatusNoContent { 48 return nil, nil 49 } 50 51 if response.StatusCode == http.StatusBadRequest { 52 return nil, []error{&errortypes.BadInput{ 53 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 54 }} 55 } 56 57 if response.StatusCode != http.StatusOK { 58 return nil, []error{&errortypes.BadServerResponse{ 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 65 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 66 return nil, []error{err} 67 } 68 69 bidResponse := adapters.NewBidderResponse() 70 71 for _, seatBid := range bidResp.SeatBid { 72 for i := range seatBid.Bid { 73 bidType, err := getMediaTypeForImp(seatBid.Bid[i], internalRequest.Imp) 74 if err != nil { 75 errs = append(errs, err) 76 } else { 77 b := &adapters.TypedBid{ 78 Bid: &seatBid.Bid[i], 79 BidType: bidType, 80 } 81 bidResponse.Bids = append(bidResponse.Bids, b) 82 } 83 } 84 } 85 return bidResponse, errs 86 } 87 88 // Builder builds a new instance of the Aax adapter for the given bidder with the given config. 89 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 90 url := buildEndpoint(config.Endpoint, config.ExtraAdapterInfo) 91 return &adapter{ 92 endpoint: url, 93 }, nil 94 } 95 96 func getMediaTypeForImp(bid openrtb2.Bid, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { 97 var bidExt aaxResponseBidExt 98 err := json.Unmarshal(bid.Ext, &bidExt) 99 if err == nil { 100 switch bidExt.AdCodeType { 101 case "banner": 102 return openrtb_ext.BidTypeBanner, nil 103 case "native": 104 return openrtb_ext.BidTypeNative, nil 105 case "video": 106 return openrtb_ext.BidTypeVideo, nil 107 } 108 } 109 110 var mediaType openrtb_ext.BidType 111 var typeCnt = 0 112 for _, imp := range imps { 113 if imp.ID == bid.ImpID { 114 if imp.Banner != nil { 115 typeCnt += 1 116 mediaType = openrtb_ext.BidTypeBanner 117 } 118 if imp.Native != nil { 119 typeCnt += 1 120 mediaType = openrtb_ext.BidTypeNative 121 } 122 if imp.Video != nil { 123 typeCnt += 1 124 mediaType = openrtb_ext.BidTypeVideo 125 } 126 } 127 } 128 if typeCnt == 1 { 129 return mediaType, nil 130 } 131 return mediaType, fmt.Errorf("unable to fetch mediaType in multi-format: %s", bid.ImpID) 132 } 133 134 func buildEndpoint(aaxUrl, hostUrl string) string { 135 136 if len(hostUrl) == 0 { 137 return aaxUrl 138 } 139 urlObject, err := url.Parse(aaxUrl) 140 if err != nil { 141 return aaxUrl 142 } 143 values := urlObject.Query() 144 values.Add("src", hostUrl) 145 urlObject.RawQuery = values.Encode() 146 return urlObject.String() 147 }