8000 Rubicon video support by snapwich · Pull Request #950 · prebid/Prebid.js · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Rubicon video support #950

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

10000
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion adapters.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
},
{
"rubicon": {
"alias": "rubiconLite"
"alias": "rubiconLite",
"supportedMediaTypes": ["video"]
}
},
{
Expand Down
137 changes: 122 additions & 15 deletions src/adapters/rubicon.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import { STATUS } from 'src/constants';

const RUBICON_BIDDER_CODE = 'rubicon';

// use deferred function call since version isn't defined yet at this point
function getIntegration() {
return 'pbjs_lite_' + $$PREBID_GLOBAL$$.version;
}

// use protocol relative urls for http or https
const FASTLANE_ENDPOINT = '//fastlane.rubiconproject.com/a/api/fastlane.json';
const VIDEO_ENDPOINT = '//optimized-by-adv.rubiconproject.com/v1/auction/video';

const TIMEOUT_BUFFER = 500;

var sizeMap = {
1:'468x60',
2:'728x90',
Expand Down Expand Up @@ -49,7 +60,12 @@ function RubiconAdapter() {

bids.forEach(bid => {
try {
ajax(buildOptimizedCall(bid), bidCallback, undefined, {withCredentials: true});
// Video endpoint only accepts POST calls
if (bid.mediaType === 'video') {
ajax(VIDEO_ENDPOINT, bidCallback, buildVideoRequestPayload(bid, bidderRequest), {withCredentials: true});
} else {
ajax(buildOptimizedCall(bid), bidCallback, undefined, {withCredentials: true});
}
} catch(err) {
utils.logError('Error sending rubicon request for placement code ' + bid.placementCode, null, err);
addErrorBid();
Expand Down Expand Up @@ -77,6 +93,82 @@ function RubiconAdapter() {
});
}

function _getScreenResolution() {
return [window.screen.width, window.screen.height].join('x');
}

function buildVideoRequestPayload(bid, bidderRequest) {
bid.startTime = new Date().getTime();

let params = bid.params;

if(!params || typeof params.video !== 'object') {
throw 'Invalid Video Bid';
}

let size;
if(params.video.playerWidth && params.video.playerHeight) {
size = [
params.video.playerWidth,
params.video.playerHeight
];
} else if(
Array.isArray(bid.sizes) && bid.sizes.length > 0 &&
Array.isArray(bid.sizes[0]) && bid.sizes[0].length > 1
) {
size = bid.sizes[0];
} else {
throw "Invalid Video Bid - No size provided";
}

let postData = {
page_url: !params.referrer ? utils.getTopWindowUrl() : params.referrer,
resolution: _getScreenResolution(),
account_id: params.accountId,
integration: getIntegration(),
timeout: bidderRequest.timeout - (Date.now() - bidderRequest.auctionStart + TIMEOUT_BUFFER),
stash_creatives: true,
ae_pass_through_parameters: params.video.aeParams,
slots: []
};

// Define the slot object
let slotData = {
site_id: params.siteId,
zone_id: params.zoneId,
position: params.position || 'btf',
floor: 0.01,
element_id: bid.placementCode,
name: bid.placementCode,
language: params.video.language,
width: size[0],
height: size[1]
};

// check and add inventory, keywords, visitor and size_id data
if(params.video.size_id) {
slotData.size_id = params.video.size_id;
} else {
throw "Invalid Video Bid - Invalid Ad Type!";
}

if(params.inventory && typeof params.inventory === 'object') {
slotData.inventory = params.inventory;
}

if(params.keywords && Array.isArray(params.keywords)) {
slotData.keywords = params.keywords;
}

if(params.visitor && typeof params.visitor === 'object') {
slotData.visitor = params.visitor;
}

postData.slots.push(slotData);

return(JSON.stringify(postData));
}

function buildOptimizedCall(bid) {
bid.startTime = new Date().getTime();

Expand Down Expand Up @@ -113,8 +205,8 @@ function RubiconAdapter() {
'alt_size_ids', parsedSizes.slice(1).join(',') || undefined,
'p_pos', position,
'rp_floor', '0.01',
'tk_flint', 'pbjs.lite',
'p_screen_res', window.screen.width +'x'+ window.screen.height,
'tk_flint', getIntegration(),
'p_screen_res', _getScreenResolution(),
'kw', keywords,
'tk_user_key', userId
];
Expand All @@ -136,7 +228,7 @@ function RubiconAdapter() {
(memo, curr, index) =>
index % 2 === 0 && queryString[index + 1] !== undefined ?
memo + curr + '=' + encodeURIComponent(queryString[index + 1]) + '&' : memo,
'//fastlane.rubiconproject.com/a/api/fastlane.json?' // use protocol relative link for http or https
FASTLANE_ENDPOINT + '?'
).slice(0, -1); // remove trailing &
}

Expand All @@ -151,23 +243,29 @@ function RubiconAdapter() {
</html>`;

function handleRpCB(responseText, bidRequest) {
let responseObj = JSON.parse(responseText); // can throw
var responseObj = JSON.parse(responseText), // can throw
ads = responseObj.ads,
adResponseKey = bidRequest.placementCode;

if(
typeof responseObj !== 'object' ||
responseObj.status !== 'ok' ||
!Array.isArray(responseObj.ads) ||
responseObj.ads.length < 1
) {
// check overall response
if(typeof responseObj !== 'object' || responseObj.status !== 'ok') {
throw 'bad response';
}

var ads = responseObj.ads;
// video ads array is wrapped in an object
if (bidRequest.mediaType === 'video' && typeof ads === 'object') {
ads = ads[adResponseKey];
}

// check the ad response
if(!Array.isArray(ads) || ads.length < 1) {
throw 'invalid ad response';
}

// if there are multiple ads, sort by CPM
ads = ads.sort(_adCpmSort);

ads.forEach(function (ad) {
ads.forEach(ad => {
if(ad.status !== 'ok') {
throw 'bad ad status';
}
Expand All @@ -178,9 +276,18 @@ function RubiconAdapter() {
bid.creative_id = ad.ad_id;
bid.bidderCode = bidRequest.bidder;
bid.cpm = ad.cpm || 0;
bid.ad = _renderCreative(ad.script, ad.impression_id);
[bid.width, bid.height] = sizeMap[ad.size_id].split('x').map(num => Number(num));
bid.dealId = ad.deal;
if (bidRequest.mediaType === 'video') {
bid.width = bidRequest.params.video.playerWidth;
bid.height = bidRequest.params.video.playerHeight;
bid.vastUrl = ad.creative_depot_url;
bid.descriptionUrl = ad.impression_id;
bid.impression_id = ad.impression_id;
} else {
bid.ad = _renderCreative(ad.script, ad.impression_id);
[bid.width, bid.height] = sizeMap[ad.size_id].split('x').map(num => Number(num));
}


try {
bidmanager.addBidResponse(bidRequest.placementCode, bid);
Expand Down
2 changes: 1 addition & 1 deletion src/adserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ exports.dfpAdserver = function (options, urlComponents) {
var bid = adserver.getWinningBidByCode();
this.urlComponents.search.description_url = encodeURIComponent(bid.descriptionUrl);
this.urlComponents.search.cust_params = getCustomParams(bid.adserverTargeting);
this.urlComponents.correlator = Date.now();
this.urlComponents.search.correlator = Date.now();
};

adserver.verifyAdserverTag = function() {
Expand Down
Loading
0