Skip to content

Commit

Permalink
[Add BidAdapter] rxrtb adapter for Perbid.js 1.0 (prebid#1950)
Browse files Browse the repository at this point in the history
* Add: rxrtb prebidAdapter

* Update: params for test

* Update: code format

* Update: code format

* Update: code format
  • Loading branch information
prebidRxRTB authored and Justas Pupelis committed Jan 10, 2018
1 parent b038a30 commit b3e7489
Show file tree
Hide file tree
Showing 3 changed files with 292 additions and 0 deletions.
140 changes: 140 additions & 0 deletions modules/rxrtbBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import * as utils from 'src/utils';
import {BANNER} from 'src/mediaTypes';
import {registerBidder} from 'src/adapters/bidderFactory';
import {config} from 'src/config';

const BIDDER_CODE = 'rxrtb';
const DEFAULT_HOST = 'bid.rxrtb.bid';
const AUCTION_TYPE = 2;
const RESPONSE_TTL = 900;

export const spec = {
code: BIDDER_CODE,
supportedMediaTypes: [BANNER],
isBidRequestValid: function (bidRequest) {
return 'params' in bidRequest && bidRequest.params.source !== undefined && bidRequest.params.id !== undefined && Number.isInteger(bidRequest.params.id) && bidRequest.params.token !== undefined;
},
buildRequests: function (validBidRequests) {
var requests = [];
for (let i = 0; i < validBidRequests.length; i++) {
let prebidReq = makePrebidRequest(validBidRequests[i]);
if (prebidReq) {
requests.push(prebidReq);
}
}

return requests;
},
interpretResponse: function (serverResponse, bidRequest) {
let rtbResp = serverResponse.body;
if ((!rtbResp) || (!rtbResp.seatbid)) {
return [];
}
let bidResponses = [];
for (let i = 0; i < rtbResp.seatbid.length; i++) {
let seatbid = rtbResp.seatbid[i];
for (let j = 0; j < seatbid.bid.length; j++) {
let bid = seatbid.bid[j];
let bidResponse = {
requestId: bid.impid,
cpm: bid.price,
width: bid.w,
height: bid.h,
mediaType: BANNER,
creativeId: bid.crid,
currency: rtbResp.cur || 'USD',
netRevenue: true,
ttl: bid.exp || RESPONSE_TTL,
ad: bid.adm
};
bidResponses.push(bidResponse);
}
}
return bidResponses;
},
getUserSyncs: function (syncOptions, serverResponses) {
return [];
}
}

registerBidder(spec);

function getDomain(url) {
var a = document.createElement('a');
a.href = url;

return a.host;
}

function makePrebidRequest(req) {
let host = req.params.host || DEFAULT_HOST;
let url = window.location.protocol + '//' + host + '/dsp?id=' + req.params.id + '&token=' + req.params.token;
let reqData = makeRtbRequest(req);
return {
method: 'POST',
url: url,
data: JSON.stringify(reqData)
};
}

function makeRtbRequest(req) {
let imp = [];
imp.push(makeImp(req));
return {
'id': req.auctionId,
'imp': imp,
'site': makeSite(req),
'device': makeDevice(),
'hb': 1,
'at': req.params.at || AUCTION_TYPE,
'cur': ['USD'],
'badv': req.params.badv || '',
'bcat': req.params.bcat || '',
};
}

function makeImp(req) {
let imp = {
'id': req.bidId,
'tagid': req.adUnitCode,
'banner': makeBanner(req)
};

if (req.params.bidfloor && Number.isInteger(req.params.bidfloor)) {
imp.bidfloor = req.params.bidfloor
}

return imp;
}

function makeBanner(req) {
let format = [];
let banner = {};
for (let i = 0; i < req.sizes.length; i++) {
format.push({
w: req.sizes[i][0],
h: req.sizes[i][1]
});
}
banner.format = format;
if (req.params.pos && Number.isInteger(req.params.pos)) {
banner.pos = req.params.pos;
}
return banner;
}

function makeSite(req) {
return {
'id': req.params.source,
'domain': getDomain(config.getConfig('publisherDomain')),
'page': utils.getTopWindowUrl(),
'ref': utils.getTopWindowReferrer()
};
}

function makeDevice() {
return {
'ua': window.navigator.userAgent || '',
'ip': 1
};
}
32 changes: 32 additions & 0 deletions modules/rxrtbBidAdapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Overview

Module Name: rxrtb Bidder Adapter

Module Type: Bidder Adapter

Maintainer: [email protected]


# Description

Module that connects to rxrtb's demand source

# Test Parameters
```javascript
var adUnits = [
{
code: 'test-ad',
sizes: [[728, 98]],
bids: [
{
bidder: 'rxrtb',
params: {
id: 89,
token: '658f11a5efbbce2f9be3f1f146fcbc22',
source: 'prebidtest'
}
}
]
},
];
```
120 changes: 120 additions & 0 deletions test/spec/modules/rxrtbBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import {expect} from 'chai';
import {spec} from 'modules/rxrtbBidAdapter';

describe('rxrtb adapater', () => {
describe('Test validate req', () => {
it('should accept minimum valid bid', () => {
let bid = {
bidder: 'rxrtb',
params: {
id: 89,
token: '658f11a5efbbce2f9be3f1f146fcbc22',
source: 'prebidtest'
}
};
const isValid = spec.isBidRequestValid(bid);

expect(isValid).to.equal(true);
});

it('should reject missing id', () => {
let bid = {
bidder: 'rxrtb',
params: {
token: '658f11a5efbbce2f9be3f1f146fcbc22',
source: 'prebidtest'
}
};
const isValid = spec.isBidRequestValid(bid);

expect(isValid).to.equal(false);
});

it('should reject id not Integer', () => {
let bid = {
bidder: 'rxrtb',
params: {
id: '123',
token: '658f11a5efbbce2f9be3f1f146fcbc22',
source: 'prebidtest'
}
};
const isValid = spec.isBidRequestValid(bid);

expect(isValid).to.equal(false);
});

it('should reject missing source', () => {
let bid = {
bidder: 'rxrtb',
params: {
id: 89,
token: '658f11a5efbbce2f9be3f1f146fcbc22'
}
};
const isValid = spec.isBidRequestValid(bid);

expect(isValid).to.equal(false);
});
});

describe('Test build request', () => {
it('minimum request', () => {
let bid = {
bidder: 'rxrtb',
sizes: [[728, 90]],
bidId: '4d0a6829338a07',
adUnitCode: 'div-gpt-ad-1460505748561-0',
auctionId: '20882439e3238c',
params: {
id: 89,
token: '658f11a5efbbce2f9be3f1f146fcbc22',
source: 'prebidtest'
},
};
const req = JSON.parse(spec.buildRequests([bid])[0].data);

expect(req).to.have.property('id');
expect(req).to.have.property('imp');
expect(req).to.have.property('device');
expect(req).to.have.property('site');
expect(req).to.have.property('hb');
expect(req.imp[0]).to.have.property('id');
expect(req.imp[0]).to.have.property('banner');
expect(req.device).to.have.property('ip');
expect(req.device).to.have.property('ua');
expect(req.site).to.have.property('id');
expect(req.site).to.have.property('domain');
});
});

describe('Test interpret response', () => {
it('General banner response', () => {
let resp = spec.interpretResponse({
body: {
id: 'abcd',
seatbid: [{
bid: [{
id: 'abcd',
impid: 'banner-bid',
price: 0.3,
w: 728,
h: 98,
adm: 'hello',
crid: 'efgh',
exp: 5
}]
}]
}
}, null)[0];

expect(resp).to.have.property('requestId', 'banner-bid');
expect(resp).to.have.property('cpm', 0.3);
expect(resp).to.have.property('width', 728);
expect(resp).to.have.property('height', 98);
expect(resp).to.have.property('creativeId', 'efgh');
expect(resp).to.have.property('ttl', 5);
expect(resp).to.have.property('ad', 'hello');
});
});
});

0 comments on commit b3e7489

Please sign in to comment.