-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2f4bb60
commit fcf50e7
Showing
5 changed files
with
274 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ | |
"sovrn", | ||
"springserve", | ||
"triplelift", | ||
"twenga", | ||
"yieldbot", | ||
"nginad", | ||
"brightcom", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import { getBidRequest } from '../utils.js'; | ||
|
||
var CONSTANTS = require('../constants.json'); | ||
var utils = require('../utils.js'); | ||
var adloader = require('../adloader.js'); | ||
var bidmanager = require('../bidmanager.js'); | ||
var bidfactory = require('../bidfactory.js'); | ||
var Adapter = require('./adapter.js'); | ||
|
||
var TwengaAdapter; | ||
TwengaAdapter = function TwengaAdapter() { | ||
var baseAdapter = Adapter.createNew('twenga'); | ||
|
||
baseAdapter.callBids = function (params) { | ||
for (var i = 0; i < params.bids.length; i++) { | ||
var bidRequest = params.bids[i]; | ||
var callbackId = bidRequest.bidId; | ||
adloader.loadScript(buildBidCall(bidRequest, callbackId)); | ||
} | ||
}; | ||
|
||
function buildBidCall(bid, callbackId) { | ||
|
||
var bidUrl = '//rtb.t.c4tw.net/Bid?'; | ||
bidUrl = utils.tryAppendQueryString(bidUrl, 's', 'h'); | ||
bidUrl = utils.tryAppendQueryString(bidUrl, 'callback', '$$PREBID_GLOBAL$$.handleTwCB'); | ||
bidUrl = utils.tryAppendQueryString(bidUrl, 'callback_uid', callbackId); | ||
bidUrl = utils.tryAppendQueryString(bidUrl, 'referrer', utils.getTopWindowUrl()); | ||
if (bid.params) { | ||
for (var key in bid.params) { | ||
var value = bid.params[key]; | ||
switch (key) { | ||
case 'placementId': key = 'id'; break; | ||
case 'siteId': key = 'sid'; break; | ||
case 'publisherId': key = 'pid'; break; | ||
case 'currency': key = 'cur'; break; | ||
case 'bidFloor': key = 'min'; break; | ||
case 'country': key = 'gz'; break; | ||
} | ||
bidUrl = utils.tryAppendQueryString(bidUrl, key, value); | ||
} | ||
} | ||
|
||
var sizes = utils.parseSizesInput(bid.sizes); | ||
if (sizes.length > 0) { | ||
bidUrl = utils.tryAppendQueryString(bidUrl, 'size', sizes.join(',')); | ||
} | ||
|
||
bidUrl += 'ta=1'; | ||
|
||
// @if NODE_ENV='debug' | ||
utils.logMessage('bid request built: ' + bidUrl); | ||
|
||
// @endif | ||
|
||
//append a timer here to track latency | ||
bid.startTime = new Date().getTime(); | ||
|
||
return bidUrl; | ||
} | ||
|
||
//expose the callback to the global object: | ||
$$PREBID_GLOBAL$$.handleTwCB = function (bidResponseObj) { | ||
|
||
var bidCode; | ||
|
||
if (bidResponseObj && bidResponseObj.callback_uid) { | ||
|
||
var responseCPM; | ||
var id = bidResponseObj.callback_uid; | ||
var placementCode = ''; | ||
var bidObj = getBidRequest(id); | ||
if (bidObj) { | ||
|
||
bidCode = bidObj.bidder; | ||
|
||
placementCode = bidObj.placementCode; | ||
|
||
bidObj.status = CONSTANTS.STATUS.GOOD; | ||
} | ||
|
||
// @if NODE_ENV='debug' | ||
utils.logMessage('JSONP callback function called for ad ID: ' + id); | ||
|
||
// @endif | ||
var bid = []; | ||
if (bidResponseObj.result && | ||
bidResponseObj.result.cpm && | ||
bidResponseObj.result.cpm !== 0 && | ||
bidResponseObj.result.ad) { | ||
|
||
var result = bidResponseObj.result; | ||
|
||
responseCPM = parseInt(result.cpm, 10); | ||
|
||
//CPM response from /Bid is dollar/cent multiplied by 10000 | ||
//in order to avoid using floats | ||
//switch CPM to "dollar/cent" | ||
responseCPM = responseCPM / 10000; | ||
|
||
var ad = result.ad.replace('%%WP%%', result.cpm); | ||
|
||
//store bid response | ||
//bid status is good (indicating 1) | ||
bid = bidfactory.createBid(1, bidObj); | ||
bid.creative_id = result.creative_id; | ||
bid.bidderCode = bidCode; | ||
bid.cpm = responseCPM; | ||
if (ad && (ad.lastIndexOf('http', 0) === 0 || ad.lastIndexOf('//', 0) === 0)) | ||
bid.adUrl = ad; | ||
else | ||
bid.ad = ad; | ||
bid.width = result.width; | ||
bid.height = result.height; | ||
|
||
bidmanager.addBidResponse(placementCode, bid); | ||
|
||
} else { | ||
//no response data | ||
// @if NODE_ENV='debug' | ||
utils.logMessage('No prebid response from Twenga for placement code ' + placementCode); | ||
|
||
// @endif | ||
//indicate that there is no bid for this placement | ||
bid = bidfactory.createBid(2, bidObj); | ||
bid.bidderCode = bidCode; | ||
bidmanager.addBidResponse(placementCode, bid); | ||
} | ||
|
||
} else { | ||
//no response data | ||
// @if NODE_ENV='debug' | ||
utils.logMessage('No prebid response for placement %%PLACEMENT%%'); | ||
|
||
// @endif | ||
} | ||
}; | ||
|
||
return { | ||
callBids: baseAdapter.callBids, | ||
setBidderCode: baseAdapter.setBidderCode, | ||
createNew: TwengaAdapter.createNew, | ||
buildBidCall: buildBidCall | ||
}; | ||
}; | ||
|
||
TwengaAdapter.createNew = function () { | ||
return new TwengaAdapter(); | ||
}; | ||
|
||
module.exports = TwengaAdapter; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
describe("twenga adapter tests", function () { | ||
|
||
var urlParse = require("url-parse"); | ||
var querystringify = require("querystringify"); | ||
var adapter = require("src/adapters/twenga"); | ||
var adLoader = require("src/adloader"); | ||
var expect = require("chai").expect; | ||
var bidmanager = require("src/bidmanager"); | ||
var CONSTANTS = require('src/constants.json'); | ||
|
||
var DEFAULT_PARAMS = { | ||
bidderCode: "twenga", | ||
bids: [{ | ||
bidId: "tw_abcd1234", | ||
sizes: [[300, 250], [300, 200]], | ||
bidder: "twenga", | ||
params: { | ||
placementId: "test", | ||
siteId: 1234, | ||
publisherId: 5678, | ||
currency: "USD", | ||
bidFloor: 0.5, | ||
country: "DE" | ||
}, | ||
requestId: "tw_efgh5678", | ||
placementCode: "tw_42" | ||
}] | ||
}; | ||
|
||
var BID_RESPONSE = { | ||
result: { | ||
cpm: 10000, | ||
width: 300, | ||
height: 250, | ||
ad: "//rtb.t.c4tw.net", | ||
creative_id: "test" | ||
}, | ||
callback_uid: "tw_abcd1234" | ||
}; | ||
|
||
it("sets url parameters", function () { | ||
var stubLoadScript = sinon.stub(adLoader, "loadScript"); | ||
|
||
adapter().callBids(DEFAULT_PARAMS); | ||
|
||
var bidUrl = stubLoadScript.getCall(0).args[0]; | ||
var parsedBidUrl = urlParse(bidUrl); | ||
var parsedBidUrlQueryString = querystringify.parse(parsedBidUrl.query); | ||
|
||
expect(parsedBidUrl.hostname).to.equal("rtb.t.c4tw.net"); | ||
expect(parsedBidUrl.pathname).to.equal("/Bid"); | ||
|
||
expect(parsedBidUrlQueryString).to.have.property("s").and.to.equal("h"); | ||
expect(parsedBidUrlQueryString).to.have.property("callback").and.to.equal("$$PREBID_GLOBAL$$.handleTwCB"); | ||
expect(parsedBidUrlQueryString).to.have.property("callback_uid").and.to.equal("tw_abcd1234"); | ||
expect(parsedBidUrlQueryString).to.have.property("id").and.to.equal("test"); | ||
|
||
stubLoadScript.restore(); | ||
}); | ||
|
||
var stringToFunction = function (s) { | ||
var scope = global; | ||
var scopeSplit = s.split('.'); | ||
for (var i = 0; i < scopeSplit.length - 1; i++) { | ||
scope = scope[scopeSplit[i]]; | ||
if (scope == undefined) return; | ||
} | ||
return scope[scopeSplit[scopeSplit.length - 1]]; | ||
}; | ||
|
||
it("creates an empty bid response if no bids", function() { | ||
var stubLoadScript = sinon.stub(adLoader, "loadScript", function(url) { | ||
var bidUrl = stubLoadScript.getCall(0).args[0]; | ||
var parsedBidUrl = urlParse(bidUrl); | ||
var parsedBidUrlQueryString = querystringify.parse(parsedBidUrl.query); | ||
|
||
var callback = stringToFunction(parsedBidUrlQueryString.callback); | ||
expect(callback).to.exist.and.to.be.a('function'); | ||
callback(undefined); | ||
}); | ||
var stubAddBidResponse = sinon.stub(bidmanager, "addBidResponse"); | ||
|
||
adapter.createNew().callBids(DEFAULT_PARAMS); | ||
|
||
expect(stubAddBidResponse.getCall(0)).to.be.null; | ||
|
||
stubAddBidResponse.restore(); | ||
stubLoadScript.restore(); | ||
}); | ||
|
||
it("creates a bid response if bid is returned", function() { | ||
var stubLoadScript = sinon.stub(adLoader, "loadScript", function(url) { | ||
var bidUrl = stubLoadScript.getCall(0).args[0]; | ||
var parsedBidUrl = urlParse(bidUrl); | ||
var parsedBidUrlQueryString = querystringify.parse(parsedBidUrl.query); | ||
|
||
$$PREBID_GLOBAL$$._bidsRequested. | ||
push({ bidderCode: DEFAULT_PARAMS.bidderCode, | ||
bids: [{ bidId: parsedBidUrlQueryString.callback_uid, | ||
placementCode: DEFAULT_PARAMS.bids[0].placementCode }]}); | ||
|
||
var callback = stringToFunction(parsedBidUrlQueryString.callback); | ||
expect(callback).to.exist.and.to.be.a('function'); | ||
callback(BID_RESPONSE); | ||
}); | ||
var stubAddBidResponse = sinon.stub(bidmanager, "addBidResponse"); | ||
|
||
adapter.createNew().callBids(DEFAULT_PARAMS); | ||
|
||
var bidResponseAd = stubAddBidResponse.getCall(0).args[1]; | ||
|
||
expect(bidResponseAd).to.have.property("cpm").and.to.equal(BID_RESPONSE.result.cpm / 10000); | ||
expect(bidResponseAd).to.have.property("adUrl").and.to.equal(BID_RESPONSE.result.ad); | ||
expect(bidResponseAd).to.have.property("width").and.to.equal(BID_RESPONSE.result.width); | ||
expect(bidResponseAd).to.have.property("height").and.to.equal(BID_RESPONSE.result.height); | ||
|
||
stubAddBidResponse.restore(); | ||
stubLoadScript.restore(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters