github.com/prebid/prebid-server@v0.275.0/adapters/pulsepoint/pulsepoint.go (about) 1 package pulsepoint 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strconv" 8 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 "github.com/prebid/openrtb/v19/openrtb2" 15 ) 16 17 type PulsePointAdapter struct { 18 URI string 19 } 20 21 // Builds an instance of PulsePointAdapter 22 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 23 bidder := &PulsePointAdapter{ 24 URI: config.Endpoint, 25 } 26 return bidder, nil 27 } 28 29 func (a *PulsePointAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 30 errs := make([]error, 0, len(request.Imp)) 31 32 var err error 33 pubID := "" 34 imps := make([]openrtb2.Imp, 0, len(request.Imp)) 35 for i := 0; i < len(request.Imp); i++ { 36 imp := request.Imp[i] 37 var bidderExt adapters.ExtImpBidder 38 if err = json.Unmarshal(imp.Ext, &bidderExt); err != nil { 39 errs = append(errs, &errortypes.BadInput{ 40 Message: err.Error(), 41 }) 42 continue 43 } 44 var pulsepointExt openrtb_ext.ExtImpPulsePoint 45 if err = json.Unmarshal(bidderExt.Bidder, &pulsepointExt); err != nil { 46 errs = append(errs, &errortypes.BadInput{ 47 Message: err.Error(), 48 }) 49 continue 50 } 51 // parse pubid and keep it for reference 52 if pubID == "" && pulsepointExt.PubID > 0 { 53 pubID = strconv.Itoa(pulsepointExt.PubID) 54 } 55 // tag id to be sent 56 imp.TagID = strconv.Itoa(pulsepointExt.TagID) 57 imps = append(imps, imp) 58 } 59 60 // verify there are valid impressions 61 if len(imps) == 0 { 62 return nil, errs 63 } 64 65 // add the publisher id from ext to the site.pub.id or app.pub.id 66 if request.Site != nil { 67 site := *request.Site 68 if site.Publisher != nil { 69 publisher := *site.Publisher 70 publisher.ID = pubID 71 site.Publisher = &publisher 72 } else { 73 site.Publisher = &openrtb2.Publisher{ID: pubID} 74 } 75 request.Site = &site 76 } else if request.App != nil { 77 app := *request.App 78 if app.Publisher != nil { 79 publisher := *app.Publisher 80 publisher.ID = pubID 81 app.Publisher = &publisher 82 } else { 83 app.Publisher = &openrtb2.Publisher{ID: pubID} 84 } 85 request.App = &app 86 } 87 88 request.Imp = imps 89 reqJSON, err := json.Marshal(request) 90 if err != nil { 91 errs = append(errs, err) 92 return nil, errs 93 } 94 headers := http.Header{} 95 headers.Add("Content-Type", "application/json;charset=utf-8") 96 headers.Add("Accept", "application/json") 97 return []*adapters.RequestData{{ 98 Method: "POST", 99 Uri: a.URI, 100 Body: reqJSON, 101 Headers: headers, 102 }}, errs 103 } 104 105 func (a *PulsePointAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 106 // passback 107 if response.StatusCode == http.StatusNoContent { 108 return nil, nil 109 } 110 // bad requests 111 if response.StatusCode == http.StatusBadRequest { 112 return nil, []error{&errortypes.BadInput{ 113 Message: fmt.Sprintf("Bad user input: HTTP status %d", response.StatusCode), 114 }} 115 } 116 // error 117 if response.StatusCode != http.StatusOK { 118 return nil, []error{&errortypes.BadServerResponse{ 119 Message: fmt.Sprintf("Bad server response: HTTP status %d", response.StatusCode), 120 }} 121 } 122 // parse response 123 var bidResp openrtb2.BidResponse 124 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 125 return nil, []error{err} 126 } 127 128 bidResponse := adapters.NewBidderResponseWithBidsCapacity(5) 129 // map imps by id 130 impsByID := make(map[string]openrtb2.Imp) 131 for i := 0; i < len(internalRequest.Imp); i++ { 132 impsByID[internalRequest.Imp[i].ID] = internalRequest.Imp[i] 133 } 134 135 var errs []error 136 for _, sb := range bidResp.SeatBid { 137 for i := 0; i < len(sb.Bid); i++ { 138 bid := sb.Bid[i] 139 imp := impsByID[bid.ImpID] 140 bidType := getBidType(imp) 141 if &imp != nil && bidType != "" { 142 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 143 Bid: &bid, 144 BidType: bidType, 145 }) 146 } 147 } 148 } 149 return bidResponse, errs 150 } 151 152 func getBidType(imp openrtb2.Imp) openrtb_ext.BidType { 153 // derive the bidtype purely from the impression itself 154 if imp.Banner != nil { 155 return openrtb_ext.BidTypeBanner 156 } else if imp.Video != nil { 157 return openrtb_ext.BidTypeVideo 158 } else if imp.Audio != nil { 159 return openrtb_ext.BidTypeAudio 160 } else if imp.Native != nil { 161 return openrtb_ext.BidTypeNative 162 } 163 return "" 164 }