github.com/prebid/prebid-server@v0.275.0/adapters/yieldmo/yieldmo.go (about)

     1  package yieldmo
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/prebid/openrtb/v19/openrtb2"
     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  
    15  type YieldmoAdapter struct {
    16  	endpoint string
    17  }
    18  
    19  type ExtImpBidderYieldmo struct {
    20  	adapters.ExtImpBidder
    21  	Data *ExtData `json:"data,omitempty"`
    22  }
    23  
    24  type ExtData struct {
    25  	PbAdslot string `json:"pbadslot"`
    26  }
    27  
    28  type Ext struct {
    29  	PlacementId string `json:"placement_id"`
    30  	Gpid        string `json:"gpid,omitempty"`
    31  }
    32  
    33  func (a *YieldmoAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
    34  	var errs []error
    35  	var adapterRequests []*adapters.RequestData
    36  
    37  	adapterReq, errors := a.makeRequest(request)
    38  	if adapterReq != nil {
    39  		adapterRequests = append(adapterRequests, adapterReq)
    40  	}
    41  	errs = append(errs, errors...)
    42  
    43  	return adapterRequests, errors
    44  }
    45  
    46  func (a *YieldmoAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) {
    47  	var errs []error
    48  
    49  	if err := preprocess(request); err != nil {
    50  		errs = append(errs, err)
    51  	}
    52  
    53  	// Last Step
    54  	reqJSON, err := json.Marshal(request)
    55  	if err != nil {
    56  		errs = append(errs, err)
    57  		return nil, errs
    58  	}
    59  
    60  	headers := http.Header{}
    61  	headers.Add("Content-Type", "application/json;charset=utf-8")
    62  
    63  	return &adapters.RequestData{
    64  		Method:  "POST",
    65  		Uri:     a.endpoint,
    66  		Body:    reqJSON,
    67  		Headers: headers,
    68  	}, errs
    69  }
    70  
    71  // Mutate the request to get it ready to send to yieldmo.
    72  func preprocess(request *openrtb2.BidRequest) error {
    73  	for i := 0; i < len(request.Imp); i++ {
    74  		var imp = request.Imp[i]
    75  		var bidderExt ExtImpBidderYieldmo
    76  
    77  		if err := json.Unmarshal(imp.Ext, &bidderExt); err != nil {
    78  			return &errortypes.BadInput{
    79  				Message: err.Error(),
    80  			}
    81  		}
    82  
    83  		var yieldmoExt openrtb_ext.ExtImpYieldmo
    84  
    85  		if err := json.Unmarshal(bidderExt.Bidder, &yieldmoExt); err != nil {
    86  			return &errortypes.BadInput{
    87  				Message: err.Error(),
    88  			}
    89  		}
    90  
    91  		var impExt Ext
    92  		impExt.PlacementId = yieldmoExt.PlacementId
    93  
    94  		if bidderExt.Data != nil {
    95  			if bidderExt.Data.PbAdslot != "" {
    96  				impExt.Gpid = bidderExt.Data.PbAdslot
    97  			}
    98  		}
    99  
   100  		impExtJSON, err := json.Marshal(impExt)
   101  		if err != nil {
   102  			return &errortypes.BadInput{
   103  				Message: err.Error(),
   104  			}
   105  		}
   106  
   107  		request.Imp[i].Ext = impExtJSON
   108  	}
   109  
   110  	return nil
   111  }
   112  
   113  // MakeBids make the bids for the bid response.
   114  func (a *YieldmoAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
   115  	if response.StatusCode == http.StatusNoContent {
   116  		return nil, nil
   117  	}
   118  
   119  	if response.StatusCode == http.StatusBadRequest {
   120  		return nil, []error{&errortypes.BadInput{
   121  			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
   122  		}}
   123  	}
   124  
   125  	if response.StatusCode != http.StatusOK {
   126  		return nil, []error{&errortypes.BadServerResponse{
   127  			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
   128  		}}
   129  	}
   130  
   131  	var bidResp openrtb2.BidResponse
   132  
   133  	if err := json.Unmarshal(response.Body, &bidResp); err != nil {
   134  		return nil, []error{err}
   135  	}
   136  
   137  	bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)
   138  
   139  	for _, sb := range bidResp.SeatBid {
   140  		for i := range sb.Bid {
   141  			bidResponse.Bids = append(bidResponse.Bids, &adapters.TypedBid{
   142  				Bid:     &sb.Bid[i],
   143  				BidType: getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp),
   144  			})
   145  		}
   146  	}
   147  	return bidResponse, nil
   148  
   149  }
   150  
   151  // Builder builds a new instance of the Yieldmo adapter for the given bidder with the given config.
   152  func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
   153  	bidder := &YieldmoAdapter{
   154  		endpoint: config.Endpoint,
   155  	}
   156  	return bidder, nil
   157  }
   158  
   159  func getMediaTypeForImp(impId string, imps []openrtb2.Imp) openrtb_ext.BidType {
   160  	//default to video unless banner exists in impression
   161  	for _, imp := range imps {
   162  		if imp.ID == impId && imp.Banner != nil {
   163  			return openrtb_ext.BidTypeBanner
   164  		}
   165  	}
   166  	return openrtb_ext.BidTypeVideo
   167  }