Skip to content

Commit

Permalink
Legacy Sortable bid adapter (prebid#2915)
Browse files Browse the repository at this point in the history
* Backport Sortable adapter to legacy (#7)

* copy over sortable adapter as well as its spce test and md
* fix missing utils.isPlainObject

* use prebid ajax instead of fetch as fetch is not supported in IE10 (#8)
  • Loading branch information
edmonl authored and idettman committed Aug 8, 2018
1 parent 9c06f8d commit fed6a3f
Show file tree
Hide file tree
Showing 3 changed files with 454 additions and 0 deletions.
139 changes: 139 additions & 0 deletions modules/sortableBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as utils from 'src/utils';
import { registerBidder } from 'src/adapters/bidderFactory';
import { config } from 'src/config';
import { BANNER } from 'src/mediaTypes';
import { REPO_AND_VERSION } from 'src/constants';
import { ajax } from 'src/ajax';

const BIDDER_CODE = 'sortable';
const SERVER_URL = 'c.deployads.com';

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],

isBidRequestValid: function(bid) {
const sortableConfig = config.getConfig('sortable');
const haveSiteId = (sortableConfig && !!sortableConfig.siteId) || bid.params.siteId;
const validFloor = !bid.params.floor || utils.isNumber(bid.params.floor);
const validSize = /\d+x\d+/;
const validFloorSizeMap = !bid.params.floorSizeMap ||
(utils.isA(bid.params.floorSizeMap, 'Object') &&
Object.keys(bid.params.floorSizeMap).every(size =>
size.match(validSize) && utils.isNumber(bid.params.floorSizeMap[size])
));
const validKeywords = !bid.params.keywords ||
(utils.isA(bid.params.keywords, 'Object') &&
Object.keys(bid.params.keywords).every(key =>
utils.isStr(key) && utils.isStr(bid.params.keywords[key])
));
return !!(bid.params.tagId && haveSiteId && validFloor && validFloorSizeMap && validKeywords && bid.sizes &&
bid.sizes.every(sizeArr => sizeArr.length == 2 && sizeArr.every(num => utils.isNumber(num))));
},

buildRequests: function(validBidReqs, bidderRequest) {
const sortableConfig = config.getConfig('sortable') || {};
const globalSiteId = sortableConfig.siteId;
let loc = utils.getTopWindowLocation();

const sortableImps = utils._map(validBidReqs, bid => {
let rv = {
id: bid.bidId,
tagid: bid.params.tagId,
banner: {
format: utils._map(bid.sizes, ([width, height]) => ({w: width, h: height}))
},
ext: {}
};
if (bid.params.floor) {
rv.bidfloor = bid.params.floor;
}
if (bid.params.keywords) {
rv.ext.keywords = bid.params.keywords;
}
if (bid.params.bidderParams) {
utils._each(bid.params.bidderParams, (params, partner) => {
rv.ext[partner] = params;
});
}
if (bid.params.floorSizeMap) {
rv.ext.floorSizeMap = bid.params.floorSizeMap;
}
return rv;
});
const sortableBidReq = {
id: utils.getUniqueIdentifierStr(),
imp: sortableImps,
site: {
domain: loc.hostname,
page: loc.href,
ref: utils.getTopWindowReferrer(),
publisher: {
id: globalSiteId || validBidReqs[0].params.siteId,
},
device: {
w: screen.width,
h: screen.height
},
},
};
return {
method: 'POST',
url: `//${SERVER_URL}/openrtb2/auction?src=${REPO_AND_VERSION}&host=${loc.host}`,
data: JSON.stringify(sortableBidReq),
options: {contentType: 'text/plain'}
};
},

interpretResponse: function(serverResponse) {
const { body: {id, seatbid} } = serverResponse;
const sortableBids = [];
if (id && seatbid) {
utils._each(seatbid, seatbid => {
utils._each(seatbid.bid, bid => {
const bidObj = {
requestId: bid.impid,
cpm: parseFloat(bid.price),
width: parseInt(bid.w),
height: parseInt(bid.h),
creativeId: bid.crid || bid.id,
dealId: bid.dealid || null,
currency: 'USD',
netRevenue: true,
mediaType: BANNER,
ttl: 60
};
if (bid.adm && bid.nurl) {
bidObj.ad = bid.adm;
bidObj.ad += utils.createTrackPixelHtml(decodeURIComponent(bid.nurl));
} else if (bid.adm) {
bidObj.ad = bid.adm;
} else if (bid.nurl) {
bidObj.adUrl = bid.nurl;
}
sortableBids.push(bidObj);
});
});
}
return sortableBids;
},

getUserSyncs: (syncOptions, responses) => {
const sortableConfig = config.getConfig('sortable');
if (syncOptions.iframeEnabled && sortableConfig && !!sortableConfig.siteId) {
let syncUrl = `//${SERVER_URL}/sync?f=html&s=${sortableConfig.siteId}&u=${encodeURIComponent(utils.getTopWindowLocation())}`;
return [{
type: 'iframe',
url: syncUrl
}];
}
},

onTimeout(details) {
ajax(`//${SERVER_URL}/prebid/timeout`, null, JSON.stringify(details), {
method: 'POST'
});
}
};

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

```
Module Name: Sortable Bid Adapter
Module Type: Bidder Adapter
Maintainer: prebid@sortable.com
```

# Description

Sortable's adapter integration to the Prebid library. Posts plain-text JSON to the /openrtb2/auction endpoint.

# Test Parameters

```
var adUnits = [
{
code: 'test-pb-leaderboard',
sizes: [[728, 90]],
bids: [{
bidder: 'sortable',
params: {
tagId: 'test-pb-leaderboard',
siteId: 'prebid.example.com',
'keywords': {
'key1': 'val1',
'key2': 'val2'
}
}
}]
}, {
code: 'test-pb-banner',
sizes: [[300, 250]],
bids: [{
bidder: 'sortable',
params: {
tagId: 'test-pb-banner',
siteId: 'prebid.example.com'
}
}]
}, {
code: 'test-pb-sidebar',
size: [[160, 600]],
bids: [{
bidder: 'sortable',
params: {
tagId: 'test-pb-sidebar',
siteId: 'prebid.example.com',
'keywords': {
'keyA': 'valA'
}
}
}]
}
]
```
Loading

0 comments on commit fed6a3f

Please sign in to comment.