Skip to content

Adkernel adapter minor update #4000

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 3 commits into from
Jul 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 18 additions & 19 deletions modules/adkernelBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@ export const spec = {
aliases: ['headbidding'],
supportedMediaTypes: [BANNER, VIDEO],
isBidRequestValid: function(bidRequest) {
return 'params' in bidRequest && typeof bidRequest.params.host !== 'undefined' &&
'zoneId' in bidRequest.params && !isNaN(Number(bidRequest.params.zoneId)) &&
bidRequest.mediaTypes && (bidRequest.mediaTypes.banner || bidRequest.mediaTypes.video);
return 'params' in bidRequest &&
typeof bidRequest.params.host !== 'undefined' &&
'zoneId' in bidRequest.params &&
!isNaN(Number(bidRequest.params.zoneId)) &&
bidRequest.params.zoneId > 0 &&
bidRequest.mediaTypes &&
(bidRequest.mediaTypes.banner || bidRequest.mediaTypes.video);
},
buildRequests: function(bidRequests, bidderRequest) {
let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo);
const gdprConsent = bidderRequest.gdprConsent;
const auctionId = bidderRequest.auctionId;
const {gdprConsent, auctionId} = bidderRequest;
const requests = [];
Object.keys(impDispatch).forEach(host => {
Object.keys(impDispatch[host]).forEach(zoneId => {
const request = buildRtbRequest(impDispatch[host][zoneId], auctionId, gdprConsent, bidderRequest.refererInfo);
requests.push({
method: 'POST',
url: `${window.location.protocol}//${host}/hb?zone=${Number(zoneId)}&v=${VERSION}`,
url: `${window.location.protocol}//${host}/hb?zone=${zoneId}&v=${VERSION}`,
data: JSON.stringify(request)
});
});
Expand All @@ -47,13 +50,12 @@ export const spec = {
}

let rtbRequest = JSON.parse(request.data);
let rtbImps = rtbRequest.imp;
let rtbBids = response.seatbid
.map(seatbid => seatbid.bid)
.reduce((a, b) => a.concat(b), []);

return rtbBids.map(rtbBid => {
let imp = find(rtbImps, imp => imp.id === rtbBid.impid);
let imp = find(rtbRequest.imp, imp => imp.id === rtbBid.impid);
let prBid = {
requestId: rtbBid.impid,
cpm: rtbBid.price,
Expand Down Expand Up @@ -119,19 +121,16 @@ function buildImp(bidRequest, secure) {
if (utils.deepAccess(bidRequest, `mediaTypes.banner`)) {
let sizes = canonicalizeSizesArray(bidRequest.mediaTypes.banner.sizes);
imp.banner = {
format: sizes.map(s => ({'w': s[0], 'h': s[1]})),
format: sizes.map(wh => utils.parseGPTSingleSizeArrayToRtbSize(wh)),
topframe: 0
};
} else if (utils.deepAccess(bidRequest, 'mediaTypes.video')) {
let size = canonicalizeSizesArray(bidRequest.mediaTypes.video.playerSize)[0];
imp.video = {
w: size[0],
h: size[1]
};
imp.video = utils.parseGPTSingleSizeArrayToRtbSize(size);
if (bidRequest.params.video) {
Object.keys(bidRequest.params.video)
.filter(param => includes(VIDEO_TARGETING, param))
.forEach(param => imp.video[param] = bidRequest.params.video[param]);
.filter(key => includes(VIDEO_TARGETING, key))
.forEach(key => imp.video[key] = bidRequest.params.video[key]);
}
}
if (secure) {
Expand Down Expand Up @@ -198,18 +197,18 @@ function getLanguage() {
*/
function createSite(refInfo) {
let url = parseUrl(refInfo.referer);
let result = {
let site = {
'domain': url.hostname,
'page': url.protocol + '://' + url.hostname + url.pathname
};
if (self === top && document.referrer) {
result.ref = document.referrer;
site.ref = document.referrer;
}
let keywords = document.getElementsByTagName('meta')['keywords'];
if (keywords && keywords.content) {
result.keywords = keywords.content;
site.keywords = keywords.content;
}
return result;
return site;
}

/**
Expand Down
64 changes: 35 additions & 29 deletions modules/adkernelBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
```
Module Name: AdKernel Bidder Adapter
Module Type: Bidder Adapter
Maintainer: denis@adkernel.com
Maintainer: prebid-dev@adkernel.com
```

# Description
Expand All @@ -14,32 +14,38 @@ Banner and video formats are supported.

# Test Parameters
```
var adUnits = [
{
code: 'banner-ad-div',
sizes: [[300, 250]], // banner size
bids: [
{
bidder: 'adkernel',
params: {
zoneId: '30164', //required parameter
host: 'cpm.metaadserving.com' //required parameter
}
}
]
}, {
code: 'video-ad-player',
sizes: [640, 480], // video player size
bids: [
{
bidder: 'adkernel',
mediaType : 'video',
params: {
zoneId: '30164', //required parameter
host: 'cpm.metaadserving.com' //required parameter
}
}
]
}
];
var adUnits = [{
code: 'banner-ad-div',
mediaTypes: {
banner: {
sizes: [[300, 250]], // banner size
}
},
bids: [
{
bidder: 'adkernel',
params: {
zoneId: '30164', //required parameter
host: 'cpm.metaadserving.com' //required parameter
}
}
]
}, {
code: 'video-ad-player',
mediaTypes: {
video: {
context: 'instream', // or 'outstream'
playerSize: [640, 480] // video player size
}
},
bids: [
{
bidder: 'adkernel',
params: {
zoneId: '30164', //required parameter
host: 'cpm.metaadserving.com' //required parameter
}
}
]
}];
```
18 changes: 15 additions & 3 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,15 +221,27 @@ export function parseSizesInput(sizeObj) {
return parsedSizes;
}

// parse a GPT style sigle size array, (i.e [300,250])
// Parse a GPT style single size array, (i.e [300, 250])
// into an AppNexus style string, (i.e. 300x250)
export function parseGPTSingleSizeArray(singleSize) {
// if we aren't exactly 2 items in this array, it is invalid
if (isArray(singleSize) && singleSize.length === 2 && (!isNaN(singleSize[0]) && !isNaN(singleSize[1]))) {
if (isValidGPTSingleSize(singleSize)) {
return singleSize[0] + 'x' + singleSize[1];
}
}

// Parse a GPT style single size array, (i.e [300, 250])
// into OpenRTB-compatible (imp.banner.w/h, imp.banner.format.w/h, imp.video.w/h) object(i.e. {w:300, h:250})
export function parseGPTSingleSizeArrayToRtbSize(singleSize) {
if (isValidGPTSingleSize(singleSize)) {
return {w: singleSize[0], h: singleSize[1]};
}
}

function isValidGPTSingleSize(singleSize) {
// if we aren't exactly 2 items in this array, it is invalid
return isArray(singleSize) && singleSize.length === 2 && (!isNaN(singleSize[0]) && !isNaN(singleSize[1]));
}

/**
* @deprecated This function will be removed soon. Use http://prebid.org/dev-docs/bidder-adaptor.html#referrers
*/
Expand Down
68 changes: 60 additions & 8 deletions test/spec/modules/adkernelBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,71 @@ import * as utils from 'src/utils';
describe('Adkernel adapter', function () {
const bid1_zone1 = {
bidder: 'adkernel',
bidId: 'Bid_01',
params: {zoneId: 1, host: 'rtb.adkernel.com'},
adUnitCode: 'ad-unit-1',
bidId: 'Bid_01',
bidderRequestId: 'req-001',
auctionId: 'auc-001',
mediaTypes: {
banner: {
sizes: [[300, 250], [300, 200]]
}
}
}, bid2_zone2 = {
bidder: 'adkernel',
bidId: 'Bid_02',
params: {zoneId: 2, host: 'rtb.adkernel.com'},
adUnitCode: 'ad-unit-2',
bidId: 'Bid_02',
bidderRequestId: 'req-001',
auctionId: 'auc-001',
mediaTypes: {
banner: {
sizes: [728, 90]
sizes: [[728, 90]]
}
}
}, bid3_host2 = {
bidder: 'adkernel',
bidId: 'Bid_02',
params: {zoneId: 1, host: 'rtb-private.adkernel.com'},
adUnitCode: 'ad-unit-2',
bidId: 'Bid_02',
bidderRequestId: 'req-001',
auctionId: 'auc-001',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
}
}, bid_without_zone = {
bidder: 'adkernel',
bidId: 'Bid_W',
params: {host: 'rtb-private.adkernel.com'},
adUnitCode: 'ad-unit-1',
bidId: 'Bid_W',
bidderRequestId: 'req-002',
auctionId: 'auc-002',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
}
}, bid_without_host = {
bidder: 'adkernel',
bidId: 'Bid_W',
params: {zoneId: 1},
adUnitCode: 'ad-unit-1',
bidId: 'Bid_W',
bidderRequestId: 'req-002',
auctionId: 'auc-002',
mediaTypes: {
banner: {
sizes: [[728, 90]]
}
}
}, bid_with_wrong_zoneId = {
bidder: 'adkernel',
bidId: 'Bid_02',
params: {zoneId: 'wrong id', host: 'rtb.adkernel.com'},
adUnitCode: 'ad-unit-2',
bidId: 'Bid_02',
bidderRequestId: 'req-002',
auctionId: 'auc-002',
mediaTypes: {
banner: {
sizes: [[728, 90]]
Expand All @@ -72,7 +84,8 @@ describe('Adkernel adapter', function () {
sizes: [[640, 480]],
params: {
zoneId: 1,
host: 'rtb.adkernel.com'
host: 'rtb.adkernel.com',
video: {api: [1, 2]}
},
mediaTypes: {
video: {
Expand All @@ -81,6 +94,19 @@ describe('Adkernel adapter', function () {
}
},
adUnitCode: 'ad-unit-1'
}, bid_multiformat = {
bidder: 'adkernel',
params: {zoneId: 1, host: 'rtb.adkernel.com'},
mediaTypes: {
banner: {sizes: [[300, 250], [300, 200]]},
video: {context: 'instream', playerSize: [[640, 480]]}
},
adUnitCode: 'ad-unit-1',
transactionId: 'f82c64b8-c602-42a4-9791-4a268f6559ed',
sizes: [[300, 250], [300, 200]],
bidId: 'Bid_01',
bidderRequestId: 'req-001',
auctionId: 'auc-001'
};

const bidResponse1 = {
Expand Down Expand Up @@ -183,6 +209,11 @@ describe('Adkernel adapter', function () {
expect(bidRequest.imp[0]).to.have.property('banner');
});

it('should have id', function () {
expect(bidRequest.imp[0]).to.have.property('id');
expect(bidRequest.imp[0].id).to.be.eql('Bid_01');
});

it('should have w/h', function () {
expect(bidRequest.imp[0].banner).to.have.property('format');
expect(bidRequest.imp[0].banner.format).to.be.eql([{w: 300, h: 250}, {w: 300, h: 200}]);
Expand Down Expand Up @@ -257,6 +288,27 @@ describe('Adkernel adapter', function () {
it('should have tagid', function () {
expect(bidRequests[0].imp[0]).to.have.property('tagid', 'ad-unit-1');
});

it('should have openrtb video impression parameters', function() {
expect(bidRequests[0].imp[0].video).to.have.property('api');
expect(bidRequests[0].imp[0].video.api).to.be.eql([1, 2]);
});
});

describe('multiformat request building', function () {
let _, bidRequests;
before(function () {
[_, bidRequests] = buildRequest([bid_multiformat]);
});
it('should contain single request', function () {
expect(bidRequests).to.have.length(1);
expect(bidRequests[0].imp).to.have.length(1);
});
it('should contain banner-only impression', function () {
expect(bidRequests[0].imp).to.have.length(1);
expect(bidRequests[0].imp[0]).to.have.property('banner');
expect(bidRequests[0].imp[0]).to.not.have.property('video');
});
});

describe('requests routing', function () {
Expand Down
Loading