github.com/prebid/prebid-server@v0.275.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/v19/openrtb2"
    10  	"github.com/prebid/prebid-server/adapters"
    11  	"github.com/prebid/prebid-server/config"
    12  	"github.com/prebid/prebid-server/errortypes"
    13  	"github.com/prebid/prebid-server/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  		}
    73  		requests = append(requests, requestData)
    74  	}
    75  	return requests, errs
    76  }
    77  
    78  func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
    79  	if adapters.IsResponseStatusCodeNoContent(responseData) {
    80  		return nil, nil
    81  	}
    82  
    83  	if err := adapters.CheckResponseStatusCodeForErrors(responseData); err != nil {
    84  		return nil, []error{err}
    85  	}
    86  
    87  	if len(responseData.Body) == 0 {
    88  		return nil, nil
    89  	}
    90  
    91  	var response openrtb2.BidResponse
    92  	if err := json.Unmarshal(responseData.Body, &response); err != nil {
    93  		return nil, []error{err}
    94  	}
    95  
    96  	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
    97  	bidResponse.Currency = response.Cur
    98  	var errs []error
    99  	for _, seatBid := range response.SeatBid {
   100  		for i := range seatBid.Bid {
   101  			bidType, err := getBidMediaType(&seatBid.Bid[i])
   102  			if err != nil {
   103  				errs = append(errs, err)
   104  				continue
   105  			}
   106  
   107  			b := &adapters.TypedBid{
   108  				Bid:     &seatBid.Bid[i],
   109  				BidType: bidType,
   110  			}
   111  			bidResponse.Bids = append(bidResponse.Bids, b)
   112  		}
   113  	}
   114  	return bidResponse, errs
   115  }
   116  
   117  func getImpressionExt(imp *openrtb2.Imp) (*openrtb_ext.ImpExtFRVRAdn, error) {
   118  	var extImpBidder adapters.ExtImpBidder
   119  	if err := json.Unmarshal(imp.Ext, &extImpBidder); err != nil {
   120  		return nil, &errortypes.BadInput{
   121  			Message: "missing ext",
   122  		}
   123  	}
   124  	var frvrAdnExt openrtb_ext.ImpExtFRVRAdn
   125  	if err := json.Unmarshal(extImpBidder.Bidder, &frvrAdnExt); err != nil {
   126  		return nil, &errortypes.BadInput{
   127  			Message: "missing ext.bidder",
   128  		}
   129  	}
   130  
   131  	if len(frvrAdnExt.PublisherID) == 0 || len(frvrAdnExt.AdUnitID) == 0 {
   132  		return nil, &errortypes.BadInput{
   133  			Message: "publisher_id and ad_unit_id are required",
   134  		}
   135  	}
   136  	return &frvrAdnExt, nil
   137  }
   138  
   139  func getBidMediaType(bid *openrtb2.Bid) (openrtb_ext.BidType, error) {
   140  	var extBid openrtb_ext.ExtBid
   141  	err := json.Unmarshal(bid.Ext, &extBid)
   142  	if err != nil {
   143  		return "", fmt.Errorf("unable to deserialize imp %v bid.ext", bid.ImpID)
   144  	}
   145  
   146  	if extBid.Prebid == nil {
   147  		return "", fmt.Errorf("imp %v with unknown media type", bid.ImpID)
   148  	}
   149  
   150  	return extBid.Prebid.Type, nil
   151  }