-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Prebid Core: refactor bidderSettings to have only one entry point #7712
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
1282769
2a45317
1d71442
19966d0
057dbc9
b0d9ca6
284ab3a
5e4c268
152296a
5abbe1b
f6c7468
0a30d07
a7f28f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,7 +59,7 @@ | |
|
||
import { | ||
flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl, generateUUID, | ||
logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr, isAllowZeroCpmBidsEnabled | ||
logMessage, bind, logError, logInfo, logWarn, isEmpty, _each, isFn, isEmptyStr, cache, isAllowZeroCpmBidsEnabled | ||
} from './utils.js'; | ||
import { getPriceBucketString } from './cpmBucketManager.js'; | ||
import { getNativeTargeting } from './native.js'; | ||
|
@@ -72,6 +72,7 @@ import find from 'core-js-pure/features/array/find.js'; | |
import includes from 'core-js-pure/features/array/includes.js'; | ||
import { OUTSTREAM } from './video.js'; | ||
import { VIDEO } from './mediaTypes.js'; | ||
import {bidderSettings} from './bidderSettings.js'; | ||
|
||
const { syncUsers } = userSync; | ||
|
||
|
@@ -615,18 +616,18 @@ export const getPriceGranularity = (mediaType, bidReq) => { | |
*/ | ||
export const getPriceByGranularity = (granularity) => { | ||
return (bid, bidReq) => { | ||
granularity = granularity || getPriceGranularity(bid.mediaType, bidReq); | ||
if (granularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) { | ||
const bidGranularity = granularity || getPriceGranularity(bid.mediaType, bidReq); | ||
if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) { | ||
return bid.pbAg; | ||
} else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) { | ||
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) { | ||
return bid.pbDg; | ||
} else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.LOW) { | ||
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.LOW) { | ||
return bid.pbLg; | ||
} else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.MEDIUM) { | ||
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.MEDIUM) { | ||
return bid.pbMg; | ||
} else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.HIGH) { | ||
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.HIGH) { | ||
return bid.pbHg; | ||
} else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.CUSTOM) { | ||
} else if (bidGranularity === CONSTANTS.GRANULARITY_OPTIONS.CUSTOM) { | ||
return bid.pbCg; | ||
} | ||
} | ||
|
@@ -642,47 +643,51 @@ export const getAdvertiserDomain = () => { | |
} | ||
} | ||
|
||
// factory for key value objs | ||
function createKeyVal(key, value) { | ||
return { | ||
key, | ||
val: (typeof value === 'function') | ||
? function (bidResponse, bidReq) { | ||
return value(bidResponse, bidReq); | ||
} | ||
: function (bidResponse) { | ||
return getValue(bidResponse, value); | ||
} | ||
}; | ||
} | ||
|
||
const defaultAdserverTargeting = cache(() => { | ||
const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS; | ||
return [ | ||
createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'), | ||
createKeyVal(TARGETING_KEYS.AD_ID, 'adId'), | ||
createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity()), | ||
createKeyVal(TARGETING_KEYS.SIZE, 'size'), | ||
createKeyVal(TARGETING_KEYS.DEAL, 'dealId'), | ||
createKeyVal(TARGETING_KEYS.SOURCE, 'source'), | ||
createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'), | ||
createKeyVal(TARGETING_KEYS.ADOMAIN, getAdvertiserDomain()), | ||
] | ||
}) | ||
|
||
/** | ||
* @param {string} mediaType | ||
* @param {string} bidderCode | ||
* @param {BidRequest} bidReq | ||
* @returns {*} | ||
*/ | ||
export function getStandardBidderSettings(mediaType, bidderCode) { | ||
// factory for key value objs | ||
function createKeyVal(key, value) { | ||
return { | ||
key, | ||
val: (typeof value === 'function') | ||
? function (bidResponse, bidReq) { | ||
return value(bidResponse, bidReq); | ||
} | ||
: function (bidResponse) { | ||
return getValue(bidResponse, value); | ||
} | ||
}; | ||
} | ||
const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS; | ||
const standardSettings = Object.assign({}, bidderSettings.settingsFor(null)); | ||
|
||
let bidderSettings = $$PREBID_GLOBAL$$.bidderSettings; | ||
if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]) { | ||
bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD] = {}; | ||
} | ||
if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) { | ||
bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = [ | ||
createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'), | ||
createKeyVal(TARGETING_KEYS.AD_ID, 'adId'), | ||
createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity()), | ||
createKeyVal(TARGETING_KEYS.SIZE, 'size'), | ||
createKeyVal(TARGETING_KEYS.DEAL, 'dealId'), | ||
createKeyVal(TARGETING_KEYS.SOURCE, 'source'), | ||
createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'), | ||
createKeyVal(TARGETING_KEYS.ADOMAIN, getAdvertiserDomain()), | ||
] | ||
if (!standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) { | ||
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = defaultAdserverTargeting(); | ||
} | ||
|
||
if (mediaType === 'video') { | ||
const adserverTargeting = bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]; | ||
const adserverTargeting = standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING].slice(); | ||
standardSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = adserverTargeting; | ||
|
||
// Adding hb_uuid + hb_cache_id | ||
[TARGETING_KEYS.UUID, TARGETING_KEYS.CACHE_ID].forEach(targetingKeyVal => { | ||
|
@@ -692,7 +697,7 @@ export function getStandardBidderSettings(mediaType, bidderCode) { | |
}); | ||
|
||
// Adding hb_cache_host | ||
if (config.getConfig('cache.url') && (!bidderCode || deepAccess(bidderSettings, `${bidderCode}.sendStandardTargeting`) !== false)) { | ||
if (config.getConfig('cache.url') && (!bidderCode || bidderSettings.get(bidderCode, 'sendStandardTargeting') !== false)) { | ||
Comment on lines
-730
to
+735
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is potentially a breaking change: previously, this would be evaluated the first time this function was called with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Breaking change... more like a bug fix! |
||
const urlInfo = parseUrl(config.getConfig('cache.url')); | ||
|
||
if (typeof find(adserverTargeting, targetingKeyVal => targetingKeyVal.key === TARGETING_KEYS.CACHE_HOST) === 'undefined') { | ||
|
@@ -703,7 +708,7 @@ export function getStandardBidderSettings(mediaType, bidderCode) { | |
} | ||
} | ||
} | ||
return bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]; | ||
return standardSettings; | ||
} | ||
|
||
export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) { | ||
|
@@ -712,19 +717,15 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) { | |
} | ||
|
||
var keyValues = {}; | ||
var bidderSettings = $$PREBID_GLOBAL$$.bidderSettings; | ||
|
||
// 1) set the keys from "standard" setting or from prebid defaults | ||
if (bidderSettings) { | ||
// initialize default if not set | ||
const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode); | ||
setKeys(keyValues, standardSettings, custBidObj, bidReq); | ||
|
||
// 2) set keys from specific bidder setting override if they exist | ||
if (bidderCode && bidderSettings[bidderCode] && bidderSettings[bidderCode][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) { | ||
setKeys(keyValues, bidderSettings[bidderCode], custBidObj, bidReq); | ||
custBidObj.sendStandardTargeting = bidderSettings[bidderCode].sendStandardTargeting; | ||
} | ||
const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode); | ||
setKeys(keyValues, standardSettings, custBidObj, bidReq); | ||
|
||
// 2) set keys from specific bidder setting override if they exist | ||
if (bidderCode && bidderSettings.getOwn(bidderCode, CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING)) { | ||
setKeys(keyValues, bidderSettings.ownSettingsFor(bidderCode), custBidObj, bidReq); | ||
custBidObj.sendStandardTargeting = bidderSettings.get(bidderCode, 'sendStandardTargeting'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another potentially breaking change: the logic here was a bit confusing, copying |
||
} | ||
|
||
// set native key value targeting | ||
|
@@ -776,19 +777,13 @@ function setKeys(keyValues, bidderSettings, custBidObj, bidReq) { | |
export function adjustBids(bid) { | ||
let code = bid.bidderCode; | ||
let bidPriceAdjusted = bid.cpm; | ||
let bidCpmAdjustment; | ||
if ($$PREBID_GLOBAL$$.bidderSettings) { | ||
if (code && $$PREBID_GLOBAL$$.bidderSettings[code] && typeof $$PREBID_GLOBAL$$.bidderSettings[code].bidCpmAdjustment === 'function') { | ||
bidCpmAdjustment = $$PREBID_GLOBAL$$.bidderSettings[code].bidCpmAdjustment; | ||
} else if ($$PREBID_GLOBAL$$.bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD] && typeof $$PREBID_GLOBAL$$.bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD].bidCpmAdjustment === 'function') { | ||
bidCpmAdjustment = $$PREBID_GLOBAL$$.bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD].bidCpmAdjustment; | ||
} | ||
if (bidCpmAdjustment) { | ||
try { | ||
bidPriceAdjusted = bidCpmAdjustment(bid.cpm, Object.assign({}, bid)); | ||
} catch (e) { | ||
logError('Error during bid adjustment', 'bidmanager.js', e); | ||
} | ||
const bidCpmAdjustment = bidderSettings.get(code || null, 'bidCpmAdjustment'); | ||
|
||
if (bidCpmAdjustment && typeof bidCpmAdjustment === 'function') { | ||
try { | ||
bidPriceAdjusted = bidCpmAdjustment(bid.cpm, Object.assign({}, bid)); | ||
} catch (e) { | ||
logError('Error during bid adjustment', 'bidmanager.js', e); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import {deepAccess, mergeDeep} from './utils.js'; | ||
import {getGlobal} from './prebidGlobal.js'; | ||
|
||
const CONSTANTS = require('./constants.json'); | ||
|
||
export function ScopedSettings(getSettings, defaultScope) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not big fan of OOP concept. In modules we have exported functions (that can be used in other modules/bidders) and private functions that are used only inside that module. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason to not using Class if you choose OOP? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because when I started working on this IE11 was still a target :) I don't have a strong preference on the syntax, I can rewrite using
Then some day I'll have to explain to you why you're wrong. But more seriously, I don't understand how you can say we barely use OOP - config, auctionManager, auction, adapterManager, adapters, etc are all objects with capabilities. Is the problem that I use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, totally :) |
||
this.getSettings = getSettings; | ||
this.defaultScope = defaultScope; | ||
} | ||
|
||
/** | ||
* Get setting value at `path` under the given scope, falling back to the default scope if needed. | ||
* If `scope` is `null`, get the setting's default value. | ||
* @param scope {String|null} | ||
* @param path {String} | ||
* @returns {*} | ||
*/ | ||
ScopedSettings.prototype.get = function (scope, path) { | ||
let value = this.getOwn(scope, path); | ||
if (typeof value === 'undefined') { | ||
value = this.getOwn(null, path); | ||
} | ||
return value; | ||
} | ||
|
||
/** | ||
* Get the setting value at `path` *without* falling back to the default value. | ||
* @param scope {String} | ||
* @param path {String} | ||
* @returns {*} | ||
*/ | ||
ScopedSettings.prototype.getOwn = function (scope, path) { | ||
scope = this.resolveScope(scope); | ||
return deepAccess(this.getSettings(), `${scope}.${path}`) | ||
} | ||
|
||
/** | ||
* @returns {string[]} all existing scopes except the default one. | ||
*/ | ||
ScopedSettings.prototype.getScopes = function () { | ||
return Object.keys(this.getSettings()).filter((scope) => scope !== this.defaultScope); | ||
} | ||
|
||
/** | ||
* @returns all settings in the given scope, merged with the settings for the default scope. | ||
*/ | ||
ScopedSettings.prototype.settingsFor = function (scope) { | ||
return mergeDeep({}, this.ownSettingsFor(null), this.ownSettingsFor(scope)); | ||
} | ||
|
||
/** | ||
* @returns all settings in the given scope, *without* any of the default settings. | ||
*/ | ||
ScopedSettings.prototype.ownSettingsFor = function (scope) { | ||
scope = this.resolveScope(scope); | ||
return this.getSettings()[scope] || {}; | ||
} | ||
|
||
ScopedSettings.prototype.resolveScope = function (scope) { | ||
if (scope == null) { | ||
return this.defaultScope; | ||
} else { | ||
return scope; | ||
} | ||
} | ||
|
||
export const bidderSettings = new ScopedSettings(() => getGlobal().bidderSettings || {}, CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD); |
Uh oh!
There was an error while loading. Please reload this page.