github.com/prebid/prebid-server@v0.275.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/adapters"
    10  	"github.com/prebid/prebid-server/config"
    11  	"github.com/prebid/prebid-server/errortypes"
    12  	"github.com/prebid/prebid-server/openrtb_ext"
    13  
    14  	"github.com/prebid/openrtb/v19/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  		})
    53  	}
    54  
    55  	request.Imp = impressions
    56  	return adapterRequests, errs
    57  }
    58  
    59  func (a *adapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
    60  	if response.StatusCode == http.StatusNoContent {
    61  		return nil, nil
    62  	}
    63  
    64  	if response.StatusCode == http.StatusBadRequest {
    65  		return nil, []error{&errortypes.BadInput{
    66  			Message: fmt.Sprintf("Bad user input: HTTP status %d. Run with request.debug = 1 for more info", response.StatusCode),
    67  		}}
    68  	}
    69  
    70  	if response.StatusCode != http.StatusOK {
    71  		return nil, []error{&errortypes.BadServerResponse{
    72  			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
    73  		}}
    74  	}
    75  
    76  	var ortbResponse openrtb2.BidResponse
    77  	err := json.Unmarshal(response.Body, &ortbResponse)
    78  	if err != nil {
    79  		return nil, []error{&errortypes.BadServerResponse{
    80  			Message: "Bad Server Response",
    81  		}}
    82  	}
    83  
    84  	impIdToImp := make(map[string]*openrtb2.Imp)
    85  	for i := range internalRequest.Imp {
    86  		imp := internalRequest.Imp[i]
    87  		impIdToImp[imp.ID] = &imp
    88  	}
    89  
    90  	bidderResponse := adapters.NewBidderResponseWithBidsCapacity(1)
    91  	for _, seatBid := range ortbResponse.SeatBid {
    92  		for i := range seatBid.Bid {
    93  			bid := seatBid.Bid[i]
    94  			bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{
    95  				Bid:     &bid,
    96  				BidType: getMediaTypeForImp(impIdToImp[bid.ImpID]),
    97  			})
    98  		}
    99  	}
   100  
   101  	return bidderResponse, nil
   102  }
   103  
   104  func getMediaTypeForImp(imp *openrtb2.Imp) openrtb_ext.BidType {
   105  	if imp != nil && imp.Banner != nil {
   106  		return openrtb_ext.BidTypeBanner
   107  	}
   108  	return openrtb_ext.BidTypeVideo
   109  }
   110  
   111  func getParams(impExt *openrtb_ext.ExtImpVideoByte) url.Values {
   112  	params := url.Values{}
   113  	params.Add("source", "pbs")
   114  	params.Add("pid", impExt.PublisherId)
   115  	if impExt.PlacementId != "" {
   116  		params.Add("placementId", impExt.PlacementId)
   117  	}
   118  	if impExt.NetworkId != "" {
   119  		params.Add("nid", impExt.NetworkId)
   120  	}
   121  	return params
   122  }
   123  
   124  func getHeaders(request *openrtb2.BidRequest) http.Header {
   125  	headers := http.Header{}
   126  	headers.Add("Content-Type", "application/json;charset=utf-8")
   127  	headers.Add("Accept", "application/json")
   128  
   129  	if request.Site != nil {
   130  		if request.Site.Domain != "" {
   131  			headers.Add("Origin", request.Site.Domain)
   132  		}
   133  		if request.Site.Ref != "" {
   134  			headers.Set("Referer", request.Site.Ref)
   135  		}
   136  	}
   137  	return headers
   138  }
   139  
   140  func parseExt(imp *openrtb2.Imp) (*openrtb_ext.ExtImpVideoByte, error) {
   141  	var bidderExt adapters.ExtImpBidder
   142  
   143  	if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
   144  		return nil, &errortypes.BadInput{
   145  			Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding extImpBidder, err: %s", imp.ID, err),
   146  		}
   147  	}
   148  
   149  	impExt := openrtb_ext.ExtImpVideoByte{}
   150  	err := json.Unmarshal(bidderExt.Bidder, &impExt)
   151  	if err != nil {
   152  		return nil, &errortypes.BadInput{
   153  			Message: fmt.Sprintf("Ignoring imp id=%s, error while decoding impExt, err: %s", imp.ID, err),
   154  		}
   155  	}
   156  
   157  	return &impExt, nil
   158  }