Skip to content

Prebid 3 adbutler #4612

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 24 commits into from
Dec 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
771b74c
Adding AdButler Adapter
dkharton Oct 14, 2016
45919de
Prevent AdButler TypeError
dharton Oct 19, 2016
5e72aac
Refactor AdButler Testing
dharton Oct 19, 2016
10ab721
Prevent AdButler TypeErrors
dharton Oct 24, 2016
38ad684
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Oct 24, 2016
79e7045
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Nov 1, 2016
7fe5aa1
Merge remote-tracking branch 'prebid/master'
dharton Nov 17, 2016
1cf22f4
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Dec 6, 2016
eca8d59
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Dec 14, 2016
252ffac
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Jan 3, 2017
add7a75
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Jan 3, 2017
35b8180
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Jan 24, 2017
2cdc25b
Merge branch 'master' of https://github.com/sparklit/Prebid.js
dharton Jan 24, 2017
f4cac5d
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Feb 14, 2017
c0ef919
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Mar 6, 2017
8f85d45
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Mar 27, 2017
1d4480a
Add optional domain parameter.
dharton Mar 27, 2017
4efc579
Merge remote-tracking branch 'refs/remotes/prebid/master'
dharton Mar 27, 2017
42b3c41
Merge remote-tracking branch 'remotes/prebid/master'
dharton Aug 17, 2017
28df88d
Merge remote-tracking branch 'remotes/prebid/master'
dharton Oct 2, 2017
5cc58bf
Merge remote-tracking branch 'remotes/prebid/master'
dharton Oct 3, 2017
cdea438
Merge remote-tracking branch 'remotes/prebid/master'
dharton Oct 6, 2017
ffba136
Merge remote-tracking branch 'remotes/prebid/master' into master-old
dharton Dec 16, 2019
16093de
Update AdButler adapter to 3.0 spec
dharton Dec 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions modules/adbutlerBidAdapter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
'use strict';

import * as utils from '../src/utils';
import {config} from '../src/config';
import {registerBidder} from '../src/adapters/bidderFactory';

const BIDDER_CODE = 'adbutler';

export const spec = {
code: BIDDER_CODE,
pageID: Math.floor(Math.random() * 10e6),
aliases: ['divreach'],

isBidRequestValid: function (bid) {
return !!(bid.params.accountID && bid.params.zoneID);
},

buildRequests: function (validBidRequests) {
let i;
let zoneID;
let bidRequest;
let accountID;
let keyword;
let domain;
let requestURI;
let serverRequests = [];
let zoneCounters = {};

for (i = 0; i < validBidRequests.length; i++) {
bidRequest = validBidRequests[i];
zoneID = utils.getBidIdParameter('zoneID', bidRequest.params);
accountID = utils.getBidIdParameter('accountID', bidRequest.params);
keyword = utils.getBidIdParameter('keyword', bidRequest.params);
domain = utils.getBidIdParameter('domain', bidRequest.params);

if (!(zoneID in zoneCounters)) {
zoneCounters[zoneID] = 0;
}

if (typeof domain === 'undefined' || domain.length === 0) {
domain = 'servedbyadbutler.com';
}

requestURI = 'https://' + domain + '/adserve/;type=hbr;';
requestURI += 'ID=' + encodeURIComponent(accountID) + ';';
requestURI += 'setID=' + encodeURIComponent(zoneID) + ';';
requestURI += 'pid=' + encodeURIComponent(spec.pageID) + ';';
requestURI += 'place=' + encodeURIComponent(zoneCounters[zoneID]) + ';';

// append the keyword for targeting if one was passed in
if (keyword !== '') {
requestURI += 'kw=' + encodeURIComponent(keyword) + ';';
}

zoneCounters[zoneID]++;
serverRequests.push({
method: 'GET',
url: requestURI,
data: {},
bidRequest: bidRequest
});
}
return serverRequests;
},

interpretResponse: function (serverResponse, bidRequest) {
const bidObj = bidRequest.bidRequest;
let bidResponses = [];
let bidResponse = {};
let isCorrectSize = false;
let isCorrectCPM = true;
let CPM;
let minCPM;
let maxCPM;
let width;
let height;

serverResponse = serverResponse.body;
if (serverResponse && serverResponse.status === 'SUCCESS' && bidObj) {
CPM = serverResponse.cpm;
minCPM = utils.getBidIdParameter('minCPM', bidObj.params);
maxCPM = utils.getBidIdParameter('maxCPM', bidObj.params);
width = parseInt(serverResponse.width);
height = parseInt(serverResponse.height);

// Ensure response CPM is within the given bounds
if (minCPM !== '' && CPM < parseFloat(minCPM)) {
isCorrectCPM = false;
}
if (maxCPM !== '' && CPM > parseFloat(maxCPM)) {
isCorrectCPM = false;
}

// Ensure that response ad matches one of the placement sizes.
utils._each(utils.deepAccess(bidObj, 'mediaTypes.banner.sizes', []), function (size) {
if (width === size[0] && height === size[1]) {
isCorrectSize = true;
}
});
if (isCorrectCPM && isCorrectSize) {
bidResponse.requestId = bidObj.bidId;
bidResponse.bidderCode = bidObj.bidder;
bidResponse.creativeId = serverResponse.placement_id;
bidResponse.cpm = CPM;
bidResponse.width = width;
bidResponse.height = height;
bidResponse.ad = serverResponse.ad_code;
bidResponse.ad += spec.addTrackingPixels(serverResponse.tracking_pixels);
bidResponse.currency = 'USD';
bidResponse.netRevenue = true;
bidResponse.ttl = config.getConfig('_bidderTimeout');
bidResponse.referrer = utils.deepAccess(bidObj, 'refererInfo.referer');
bidResponses.push(bidResponse);
}
}
return bidResponses;
},

addTrackingPixels: function (trackingPixels) {
let trackingPixelMarkup = '';
utils._each(trackingPixels, function (pixelURL) {
let trackingPixel = '<img height="0" width="0" border="0" style="display:none;" src="';
trackingPixel += pixelURL;
trackingPixel += '">';

trackingPixelMarkup += trackingPixel;
});
return trackingPixelMarkup;
}
};
registerBidder(spec);
Empty file.
221 changes: 221 additions & 0 deletions test/spec/modules/adbutlerBidAdapter_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import {expect} from 'chai';
import {spec} from 'modules/adbutlerBidAdapter';

describe('AdButler adapter', function () {
let bidRequests;

beforeEach(function () {
bidRequests = [
{
bidder: 'adbutler',
params: {
accountID: '167283',
zoneID: '210093',
keyword: 'red',
minCPM: '1.00',
maxCPM: '5.00'
},
placementCode: '/19968336/header-bid-tag-1',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 600]],
},
},
bidId: '23acc48ad47af5',
auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99',
bidderRequestId: '1c56ad30b9b8ca8',
transactionId: '92489f71-1bf2-49a0-adf9-000cea934729'
}
];
});

describe('implementation', function () {
describe('for requests', function () {
it('should accept valid bid', function () {
let validBid = {
bidder: 'adbutler',
params: {
accountID: '167283',
zoneID: '210093'
}
},
isValid = spec.isBidRequestValid(validBid);

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

it('should reject invalid bid', function () {
let invalidBid = {
bidder: 'adbutler',
params: {
accountID: '167283',
}
},
isValid = spec.isBidRequestValid(invalidBid);

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

it('should use custom domain string', function () {
let bidRequests = [
{
bidId: '3c9408cdbf2f68',
sizes: [[300, 250]],
bidder: 'adbutler',
params: {
accountID: '107878',
zoneID: '86133',
domain: 'servedbyadbutler.com.dan.test'
},
auctionId: '10b327aa396609',
placementCode: '/123456/header-bid-tag-1'
}
],
requests = spec.buildRequests(bidRequests),
requestURL = requests[0].url;

expect(requestURL).to.have.string('.dan.test');
});

it('should set default domain', function () {
let requests = spec.buildRequests(bidRequests),
request = requests[0];

let [domain] = request.url.split('/adserve/');

expect(domain).to.equal('https://servedbyadbutler.com');
});

it('should set the keyword parameter', function () {
let requests = spec.buildRequests(bidRequests),
requestURL = requests[0].url;

expect(requestURL).to.have.string(';kw=red;');
});

it('should increment the count for the same zone', function () {
let bidRequests = [
{
sizes: [[300, 250]],
bidder: 'adbutler',
params: {
accountID: '107878',
zoneID: '86133',
}
}, {
sizes: [[300, 250]],
bidder: 'adbutler',
params: {
accountID: '107878',
zoneID: '86133',
}
},
],
requests = spec.buildRequests(bidRequests),
firstRequest = requests[0].url,
secondRequest = requests[1].url;

expect(firstRequest).to.have.string(';place=0;');
expect(secondRequest).to.have.string(';place=1;');
});
});

describe('bid responses', function () {
it('should return complete bid response', function () {
let serverResponse = {
body: {
status: 'SUCCESS',
account_id: 167283,
zone_id: 210093,
cpm: 1.5,
width: 300,
height: 250,
place: 0,
ad_code: '<img src="http://image.source.com/img" alt="" title="" border="0" width="300" height="250">',
tracking_pixels: [
'http://tracking.pixel.com/params=info'
]
}
},
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]});

expect(bids).to.be.lengthOf(1);

expect(bids[0].bidderCode).to.equal('adbutler');
expect(bids[0].cpm).to.equal(1.5);
expect(bids[0].width).to.equal(300);
expect(bids[0].height).to.equal(250);
expect(bids[0].currency).to.equal('USD');
expect(bids[0].netRevenue).to.equal(true);
expect(bids[0].ad).to.have.length.above(1);
expect(bids[0].ad).to.have.string('http://tracking.pixel.com/params=info');
});

it('should return empty bid response', function () {
let serverResponse = {
body: {
status: 'NO_ELIGIBLE_ADS',
zone_id: 210083,
width: 300,
height: 250,
place: 0
}
},
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]});

expect(bids).to.be.lengthOf(0);
});

it('should return empty bid response on incorrect size', function () {
let serverResponse = {
body: {
status: 'SUCCESS',
account_id: 167283,
zone_id: 210083,
cpm: 1.5,
width: 728,
height: 90,
place: 0
}
},
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]});

expect(bids).to.be.lengthOf(0);
});

it('should return empty bid response with CPM too low', function () {
let serverResponse = {
body: {
status: 'SUCCESS',
account_id: 167283,
zone_id: 210093,
cpm: 0.75,
width: 300,
height: 250,
place: 0
}
},
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]});

expect(bids).to.be.lengthOf(0);
});

it('should return empty bid response with CPM too high', function () {
let serverResponse = {
body: {
status: 'SUCCESS',
account_id: 167283,
zone_id: 210093,
cpm: 7,
width: 300,
height: 250,
place: 0
}
},
bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]});

expect(bids).to.be.lengthOf(0);
});
});
});
});