diff --git a/adapters.json b/adapters.json index 18b4e1ba691..5c6f84a193d 100644 --- a/adapters.json +++ b/adapters.json @@ -14,6 +14,7 @@ "piximedia", "pubmatic", "pulsepoint", + "rhythmone", "rubicon", "sekindo", "sonobi", diff --git a/src/adapters/rhythmone.js b/src/adapters/rhythmone.js new file mode 100644 index 00000000000..46f3ffb0160 --- /dev/null +++ b/src/adapters/rhythmone.js @@ -0,0 +1,343 @@ +var bidmanager = require('../bidmanager.js'), + bidfactory = require('../bidfactory.js'), + utils = require('../utils.js'), + CONSTANTS = require('../constants.json'); + +import {ajax as ajax} from '../ajax'; + +function track(debug, p1, p2, p3) { + if(debug === true){ + console.log('GA: %s %s %s', p1, p2, p3 || ''); + } +} + +var w = (typeof window !== "undefined" ? window : {}); +w.trackR1Impression = track; + +module.exports = function(bidManager, global, loader){ + + var version = "0.9.0.0", + defaultZone = "1r", + defaultPath = "mvo", + bidfloor = 0, + currency = "USD", + debug = false, + auctionEnded = false, + requestCompleted = false, + placementCodes = {}; + + if(typeof global === "undefined") + global = window; + + if(typeof bidManager === "undefined") + bidManager = bidmanager; + + if(typeof loader === "undefined") + loader = ajax; + + function applyMacros(txt, values){ + return txt.replace(/\{([^\}]+)\}/g, function(match){ + var v = values[match.replace(/[\{\}]/g, "").toLowerCase()]; + if(typeof v !== "undefined") return v; + return match; + }); + } + + function load(bidParams, url, postData, callback){ + if(bidParams.method === "get"){ + loader(url, function(responseText, response){ + if(response.status === 200) + callback(200, "success", response.responseText); + else + callback(-1, "http error "+response.status, response.responseText); + }, false, {method:"GET"}); + } + else{ + loader(url, function(responseText, response){ + if(response.status === 200) + callback(200, "success", response.responseText); + else + callback(-1, "http error "+response.status, response.responseText); + }, postData, {method:"POST", contentType: "application/json"}); + } + } + + var bidderCode = "rhythmone", + bidLostTimeout = null; + + function setIfPresent(o, key, value){ + try{ + if(typeof value === "function") + o[key] = value(); + }catch(ex){} + } + + function logToConsole(txt){ + if(debug) + console.log(txt); + } + + function sniffAuctionEnd(){ + + global.$$PREBID_GLOBAL$$.onEvent('bidWon', function (e) { + + if(e.bidderCode === bidderCode){ + placementCodes[e.adUnitCode] = true; + track(debug, 'hb', "bidWon"); + } + + if(auctionEnded){ + clearTimeout(bidLostTimeout); + bidLostTimeout = setTimeout(function(){ + for(var k in placementCodes) + if(placementCodes[k] === false) + track(debug, 'hb', "bidLost"); + }, 50); + } + }); + + global.$$PREBID_GLOBAL$$.onEvent('auctionEnd', function () { + + auctionEnded = true; + + if(requestCompleted === false) + track(debug, 'hb', 'rmpReplyFail', "prebid timeout post auction"); + }); + } + + function getBidParameters(bids){ + for(var i=0;i 0) + return d[d.length-1]; + return global.top.document.location.hostname; + }); + setIfPresent(o.site, "name", function(){return global.top.document.title;}); + + o.device.devicetype = ((/(ios|ipod|ipad|iphone|android)/i).test(global.navigator.userAgent) ? 1 : ((/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(global.navigator.userAgent) ? 3 : 2)); + + setIfPresent(o.device, "h", function(){return global.screen.height;}); + setIfPresent(o.device, "w", function(){return global.screen.width;}); + + for(var i = 0; i\"\"", + "adomain": ["www.rhythmone.com"], + "cid": "35857", + "cat": [], + "h": 250, + "w": 300 + } + ], + "seat": "14", + "group": 0 + } + ], + "bidid": "ff8b09b1-5264-52be-4b7b-0156526452bf" + }; + + var endEvent = function(){}, + wonEvent = function(){};; + + var z = new r1( + { + addBidResponse: function(placementcode, adResponse){ + it("should echo placementcode div-gpt-ad-1438287399331-0", function(){ + assert.equal(placementcode, "div-gpt-ad-1438287399331-0"); + }); + it("should have the expected ad response", function(){ + assert.equal((adResponse.ad.length > 0), true); + assert.equal(adResponse.width, 300); + assert.equal(adResponse.height, 250); + assert.equal(adResponse.cpm, 1); + assert.equal(adResponse.bidderCode, "rhythmone"); + }); + } + }, + { + "navigator":{}, + "pbjs":{ + "onEvent":function(e, f){ + if(e.toLowerCase() === "auctionend") endEvent = f; + if(e.toLowerCase() === "bidwon") wonEvent = f; + }, + "getBidResponses":function(){return {"div-gpt-ad-1438287399331-0":{"bids":[{cpm:1,bidderCode:"rhythmone"},{cpm:2,bidderCode:"rhythmone"}]}};} + } + }, + function(url, callback){ + callback(JSON.stringify(fakeResponse), {status:200, responseText: JSON.stringify(fakeResponse)}); + }); + + z.callBids({ + "bidderCode":"rhythmone", + "bids":[ + { + "bidder":"rhythmone", + "params":{ + "placementId":"xyz", + "keywords":"", + "categories":[], + "trace":true, + "method":"get", + "endpoint":"http://fakedomain.com" + }, + "placementCode":"div-gpt-ad-1438287399331-0", + "sizes":[[300,250]] + } + ] + }); + + endEvent(); + wonEvent({ + bidderCode: "rhythmone", + adUnitCode: "div-gpt-ad-1438287399331-0" + }); + }); +}); \ No newline at end of file