-
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.
* YieldNexus Bid Adapter v1 * Apply code-review changes requested by @jsneker Removed redundant decration of 'onTik which does nothing. Import banner & video constants instead of hard-coding them. Remove usage of "config.getConfig('pageurl')". Also updated the "spid" to 1249. * Remove unused 'config' import * Update demo account IDs for both banner & video * Add video renderer support * Fix unit test checking url * Fix code linting errors * Add missing import statement
- Loading branch information
1 parent
890315b
commit edc9d43
Showing
3 changed files
with
556 additions
and
0 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 |
---|---|---|
@@ -0,0 +1,193 @@ | ||
import * as utils from 'src/utils'; | ||
import { registerBidder } from 'src/adapters/bidderFactory'; | ||
import { BANNER, VIDEO } from 'src/mediaTypes'; | ||
import { Renderer } from 'src/Renderer'; | ||
|
||
const pixKey = 'utrk'; | ||
|
||
function startsWith(str, search) { | ||
return str.substr(0, search.length) === search; | ||
} | ||
|
||
export const spec = { | ||
code: 'yieldnexus', | ||
aliases: [], | ||
supportedMediaTypes: [BANNER, VIDEO], | ||
|
||
isBidRequestValid: function(bid) { | ||
if (!bid.params.spid) { | ||
return false; | ||
} else if (typeof bid.params.spid !== 'string') { | ||
return false; | ||
} | ||
return (typeof bid.params.instl === 'undefined' || bid.params.instl === 0 || bid.params.instl === 1) && | ||
(typeof bid.params.bidfloor === 'undefined' || typeof bid.params.bidfloor === 'number') && | ||
(typeof bid.params['protocols'] === 'undefined' || Array.isArray(bid.params['protocols'])) && | ||
(typeof bid.params['adpos'] === 'undefined' || typeof bid.params['adpos'] === 'number'); | ||
}, | ||
|
||
buildRequests: function(validBidRequests, bidderRequest) { | ||
return validBidRequests.map(bidRequest => { | ||
let referrer = ''; | ||
try { | ||
referrer = window.top.document.referrer; | ||
} catch (e) { | ||
try { | ||
referrer = window.document.referrer; | ||
} catch (e) { | ||
} | ||
} | ||
const url = utils.getTopWindowUrl(); | ||
const domainStart = url.indexOf('://') + 3; | ||
const req = { | ||
id: bidRequest.auctionId, | ||
site: { | ||
domain: url.substring(domainStart, url.indexOf('/', domainStart) < 0 ? url.length : url.indexOf('/', domainStart)), | ||
page: url, | ||
ref: referrer | ||
}, | ||
device: { | ||
ua: navigator.userAgent | ||
}, | ||
imp: [], | ||
ext: {} | ||
}; | ||
if (bidderRequest && bidderRequest.gdprConsent) { | ||
req.ext.gdpr_consent = { | ||
consent_string: bidderRequest.gdprConsent.consentString, | ||
consent_required: bidderRequest.gdprConsent.gdprApplies | ||
}; | ||
} | ||
let topFrame; | ||
try { | ||
topFrame = window.top === window ? 1 : 0; | ||
} catch (e) { | ||
topFrame = 0; | ||
} | ||
const imp = { | ||
id: bidRequest.transactionId, | ||
instl: bidRequest.params.instl === 1 ? 1 : 0, | ||
tagid: bidRequest.adUnitCode, | ||
bidfloor: bidRequest.params.bidfloor || 0, | ||
bidfloorcur: 'USD', | ||
secure: startsWith(utils.getTopWindowUrl().toLowerCase(), 'http://') ? 0 : 1 | ||
}; | ||
if (!bidRequest.mediaTypes || bidRequest.mediaTypes.banner) { | ||
imp.banner = { | ||
w: bidRequest.sizes.length ? bidRequest.sizes[0][0] : 300, | ||
h: bidRequest.sizes.length ? bidRequest.sizes[0][1] : 250, | ||
pos: bidRequest.params.pos || 0, | ||
topframe: topFrame | ||
}; | ||
} else if (bidRequest.mediaTypes.video) { | ||
imp.video = { | ||
w: bidRequest.sizes.length ? bidRequest.sizes[0][0] : 300, | ||
h: bidRequest.sizes.length ? bidRequest.sizes[0][1] : 250, | ||
protocols: bidRequest.params.protocols || [1, 2, 3, 4, 5, 6], | ||
pos: bidRequest.params.pos || 0, | ||
topframe: topFrame | ||
}; | ||
} else { | ||
return; | ||
} | ||
req.imp.push(imp); | ||
return { | ||
method: 'POST', | ||
url: `https://ssp.ynxs.io/r/${bidRequest.params.spid}/bidr?bidder=prebid&rformat=open_rtb&reqformat=rtb_json` + (bidRequest.params.query ? '&' + bidRequest.params.query : ''), | ||
data: req, | ||
bidRequest | ||
}; | ||
}); | ||
}, | ||
|
||
interpretResponse: function(serverResponse, bidRequest) { | ||
const outBids = []; | ||
if (serverResponse && serverResponse.body) { | ||
const bids = serverResponse.body.seatbid.reduce((acc, seatBid) => acc.concat(seatBid.bid), []); | ||
bids.forEach(bid => { | ||
const outBid = { | ||
requestId: bidRequest.bidRequest.bidId, | ||
cpm: bid.price, | ||
width: bid.w, | ||
height: bid.h, | ||
ttl: 15 * 60, | ||
creativeId: bid.crid, | ||
netRevenue: true, | ||
currency: bid.cur || serverResponse.body.cur | ||
}; | ||
if (!bidRequest.bidRequest.mediaTypes || bidRequest.bidRequest.mediaTypes.banner) { | ||
outBids.push(Object.assign({}, outBid, { mediaType: 'banner', ad: bid.adm })); | ||
} else if (bidRequest.bidRequest.mediaTypes.video) { | ||
const context = utils.deepAccess(bidRequest.bidRequest, 'mediaTypes.video.context'); | ||
outBids.push(Object.assign({}, outBid, { | ||
mediaType: 'video', | ||
vastUrl: bid.ext.vast_url, | ||
vastXml: bid.adm, | ||
renderer: context === 'outstream' ? newRenderer(bidRequest.bidRequest, bid) : undefined | ||
})); | ||
} | ||
}); | ||
} | ||
return outBids; | ||
}, | ||
|
||
getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { | ||
const syncs = []; | ||
const gdprApplies = gdprConsent && (typeof gdprConsent.gdprApplies === 'boolean') ? gdprConsent.gdprApplies : false; | ||
const suffix = gdprApplies ? 'gc=' + encodeURIComponent(gdprConsent.consentString) : 'gc=missing'; | ||
serverResponses.forEach(resp => { | ||
if (resp.body) { | ||
const bidResponse = resp.body; | ||
if (bidResponse.ext && Array.isArray(bidResponse.ext[pixKey])) { | ||
bidResponse.ext[pixKey].forEach(pixel => syncs.push({ type: pixel.type, url: pixel.url + (pixel.url.indexOf('?') > 0 ? '&' + suffix : '?' + suffix) })); | ||
} | ||
if (Array.isArray(bidResponse.seatbid)) { | ||
bidResponse.seatbid.forEach(seatBid => { | ||
if (Array.isArray(seatBid.bid)) { | ||
seatBid.bid.forEach(bid => { | ||
if (bid.ext && Array.isArray(bid.ext[pixKey])) { | ||
bid.ext[pixKey].forEach(pixel => syncs.push({ type: pixel.type, url: pixel.url + (pixel.url.indexOf('?') > 0 ? '&' + suffix : '?' + suffix) })); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
} | ||
}); | ||
return syncs; | ||
} | ||
}; | ||
|
||
function newRenderer(bidRequest, bid, rendererOptions = {}) { | ||
let rendererUrl = '//s.gambid.io/video/latest/renderer.js'; | ||
if (bid.ext && bid.ext.renderer_url) { | ||
rendererUrl = bid.ext.renderer_url; | ||
} | ||
if (bidRequest.params && bidRequest.params.rendererUrl) { | ||
rendererUrl = bidRequest.params.rendererUrl; | ||
} | ||
const renderer = Renderer.install({ url: rendererUrl, config: rendererOptions, loaded: false }); | ||
renderer.setRender(renderOutstream); | ||
return renderer; | ||
} | ||
|
||
function renderOutstream(bid) { | ||
bid.renderer.push(() => { | ||
window[ 'GambidPlayer' ].renderAd({ | ||
id: bid.adUnitCode + '/' + bid.adId, | ||
debug: window.location.href.indexOf('pbjsDebug') >= 0, | ||
placement: document.getElementById(bid.adUnitCode), | ||
width: bid.width, | ||
height: bid.height, | ||
events: { | ||
ALL_ADS_COMPLETED: () => window.setTimeout(() => { | ||
window[ 'GambidPlayer' ].removeAd(bid.adUnitCode + '/' + bid.adId); | ||
}, 300) | ||
}, | ||
vastUrl: bid.vastUrl, | ||
vastXml: bid.vastXml | ||
}); | ||
}); | ||
} | ||
|
||
registerBidder(spec); |
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,53 @@ | ||
# Overview | ||
|
||
``` | ||
Module Name: YieldNexus Bid Adapter | ||
Module Type: Bidder Adapter | ||
Maintainer: [email protected] | ||
``` | ||
|
||
# Description | ||
|
||
Adds support to query the YieldNexus platform for bids. The YieldNexus platform supports banners & video. | ||
|
||
Only one parameter is required: `spid`, which provides your YieldNexus account number. | ||
|
||
# Test Parameters | ||
``` | ||
var adUnits = [ | ||
// Banner: | ||
{ | ||
code: 'banner-ad-unit', | ||
sizes: [[300, 250]], | ||
bids: [{ | ||
bidder: 'yieldnexus', | ||
params: { | ||
spid: '1253', // your supply ID in your YieldNexus dashboard | ||
bidfloor: 0.03, // an optional custom bid floor | ||
adpos: 1, // ad position on the page (optional) | ||
instl: 0 // interstitial placement? (0 or 1, optional) | ||
} | ||
}] | ||
}, | ||
// Outstream video: | ||
{ | ||
code: 'video-ad-unit', | ||
sizes: [[640, 480]], | ||
mediaTypes: { | ||
video: { | ||
context: 'outstream', | ||
playerSize: [640, 480] | ||
} | ||
}, | ||
bids: [ { | ||
bidder: 'yieldnexus', | ||
params: { | ||
spid: '1254', // your supply ID in your YieldNexus dashboard | ||
bidfloor: 0.03, // an optional custom bid floor | ||
adpos: 1, // ad position on the page (optional) | ||
instl: 0 // interstitial placement? (0 or 1, optional) | ||
} | ||
}] | ||
} | ||
]; | ||
``` |
Oops, something went wrong.