-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Optimize AOL adapter and heavily reduce the size #653
Changes from all commits
9c53431
67c307a
38bd3ae
981fb75
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 |
---|---|---|
@@ -1,183 +1,140 @@ | ||
var utils = require('../utils.js'); | ||
var bidfactory = require('../bidfactory.js'); | ||
var bidmanager = require('../bidmanager.js'); | ||
var adloader = require('../adloader'); | ||
|
||
var AolAdapter = function AolAdapter() { | ||
|
||
// constants | ||
var ADTECH_URI = 'https://secure-ads.pictela.net/rm/marketplace/pubtaglib/0_4_0/pubtaglib_0_4_0.js'; | ||
var ADTECH_BIDDER_NAME = 'aol'; | ||
var ADTECH_PUBAPI_CONFIG = { | ||
pixelsDivId: 'pixelsDiv', | ||
defaultKey: 'aolBid', | ||
roundingConfig: [ | ||
{ | ||
from: 0, | ||
to: 999, | ||
roundFunction: 'tenCentsRound' | ||
}, { | ||
from: 1000, | ||
to: -1, | ||
roundValue: 1000 | ||
} | ||
], | ||
pubApiOK: _addBid, | ||
pubApiER: _addErrorBid | ||
const utils = require('../utils.js'); | ||
const ajax = require('../ajax.js').ajax; | ||
const bidfactory = require('../bidfactory.js'); | ||
const bidmanager = require('../bidmanager.js'); | ||
|
||
const AolAdapter = function AolAdapter() { | ||
|
||
const pubapiTemplate = template`${'protocol'}://${'host'}/pubapi/3.0/${'network'}/${'placement'}/${'pageid'}/${'sizeid'}/ADTECH;v=2;cmd=bid;cors=yes;alias=${'alias'}${'bidfloor'};misc=${'misc'}`; | ||
const BIDDER_CODE = 'aol'; | ||
const SERVER_MAP = { | ||
us: 'adserver-us.adtech.advertising.com', | ||
eu: 'adserver-eu.adtech.advertising.com', | ||
as: 'adserver-as.adtech.advertising.com' | ||
}; | ||
|
||
var bids; | ||
var bidsMap = {}; | ||
var d = window.document; | ||
var h = d.getElementsByTagName('HEAD')[0]; | ||
var dummyUnitIdCount = 0; | ||
|
||
/** | ||
* @private create a div that we'll use as the | ||
* location for the AOL unit; AOL will document.write | ||
* if the div is not present in the document. | ||
* @param {String} id to identify the div | ||
* @return {String} the id used with the div | ||
*/ | ||
function _dummyUnit(id) { | ||
var div = d.createElement('DIV'); | ||
|
||
if (!id || !id.length) { | ||
id = 'ad-placeholder-' + (++dummyUnitIdCount); | ||
} | ||
|
||
div.id = id + '-head-unit'; | ||
h.appendChild(div); | ||
return div.id; | ||
function template(strings, ...keys) { | ||
return function(...values) { | ||
let dict = values[values.length - 1] || {}; | ||
let result = [strings[0]]; | ||
keys.forEach(function(key, i) { | ||
let value = Number.isInteger(key) ? values[key] : dict[key]; | ||
result.push(value, strings[i + 1]); | ||
}); | ||
return result.join(''); | ||
}; | ||
} | ||
|
||
/** | ||
* @private Add a succesful bid response for aol | ||
* @param {ADTECHResponse} response the response for the bid | ||
* @param {ADTECHContext} context the context passed from aol | ||
*/ | ||
function _addBid(response, context) { | ||
var bid = bidsMap[context.alias]; | ||
var cpm; | ||
|
||
if (!bid) { | ||
utils.logError('mismatched bid: ' + context.placement, ADTECH_BIDDER_NAME, context); | ||
return; | ||
} | ||
function _buildPubapiUrl(bid) { | ||
const params = bid.params; | ||
const serverParam = params.server; | ||
let regionParam = params.region || 'us'; | ||
let server; | ||
|
||
cpm = response.getCPM(); | ||
if (cpm === null || isNaN(cpm)) { | ||
return _addErrorBid(response, context); | ||
if (!SERVER_MAP.hasOwnProperty(regionParam)) { | ||
console.warn(`Unknown region '${regionParam}' for AOL bidder.`); | ||
regionParam = 'us'; // Default region. | ||
} | ||
|
||
// clean up--we no longer need to store the bid | ||
delete bidsMap[context.alias]; | ||
|
||
var bidResponse = bidfactory.createBid(1); | ||
var ad = response.getCreative(); | ||
if (typeof response.getPixels() !== 'undefined') { | ||
ad += response.getPixels(); | ||
if (serverParam) { | ||
server = serverParam; | ||
} else { | ||
server = SERVER_MAP[regionParam]; | ||
} | ||
bidResponse.bidderCode = ADTECH_BIDDER_NAME; | ||
bidResponse.ad = ad; | ||
bidResponse.cpm = cpm; | ||
bidResponse.width = response.getAdWidth(); | ||
bidResponse.height = response.getAdHeight(); | ||
bidResponse.creativeId = response.getCreativeId(); | ||
|
||
// add it to the bid manager | ||
// Set region param, used by AOL analytics. | ||
params.region = regionParam; | ||
|
||
return pubapiTemplate({ | ||
protocol: (document.location.protocol === 'https:') ? 'https' : 'http', | ||
host: server, | ||
network: params.network, | ||
placement: parseInt(params.placement), | ||
pageid: params.pageId || 0, | ||
sizeid: params.sizeId || 0, | ||
alias: params.alias || utils.getUniqueIdentifierStr(), | ||
bidfloor: (typeof params.bidFloor !== 'undefined') ? | ||
`;bidfloor=${params.bidFloor.toString()}` : '', | ||
misc: new Date().getTime() // cache busting | ||
}); | ||
} | ||
|
||
function _addErrorBidResponse(bid, response = {}) { | ||
const bidResponse = bidfactory.createBid(2, bid); | ||
bidResponse.bidderCode = BIDDER_CODE; | ||
bidResponse.reason = response.nbr; | ||
bidResponse.raw = response; | ||
bidmanager.addBidResponse(bid.placementCode, bidResponse); | ||
} | ||
|
||
/** | ||
* @private Add an error bid response for aol | ||
* @param {ADTECHResponse} response the response for the bid | ||
* @param {ADTECHContext} context the context passed from aol | ||
*/ | ||
function _addErrorBid(response, context) { | ||
var bid = bidsMap[context.alias]; | ||
function _addBidResponse(bid, response) { | ||
let bidData; | ||
|
||
if (!bid) { | ||
utils.logError('mismatched bid: ' + context.placement, ADTECH_BIDDER_NAME, context); | ||
try { | ||
bidData = response.seatbid[0].bid[0]; | ||
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. An empty bid or "no bid" response causes this to fail which throws an error, though a response with an empty 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. When an error is thrown here, |
||
} catch (e) { | ||
_addErrorBidResponse(bid, response); | ||
return; | ||
} | ||
|
||
// clean up--we no longer need to store the bid | ||
delete bidsMap[context.alias]; | ||
let cpm; | ||
|
||
var bidResponse = bidfactory.createBid(2); | ||
bidResponse.bidderCode = ADTECH_BIDDER_NAME; | ||
bidResponse.reason = response.getNbr(); | ||
bidResponse.raw = response.getResponse(); | ||
bidmanager.addBidResponse(bid.placementCode, bidResponse); | ||
} | ||
if (bidData.ext && bidData.ext.encp) { | ||
cpm = bidData.ext.encp; | ||
} else { | ||
cpm = bidData.price; | ||
|
||
/** | ||
* @private map a prebid bidrequest to an ADTECH/aol bid request | ||
* @param {Bid} bid the bid request | ||
* @return {Object} the bid request, formatted for the ADTECH/DAC api | ||
*/ | ||
function _mapUnit(bid) { | ||
var alias = bid.params.alias || utils.getUniqueIdentifierStr(); | ||
|
||
// save the bid | ||
bidsMap[alias] = bid; | ||
|
||
return { | ||
adContainerId: _dummyUnit(bid.params.adContainerId), | ||
server: bid.params.server, // By default, DAC.js will use the US region endpoint (adserver.adtechus.com) | ||
sizeid: bid.params.sizeId || 0, | ||
pageid: bid.params.pageId, | ||
secure: document.location.protocol === 'https:', | ||
serviceType: 'pubapi', | ||
performScreenDetection: false, | ||
alias: alias, | ||
network: bid.params.network, | ||
placement: parseInt(bid.params.placement), | ||
gpt: { | ||
adUnitPath: bid.params.adUnitPath || bid.placementCode, | ||
size: bid.params.size || (bid.sizes || [])[0] | ||
}, | ||
params: { | ||
cors: 'yes', | ||
cmd: 'bid', | ||
bidfloor: (typeof bid.params.bidFloor !== "undefined") ? bid.params.bidFloor.toString() : '' | ||
}, | ||
pubApiConfig: ADTECH_PUBAPI_CONFIG, | ||
placementCode: bid.placementCode | ||
}; | ||
} | ||
if (cpm === null || isNaN(cpm)) { | ||
utils.logError('Invalid price in bid response', BIDDER_CODE, bid); | ||
_addErrorBidResponse(bid, response); | ||
return; | ||
} | ||
} | ||
|
||
/** | ||
* @private once ADTECH is loaded, request bids by | ||
* calling ADTECH.loadAd | ||
*/ | ||
function _reqBids() { | ||
if (!window.ADTECH) { | ||
utils.logError('window.ADTECH is not present!', ADTECH_BIDDER_NAME); | ||
return; | ||
let ad = bidData.adm; | ||
if (bidData.ext && bidData.ext.pixels) { | ||
ad += bidData.ext.pixels; | ||
} | ||
|
||
// get the bids | ||
utils._each(bids, function (bid) { | ||
var bidreq = _mapUnit(bid); | ||
window.ADTECH.loadAd(bidreq); | ||
}); | ||
const bidResponse = bidfactory.createBid(1, bid); | ||
bidResponse.bidderCode = BIDDER_CODE; | ||
bidResponse.ad = ad; | ||
bidResponse.cpm = cpm; | ||
bidResponse.width = bidData.w; | ||
bidResponse.height = bidData.h; | ||
bidResponse.creativeId = bidData.crid; | ||
bidResponse.pubapiId = response.id; | ||
bidResponse.currencyCode = response.cur; | ||
if (bidData.dealid) { | ||
bidResponse.dealId = bidData.dealid; | ||
} | ||
|
||
bidmanager.addBidResponse(bid.placementCode, bidResponse); | ||
} | ||
|
||
/** | ||
* @public call the bids | ||
* this requests the specified bids | ||
* from aol marketplace | ||
* @param {Object} params | ||
* @param {Array} params.bids the bids to be requested | ||
*/ | ||
function _callBids(params) { | ||
window.bidRequestConfig = window.bidRequestConfig || {}; | ||
window.dacBidRequestConfigs = window.dacBidRequestConfigs || {}; | ||
bids = params.bids; | ||
if (!bids || !bids.length) return; | ||
adloader.loadScript(ADTECH_URI, _reqBids, true); | ||
utils._each(params.bids, bid => { | ||
const pubapiUrl = _buildPubapiUrl(bid); | ||
|
||
ajax(pubapiUrl, response => { | ||
if (!response && response.length <= 0) { | ||
utils.logError('Empty bid response', BIDDER_CODE, bid); | ||
_addErrorBidResponse(bid, response); | ||
return; | ||
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. For an empty bid response, you will still want to add a bid response, likely 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. Thanks for the suggestion. This is now fixed. |
||
} | ||
|
||
try { | ||
response = JSON.parse(response); | ||
} catch (e) { | ||
utils.logError('Invalid JSON in bid response', BIDDER_CODE, bid); | ||
_addErrorBidResponse(bid, response); | ||
return; | ||
} | ||
|
||
_addBidResponse(bid, response); | ||
|
||
}, null, { withCredentials: true }); | ||
}); | ||
} | ||
|
||
return { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
console.warn
doesn't play nice in IE 9. Please useutils.logWarn
instead for safety.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for using
console.warn()
directly is that this warning is meant to be shown when a publisher is configuring a site and uses incorrect region. I want to show the warning even if the debug mode is turned off, so the publisher can see what's wrong. And I expect publisher to be configuring it in a browser other than IE9 🤔. After the site is configured correctly, the warning should go away, so I believe it is safe to use thisconsole.warn()
. If you feel otherwise, please let me know.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair enough I suppose. Thanks