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

adding yieldbot adapter #35

Merged
merged 1 commit into from
Aug 31, 2015
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
10 changes: 8 additions & 2 deletions integrationExamples/gpt/pbjs_example_gpt.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
params: {
aid: '{id}'
}
},
},
// 1 ad unit can also be targeted by multiple bids from 1 bidder
{
bidder: 'pubmatic',
Expand Down Expand Up @@ -110,6 +110,12 @@
rp_tracking : '{id}',
rp_floor : '0.1'
}
}, {
bidder: 'yieldbot',
params: {
pub: '{id}',
name: '{id}'
}
}]
}];

Expand Down Expand Up @@ -241,4 +247,4 @@ <h2>Prebid.js Test</h2>

</body>

</html>
</html>
2 changes: 2 additions & 0 deletions src/adaptermanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ var OpenxAdapter = require('./adapters/openx');
var PubmaticAdapter = require('./adapters/pubmatic.js');
var CriteoAdapter = require('./adapters/criteo');
var AmazonAdapter = require('./adapters/amazon');
var YieldbotAdapter = require('./adapters/yieldbot');
var bidmanager = require('./bidmanager.js');
var utils = require('./utils.js');
var CONSTANTS = require('./constants.json');
Expand Down Expand Up @@ -50,3 +51,4 @@ registerBidAdapter(OpenxAdapter(), 'openx');
registerBidAdapter(PubmaticAdapter(), 'pubmatic');
registerBidAdapter(CriteoAdapter(), 'criteo');
registerBidAdapter(AmazonAdapter(), 'amazon');
registerBidAdapter(YieldbotAdapter(), 'yieldbot');
5 changes: 3 additions & 2 deletions src/adapters/rubicon.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ var RubiconAdapter = function RubiconAdapter() {

}

pbjs.handleRubiconCallback = function(response) {
window.pbjs = window.pbjs || {que: []};
Copy link
Member

Choose a reason for hiding this comment

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

Good catch. Could you refactor this into the first line of src/prebid.js - since this is an issue with pbjs being undefined other adapters could also have this issue. Thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah I'll take this out of here and put in a separate PR for that

window.pbjs.handleRubiconCallback = function(response) {
var placementCode = '';

var bid = {};
Expand Down Expand Up @@ -169,4 +170,4 @@ var RubiconAdapter = function RubiconAdapter() {
//end of Rubicon bid adaptor
};

module.exports = RubiconAdapter;
module.exports = RubiconAdapter;
222 changes: 222 additions & 0 deletions src/adapters/yieldbot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
/**
* @file yieldbot adapter
*/
var utils = require('../utils'),
adloader = require('../adloader'),
bidmanager = require('../bidmanager'),
bidfactory = require('../bidfactory');

function YieldbotAdapter() {

var toString = Object.prototype.toString,
hasOwnProperty = Object.prototype.hasOwnProperty,
ybq = window.ybotq || (window.ybotq = []),
t_Arr = 'Array',
t_Str = 'String',
t_Fn = 'Function',
bidmap = {};

// constants
var YB = 'YIELDBOT',
YB_URL = '//cdn.yldbt.com/js/yieldbot.intent.js',
CREATIVE_TEMPLATE = "<script type='text/javascript' src='" +
YB_URL + "'></script><script type='text/javascript'>var ybotq=ybotq||[];" +
"ybotq.push(function(){yieldbot.renderAd('%%SLOT%%:%%SIZE%%');})" +
"</script>";

/**
* Return if the object is of the
* given type.
* @param {*} object to test
* @param {String} _t type string (e.g., Array)
* @return {Boolean} if object is of type _t
*/
function isA(object, _t) {
return toString.call(object) === '[object ' + _t + ']';
}

/**
* Return if the object is "empty";
* this includes falsey, no keys, or no items at indices
* @param {*} object object to test
* @return {Boolean} if object is empty
*/
function isEmpty(object) {
if (!object) return true;
if (isA(object, t_Arr) || isA(object, t_Str)) return !(object.length > 0);
for (var k in object) {
if (hasOwnProperty.call(object, k)) return false;
}
return true;
}

/**
* Iterate object with the function
* falls back to es5 `forEach`
* @param {Array|Object} object
* @param {Function(value, key, object)} fn
*/
function _each(object, fn) {
if (isEmpty(object)) return;
if (isA(object.forEach, t_Fn)) return object.forEach(fn);

var k = 0,
l = object.length;

if (l > 0) {
for (; k < l; k++) fn(object[k], k, object);
} else {
for (k in object) fn(object[k], k, object);
}
}

var yb = {

/**
* basic template: %%MY_VAR_TO_TPL%%
*/
tplRxp: /%%(\w+)%%/g,

/**
* Normalize a size; if the user gives us
* a dim array, produce a wxh string
* @param {String|Array} size
* @return {String} WxH string
*/
formatSize: function (size) {
return isA(size, t_Arr) ? size.join('x') : size;
},

/**
* Return a creative from its template
* @param {String} slot -- this is the yieldbot slot code
* @param {String|Array} size that the bid was for
* @return {String} the creative's HTML
*/
creative: function (slot, size) {

var args = {
slot: slot,
size: yb.formatSize(size),
};

return CREATIVE_TEMPLATE.replace(yb.tplRxp, function ($0, $1) {
return args[($1 || '').toLowerCase()];
});
},

/**
* Produce a bid for our bidmanager,
* set the relevant attributes from
* our returned yieldbot string
* @param {String} yieldBotStr the string from yieldbot page targeting
* @return {Bid} a bid for the bidmanager
*/
makeBid: function (placement, slot, params) {
var dim = params.ybot_size.split('x'),
bid = bidfactory.createBid(1);

bid.bidderCode = 'yieldbot';
bid.width = parseInt(dim[0]);
bid.height = parseInt(dim[1]);
bid.code = slot;
bid.size = params.ybot_size;
bid.cpm = parseInt(params.ybot_cpm) / 100.0;
bid.ad = yb.creative(slot, params.ybot_size);
bid.placementCode = placement;
return bid;
},

/**
* Add a slot to yieldbot (to request a bid)
* @param {Bid} bid this should be a bid from prebid
*/
registerSlot: function (bid) {
ybq.push(function () {
bidmap[bid.params.name] = bid.placementCode;
yieldbot.defineSlot(bid.params.name, {
sizes: bid.params.sizes
});
});
}
};

function addErrorBid(placementCode, yslot, params) {
var bid = bidfactory.createBid(2);
bid.bidderCode = 'yieldbot';
bid.placementCode = placementCode;
bid.code = yslot;
bid.__raw = params;

utils.logError('invalid response; adding error bid: ' + placementCode, YB);
bidmanager.addBidResponse(placementCode, bid);
}

/**
* Handle the response from yieldbot;
* this is pushed into the yieldbot queue
* after we set up all of the slots.
*/
function responseHandler() {
_each(bidmap, function (placementCode, yslot) {
// get the params for the slot
var params = yieldbot.getSlotCriteria(yslot);

if (!params || ((params || {}).ybot_ad === 'n')) {
return addErrorBid(placementCode, yslot, params);
}

bidmanager.addBidResponse(placementCode, yb.makeBid(placementCode, yslot, params));
});
}

/**
* @public call bids; set the slots
* for yieldbot + add the publisher id.
* @param {Object} params
* @param {Array<Bid>} params.bids the bids we want to make
*/
function _callBids(params) {
// download the yieldbot intent tag
adloader.loadScript(YB_URL);

_each(params.bids, function (bid, i) {

if (!bid.params) {
utils.logError("invalid bid!", YB);
return;
}

// normalize the bid & fallback onto the slot
// for the sizes; in case they said `code`, make it `name`
bid.params.sizes = isEmpty(bid.params.sizes) ? bid.sizes : bid.params.sizes;
bid.params.name = bid.params.name || bid.params.code;

// on the first bid,
// set the yieldbot publisher id
if (i === 0) {
if (!bid.params.pub) {
utils.logError("no publisher id provided!", YB);
return;
}

ybq.push(function(){ yieldbot.pub(bid.params.pub);});
}

yb.registerSlot(bid);
});

ybq.push(function () {
yieldbot.enableAsync();
yieldbot.go();
});

ybq.push(responseHandler);
}

return {
callBids: _callBids
};
}

module.exports = YieldbotAdapter;