github.com/prebid/prebid-server/v2@v2.18.0/bidadjustment/build_rules.go (about)

     1  package bidadjustment
     2  
     3  import (
     4  	"github.com/prebid/prebid-server/v2/errortypes"
     5  	"github.com/prebid/prebid-server/v2/openrtb_ext"
     6  )
     7  
     8  const (
     9  	VideoInstream  = "video-instream"
    10  	VideoOutstream = "video-outstream"
    11  )
    12  
    13  // BuildRules() will populate the rules map with a rule that's a combination of the mediaType, bidderName, and dealId for a particular adjustment
    14  // The result will be a map that'll map a given rule with its adjustment
    15  func BuildRules(bidAdjustments *openrtb_ext.ExtRequestPrebidBidAdjustments) map[string][]openrtb_ext.Adjustment {
    16  	if bidAdjustments == nil {
    17  		return nil
    18  	}
    19  	rules := make(map[string][]openrtb_ext.Adjustment)
    20  
    21  	buildRulesForMediaType(string(openrtb_ext.BidTypeBanner), bidAdjustments.MediaType.Banner, rules)
    22  	buildRulesForMediaType(string(openrtb_ext.BidTypeAudio), bidAdjustments.MediaType.Audio, rules)
    23  	buildRulesForMediaType(string(openrtb_ext.BidTypeNative), bidAdjustments.MediaType.Native, rules)
    24  	buildRulesForMediaType(VideoInstream, bidAdjustments.MediaType.VideoInstream, rules)
    25  	buildRulesForMediaType(VideoOutstream, bidAdjustments.MediaType.VideoOutstream, rules)
    26  	buildRulesForMediaType(WildCard, bidAdjustments.MediaType.WildCard, rules)
    27  
    28  	return rules
    29  }
    30  
    31  func buildRulesForMediaType(mediaType string, rulesByBidder map[openrtb_ext.BidderName]openrtb_ext.AdjustmentsByDealID, rules map[string][]openrtb_ext.Adjustment) {
    32  	for bidderName := range rulesByBidder {
    33  		for dealID, adjustments := range rulesByBidder[bidderName] {
    34  			rule := mediaType + Delimiter + string(bidderName) + Delimiter + dealID
    35  			rules[rule] = adjustments
    36  		}
    37  	}
    38  }
    39  
    40  // Merge takes bid adjustments defined on the request and on the account, and combines/validates them, with the adjustments on the request taking precedence.
    41  func Merge(req *openrtb_ext.RequestWrapper, acctBidAdjs *openrtb_ext.ExtRequestPrebidBidAdjustments) (*openrtb_ext.ExtRequestPrebidBidAdjustments, error) {
    42  	mergedBidAdj, err := merge(req, acctBidAdjs)
    43  	if err != nil {
    44  		return nil, err
    45  	}
    46  	if !Validate(mergedBidAdj) {
    47  		mergedBidAdj = nil
    48  		err = &errortypes.Warning{
    49  			WarningCode: errortypes.BidAdjustmentWarningCode,
    50  			Message:     "bid adjustment on account was invalid",
    51  		}
    52  	}
    53  	return mergedBidAdj, err
    54  }
    55  
    56  func merge(req *openrtb_ext.RequestWrapper, acct *openrtb_ext.ExtRequestPrebidBidAdjustments) (*openrtb_ext.ExtRequestPrebidBidAdjustments, error) {
    57  	reqExt, err := req.GetRequestExt()
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	extPrebid := reqExt.GetPrebid()
    62  
    63  	if extPrebid == nil || extPrebid.BidAdjustments == nil {
    64  		return acct, nil
    65  	}
    66  
    67  	if acct == nil {
    68  		return extPrebid.BidAdjustments, nil
    69  	}
    70  
    71  	extPrebid.BidAdjustments.MediaType.Banner = mergeForMediaType(extPrebid.BidAdjustments.MediaType.Banner, acct.MediaType.Banner)
    72  	extPrebid.BidAdjustments.MediaType.Native = mergeForMediaType(extPrebid.BidAdjustments.MediaType.Native, acct.MediaType.Native)
    73  	extPrebid.BidAdjustments.MediaType.Audio = mergeForMediaType(extPrebid.BidAdjustments.MediaType.Audio, acct.MediaType.Audio)
    74  	extPrebid.BidAdjustments.MediaType.VideoInstream = mergeForMediaType(extPrebid.BidAdjustments.MediaType.VideoInstream, acct.MediaType.VideoInstream)
    75  	extPrebid.BidAdjustments.MediaType.VideoOutstream = mergeForMediaType(extPrebid.BidAdjustments.MediaType.VideoOutstream, acct.MediaType.VideoOutstream)
    76  	extPrebid.BidAdjustments.MediaType.WildCard = mergeForMediaType(extPrebid.BidAdjustments.MediaType.WildCard, acct.MediaType.WildCard)
    77  
    78  	return extPrebid.BidAdjustments, nil
    79  }
    80  
    81  func mergeForMediaType(reqAdj, acctAdj map[openrtb_ext.BidderName]openrtb_ext.AdjustmentsByDealID) map[openrtb_ext.BidderName]openrtb_ext.AdjustmentsByDealID {
    82  	if reqAdj != nil && acctAdj == nil {
    83  		return reqAdj
    84  	}
    85  	if reqAdj == nil && acctAdj != nil {
    86  		return acctAdj
    87  	}
    88  
    89  	for bidderName, dealIDToAdjustments := range acctAdj {
    90  		if _, ok := reqAdj[bidderName]; ok {
    91  			for dealID, acctAdjustments := range acctAdj[bidderName] {
    92  				if _, ok := reqAdj[bidderName][dealID]; !ok {
    93  					reqAdj[bidderName][dealID] = acctAdjustments
    94  				}
    95  			}
    96  		} else {
    97  			reqAdj[bidderName] = dealIDToAdjustments
    98  		}
    99  	}
   100  	return reqAdj
   101  }