Skip to content

Commit

Permalink
Update Sonobi adapter for: config settings, video, floor, deals, unit…
Browse files Browse the repository at this point in the history
… tests
  • Loading branch information
studnicky committed Sep 1, 2016
1 parent 9789ed1 commit ca909e8
Show file tree
Hide file tree
Showing 3 changed files with 438 additions and 147 deletions.
148 changes: 85 additions & 63 deletions src/adapters/sonobi.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,89 +4,111 @@ var adloader = require('../adloader.js');
var utils = require('../utils');

var SonobiAdapter = function SonobiAdapter(){
var test = false; // tag tester = true || false
var cb_map = {};
var keymakerAssoc = {}; // Remember placement codes for callback mapping
var bidIdAssoc = {}; // Remember bids for bid complete reporting

function _phone_in(params){
function _phone_in(request){
var trinity = 'https://apex.go.sonobi.com/trinity.js?key_maker=';
var bids = params.bids || [];
adloader.loadScript(trinity + JSON.stringify(_keymaker(bids)) + '&cv=' + _operator());
var adSlots = request.bids || [];
var bidderRequestId = request.bidderRequestId;
adloader.loadScript(trinity + JSON.stringify(_keymaker(adSlots)) + '&cv=' + _operator(bidderRequestId));
}

function _keymaker(bids){ // Make keys
function _keymaker(adSlots){ // Keymaker makes keys
var keyring = {};
utils._each(bids, function(o){
var sizes = utils.parseSizesInput(o.sizes).toString();
if (utils.isEmpty(sizes)){
utils.logWarn('Sonobi adapter expects sizes for ' + o.placementCode);
}
switch(true){
case (!o.params.ad_unit && !o.params.placement_id):
utils.logError('Sonobi unable to bid: Missing parameters for ' + o.placementCode);
break;
case (!!o.params.ad_unit && !!o.params.placement_id):
utils.logError('Sonobi unable to bid: Extra parameters for ' + o.placementCode);
break;
case (!!o.params.ad_unit && o.params.ad_unit.length === 0):
utils.logError('Sonobi unable to bid: Empty ad_unit for ' + o.placementCode);
break;
case (!!o.params.placement_id && o.params.placement_id.length === 0):
utils.logError('Sonobi unable to bid: Empty placement_id for ' + o.placementCode);
break;
case (!!o.params.placement_id): // Morpeus style
keyring[o.params.dom_id] = o.params.placement_id + (test ? '-test' : '') + '|' + sizes;
cb_map[o.params.dom_id] = o.placementCode;
break;
case (!!o.params.ad_unit && o.params.ad_unit.charAt(0) !== '/'):
// DFP docs do not necessarily require leading slash? - add it in if it's not there.
o.params.ad_unit = '/' + o.params.ad_unit;
/* falls through */
case (!!o.params.ad_unit): // Cypher style
keyring[o.params.ad_unit + '|' + o.params.dom_id] = sizes;
cb_map[o.params.ad_unit + '|' + o.params.dom_id] = o.placementCode;
break;
default: // I don't know how it's broken, but it is.
utils.logError('Sonobi unable to bid: Improper parameters for ' + o.placementCode);
utils._each(adSlots, function(bidSlot){
if(bidSlot.params){
// Optional (please don't set these as the word 'OPTIONAL' come on now why would you think that was OK?)
var dom_id = (bidSlot.params.dom_id && !utils.isEmpty(bidSlot.params.dom_id)) ? bidSlot.params.dom_id : !utils.isEmpty(bidSlot.placementCode) ? bidSlot.placementCode : "dom_" + utils.getUniqueIdentifierStr();
var floor = (bidSlot.params.floor) ? bidSlot.params.floor : null;
// Mandatory
var slotIdentifier = (bidSlot.params.ad_unit) ? bidSlot.params.ad_unit : (bidSlot.params.placement_id) ? bidSlot.params.placement_id : null;
var sizes = utils.parseSizesInput(bidSlot.sizes).toString() || null;
if (utils.isEmpty(sizes)){
utils.logError('Sonobi adapter expects sizes for ' + bidSlot.placementCode);
}
var args = (sizes) ? ((floor) ? (sizes + '|f=' + floor) : (sizes)) : (floor) ? ('f=' + floor) : '';
if (/[0-9a-fA-F]+/.test(slotIdentifier) && slotIdentifier.length === 20){
// Placements are 20 character hex
keyring[dom_id] = slotIdentifier + '|' + args;
keymakerAssoc[dom_id] = bidSlot.placementCode;
bidIdAssoc[bidSlot.placementCode] = bidSlot;
} else if (/\/?[0-9]*\/(.*\/?)*/.test(slotIdentifier)){
// AdUnitCode rules from DFP allow a lot of things you wouldn't expect
slotIdentifier = slotIdentifier.charAt(0) === '/' ? slotIdentifier : '/' + slotIdentifier;
// Consistency isn't really their thing they can't even decide if leading slash matters
keyring[slotIdentifier + '|' + dom_id] = args;
keymakerAssoc[slotIdentifier + '|' + dom_id] = bidSlot.placementCode;
bidIdAssoc[bidSlot.placementCode] = bidSlot;
} else {
keymakerAssoc[dom_id] = bidSlot.placementCode;
bidIdAssoc[bidSlot.placementCode] = bidSlot;
_failure(bidSlot.placementCode);
utils.logError('The ad unit code or Sonobi Placement id for slot ' + bidSlot.placementCode + ' is invalid');
}
}
});
return keyring;
}

function _operator(){ // Uniqify callbacks
var uniq = "cb" + utils.getUniqueIdentifierStr();
window[uniq] = _trinity;
return uniq;
function _operator(bidderRequestId){ // Name jsonp callbacks by request
var cb_name = "sbi_" + bidderRequestId;
window[cb_name] = _trinity;
return cb_name;
}

function _trinity(response){ // Callback
function _trinity(response){ // Call back
var slots = response.slots || {};
var sbi_dc = response.sbi_dc || '';
var bidObject = {};
for (var slot in slots) {
if (slots[slot].sbi_aid){
bidObject = bidfactory.createBid(1);
bidObject.bidderCode = 'sonobi';
bidObject.cpm = Number(slots[slot].sbi_mouse);
bidObject.ad = _get_creative(sbi_dc, slots[slot].sbi_aid);
bidObject.width = Number(slots[slot].sbi_size.split('x')[0]);
bidObject.height = Number(slots[slot].sbi_size.split('x')[1]);
bidmanager.addBidResponse(cb_map[slot], bidObject);
} else { // No aid? No ad.
bidObject = bidfactory.createBid(2);
bidObject.bidderCode = 'sonobi';
bidmanager.addBidResponse(cb_map[slot], bidObject);
utils._each(slots, function(bid, slot_id){
var placementCode = keymakerAssoc[slot_id];
if (bid.sbi_aid && bid.sbi_mouse && bid.sbi_size){ // I got the money you got the stuff?
_success(placementCode, sbi_dc, bid);
} else {
_failure(placementCode);
}
delete keymakerAssoc[slot_id]; // You're done get outta here
});
}

function _seraph(placementCode){ // Search for the one
var theOne = bidIdAssoc[placementCode];
delete bidIdAssoc[placementCode]; // Eliminate him
return theOne;
}

function _success(placementCode, sbi_dc, bid){
var goodBid = bidfactory.createBid(1, _seraph(placementCode));
if(bid.sbi_dozer){
goodBid.dealId = bid.sbi_dozer;
}
goodBid.bidderCode = 'sonobi';
goodBid.ad = _creative(sbi_dc, bid.sbi_aid);
goodBid.cpm = Number(bid.sbi_mouse);
// Video creatives will return sbi_size="outstream", default to 1x1
goodBid.width = Number(bid.sbi_size.split('x')[0]) || 1;
goodBid.height = Number(bid.sbi_size.split('x')[1]) || 1;
bidmanager.addBidResponse(placementCode, goodBid);
}

function _failure(placementCode){
var failBid = bidfactory.createBid(2, _seraph(placementCode));
failBid.bidderCode = 'sonobi';
bidmanager.addBidResponse(placementCode, failBid);
}

function _get_creative(sbi_dc, sbi_aid){
var creative = '<scr' + 'ipt type="text/javascript"src="https://' + sbi_dc;
creative += 'apex.go.sonobi.com/sbi.js?as=dfps&aid=' + sbi_aid;
creative += '"></scr' + 'ipt>';
return creative;
function _creative(sbi_dc, sbi_aid){
var src = 'https://' + sbi_dc + 'apex.go.sonobi.com/sbi.js?aid=' + sbi_aid + '&as=null';
return '<script type="text/javascript" src="' + src + '"></script>';
}

return { callBids: _phone_in };
return {
callBids: _phone_in,
formRequest: _keymaker,
parseResponse: _trinity,
success: _success,
failure: _failure
};
};

module.exports = SonobiAdapter;
84 changes: 0 additions & 84 deletions test/fixtures/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -973,90 +973,6 @@ export function getAdUnits() {
"requestId": "1ff753bd4ae5cb"
}
]
},
{
"code": "/7780971/apex_sparks_300",
"sizes": [
[
300,
250
]
],
"bids": [
{
"bidder": "sonobi",
"params": {
"dom_id": "div-gpt-ad-1455548812677-0",
"ad_unit": "/7780971/apex_sparks_300"
},
"placementCode": "/7780971/apex_sparks_300",
"sizes": [
[
300,
250
]
],
"bidId": "43a45a2cd8c6ef9",
"bidderRequestId": "42e2fe519b7c653",
"requestId": "1ff753bd4ae5cb"
}
]
},
{
"code": "/7780971/apex_sparks_skyscraper_x600",
"sizes": [
[
300,
600
]
],
"bids": [
{
"bidder": "sonobi",
"params": {
"dom_id": "div-gpt-ad-1455548812677-1",
"placement_id": "21d2da738fe0ba795cfb-test"
},
"placementCode": "/7780971/apex_sparks_skyscraper_x600",
"sizes": [
[
300,
600
]
],
"bidId": "44f16af92ca7607",
"bidderRequestId": "42e2fe519b7c653",
"requestId": "1ff753bd4ae5cb"
}
]
},
{
"code": "/7780971/apex_sparks_banner_x90",
"sizes": [
[
728,
90
]
],
"bids": [
{
"bidder": "sonobi",
"params": {
"dom_id": "div-gpt-ad-1455548812677-2",
"ad_unit": "/7780971/apex_sparks_banner_x90"
},
"placementCode": "/7780971/apex_sparks_banner_x90",
"sizes": [
[
728,
90
]
],
"bidId": "45e5c0084508efb",
"bidderRequestId": "42e2fe519b7c653",
"requestId": "1ff753bd4ae5cb"
}
]
}
];
};
Expand Down
Loading

0 comments on commit ca909e8

Please sign in to comment.