Skip to content
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

Add 'hb_cache_host' targeting for video bids when cache is set #3654

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 57 additions & 59 deletions src/auction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -505,6 +506,20 @@ function setupBidTargeting(bidObject, bidderRequest) {
}

export function getStandardBidderSettings(mediaType) {
// 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');
Expand All @@ -515,67 +530,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;
}
},
{
key: CONSTANTS.TARGETING_KEYS.SOURCE,
val: function (bidResponse) {
return bidResponse.source;
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.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'));
}
});

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest moving this block out of the check for bidderSettings.standard.adServerTargeting so that if a user does set that value, hb_cache_host is set anyhow. Probably the right approach is to check:

  • when getConfig('cache.url') is set
    -- if hb_cache_host is not already set by the user, set it

And while we're at it, let's drop hb_cache_path. I should be consistent in my desire to minimize our targeting footprint, so if we don't need hb_cache_path, let's not set it.

// Adding hb_cache_host
if (config.getConfig('cache.url')) {
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];
Expand Down
3 changes: 2 additions & 1 deletion src/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
12 changes: 12 additions & 0 deletions test/spec/auctionmanager_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -167,6 +168,11 @@ describe('auctionmanager.js', function () {
});

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';
Expand Down Expand Up @@ -229,6 +235,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';
Expand Down Expand Up @@ -288,6 +299,7 @@ describe('auctionmanager.js', function () {
};

let expected = getDefaultExpected(videoBid);

let response = getKeyValueTargetingPairs(videoBid.bidderCode, videoBid);
assert.deepEqual(response, expected);
});
Expand Down