Skip to content

Commit

Permalink
Merge branch 'master' of github.com:prebid/Prebid.js into prebid-1.0
Browse files Browse the repository at this point in the history
# Conflicts:
#	modules/adformBidAdapter.js
#	modules/prebidServerBidAdapter.js
#	modules/sekindoUMBidAdapter.js
#	modules/serverbidBidAdapter.js
#	src/adaptermanager.js
#	src/utils.js
#	test/spec/modules/adformBidAdapter_spec.js
#	test/spec/modules/carambolaBidAdapter_spec.js
#	test/spec/modules/lifestreetBidAdapter_spec.js
#	test/spec/modules/sekindoUMBidAdapter_spec.js
#	test/spec/modules/serverbidBidAdapter_spec.js
#	test/spec/modules/yieldbotBidAdapter_spec.js
  • Loading branch information
jaiminpanchal27 committed Dec 6, 2017
2 parents d5f0a21 + 4fc8fa5 commit 1f115d0
Show file tree
Hide file tree
Showing 17 changed files with 1,330 additions and 21 deletions.
2 changes: 1 addition & 1 deletion modules/prebidServerBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export function PrebidServer() {
/* Prebid executes this function when the page asks to send out bid requests */
baseAdapter.callBids = function(s2sBidRequest, bidRequests, addBidResponse, done, ajax) {
const isDebug = !!getConfig('debug');
const adUnits = utils.cloneJson(s2sBidRequest.ad_units);
const adUnits = utils.deepClone(s2sBidRequest.ad_units);
adUnits.forEach(adUnit => {
let videoMediaType = utils.deepAccess(adUnit, 'mediaTypes.video');
if (videoMediaType) {
Expand Down
235 changes: 235 additions & 0 deletions modules/readpeakBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
import {logError, getTopWindowLocation} from 'src/utils';
import { registerBidder } from 'src/adapters/bidderFactory';

export const ENDPOINT = '//app.readpeak.com/header/prebid';

const NATIVE_DEFAULTS = {
TITLE_LEN: 70,
DESCR_LEN: 120,
SPONSORED_BY_LEN: 50,
IMG_MIN: 150,
ICON_MIN: 50,
CTA_LEN: 50,
};

const BIDDER_CODE = 'readpeak'

export const spec = {

code: BIDDER_CODE,

supportedMediaTypes: ['native'],

isBidRequestValid: bid => (
!!(bid && bid.params && bid.params.publisherId && bid.nativeParams)
),

buildRequests: bidRequests => {
const request = {
id: bidRequests[0].bidderRequestId,
imp: bidRequests.map(slot => impression(slot)).filter(imp => imp.native != null),
site: site(bidRequests),
app: app(bidRequests),
device: device(),
isPrebid: true,
}

return {
method: 'POST',
url: ENDPOINT,
data: JSON.stringify(request),
}
},

interpretResponse: (response, request) => (
bidResponseAvailable(request, response)
),
};

function bidResponseAvailable(bidRequest, bidResponse) {
const idToImpMap = {};
const idToBidMap = {};
if (!bidResponse['body']) {
return []
}
bidResponse = bidResponse.body
parse(bidRequest.data).imp.forEach(imp => {
idToImpMap[imp.id] = imp;
});
if (bidResponse) {
bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => {
idToBidMap[bid.impid] = bid;
}));
}
const bids = [];
Object.keys(idToImpMap).forEach(id => {
if (idToBidMap[id]) {
const bid = {
requestId: id,
cpm: idToBidMap[id].price,
creativeId: idToBidMap[id].crid,
ttl: 300,
netRevenue: true,
mediaType: 'native',
currency: bidResponse.cur,
native: nativeResponse(idToImpMap[id], idToBidMap[id]),
};
bids.push(bid);
}
});
return bids;
}

function impression(slot) {
return {
id: slot.bidId,
native: nativeImpression(slot),
bidfloor: slot.params.bidfloor || 0,
bidfloorcur: slot.params.bidfloorcur || 'USD'
};
}

function nativeImpression(slot) {
if (slot.nativeParams) {
const assets = [];
addAsset(assets, titleAsset(1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN));
addAsset(assets, imageAsset(2, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN));
addAsset(assets, dataAsset(3, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN));
addAsset(assets, dataAsset(4, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN));
addAsset(assets, dataAsset(5, slot.nativeParams.cta, 12, NATIVE_DEFAULTS.CTA_LEN));
return {
request: JSON.stringify({ assets }),
ver: '1.1',
};
}
return null;
}

function addAsset(assets, asset) {
if (asset) {
assets.push(asset);
}
}

function titleAsset(id, params, defaultLen) {
if (params) {
return {
id,
required: params.required ? 1 : 0,
title: {
len: params.len || defaultLen,
},
};
}
return null;
}

function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) {
return params ? {
id,
required: params.required ? 1 : 0,
img: {
type,
wmin: params.wmin || defaultMinWidth,
hmin: params.hmin || defaultMinHeight,
}
} : null;
}

function dataAsset(id, params, type, defaultLen) {
return params ? {
id,
required: params.required ? 1 : 0,
data: {
type,
len: params.len || defaultLen,
}
} : null;
}

function site(bidderRequest) {
const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.publisherId : '0';
const appParams = bidderRequest[0].params.app;
if (!appParams) {
return {
publisher: {
id: pubId.toString(),
},
id: pubId.toString(),
ref: referrer(),
page: getTopWindowLocation().href,
domain: getTopWindowLocation().hostname
}
}
return null;
}

function app(bidderRequest) {
const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.publisherId : '0';
const appParams = bidderRequest[0].params.app;
if (appParams) {
return {
publisher: {
id: pubId.toString(),
},
bundle: appParams.bundle,
storeurl: appParams.storeUrl,
domain: appParams.domain,
}
}
return null;
}

function referrer() {
try {
return window.top.document.referrer;
} catch (e) {
return document.referrer;
}
}

function device() {
return {
ua: navigator.userAgent,
language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage),
};
}

function parse(rawResponse) {
try {
if (rawResponse) {
if (typeof rawResponse === 'object') {
return rawResponse
} else {
return JSON.parse(rawResponse);
}
}
} catch (ex) {
logError('readpeakBidAdapter.safeParse', 'ERROR', ex);
}
return null;
}

function nativeResponse(imp, bid) {
if (imp && imp['native']) {
const nativeAd = parse(bid.adm);
const keys = {};
if (nativeAd && nativeAd.assets) {
nativeAd.assets.forEach(asset => {
keys.title = asset.title ? asset.title.text : keys.title;
keys.body = asset.data && asset.id === 4 ? asset.data.value : keys.body;
keys.sponsoredBy = asset.data && asset.id === 3 ? asset.data.value : keys.sponsoredBy;
keys.image = asset.img && asset.id === 2 ? asset.img.url : keys.image;
keys.cta = asset.data && asset.id === 5 ? asset.data.value : keys.cta;
});
if (nativeAd.link) {
keys.clickUrl = encodeURIComponent(nativeAd.link.url);
}
keys.impressionTrackers = nativeAd.imptrackers;
return keys;
}
}
return null;
}

registerBidder(spec);
29 changes: 29 additions & 0 deletions modules/readpeakBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Overview

Module Name: ReadPeak Bid Adapter

Module Type: Bidder Adapter

Maintainer: kurre.stahlberg@readpeak.com

# Description

Module that connects to ReadPeak's demand sources

This adapter requires setup and approval from ReadPeak.
Please reach out to your account team or hello@readpeak.com for more information.

# Test Parameters
```javascript
var adUnits = [{
code: 'test-native',
mediaTypes: { native: { type: 'image' } },
bids: [{
bidder: 'readpeak',
params: {
bidfloor: 5.00,
publisherId: '11bc5dd5-7421-4dd8-c926-40fa653bec76'
},
}]
}];
```
115 changes: 115 additions & 0 deletions modules/sekindoUMBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import * as utils from 'src/utils';
import {registerBidder} from 'src/adapters/bidderFactory';
export const spec = {
code: 'sekindoUM',
supportedMediaTypes: ['video'],
/**
* Determines whether or not the given bid request is valid.
*
* @param {BidRequest} bid The bid params to validate.
* @return boolean True if this is a valid bid, and false otherwise.
*/
isBidRequestValid: function(bid) {
if (bid.mediaType == 'video' || (typeof bid.mediaTypes == 'object' && typeof bid.mediaTypes.video == 'object')) {
if (typeof bid.params.video != 'object' || typeof bid.params.video.playerWidth == 'undefined' || typeof bid.params.video.playerHeight == 'undefined') {
return false;
}
}
return !!(bid.params.spaceId);
},
/**
* Make a server request from the list of BidRequests.
*
* @param {validBidRequests[]} - an array of bids
* @return ServerRequest Info describing the request to the server.
*/
buildRequests: function(validBidRequests, bidderRequest) {
var pubUrl = null;
if (parent !== window) {
pubUrl = document.referrer;
} else {
pubUrl = window.location.href;
}

return validBidRequests.map(bidRequest => {
var subId = utils.getBidIdParameter('subId', bidRequest.params);
var spaceId = utils.getBidIdParameter('spaceId', bidRequest.params);
var bidfloor = utils.getBidIdParameter('bidfloor', bidRequest.params);
var protocol = (document.location.protocol === 'https:' ? 's' : '');
var queryString = '';

queryString = utils.tryAppendQueryString(queryString, 's', spaceId);
queryString = utils.tryAppendQueryString(queryString, 'subId', subId);
queryString = utils.tryAppendQueryString(queryString, 'pubUrl', pubUrl);
queryString = utils.tryAppendQueryString(queryString, 'hbTId', bidRequest.transactionId);
queryString = utils.tryAppendQueryString(queryString, 'hbBidId', bidRequest.bidId);
queryString = utils.tryAppendQueryString(queryString, 'hbver', '4');
queryString = utils.tryAppendQueryString(queryString, 'hbcb', '1');/// legasy
queryString = utils.tryAppendQueryString(queryString, 'dcpmflr', bidfloor);
queryString = utils.tryAppendQueryString(queryString, 'protocol', protocol);
if (bidRequest.mediaType === 'video' || (typeof bidRequest.mediaTypes == 'object' && typeof bidRequest.mediaTypes.video == 'object')) {
queryString = utils.tryAppendQueryString(queryString, 'x', bidRequest.params.playerWidth);
queryString = utils.tryAppendQueryString(queryString, 'y', bidRequest.params.playerHeight);
if (typeof vid_vastType != 'undefined') {
queryString = utils.tryAppendQueryString(queryString, 'vid_vastType', bidRequest.params.vid_vastType);
}
if (typeof bidRequest.mediaTypes == 'object' && typeof bidRequest.mediaTypes.video == 'object' && typeof bidRequest.mediaTypes.video.context == 'string') {
queryString = utils.tryAppendQueryString(queryString, 'vid_context', bidRequest.mediaTypes.video.context);
}
}

var endpointUrl = 'http' + protocol + '://hb.sekindo.com/live/liveView.php';

return {
method: 'GET',
url: endpointUrl,
data: queryString,
};
});
},
/**
* Unpack the response from the server into a list of bids.
*
* @param {*} serverResponse A successful response from the server.
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function(serverResponse, bidRequest) {
if (typeof serverResponse !== 'object') {
return [];
}

let bidResponses = [];
var bidResponse = {
requestId: serverResponse.body.id,
bidderCode: spec.code,
cpm: serverResponse.body.cpm,
width: serverResponse.body.width,
height: serverResponse.body.height,
creativeId: serverResponse.body.creativeId,
currency: serverResponse.body.currency,
netRevenue: serverResponse.body.netRevenue,
ttl: serverResponse.body.ttl
};
if (bidRequest.mediaType == 'video') {
if (typeof serverResponse.body.vastUrl != 'undefined') {
bidResponse.vastUrl = serverResponse.body.vastUrl;
} else {
bidResponse.vastXml = serverResponse.body.vastXml;
}
} else {
bidResponse.ad = serverResponse.body.ad;
}

bidResponses.push(bidResponse);
return bidResponses;
},
getUserSyncs: function(syncOptions) {
if (syncOptions.iframeEnabled) {
return [{
type: 'iframe',
url: 'ADAPTER_SYNC_URL'
}];
}
}
}
registerBidder(spec);
Loading

0 comments on commit 1f115d0

Please sign in to comment.