github.com/prebid/prebid-server/v2@v2.18.0/adapters/bidder.go (about)

     1  package adapters
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"net/http"
     7  
     8  	"github.com/prebid/openrtb/v20/openrtb2"
     9  	"github.com/prebid/prebid-server/v2/config"
    10  	"github.com/prebid/prebid-server/v2/currency"
    11  	"github.com/prebid/prebid-server/v2/metrics"
    12  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    13  )
    14  
    15  // Bidder describes how to connect to external demand.
    16  type Bidder interface {
    17  	// MakeRequests makes the HTTP requests which should be made to fetch bids.
    18  	//
    19  	// Bidder implementations can assume that the incoming BidRequest has:
    20  	//
    21  	//   1. Only {Imp.Type, Platform} combinations which are valid, as defined by the static/bidder-info.{bidder}.yaml file.
    22  	//   2. Imp.Ext of the form {"bidder": params}, where "params" has been validated against the static/bidder-params/{bidder}.json JSON Schema.
    23  	//
    24  	// nil return values are acceptable, but nil elements *inside* those slices are not.
    25  	//
    26  	// The errors should contain a list of errors which explain why this bidder's bids will be
    27  	// "subpar" in some way. For example: the request contained ad types which this bidder doesn't support.
    28  	//
    29  	// If the error is caused by bad user input, return an errortypes.BadInput.
    30  	MakeRequests(request *openrtb2.BidRequest, reqInfo *ExtraRequestInfo) ([]*RequestData, []error)
    31  
    32  	// MakeBids unpacks the server's response into Bids.
    33  	//
    34  	// The bids can be nil (for no bids), but should not contain nil elements.
    35  	//
    36  	// The errors should contain a list of errors which explain why this bidder's bids will be
    37  	// "subpar" in some way. For example: the server response didn't have the expected format.
    38  	//
    39  	// If the error was caused by bad user input, return a errortypes.BadInput.
    40  	// If the error was caused by a bad server response, return a errortypes.BadServerResponse
    41  	MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *RequestData, response *ResponseData) (*BidderResponse, []error)
    42  }
    43  
    44  // TimeoutBidder is used to identify bidders that support timeout notifications.
    45  type TimeoutBidder interface {
    46  	Bidder
    47  
    48  	// MakeTimeoutNotification functions much the same as MakeRequests, except it is fed the bidder request that timed out,
    49  	// and expects that only one notification "request" will be generated. A use case for multiple timeout notifications
    50  	// has not been anticipated.
    51  	//
    52  	// Do note that if MakeRequests returns multiple requests, and more than one of these times out, MakeTimeoutNotice will be called
    53  	// once for each timed out request.
    54  	MakeTimeoutNotification(req *RequestData) (*RequestData, []error)
    55  }
    56  
    57  // BidderResponse wraps the server's response with the list of bids and the currency used by the bidder.
    58  //
    59  // Currency declaration is not mandatory but helps to detect an eventual currency mismatch issue.
    60  // From the bid response, the bidder accepts a list of valid currencies for the bid.
    61  // The currency is the same across all bids.
    62  type BidderResponse struct {
    63  	Currency             string
    64  	Bids                 []*TypedBid
    65  	FledgeAuctionConfigs []*openrtb_ext.FledgeAuctionConfig
    66  }
    67  
    68  // NewBidderResponseWithBidsCapacity create a new BidderResponse initialising the bids array capacity and the default currency value
    69  // to "USD".
    70  //
    71  // bidsCapacity allows to set initial Bids array capacity.
    72  // By default, currency is USD but this behavior might be subject to change.
    73  func NewBidderResponseWithBidsCapacity(bidsCapacity int) *BidderResponse {
    74  	return &BidderResponse{
    75  		Currency: "USD",
    76  		Bids:     make([]*TypedBid, 0, bidsCapacity),
    77  	}
    78  }
    79  
    80  // NewBidderResponse create a new BidderResponse initialising the bids array and the default currency value
    81  // to "USD".
    82  //
    83  // By default, Bids capacity will be set to 0.
    84  // By default, currency is USD but this behavior might be subject to change.
    85  func NewBidderResponse() *BidderResponse {
    86  	return NewBidderResponseWithBidsCapacity(0)
    87  }
    88  
    89  // TypedBid packages the openrtb2.Bid with any bidder-specific information that PBS needs to populate an
    90  // openrtb_ext.ExtBidPrebid.
    91  //
    92  // TypedBid.Bid.Ext will become "response.seatbid[i].bid.ext.bidder" in the final OpenRTB response.
    93  // TypedBid.BidMeta will become "response.seatbid[i].bid.ext.prebid.meta" in the final OpenRTB response.
    94  // TypedBid.BidType will become "response.seatbid[i].bid.ext.prebid.type" in the final OpenRTB response.
    95  // TypedBid.BidVideo will become "response.seatbid[i].bid.ext.prebid.video" in the final OpenRTB response.
    96  // TypedBid.DealPriority is optionally provided by adapters and used internally by the exchange to support deal targeted campaigns.
    97  // TypedBid.Seat new seat under which the bid should pe placed. Default is adapter name
    98  type TypedBid struct {
    99  	Bid          *openrtb2.Bid
   100  	BidMeta      *openrtb_ext.ExtBidPrebidMeta
   101  	BidType      openrtb_ext.BidType
   102  	BidVideo     *openrtb_ext.ExtBidPrebidVideo
   103  	DealPriority int
   104  	Seat         openrtb_ext.BidderName
   105  }
   106  
   107  // RequestData and ResponseData exist so that prebid-server core code can implement its "debug" functionality
   108  // uniformly across all Bidders.
   109  // It will also let us experiment with valyala/vasthttp vs. net/http without changing every adapter (see #152)
   110  
   111  // ResponseData packages together information from the server's http.Response.
   112  type ResponseData struct {
   113  	StatusCode int
   114  	Body       []byte
   115  	Headers    http.Header
   116  }
   117  
   118  // RequestData packages together the fields needed to make an http.Request.
   119  type RequestData struct {
   120  	Method  string
   121  	Uri     string
   122  	Body    []byte
   123  	Headers http.Header
   124  	ImpIDs  []string
   125  }
   126  
   127  // ExtImpBidder can be used by Bidders to unmarshal any request.imp[i].ext.
   128  type ExtImpBidder struct {
   129  	Prebid *openrtb_ext.ExtImpPrebid `json:"prebid"`
   130  
   131  	// Bidder contain the bidder-specific extension. Each bidder should unmarshal this using their
   132  	// corresponding openrtb_ext.ExtImp{Bidder} struct.
   133  	//
   134  	// For example, the Appnexus Bidder should unmarshal this with an openrtb_ext.ExtImpAppnexus object.
   135  	//
   136  	// Bidder implementations may safely assume that this JSON has been validated by their
   137  	// static/bidder-params/{bidder}.json file.
   138  	Bidder json.RawMessage `json:"bidder"`
   139  
   140  	AuctionEnvironment openrtb_ext.AuctionEnvironmentType `json:"ae,omitempty"`
   141  }
   142  
   143  func (r *RequestData) SetBasicAuth(username string, password string) {
   144  	r.Headers.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password)))
   145  }
   146  
   147  type ExtraRequestInfo struct {
   148  	PbsEntryPoint              metrics.RequestType
   149  	GlobalPrivacyControlHeader string
   150  	CurrencyConversions        currency.Conversions
   151  }
   152  
   153  func NewExtraRequestInfo(c currency.Conversions) ExtraRequestInfo {
   154  	return ExtraRequestInfo{
   155  		CurrencyConversions: c,
   156  	}
   157  }
   158  
   159  // ConvertCurrency converts a given amount from one currency to another, or returns:
   160  //   - Error if the `from` or `to` arguments are malformed or unknown ISO-4217 codes.
   161  //   - ConversionNotFoundError if the conversion mapping is unknown to Prebid Server
   162  //     and not provided in the bid request.
   163  func (r ExtraRequestInfo) ConvertCurrency(value float64, from, to string) (float64, error) {
   164  	if rate, err := r.CurrencyConversions.GetRate(from, to); err == nil {
   165  		return value * rate, nil
   166  	} else {
   167  		return 0, err
   168  	}
   169  }
   170  
   171  type Builder func(openrtb_ext.BidderName, config.Adapter, config.Server) (Bidder, error)