Skip to content

Commit

Permalink
Add 7xbid adapter to compatible with prebid 3.0 (#4908)
Browse files Browse the repository at this point in the history
* 7xbid adapter

* fix error when cli build

* update to implement prebid 3.0

* remove unneeded code

Co-authored-by: Nguyen Le Thinh <thinhnl@geniee.co.jp>
  • Loading branch information
7XBID00 and thinhnl authored Mar 10, 2020
1 parent 5d4c823 commit 9325d22
Show file tree
Hide file tree
Showing 3 changed files with 320 additions and 1 deletion.
159 changes: 159 additions & 0 deletions modules/7xbidBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import * as utils from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';

const BIDDER_CODE = '7xbid';
const BIDDER_ALIAS = '7xb';
const ENDPOINT_BANNER = '//bidder.7xbid.com/api/v1/prebid/banner';
const ENDPOINT_NATIVE = '//bidder.7xbid.com/api/v1/prebid/native';
const COOKIE_SYNC_URL = '//bidder.7xbid.com/api/v1/cookie/gen';
const SUPPORTED_MEDIA_TYPES = ['banner', 'native'];
const SUPPORTED_CURRENCIES = ['USD', 'JPY'];
const DEFAULT_CURRENCY = 'JPY';
const NET_REVENUE = true;

/**
* updated to support prebid 3.0 - remove utils.getTopWindowUrl()
*/

const _encodeURIComponent = function(a) {
let b = window.encodeURIComponent(a);
b = b.replace(/'/g, '%27');
return b;
}

export const _getUrlVars = function(url) {
var hash;
var myJson = {};
var hashes = url.slice(url.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
myJson[hash[0]] = hash[1];
}
return myJson;
}

export const spec = {
code: BIDDER_CODE,
aliases: [BIDDER_ALIAS], // short code
supportedMediaTypes: SUPPORTED_MEDIA_TYPES,
isBidRequestValid: function(bid) {
if (!(bid.params.placementId)) {
return false;
}

if (bid.params.hasOwnProperty('currency') &&
SUPPORTED_CURRENCIES.indexOf(bid.params.currency) === -1) {
utils.logInfo('Invalid currency type, we support only JPY and USD!')
return false;
}

return true;
},
/**
* 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) {
let serverRequests = [];
var refererInfo;
if (bidderRequest && bidderRequest.refererInfo) {
refererInfo = bidderRequest.refererInfo;
}
validBidRequests.forEach((bid, i) => {
let endpoint = ENDPOINT_BANNER
let data = {
'placementid': bid.params.placementId,
'cur': bid.params.hasOwnProperty('currency') ? bid.params.currency : DEFAULT_CURRENCY,
'ua': navigator.userAgent,
'loc': utils.deepAccess(bidderRequest, 'refererInfo.referer'),
'topframe': (window.parent === window.self) ? 1 : 0,
'sw': screen && screen.width,
'sh': screen && screen.height,
'cb': Math.floor(Math.random() * 99999999999),
'tpaf': 1,
'cks': 1,
'requestid': bid.bidId
};

if (bid.hasOwnProperty('nativeParams')) {
endpoint = ENDPOINT_NATIVE
data.tkf = 1 // return url tracker
data.ad_track = '1'
data.apiv = '1.1.0'
}

if (refererInfo && refererInfo.referer) {
data.referer = refererInfo.referer;
} else {
data.referer = '';
}

serverRequests.push({
method: 'GET',
url: endpoint,
data: utils.parseQueryStringParameters(data)
})
})

return serverRequests;
},
interpretResponse: function(serverResponse, request) {
const data = _getUrlVars(request.data)
const successBid = serverResponse.body || {};
let bidResponses = [];
if (successBid.hasOwnProperty(data.placementid)) {
let bid = successBid[data.placementid]
let bidResponse = {
requestId: bid.requestid,
cpm: bid.price,
creativeId: bid.creativeId,
currency: bid.cur,
netRevenue: NET_REVENUE,
ttl: 700
};

if (bid.hasOwnProperty('title')) { // it is native ad response
bidResponse.mediaType = 'native'
bidResponse.native = {
title: bid.title,
body: bid.description,
cta: bid.cta,
sponsoredBy: bid.advertiser,
clickUrl: _encodeURIComponent(bid.landingURL),
impressionTrackers: bid.trackings,
}
if (bid.screenshots) {
bidResponse.native.image = {
url: bid.screenshots.url,
height: bid.screenshots.height,
width: bid.screenshots.width,
}
}
if (bid.icon) {
bidResponse.native.icon = {
url: bid.icon.url,
height: bid.icon.height,
width: bid.icon.width,
}
}
} else {
bidResponse.ad = bid.adm
bidResponse.width = bid.width
bidResponse.height = bid.height
}

bidResponses.push(bidResponse);
}

return bidResponses;
},
getUserSyncs: function(syncOptions, serverResponses) {
return [{
type: 'image',
url: COOKIE_SYNC_URL
}];
}
}
registerBidder(spec);
1 change: 0 additions & 1 deletion modules/7xbidBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ Module that connects to 7xbid's demand sources
params: {
placementId: 1425292,
currency: 'USD'

}
}
]
Expand Down
161 changes: 161 additions & 0 deletions test/spec/modules/7xbidBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import {expect} from 'chai';
import {spec, _getUrlVars} from 'modules/7xbidBidAdapter';
import * as utils from 'src/utils';
import {config} from 'src/config';

const BASE_URI = '//bidder.7xbid.com/api/v1/prebid/banner'
const NATIVE_BASE_URI = '//bidder.7xbid.com/api/v1/prebid/native'

describe('7xbid adapter', function() {
let bidRequests;
let nativeBidRequests;

beforeEach(function() {
bidRequests = [
{
bidder: '7xbid',
params: {
placementId: 1425292,
currency: 'USD'
}
}
]

nativeBidRequests = [
{
bidder: '7xbid',
params: {
placementId: 1429695,
currency: 'USD'
},
nativeParams: {
title: {
required: true,
len: 80
},
image: {
required: true,
sizes: [150, 50]
},
sponsoredBy: {
required: true
}
}
}
]
})
describe('isBidRequestValid', function () {
it('valid bid case', function () {
let validBid = {
bidder: '7xbid',
params: {
placementId: 1425292,
currency: 'USD'
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(true);
});

it('invalid bid case: placementId is not passed', function() {
let validBid = {
bidder: '7xbid',
params: {
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(false);
})

it('invalid bid case: currency is not support', function() {
let validBid = {
bidder: '7xbid',
params: {
placementId: 1108295,
currency: 'AUD'
}
}
let isValid = spec.isBidRequestValid(validBid);
expect(isValid).to.equal(false);
})
})

describe('buildRequests', function () {
it('sends bid request to ENDPOINT via GET', function () {
const request = spec.buildRequests(bidRequests)[0];
expect(request.url).to.equal(BASE_URI);
expect(request.method).to.equal('GET');
});

it('sends native bid request to ENDPOINT via GET', function () {
const request = spec.buildRequests(nativeBidRequests)[0];
expect(request.url).to.equal(NATIVE_BASE_URI);
expect(request.method).to.equal('GET');
});

it('buildRequests function should not modify original bidRequests object', function () {
let originalBidRequests = utils.deepClone(bidRequests);
let request = spec.buildRequests(bidRequests);
expect(bidRequests).to.deep.equal(originalBidRequests);
});

it('buildRequests function should not modify original nativeBidRequests object', function () {
let originalBidRequests = utils.deepClone(nativeBidRequests);
let request = spec.buildRequests(nativeBidRequests);
expect(nativeBidRequests).to.deep.equal(originalBidRequests);
});

it('Request params check', function() {
let request = spec.buildRequests(bidRequests)[0];
const data = _getUrlVars(request.data)
expect(parseInt(data.placementid)).to.exist.and.to.equal(bidRequests[0].params.placementId);
expect(data.cur).to.exist.and.to.equal(bidRequests[0].params.currency);
})

it('Native request params check', function() {
let request = spec.buildRequests(nativeBidRequests)[0];
const data = _getUrlVars(request.data)
expect(parseInt(data.placementid)).to.exist.and.to.equal(nativeBidRequests[0].params.placementId);
expect(data.cur).to.exist.and.to.equal(nativeBidRequests[0].params.currency);
})
})

describe('interpretResponse', function () {
let response = {
1425292:
{
'creativeId': '<!-- CREATIVE ID -->',
'cur': 'USD',
'price': 0.0920,
'width': 300,
'height': 250,
'requestid': '2e42361a6172bf',
'adm': '<!-- ADS TAG -->'
}
}

it('should get correct bid response', function () {
let expectedResponse = [
{
'requestId': '2e42361a6172bf',
'cpm': 0.0920,
'width': 300,
'height': 250,
'netRevenue': true,
'currency': 'USD',
'creativeId': '<!-- CREATIVE ID -->',
'ttl': 700,
'ad': '<!-- ADS TAG -->'
}
];
let request = spec.buildRequests(bidRequests)[0];
let result = spec.interpretResponse({body: response}, request);
expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0]));
expect(result[0].cpm).to.not.equal(null);
expect(result[0].creativeId).to.not.equal(null);
expect(result[0].ad).to.not.equal(null);
expect(result[0].currency).to.equal('USD');
expect(result[0].netRevenue).to.equal(true);
});
})
})

0 comments on commit 9325d22

Please sign in to comment.