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

     1  package adman
     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  // AdmanAdapter struct
    16  type AdmanAdapter struct {
    17  	URI string
    18  }
    19  
    20  // Builder builds a new instance of the Adman adapter for the given bidder with the given config.
    21  func Builder(bidderName openrtb_ext.BidderName, config config.Adapter, server config.Server) (adapters.Bidder, error) {
    22  	bidder := &AdmanAdapter{
    23  		URI: config.Endpoint,
    24  	}
    25  	return bidder, nil
    26  }
    27  
    28  // MakeRequests create bid request for adman demand
    29  func (a *AdmanAdapter) MakeRequests(request *openrtb2.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
    30  	var errs []error
    31  	var admanExt openrtb_ext.ExtImpAdman
    32  	var err error
    33  
    34  	var adapterRequests []*adapters.RequestData
    35  
    36  	reqCopy := *request
    37  	for _, imp := range request.Imp {
    38  		reqCopy.Imp = []openrtb2.Imp{imp}
    39  
    40  		var bidderExt adapters.ExtImpBidder
    41  		if err = json.Unmarshal(reqCopy.Imp[0].Ext, &bidderExt); err != nil {
    42  			errs = append(errs, err)
    43  			continue
    44  		}
    45  
    46  		if err = json.Unmarshal(bidderExt.Bidder, &admanExt); err != nil {
    47  			errs = append(errs, err)
    48  			continue
    49  		}
    50  
    51  		reqCopy.Imp[0].TagID = admanExt.TagID
    52  
    53  		adapterReq, errors := a.makeRequest(&reqCopy)
    54  		if adapterReq != nil {
    55  			adapterRequests = append(adapterRequests, adapterReq)
    56  		}
    57  		errs = append(errs, errors...)
    58  	}
    59  	return adapterRequests, errs
    60  }
    61  
    62  func (a *AdmanAdapter) makeRequest(request *openrtb2.BidRequest) (*adapters.RequestData, []error) {
    63  
    64  	var errs []error
    65  
    66  	reqJSON, err := json.Marshal(request)
    67  
    68  	if err != nil {
    69  		errs = append(errs, err)
    70  		return nil, errs
    71  	}
    72  
    73  	headers := http.Header{}
    74  	headers.Add("Content-Type", "application/json;charset=utf-8")
    75  	headers.Add("Accept", "application/json")
    76  	return &adapters.RequestData{
    77  		Method:  "POST",
    78  		Uri:     a.URI,
    79  		Body:    reqJSON,
    80  		Headers: headers,
    81  		ImpIDs:  openrtb_ext.GetImpIDs(request.Imp),
    82  	}, errs
    83  }
    84  
    85  // MakeBids makes the bids
    86  func (a *AdmanAdapter) MakeBids(internalRequest *openrtb2.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
    87  	var errs []error
    88  
    89  	if response.StatusCode == http.StatusNoContent {
    90  		return nil, nil
    91  	}
    92  
    93  	if response.StatusCode == http.StatusNotFound {
    94  		return nil, []error{&errortypes.BadServerResponse{
    95  			Message: fmt.Sprintf("Unexpected status code: %d. Run with request.debug = 1 for more info", response.StatusCode),
    96  		}}
    97  	}
    98  
    99  	var bidResp openrtb2.BidResponse
   100  
   101  	if err := json.Unmarshal(response.Body, &bidResp); err != nil {
   102  		return nil, []error{err}
   103  	}
   104  
   105  	bidResponse := adapters.NewBidderResponseWithBidsCapacity(1)
   106  
   107  	for _, sb := range bidResp.SeatBid {
   108  		for i := range sb.Bid {
   109  			bidType, err := getMediaTypeForImp(sb.Bid[i].ImpID, internalRequest.Imp)
   110  			if err != nil {
   111  				errs = append(errs, err)
   112  			} else {
   113  				b := &adapters.TypedBid{
   114  					Bid:     &sb.Bid[i],
   115  					BidType: bidType,
   116  				}
   117  				bidResponse.Bids = append(bidResponse.Bids, b)
   118  			}
   119  		}
   120  	}
   121  	return bidResponse, errs
   122  }
   123  
   124  func getMediaTypeForImp(impID string, imps []openrtb2.Imp) (openrtb_ext.BidType, error) {
   125  	mediaType := openrtb_ext.BidTypeBanner
   126  	for _, imp := range imps {
   127  		if imp.ID == impID {
   128  			if imp.Banner == nil && imp.Video != nil {
   129  				mediaType = openrtb_ext.BidTypeVideo
   130  			}
   131  			return mediaType, nil
   132  		}
   133  	}
   134  
   135  	// This shouldnt happen. Lets handle it just incase by returning an error.
   136  	return "", &errortypes.BadInput{
   137  		Message: fmt.Sprintf("Failed to find impression \"%s\" ", impID),
   138  	}
   139  }