github.com/prebid/prebid-server@v0.275.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/v19/openrtb2" 9 "github.com/prebid/prebid-server/adapters" 10 "github.com/prebid/prebid-server/config" 11 "github.com/prebid/prebid-server/errortypes" 12 "github.com/prebid/prebid-server/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 } 95 96 return []*adapters.RequestData{requestData}, errors 97 } 98 99 func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) { 100 if responseData.StatusCode == http.StatusNoContent { 101 return nil, nil 102 } 103 104 if responseData.StatusCode == http.StatusBadRequest { 105 err := &errortypes.BadInput{ 106 Message: "Unexpected status code: 400. Bad request from publisher.", 107 } 108 return nil, []error{err} 109 } 110 111 if responseData.StatusCode != http.StatusOK { 112 err := &errortypes.BadServerResponse{ 113 Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode), 114 } 115 return nil, []error{err} 116 } 117 118 var response openrtb2.BidResponse 119 if err := json.Unmarshal(responseData.Body, &response); err != nil { 120 return nil, []error{err} 121 } 122 123 bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp)) 124 bidResponse.Currency = response.Cur 125 var errors []error 126 for _, seatBid := range response.SeatBid { 127 for i, bid := range seatBid.Bid { 128 bidType, err := getMediaTypeForBid(bid) 129 if err != nil { 130 errors = append(errors, err) 131 continue 132 } 133 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 134 Bid: &seatBid.Bid[i], 135 BidType: bidType, 136 }) 137 } 138 } 139 140 return bidResponse, errors 141 } 142 143 func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) { 144 if bid.Ext != nil { 145 var bidExt openrtb_ext.ExtBid 146 err := json.Unmarshal(bid.Ext, &bidExt) 147 if err == nil && bidExt.Prebid != nil { 148 return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type)) 149 } 150 } 151 152 return "", &errortypes.BadServerResponse{ 153 Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID), 154 } 155 }