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

Appnexus targeting function #920

Merged
merged 6 commits into from
Jan 18, 2017
Merged
Show file tree
Hide file tree
Changes from all 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
182 changes: 16 additions & 166 deletions src/prebid.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @module $$PREBID_GLOBAL$$ */

import { getGlobal } from './prebidGlobal';
import {flatten, uniques, isGptPubadsDefined, getHighestCpm, adUnitsFilter} from './utils';
import {flatten, uniques, isGptPubadsDefined, adUnitsFilter} from './utils';
import { videoAdUnit, hasNonVideoBidder } from './video';
import 'polyfill';
import {parse as parseURL, format as formatURL} from './url';
Expand All @@ -17,6 +17,7 @@ var bidfactory = require('./bidfactory');
var adloader = require('./adloader');
var events = require('./events');
var adserver = require('./adserver.js');
var targeting = require('./targeting.js');

/* private variables */

Expand All @@ -27,7 +28,6 @@ var BID_WON = CONSTANTS.EVENTS.BID_WON;

var auctionRunning = false;
var bidRequestQueue = [];
var pbTargetingKeys = [];

var eventValidators = {
bidWon: checkDefinedPlacement
Expand Down Expand Up @@ -113,166 +113,6 @@ function checkDefinedPlacement(id) {
return true;
}

function resetPresetTargeting() {
if (isGptPubadsDefined()) {
window.googletag.pubads().getSlots().forEach(slot => {
pbTargetingKeys.forEach(function(key){
slot.setTargeting(key,null);
});
});
}
}

function setTargeting(targetingConfig) {
window.googletag.pubads().getSlots().forEach(slot => {
targetingConfig.filter(targeting => Object.keys(targeting)[0] === slot.getAdUnitPath() ||
Object.keys(targeting)[0] === slot.getSlotElementId())
.forEach(targeting => targeting[Object.keys(targeting)[0]]
.forEach(key => {
key[Object.keys(key)[0]]
.map((value) => {
utils.logMessage(`Attempting to set key value for slot: ${slot.getSlotElementId()} key: ${Object.keys(key)[0]} value: ${value}`);
return value;
})
.forEach(value => {
slot.setTargeting(Object.keys(key)[0], value);
});
}));
});
}

function getStandardKeys() {
return bidmanager.getStandardBidderAdServerTargeting() // in case using a custom standard key set
.map(targeting => targeting.key)
.concat(CONSTANTS.TARGETING_KEYS).filter(uniques); // standard keys defined in the library.
}

function getWinningBids(adUnitCode) {
// use the given adUnitCode as a filter if present or all adUnitCodes if not
const adUnitCodes = adUnitCode ?
[adUnitCode] :
$$PREBID_GLOBAL$$._adUnitCodes;

return $$PREBID_GLOBAL$$._bidsReceived
.filter(bid => adUnitCodes.includes(bid.adUnitCode))
.filter(bid => bid.cpm > 0)
.map(bid => bid.adUnitCode)
.filter(uniques)
.map(adUnitCode => $$PREBID_GLOBAL$$._bidsReceived
.filter(bid => bid.adUnitCode === adUnitCode ? bid : null)
.reduce(getHighestCpm,
{
adUnitCode: adUnitCode,
cpm: 0,
adserverTargeting: {},
timeToRespond: 0
}));
}

function getWinningBidTargeting() {
let winners = getWinningBids();

// winning bids with deals need an hb_deal targeting key
winners
.filter(bid => bid.dealId)
.map(bid => bid.adserverTargeting.hb_deal = bid.dealId);

let standardKeys = getStandardKeys();
winners = winners.map(winner => {
return {
[winner.adUnitCode]: Object.keys(winner.adserverTargeting)
.filter(key =>
typeof winner.sendStandardTargeting === "undefined" ||
winner.sendStandardTargeting ||
standardKeys.indexOf(key) === -1)
.map(key => ({ [key.substring(0, 20)]: [winner.adserverTargeting[key]] }))
};
});

return winners;
}

function getDealTargeting() {
return $$PREBID_GLOBAL$$._bidsReceived.filter(bid => bid.dealId).map(bid => {
const dealKey = `hb_deal_${bid.bidderCode}`;
return {
[bid.adUnitCode]: getTargetingMap(bid, CONSTANTS.TARGETING_KEYS)
.concat({ [dealKey.substring(0, 20)]: [bid.adserverTargeting[dealKey]] })
};
});
}

/**
* Get custom targeting keys for bids that have `alwaysUseBid=true`.
*/
function getAlwaysUseBidTargeting(adUnitCodes) {
let standardKeys = getStandardKeys();
return $$PREBID_GLOBAL$$._bidsReceived
.filter(adUnitsFilter.bind(this, adUnitCodes))
.map(bid => {
if (bid.alwaysUseBid) {
return {
[bid.adUnitCode]: Object.keys(bid.adserverTargeting).map(key => {
// Get only the non-standard keys of the losing bids, since we
// don't want to override the standard keys of the winning bid.
if (standardKeys.indexOf(key) > -1) {
return;
}

return { [key.substring(0, 20)]: [bid.adserverTargeting[key]] };

}).filter(key => key) // remove empty elements
};
}
})
.filter(bid => bid); // removes empty elements in array;
}

function getBidLandscapeTargeting(adUnitCodes) {
const standardKeys = CONSTANTS.TARGETING_KEYS;

return $$PREBID_GLOBAL$$._bidsReceived
.filter(adUnitsFilter.bind(this, adUnitCodes))
.map(bid => {
if (bid.adserverTargeting) {
return {
[bid.adUnitCode]: getTargetingMap(bid, standardKeys)
};
}
}).filter(bid => bid); // removes empty elements in array
}

function getTargetingMap(bid, keys) {
return keys.map(key => {
return {
[`${key}_${bid.bidderCode}`.substring(0, 20)]: [bid.adserverTargeting[key]]
};
});
}

function getAllTargeting(adUnitCode) {
const adUnitCodes = adUnitCode && adUnitCode.length ? [adUnitCode] : $$PREBID_GLOBAL$$._adUnitCodes;

// Get targeting for the winning bid. Add targeting for any bids that have
// `alwaysUseBid=true`. If sending all bids is enabled, add targeting for losing bids.
var targeting = getWinningBidTargeting(adUnitCodes)
.concat(getAlwaysUseBidTargeting(adUnitCodes))
.concat($$PREBID_GLOBAL$$._sendAllBids ? getBidLandscapeTargeting(adUnitCodes) : [])
.concat(getDealTargeting(adUnitCodes));

//store a reference of the targeting keys
targeting.map(adUnitCode => {
Object.keys(adUnitCode).map(key => {
adUnitCode[key].map(targetKey => {
if (pbTargetingKeys.indexOf(Object.keys(targetKey)[0]) === -1) {
pbTargetingKeys = Object.keys(targetKey).concat(pbTargetingKeys);
}
});
});
});
return targeting;
}

/**
* When a request for bids is made any stale bids remaining will be cleared for
* a placement included in the outgoing bid request.
Expand Down Expand Up @@ -333,7 +173,7 @@ $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode = function(adUnitCode) {

$$PREBID_GLOBAL$$.getAdserverTargeting = function (adUnitCode) {
utils.logInfo('Invoking $$PREBID_GLOBAL$$.getAdserverTargeting', arguments);
return getAllTargeting(adUnitCode)
return targeting.getAllTargeting(adUnitCode)
.map(targeting => {
return {
[Object.keys(targeting)[0]]: targeting[Object.keys(targeting)[0]]
Expand Down Expand Up @@ -403,9 +243,19 @@ $$PREBID_GLOBAL$$.setTargetingForGPTAsync = function () {
}

//first reset any old targeting
resetPresetTargeting();
targeting.resetPresetTargeting();
//now set new targeting keys
setTargeting(getAllTargeting());
targeting.setTargeting(targeting.getAllTargeting());
};

$$PREBID_GLOBAL$$.setTargetingForAst = function() {
utils.logInfo('Invoking $$PREBID_GLOBAL$$.setTargetingForAn', arguments);
if(!targeting.isApntagDefined()) {
utils.logError('window.apntag is not defined on the page');
return;
}

targeting.setTargetingForAst();
};

/**
Expand Down Expand Up @@ -837,7 +687,7 @@ $$PREBID_GLOBAL$$.setBidderSequence = function (order) {
* @return {array} array containing highest cpm bid object(s)
*/
$$PREBID_GLOBAL$$.getHighestCpmBids = function (adUnitCode) {
return getWinningBids(adUnitCode);
return targeting.getWinningBids(adUnitCode);
};

$$PREBID_GLOBAL$$.que.push(() => listenMessagesFromCreative());
Expand Down
Loading