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

     1  package videobyte
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  	"net/url"
     8  
     9  	"github.com/prebid/prebid-server/v2/adapters"
    10  	"github.com/prebid/prebid-server/v2/config"
    11  	"github.com/prebid/prebid-server/v2/errortypes"
    12  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    13  
    14  	"github.com/prebid/openrtb/v20/openrtb2"
    15  )
    16  
    17  type adapter struct {
    18  	endpoint string
    19  }
    20  
    21  func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
    22  	bidder := &adapter{
    23  		endpoint: config.Endpoint,
    24  	}
    25  	return bidder, nil
    26  }
    27  
    28  func (a *adapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
    29  	impressions := request.Imp
    30  	adapterRequests := make([]*adapters.RequestData, 0, len(impressions))
    31  	var errs []error
    32  
    33  	for _, impression := range impressions {
    34  		impExt, err := parseExt(&impression)
    35  		if err != nil {
    36  			errs = append(errs, err)
    37  			continue
    38  		}
    39  
    40  		request.Imp = []openrtb2.Imp{impression}
    41  		body, err := json.Marshal(request)
    42  		if err != nil {
    43  			errs = append(errs, err)
    44  			continue
    45  		}
    46  
    47  		adapterRequests = append(adapterRequests, &adapters.RequestData{
    48  			Method:  http.MethodPost,
    49  			Uri:     a.endpoint + "?" + getParams(impExt).Encode(),
    50  			Body:    body,
    51  			Headers: getHeaders(request),
    52  			ImpIDs:  openrtb_ext.GetImpIDs(request.Imp),
    53  		})
    54  	}
    55  
    56  	request.Imp = impressions
    57  	return adapterRequests, errs
    58  }
    59  
    60  func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
    61  	if response.StatusCode == http.StatusNoContent {
    62  		return nil, nil
    63  	}
    64  
    65  	if response.StatusCode == http.StatusBadRequest {
    66  		return nil, []error{&errortypes.BadInput{
    67  			Message: fmt.Sprintf("Bad user input: HTTP status %d. Run with request.debug = 1 for more info", response.StatusCode),
    68  		}}
    69  	}
    70  
    71  	if response.StatusCode != http.StatusOK {
    72  		return nil, []error{&errortypes.BadServerResponse{
    73  			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
    74  		}}
    75  	}
    76  
    77  	var ortbResponse openrtb2.BidResponse
    78  	err := json.Unmarshal(response.Body, &ortbResponse)
    79  	if err != nil {
    80  		return nil, []error{&errortypes.BadServerResponse{
    81  			Message: "Bad Server Response",
    82  		}}
    83  	}
    84  
    85  	impIdToImp := make(map[string]*openrtb2.Imp)
    86  	for i := range internalRequest.Imp {
    87  		imp := internalRequest.Imp[i]
    88  		impIdToImp[imp.ID] = &imp
    89  	}
    90  
    91  	bidderResponse := adapters.NewBidderResponseWithBidsCapacity(1)
    92  	for _, seatBid := range ortbResponse.SeatBid {
    93  		for i := range seatBid.Bid {
    94  			bid := seatBid.Bid[i]
    95  			bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{
    96  				Bid:     &bid,
    97  				BidType: getMediaTypeForImp(impIdToImp[bid.ImpID]),
    98  			})
    99  		}
   100  	}
   101  
   102  	return bidderResponse, nil
   103  }
   104  
   105  func getMediaTypeForImp(imp *openrtb2.Imp) openrtb_ext.BidType {
   106  	if imp != nil && imp.Banner != nil {
   107  		return openrtb_ext.BidTypeBanner
   108  	}
   109  	return openrtb_ext.BidTypeVideo
   110  }
   111  
   112  func getParams(impExt *openrtb_ext.ExtImpVideoByte) url.Values {
   113  	params := url.Values{}
   114  	params.Add("source", "pbs")
   115  	params.Add("pid", impExt.PublisherId)
   116  	if impExt.PlacementId != "" {
   117  		params.Add("placementId", impExt.PlacementId)
   118  	}
   119  	if impExt.NetworkId != "" {
   120  		params.Add("nid", impExt.NetworkId)
   121  	}
   122  	return params
   123  }
   124  
   125  func getHeaders(request *openrtb2.BidRequest) http.Header {
   126  	headers := http.Header{}
   127  	headers.Add("Content-Type", "application/json;charset=utf-8")
   128  	headers.Add("Accept", "application/json")
   129  
   130  	if request.Site != nil {
   131  		if request.Site.Domain != "" {
   132  			headers.Add("Origin", request.Site.Domain)
   133  		}
   134  		if request.Site.Ref != "" {
   135  			headers.Set("Referer", request.Site.Ref)
   136  		}
   137  	}
   138  	return headers
   139  }
   140  
   141  func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpVideoByte, error) {
   142  	var bidderExt adapters.ExtImpBidder
   143  
   144  	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
   145  		return nil, &errortypes.BadInput{
   146  			Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err),
   147  		}
   148  	}
   149  
   150  	impExt := openrtb_ext.ExtImpVideoByte{}
   151  	err := json.Unmarshal(bidderExt.Bidder, &impExt)
   152  	if err != nil {
   153  		return nil, &errortypes.BadInput{
   154  			Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err),
   155  		}
   156  	}
   157  
   158  	return &impExt, nil
   159  }