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 AdGeneration and Kargo #8

Merged
merged 4 commits into from
Nov 15, 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
2 changes: 2 additions & 0 deletions adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"adbutler",
"adequant",
"adform",
"adg",
"adkernel",
"admedia",
"adyoulike",
Expand All @@ -24,6 +25,7 @@
"hiromedia",
"indexExchange",
"innity",
"kargo",
"kruxlink",
"getintent",
"inneractive",
Expand Down
131 changes: 131 additions & 0 deletions src/adapters/adg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import * as Adapter from './adapter.js';
import bidfactory from '../bidfactory';
import bidmanager from '../bidmanager';
import * as utils from '../utils';
import {ajax} from '../ajax';
import {STATUS} from '../constants';

const ADG_BIDDER_CODE = 'adg';

var AdgAdapter = function AdgAdapter() {

function _callBids(bidderRequest) {
var bids = bidderRequest.bids || [];
bids.forEach(bid => {
try {
ajax(buildOptimizedCall(bid), bidCallback, undefined, {withCredentials: true});
} catch (err) {
utils.logError(`XHR error, placement code is ${bid.placementCode} in adg`, null, err);
addErrorBid();
}

function bidCallback(responseText) {
try {
utils.logMessage(`XHR callback function called for ad ID: ${bid.bidId}`);
bidmanager.addBidResponse(bid.placementCode,generateBitResponse(responseText,bid));
} catch (err) {
if (typeof err === 'string') {
utils.logWarn(`XHR response error, ${err} placement code is ${bid.placementCode} in adg`);
} else {
utils.logError(`XHR response error, placement code is ${bid.placementCode} in adg`, null, err);
}
addErrorBid();
}
}

function addErrorBid() {
let badBid = bidfactory.createBid(STATUS.NO_BID, bid);
badBid.bidderCode = bid.bidder;
bidmanager.addBidResponse(bid.placementCode, badBid);
}
});
}

//for ADG
function buildOptimizedCall(bid) {
bid.startTime = new Date().getTime();
var id = utils.getBidIdParameter('id', bid.params);
let url = bid.params.debug ? 'http://api-test.scaleout.jp/adsv/v1?' : 'https://d.socdm.com/adsv/v1?';
url = utils.tryAppendQueryString(url, 'posall', 'SSPLOC');
url = utils.tryAppendQueryString(url, 'id', id);
url = utils.tryAppendQueryString(url, 'sdktype', '0');
url = utils.tryAppendQueryString(url, 'hb', 'true');
url = utils.tryAppendQueryString(url, 't', 'json3');
if (bid.params.labels){
let labels = bid.params.labels;
for (let key in labels){
url = utils.tryAppendQueryString(url, key, labels[key]);
}
}

//remove the trailing "&"
if (url.lastIndexOf('&') === url.length - 1) {
url = url.substring(0, url.length - 1);
}
return url;
}

function generateBitResponse(responseText, bidRequest) {
let res = JSON.parse(responseText);
if (typeof res !== 'object') {
throw 'bad response';
}
return res.results.length > 0 ? createBid(bidRequest, res) : invalidBidResponse(bidRequest);

function createBid(bidRequest, res) {
let bid = bidfactory.createBid(STATUS.GOOD, bidRequest);
bid.bidderCode = bidRequest.bidder;
bid.cpm = res.cpm || 0;
bid.dealId = res.dealid || '';

let ad = `<!-- adgen -->${res.ad}`;
ad = insertBeforeBody(ad, res.beacon);
if (res.vastxml && res.vastxml.length > 0) {
ad = `<div id="apvad-${bidRequest.placementCode}"></div>` +
insertBeforeBody(ad, createAPVTag() + insertVASTMethod(bidRequest.placementCode, res.vastxml));
}
bid.ad = ad;
[bid.width, bid.height] = [bidRequest.params.width, bidRequest.params.height];

return bid;
}

function createAPVTag() {
const APVURL = 'https://cdn.apvdr.com/js/VideoAd.min.js';
let apvScript = document.createElement('script');
apvScript.type = 'text/javascript';
apvScript.id = 'apv';
apvScript.src = APVURL;
return apvScript.outerHTML;
}

function insertVASTMethod(targetId, vastXml) {
let apvVideoAdParam = {
s: targetId
};
let script = document.createElement(`script`);
script.type = 'text/javascript';
script.innerHTML = `(function(){ new APV.VideoAd(${JSON.stringify(apvVideoAdParam)}).load('${vastXml.replace(/\r?\n/g, "")}'); })();`;
return script.outerHTML;
}

function insertBeforeBody(ad, data) {
return ad.replace(/<\/\s?body>/, data +'</body>');
}

function invalidBidResponse(bidRequest) {
let bid = bidfactory.createBid(2, bidRequest);
bid.bidderCode = bidRequest.bidder;
}
}

return Object.assign(Adapter.createNew(ADG_BIDDER_CODE), {
callBids: _callBids,
createNew: AdgAdapter.createNew
});
};

AdgAdapter.createNew = function () {
return new AdgAdapter();
};
module.exports = AdgAdapter;
168 changes: 168 additions & 0 deletions src/adapters/kargo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
const bidfactory = require('../bidfactory.js');
const bidmanager = require('../bidmanager.js');
const adloader = require('../adloader.js');
const utils = require('../utils.js');
const adaptermanager = require('../adaptermanager');
const CONSTANTS = require('../constants.json');
const HOST = $$PREBID_GLOBAL$$.kargo_kraken_host || 'https://krk.kargo.com';

const KargoAdapter = function KargoAdapter() {
function _handleBid(bids) {
return function wrappedHandleBid(adUnits) {
utils._map(bids, bid => {
let adUnit = adUnits[bid.params.placementId];

if (adUnit) {
bidmanager.addBidResponse(bid.placementCode, _createBid(adUnit));

if (adUnit.receivedTracker) {
var el = document.createElement('img');
el.src = adUnit.receivedTracker;
document.body.appendChild(el);
}
}
});
};
}

function _createBid(adUnit) {
let bidObject = bidfactory.createBid(CONSTANTS.STATUS.GOOD);
bidObject.bidderCode = 'kargo';
bidObject.cpm = Number(adUnit.cpm);
bidObject.ad = adUnit.adm;
bidObject.width = adUnit.width;
bidObject.height = adUnit.height;
return bidObject;
}

function _callBids(params) {
const transformedParams = Object.assign({}, {
timeout: params.timeout,
currency: 'USD',
cpmGranularity: 1,
cpmRange: {
floor: 0,
ceil: 20
},
adSlotIds: utils._map(params.bids, bid => bid.params.placementId)
}, _getAllMetadata());
const encodedParams = encodeURIComponent(JSON.stringify(transformedParams));
const callbackName = `kargo_prebid_${params.requestId.replace(/-/g, '_')}`;

$$PREBID_GLOBAL$$[callbackName] = _handleBid(params.bids);

adloader.loadScript(`${HOST}/api/v1/bid?json=${encodedParams}&cb=window.${preBidNameSpace}.${callbackName}`);
}

function _readCookie(name) {
let nameEquals = `${name}=`;
let cookies = document.cookie.split(';');

for (let key in cookies) {
let cookie = cookies[key];
while (cookie.charAt(0) === ' ') {
cookie = cookie.substring(1, cookie.length);
}

if (cookie.indexOf(nameEquals) === 0) {
return cookie.substring(nameEquals.length, cookie.length);
}
}

return null;
}

function _getCrbIds() {
try {
const crb = JSON.parse(decodeURIComponent(_readCookie('krg_crb')));
var syncIds = {};

if (crb && crb.v) {
var vParsed = JSON.parse(atob(crb.v));

if (vParsed && vParsed.syncIds) {
syncIds = vParsed.syncIds;
}
}

return syncIds;
} catch (e) {
return {};
}
}

function _getUid() {
try {
const uid = JSON.parse(decodeURIComponent(_readCookie('krg_uid')));
var vData = {};

if (uid && uid.v) {
vData = uid.v;
}

return vData;
} catch (e) {
return {};
}
}

function _getKruxUserId() {
return _getLocalStorageSafely('kxkar_user');
}

function _getKruxSegments() {
return _getLocalStorageSafely('kxkar_segs');
}

function _getKrux() {
const segmentsStr = _getKruxSegments();
var segments = [];

if (segmentsStr) {
segments = segmentsStr.split(',');
}

return {
userID: _getKruxUserId(),
segments: segments
};
}

function _getLocalStorageSafely(key) {
try {
return localStorage.getItem(key);
} catch (e) {
return null;
}
}

function _getUserIds() {
const uid = _getUid();
const crbIds = _getCrbIds();

return {
kargoID: uid.userId,
clientID: uid.clientId,
crbIDs: crbIds,
optOut: uid.optOut
};
}

function _getAllMetadata() {
return {
userIDs: _getUserIds(),
krux: _getKrux(),
pageURL: window.location.href
};
}

// Export the callBids function, so that prebid.js can execute
// this function when the page asks to send out bid requests.
return {
callBids: _callBids
};
};

//adaptermanager.registerBidAdapter(new KargoAdapter(), 'kargo');

module.exports = KargoAdapter;