github.com/prebid/prebid-server/v2@v2.18.0/adapters/adf/adf.go (about) 1 package adf 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 adapter struct { 16 endpoint string 17 } 18 19 type adfRequestExt struct { 20 openrtb_ext.ExtRequest 21 PriceType string `json:"pt"` 22 } 23 24 // Builder builds a new instance of the Adf adapter for the given bidder with the given config. 25 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 26 bidder := &adapter{ 27 endpoint: config.Endpoint, 28 } 29 return bidder, nil 30 } 31 32 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 33 var errors []error 34 var validImps = make([]openrtb2.Imp, 0, len(request.Imp)) 35 priceType := "" 36 37 for _, imp := range request.Imp { 38 var bidderExt adapters.ExtImpBidder 39 if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil { 40 errors = append(errors, &errortypes.BadInput{ 41 Message: err.Error(), 42 }) 43 continue 44 } 45 46 var adfImpExt openrtb_ext.ExtImpAdf 47 if err := json.Unmarshal(bidderExt.Bidder, &adfImpExt); err != nil { 48 errors = append(errors, &errortypes.BadInput{ 49 Message: err.Error(), 50 }) 51 continue 52 } 53 54 imp.TagID = adfImpExt.MasterTagID.String() 55 validImps = append(validImps, imp) 56 57 // If imps specify priceType they should all be the same. If they differ, only the first one will be used 58 if adfImpExt.PriceType != "" && priceType == "" { 59 priceType = adfImpExt.PriceType 60 } 61 } 62 63 if priceType != "" { 64 requestExt := adfRequestExt{} 65 var err error 66 67 if len(request.Ext) > 0 { 68 if err = json.Unmarshal(request.Ext, &requestExt); err != nil { 69 errors = append(errors, err) 70 } 71 } 72 73 if err == nil { 74 requestExt.PriceType = priceType 75 76 if request.Ext, err = json.Marshal(&requestExt); err != nil { 77 errors = append(errors, err) 78 } 79 } 80 } 81 82 request.Imp = validImps 83 84 requestJSON, err := json.Marshal(request) 85 if err != nil { 86 errors = append(errors, err) 87 return nil, errors 88 } 89 90 requestData := &adapters.RequestData{ 91 Method: "POST", 92 Uri: a.endpoint, 93 Body: requestJSON, 94 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 95 } 96 97 return []*adapters.RequestData{requestData}, errors 98 } 99 100 func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 101 if responseData.StatusCode == http.StatusNoContent { 102 return nil, nil 103 } 104 105 if responseData.StatusCode == http.StatusBadRequest { 106 err := &errortypes.BadInput{ 107 Message: "Unexpected status code: 400. Bad request from publisher.", 108 } 109 return nil, []error{err} 110 } 111 112 if responseData.StatusCode != http.StatusOK { 113 err := &errortypes.BadServerResponse{ 114 Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode), 115 } 116 return nil, []error{err} 117 } 118 119 var response openrtb2.BidResponse 120 if err := json.Unmarshal(responseData.Body, &response); err != nil { 121 return nil, []error{err} 122 } 123 124 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) 125 bidResponse.Currency = response.Cur 126 var errors []error 127 for _, seatBid := range response.SeatBid { 128 for i, bid := range seatBid.Bid { 129 bidType, err := getMediaTypeForBid(bid) 130 if err != nil { 131 errors = append(errors, err) 132 continue 133 } 134 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 135 Bid: &seatBid.Bid[i], 136 BidType: bidType, 137 }) 138 } 139 } 140 141 return bidResponse, errors 142 } 143 144 func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { 145 if bid.Ext != nil { 146 var bidExt openrtb_ext.ExtBid 147 err := json.Unmarshal(bid.Ext, &bidExt) 148 if err == nil && bidExt.Prebid != nil { 149 return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) 150 } 151 } 152 153 return "", &errortypes.BadServerResponse{ 154 Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), 155 } 156 }