github.com/prebid/prebid-server/v2@v2.18.0/adapters/mobfoxpb/mobfoxpb.go (about) 1 package mobfoxpb 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strings" 8 9 "github.com/buger/jsonparser" 10 "github.com/prebid/openrtb/v20/openrtb2" 11 "github.com/prebid/prebid-server/v2/adapters" 12 "github.com/prebid/prebid-server/v2/config" 13 "github.com/prebid/prebid-server/v2/errortypes" 14 "github.com/prebid/prebid-server/v2/openrtb_ext" 15 ) 16 17 const ( 18 ROUTE_NATIVE = "o" 19 ROUTE_RTB = "rtb" 20 METHOD_NATIVE = "ortb" 21 METHOD_RTB = "req" 22 MACROS_ROUTE = "__route__" 23 MACROS_METHOD = "__method__" 24 MACROS_KEY = "__key__" 25 ) 26 27 type adapter struct { 28 URI string 29 } 30 31 // Builder builds a new instance of the Mobfox adapter for the given bidder with the given config. 32 func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) { 33 bidder := &adapter{ 34 URI: config.Endpoint, 35 } 36 return bidder, nil 37 } 38 39 // MakeRequests create bid request for mobfoxpb demand 40 func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) { 41 var errs []error 42 var route string 43 var method string 44 var adapterRequests []*adapters.RequestData 45 46 requestURI := a.URI 47 reqCopy := *request 48 imp := request.Imp[0] 49 tagID, errTag := jsonparser.GetString(imp.Ext, "bidder", "TagID") 50 key, errKey := jsonparser.GetString(imp.Ext, "bidder", "key") 51 if errTag != nil && errKey != nil { 52 errs = append(errs, &errortypes.BadInput{ 53 Message: fmt.Sprintf("Invalid or non existing key and tagId, atleast one should be present"), 54 }) 55 return nil, errs 56 } 57 58 if key != "" { 59 route = ROUTE_RTB 60 method = METHOD_RTB 61 requestURI = strings.Replace(requestURI, MACROS_KEY, key, 1) 62 } else if tagID != "" { 63 method = METHOD_NATIVE 64 route = ROUTE_NATIVE 65 } 66 67 requestURI = strings.Replace(requestURI, MACROS_ROUTE, route, 1) 68 requestURI = strings.Replace(requestURI, MACROS_METHOD, method, 1) 69 70 reqCopy.Imp = []openrtb2.Imp{imp} 71 adapterReq, err := a.makeRequest(&reqCopy, requestURI) 72 if err != nil { 73 errs = append(errs, err) 74 } 75 if adapterReq != nil { 76 adapterRequests = append(adapterRequests, adapterReq) 77 } 78 return adapterRequests, errs 79 } 80 81 func (a *adapter) makeRequest(request *openrtb2.BidRequest, requestURI string) (*adapters.RequestData, error) { 82 reqJSON, err := json.Marshal(request) 83 84 if err != nil { 85 return nil, err 86 } 87 88 headers := http.Header{} 89 headers.Add("Content-Type", "application/json;charset=utf-8") 90 headers.Add("Accept", "application/json") 91 return &adapters.RequestData{ 92 Method: "POST", 93 Uri: requestURI, 94 Body: reqJSON, 95 Headers: headers, 96 ImpIDs: openrtb_ext.GetImpIDs(request.Imp), 97 }, nil 98 } 99 100 // MakeBids makes the bids 101 func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) { 102 var errs []error 103 104 if response.StatusCode == http.StatusNoContent { 105 return nil, nil 106 } 107 108 if response.StatusCode != http.StatusOK { 109 return nil, []error{&errortypes.BadServerResponse{ 110 Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode), 111 }} 112 } 113 114 var bidResp openrtb2.BidResponse 115 116 if err := json.Unmarshal(response.Body, &bidResp); err != nil { 117 return nil, []error{err} 118 } 119 120 bidResponse := adapters.NewBidderResponseWithBidsCapacity(1) 121 122 for _, sb := range bidResp.SeatBid { 123 for _, bid := range sb.Bid { 124 bidType, err := getMediaTypeForImp(bid.ImpID, internalRequest.Imp) 125 if err != nil { 126 errs = append(errs, err) 127 } else { 128 bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{ 129 Bid: &bid, 130 BidType: bidType, 131 }) 132 } 133 } 134 } 135 return bidResponse, errs 136 } 137 138 func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) { 139 mediaType := openrtb_ext.BidTypeBanner 140 for _, imp := range imps { 141 if imp.ID == impID { 142 if imp.Banner != nil { 143 mediaType = openrtb_ext.BidTypeBanner 144 } else if imp.Video != nil { 145 mediaType = openrtb_ext.BidTypeVideo 146 } else if imp.Native != nil { 147 mediaType = openrtb_ext.BidTypeNative 148 } 149 return mediaType, nil 150 } 151 } 152 153 // This shouldnt happen. Lets handle it just incase by returning an error. 154 return "", &errortypes.BadServerResponse{ 155 Message: fmt.Sprintf("Failed to find impression \"%s\"", impID), 156 } 157 }