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

     1  package theadx
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/prebid/openrtb/v20/openrtb2"
     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  
    15  type adapter struct {
    16  	endpoint string
    17  }
    18  
    19  // Builder builds a new instance of the theadx adapter for the given bidder with the given config.
    20  func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
    21  	bidder := &adapter{
    22  		endpoint: config.Endpoint,
    23  	}
    24  	return bidder, nil
    25  }
    26  func getHeaders(request *openrtb2.BidRequest) http.Header {
    27  	headers := http.Header{}
    28  	headers.Add("Content-Type", "application/json;charset=utf-8")
    29  	headers.Add("Accept", "application/json")
    30  	headers.Add("X-Openrtb-Version", "2.5")
    31  	headers.Add("X-TEST", "1")
    32  
    33  	if request.Device != nil {
    34  		if len(request.Device.UA) > 0 {
    35  			headers.Add("X-Device-User-Agent", request.Device.UA)
    36  		}
    37  
    38  		if len(request.Device.IPv6) > 0 {
    39  			headers.Add("X-Real-IP", request.Device.IPv6)
    40  		}
    41  
    42  		if len(request.Device.IP) > 0 {
    43  			headers.Add("X-Real-IP", request.Device.IP)
    44  		}
    45  	}
    46  
    47  	return headers
    48  }
    49  func (a *adapter) MakeRequests(request *openrtb2.BidRequest, requestInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
    50  	var errors []error
    51  	var validImps = make([]openrtb2.Imp, 0, len(request.Imp))
    52  
    53  	for _, imp := range request.Imp {
    54  		var bidderExt adapters.ExtImpBidder
    55  		if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
    56  			errors = append(errors, &errortypes.BadInput{
    57  				Message: err.Error(),
    58  			})
    59  			continue
    60  		}
    61  
    62  		var theadxImpExt openrtb_ext.ExtImpTheadx
    63  		if err := json.Unmarshal(bidderExt.Bidder, &theadxImpExt); err != nil {
    64  			errors = append(errors, &errortypes.BadInput{
    65  				Message: err.Error(),
    66  			})
    67  			continue
    68  		}
    69  
    70  		imp.TagID = theadxImpExt.TagID.String()
    71  		validImps = append(validImps, imp)
    72  	}
    73  
    74  	request.Imp = validImps
    75  
    76  	requestJSON, err := json.Marshal(request)
    77  	if err != nil {
    78  		errors = append(errors, err)
    79  		return nil, errors
    80  	}
    81  
    82  	requestData := &adapters.RequestData{
    83  		Method:  "POST",
    84  		Uri:     a.endpoint,
    85  		Body:    requestJSON,
    86  		Headers: getHeaders(request),
    87  		ImpIDs:  openrtb_ext.GetImpIDs(request.Imp),
    88  	}
    89  
    90  	return []*adapters.RequestData{requestData}, errors
    91  }
    92  
    93  func (a *adapter) MakeBids(request *openrtb2.BidRequest, requestData *adapters.RequestData, responseData *adapters.ResponseData) (*adapters.BidderResponse, []error) {
    94  	if responseData.StatusCode == http.StatusNoContent {
    95  		return nil, nil
    96  	}
    97  
    98  	if responseData.StatusCode == http.StatusBadRequest {
    99  		err := &errortypes.BadInput{
   100  			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", responseData.StatusCode),
   101  		}
   102  		return nil, []error{err}
   103  	}
   104  
   105  	if responseData.StatusCode != http.StatusOK {
   106  		err := &errortypes.BadServerResponse{
   107  			Message: fmt.Sprintf("Unexpected status code: %d.", responseData.StatusCode),
   108  		}
   109  		return nil, []error{err}
   110  	}
   111  
   112  	var response openrtb2.BidResponse
   113  	if err := json.Unmarshal(responseData.Body, &response); err != nil {
   114  		return nil, []error{err}
   115  	}
   116  
   117  	bidResponse := adapters.NewBidderResponseWithBidsCapacity(len(request.Imp))
   118  	bidResponse.Currency = response.Cur
   119  	var errors []error
   120  	for _, seatBid := range response.SeatBid {
   121  		for i, bid := range seatBid.Bid {
   122  			bidType, err := getMediaTypeForBid(bid)
   123  			if err != nil {
   124  				errors = append(errors, err)
   125  				continue
   126  			}
   127  			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
   128  				Bid:     &seatBid.Bid[i],
   129  				BidType: bidType,
   130  			})
   131  		}
   132  	}
   133  
   134  	return bidResponse, errors
   135  }
   136  
   137  func getMediaTypeForBid(bid openrtb2.Bid) (openrtb_ext.BidType, error) {
   138  	if bid.Ext != nil {
   139  		var bidExt openrtb_ext.ExtBid
   140  		err := json.Unmarshal(bid.Ext, &bidExt)
   141  		if err == nil && bidExt.Prebid != nil {
   142  			return openrtb_ext.ParseBidType(string(bidExt.Prebid.Type))
   143  		}
   144  	}
   145  
   146  	return "", &errortypes.BadServerResponse{
   147  		Message: fmt.Sprintf("Failed to parse impression \"%s\" mediatype", bid.ImpID),
   148  	}
   149  }