diff --git a/src/auction.js b/src/auction.js index bf3f1bb1b71..7cb08af7402 100644 --- a/src/auction.js +++ b/src/auction.js @@ -48,7 +48,8 @@ * @property {function(): void} callBids - sends requests to all adapters for bids */ -import { uniques, flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest } from './utils'; +import { uniques, flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue } from './utils'; +import { parse as parseURL } from './url'; import { getPriceBucketString } from './cpmBucketManager'; import { getNativeTargeting } from './native'; import { getCacheUrl, store } from './videoCache'; @@ -504,7 +505,26 @@ function setupBidTargeting(bidObject, bidderRequest) { bidObject.adserverTargeting = Object.assign(bidObject.adserverTargeting || {}, keyValues); } -export function getStandardBidderSettings(mediaType) { +/** + * @param {string} mediaType + * @param {string} bidderCode + * @returns {*} + */ +export function getStandardBidderSettings(mediaType, bidderCode) { + // factory for key value objs + function createKeyVal(key, value) { + return { + key, + val: (typeof value === 'function') + ? function (bidResponse) { + return value(bidResponse); + } + : function (bidResponse) { + return getValue(bidResponse, value); + } + }; + } + const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS; // Use the config value 'mediaTypeGranularity' if it has been set for mediaType, else use 'priceGranularity' const mediaTypeGranularity = config.getConfig(`mediaTypePriceGranularity.${mediaType}`); const granularity = (typeof mediaType === 'string' && mediaTypeGranularity) ? ((typeof mediaTypeGranularity === 'string') ? mediaTypeGranularity : 'custom') : config.getConfig('priceGranularity'); @@ -515,67 +535,50 @@ export function getStandardBidderSettings(mediaType) { } 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] = [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - if (granularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) { - return bidResponse.pbAg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) { - return bidResponse.pbDg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.LOW) { - return bidResponse.pbLg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.MEDIUM) { - return bidResponse.pbMg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.HIGH) { - return bidResponse.pbHg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.CUSTOM) { - return bidResponse.pbCg; - } - } - }, { - key: CONSTANTS.TARGETING_KEYS.SIZE, - val: function (bidResponse) { - return bidResponse.size; - } - }, { - key: CONSTANTS.TARGETING_KEYS.DEAL, - val: function (bidResponse) { - return bidResponse.dealId; + createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'), + createKeyVal(TARGETING_KEYS.AD_ID, 'adId'), + createKeyVal(TARGETING_KEYS.PRICE_BUCKET, function(bidResponse) { + if (granularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) { + return bidResponse.pbAg; + } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) { + return bidResponse.pbDg; + } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.LOW) { + return bidResponse.pbLg; + } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.MEDIUM) { + return bidResponse.pbMg; + } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.HIGH) { + return bidResponse.pbHg; + } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.CUSTOM) { + return bidResponse.pbCg; } - }, - { - key: CONSTANTS.TARGETING_KEYS.SOURCE, - val: function (bidResponse) { - return bidResponse.source; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.FORMAT, - val: function (bidResponse) { - return bidResponse.mediaType; - } - }, + }), + createKeyVal(TARGETING_KEYS.SIZE, 'size'), + createKeyVal(TARGETING_KEYS.DEAL, 'dealId'), + createKeyVal(TARGETING_KEYS.SOURCE, 'source'), + createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'), ] + } - if (mediaType === 'video') { - [CONSTANTS.TARGETING_KEYS.UUID, CONSTANTS.TARGETING_KEYS.CACHE_ID].forEach(item => { - bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING].push({ - key: item, - val: function val(bidResponse) { - return bidResponse.videoCacheKey; - } - }) - }); + if (mediaType === 'video') { + const adserverTargeting = bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]; + + // Adding hb_uuid + hb_cache_id + [TARGETING_KEYS.UUID, TARGETING_KEYS.CACHE_ID].forEach(targetingKeyVal => { + if (typeof find(adserverTargeting, kvPair => kvPair.key === targetingKeyVal) === 'undefined') { + adserverTargeting.push(createKeyVal(targetingKeyVal, 'videoCacheKey')); + } + }); + + // Adding hb_cache_host + if (config.getConfig('cache.url') && (!bidderCode || utils.deepAccess(bidderSettings, `${bidderCode}.sendStandardTargeting`) !== false)) { + const urlInfo = parseURL(config.getConfig('cache.url')); + + if (typeof find(adserverTargeting, targetingKeyVal => targetingKeyVal.key === TARGETING_KEYS.CACHE_HOST) === 'undefined') { + adserverTargeting.push(createKeyVal(TARGETING_KEYS.CACHE_HOST, function(bidResponse) { + return utils.deepAccess(bidResponse, `adserverTargeting.${TARGETING_KEYS.CACHE_HOST}`) + ? bidResponse.adserverTargeting[TARGETING_KEYS.CACHE_HOST] : urlInfo.hostname; + })); + } } } return bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]; @@ -592,7 +595,7 @@ export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) { // 1) set the keys from "standard" setting or from prebid defaults if (bidderSettings) { // initialize default if not set - const standardSettings = getStandardBidderSettings(custBidObj.mediaType); + const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode); setKeys(keyValues, standardSettings, custBidObj); // 2) set keys from specific bidder setting override if they exist diff --git a/src/constants.json b/src/constants.json index 1a78e376150..a181df3f684 100644 --- a/src/constants.json +++ b/src/constants.json @@ -64,7 +64,8 @@ "SOURCE": "hb_source", "FORMAT": "hb_format", "UUID": "hb_uuid", - "CACHE_ID": "hb_cache_id" + "CACHE_ID": "hb_cache_id", + "CACHE_HOST": "hb_cache_host" }, "NATIVE_KEYS": { "title": "hb_native_title", diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index aab1da11653..9c936ace421 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -142,6 +142,7 @@ describe('auctionmanager.js', function () { if (bid.mediaType === 'video') { expected[ CONSTANTS.TARGETING_KEYS.UUID ] = bid.videoCacheKey; expected[ CONSTANTS.TARGETING_KEYS.CACHE_ID ] = bid.videoCacheKey; + expected[ CONSTANTS.TARGETING_KEYS.CACHE_HOST ] = 'prebid.adnxs.com'; } if (!keys) { return expected; @@ -162,11 +163,18 @@ describe('auctionmanager.js', function () { it('No bidder level configuration defined - default', function () { $$PREBID_GLOBAL$$.bidderSettings = {}; let expected = getDefaultExpected(bid); + // remove hb_cache_host from expected + delete expected.hb_cache_host; let response = getKeyValueTargetingPairs(bid.bidderCode, bid); assert.deepEqual(response, expected); }); it('No bidder level configuration defined - default for video', function () { + config.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + } + }); $$PREBID_GLOBAL$$.bidderSettings = {}; let videoBid = utils.deepClone(bid); videoBid.mediaType = 'video'; @@ -229,6 +237,11 @@ describe('auctionmanager.js', function () { }); it('Custom configuration for all bidders with video bid', function () { + config.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + } + }); let videoBid = utils.deepClone(bid); videoBid.mediaType = 'video'; videoBid.videoCacheKey = 'abc123def'; @@ -288,6 +301,7 @@ describe('auctionmanager.js', function () { }; let expected = getDefaultExpected(videoBid); + let response = getKeyValueTargetingPairs(videoBid.bidderCode, videoBid); assert.deepEqual(response, expected); });