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

     1  package frvradn
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"strings"
     8  
     9  	"github.com/prebid/openrtb/v20/openrtb2"
    10  	"github.com/prebid/prebid-server/v2/adapters"
    11  	"github.com/prebid/prebid-server/v2/config"
    12  	"github.com/prebid/prebid-server/v2/errortypes"
    13  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    14  )
    15  
    16  type adapter struct {
    17  	uri string
    18  }
    19  
    20  func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
    21  	if config.Endpoint == "" {
    22  		return nil, errors.New("missing endpoint adapter parameter")
    23  	}
    24  
    25  	bidder := &adapter{
    26  		uri: config.Endpoint,
    27  	}
    28  	return bidder, nil
    29  }
    30  
    31  func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
    32  	var requests []*adapters.RequestData
    33  	var errs []error
    34  
    35  	requestCopy := *request
    36  	for _, imp := range request.Imp {
    37  		frvrAdnExt, err := getImpressionExt(&imp)
    38  		if err != nil {
    39  			errs = append(errs, err)
    40  			continue
    41  		}
    42  
    43  		if imp.BidFloor > 0 && imp.BidFloorCur != "" && strings.ToUpper(imp.BidFloorCur) != "USD" {
    44  			convertedValue, err := requestInfo.ConvertCurrency(imp.BidFloor, imp.BidFloorCur, "USD")
    45  			if err != nil {
    46  				errs = append(errs, err)
    47  				continue
    48  			}
    49  			imp.BidFloorCur = "USD"
    50  			imp.BidFloor = convertedValue
    51  		}
    52  
    53  		ext, err := json.Marshal(frvrAdnExt)
    54  		if err != nil {
    55  			errs = append(errs, err)
    56  			continue
    57  		}
    58  		imp.Ext = ext
    59  
    60  		requestCopy.Imp = []openrtb2.Imp{imp}
    61  
    62  		requestJSON, err := json.Marshal(requestCopy)
    63  		if err != nil {
    64  			errs = append(errs, err)
    65  			continue
    66  		}
    67  
    68  		requestData := &adapters.RequestData{
    69  			Method: "POST",
    70  			Uri:    a.uri,
    71  			Body:   requestJSON,
    72  			ImpIDs: openrtb_ext.GetImpIDs(requestCopy.Imp),
    73  		}
    74  		requests = append(requests, requestData)
    75  	}
    76  	return requests, errs
    77  }
    78  
    79  func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
    80  	if adapters.IsResponseStatusCodeNoContent(responseData) {
    81  		return nil, nil
    82  	}
    83  
    84  	if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
    85  		return nil, []error{err}
    86  	}
    87  
    88  	if len(responseData.Body) == 0 {
    89  		return nil, nil
    90  	}
    91  
    92  	var response openrtb2.BidResponse
    93  	if err := json.Unmarshal(responseData.Body, &response); err != nil {
    94  		return nil, []error{err}
    95  	}
    96  
    97  	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
    98  	bidResponse.Currency = response.Cur
    99  	var errs []error
   100  	for _, seatBid := range response.SeatBid {
   101  		for i := range seatBid.Bid {
   102  			bidType, err := getBidMediaType(&seatBid.Bid[i])
   103  			if err != nil {
   104  				errs = append(errs, err)
   105  				continue
   106  			}
   107  
   108  			b := &adapters.TypedBid{
   109  				Bid:     &seatBid.Bid[i],
   110  				BidType: bidType,
   111  			}
   112  			bidResponse.Bids = append(bidResponse.Bids, b)
   113  		}
   114  	}
   115  	return bidResponse, errs
   116  }
   117  
   118  func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtFRVRAdn, error) {
   119  	var extImpBidder adapters.ExtImpBidder
   120  	if err := json.Unmarshal(imp.Ext, &extImpBidder); err != nil {
   121  		return nil, &errortypes.BadInput{
   122  			Message: "missing ext",
   123  		}
   124  	}
   125  	var frvrAdnExt openrtb_ext.ImpExtFRVRAdn
   126  	if err := json.Unmarshal(extImpBidder.Bidder, &frvrAdnExt); err != nil {
   127  		return nil, &errortypes.BadInput{
   128  			Message: "missing ext.bidder",
   129  		}
   130  	}
   131  
   132  	if len(frvrAdnExt.PublisherID) == 0 || len(frvrAdnExt.AdUnitID) == 0 {
   133  		return nil, &errortypes.BadInput{
   134  			Message: "publisher_id and ad_unit_id are required",
   135  		}
   136  	}
   137  	return &frvrAdnExt, nil
   138  }
   139  
   140  func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) {
   141  	var extBid openrtb_ext.ExtBid
   142  	err := json.Unmarshal(bid.Ext, &extBid)
   143  	if err != nil {
   144  		return "", fmt.Errorf("unable to deserialize imp %v bid.ext", bid.ImpID)
   145  	}
   146  
   147  	if extBid.Prebid == nil {
   148  		return "", fmt.Errorf("imp %v with unknown media type", bid.ImpID)
   149  	}
   150  
   151  	return extBid.Prebid.Type, nil
   152  }