Skip to content

Commit

Permalink
Synacor media bidder updates: filter bad sizes & extra video paramete…
Browse files Browse the repository at this point in the history
…rs (prebid#3885)

* Synacor media bidder updates:
- Filter out 1x1 & 1x2 adsizes that we don't support
- Added a bunch of openrtb video params

* SynacormediaBidAdapter: Replace let with const

* SynacormediaBidAdapter: Replace let with const

* SynacormediaBidAdapter: Updated setValidVideoParams

Updated setValidVideoParams so that the length check works correctly.
  • Loading branch information
amuraco authored and sa1omon committed Nov 28, 2019
1 parent fe47224 commit 8e2715a
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 49 deletions.
99 changes: 58 additions & 41 deletions modules/synacormediaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import includes from 'core-js/library/fn/array/includes';

const BID_HOST = '//prebid.technoratimedia.com';
const USER_SYNC_HOST = '//ad-cdn.technoratimedia.com';
const VIDEO_PARAMS = [ 'minduration', 'maxduration' ];

const VIDEO_PARAMS = [ 'minduration', 'maxduration', 'startdelay', 'placement', 'linearity', 'mimes', 'protocols', 'api' ];
const BLOCKED_AD_SIZES = [
'1x1',
'1x2'
];
export const spec = {
code: 'synacormedia',
supportedMediaTypes: [ BANNER, VIDEO ],
Expand All @@ -19,15 +22,17 @@ export const spec = {
bid.mediaTypes.hasOwnProperty('video');
},
isBidRequestValid: function(bid) {
return !!(bid && bid.params && bid.params.placementId && bid.params.seatId);
const hasRequiredParams = bid && bid.params && bid.params.hasOwnProperty('placementId') && bid.params.hasOwnProperty('seatId');
const hasAdSizes = bid && getAdUnitSizes(bid).filter(size => BLOCKED_AD_SIZES.indexOf(size.join('x')) === -1).length > 0
return !!(hasRequiredParams && hasAdSizes);
},

buildRequests: function(validBidReqs, bidderRequest) {
if (!validBidReqs || !validBidReqs.length || !bidderRequest) {
return;
}
let refererInfo = bidderRequest.refererInfo;
let openRtbBidRequest = {
const refererInfo = bidderRequest.refererInfo;
const openRtbBidRequest = {
id: bidderRequest.auctionId,
site: {
domain: location.hostname,
Expand All @@ -40,15 +45,16 @@ export const spec = {
imp: []
};
let seatId = null;

validBidReqs.forEach((bid, i) => {
if (seatId && seatId !== bid.params.seatId) {
logWarn(`Synacormedia: there is an inconsistent seatId: ${bid.params.seatId} but only sending bid requests for ${seatId}, you should double check your configuration`);
return;
} else {
seatId = bid.params.seatId;
}
let placementId = bid.params.placementId;
let bidFloor = bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null;
const placementId = bid.params.placementId;
const bidFloor = bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null;
if (isNaN(bidFloor)) {
logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`);
}
Expand All @@ -57,34 +63,39 @@ export const spec = {
logWarn(`Synacormedia: there is an invalid POS: ${bid.params.pos}`);
pos = 0;
}
let videoOrBannerKey = this.isVideoBid(bid) ? 'video' : 'banner';
getAdUnitSizes(bid).forEach((size, i) => {
if (!size || size.length != 2) {
return;
}
let size0 = size[0];
let size1 = size[1];
let imp = {
id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`,
tagid: placementId
};
if (bidFloor !== null && !isNaN(bidFloor)) {
imp.bidfloor = bidFloor;
}
const videoOrBannerKey = this.isVideoBid(bid) ? 'video' : 'banner';
getAdUnitSizes(bid)
.filter(size => BLOCKED_AD_SIZES.indexOf(size.join('x')) === -1)
.forEach((size, i) => {
if (!size || size.length != 2) {
return;
}
const size0 = size[0];
const size1 = size[1];
const imp = {
id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`,
tagid: placementId
};
if (bidFloor !== null && !isNaN(bidFloor)) {
imp.bidfloor = bidFloor;
}

let videoOrBannerValue = {
w: size0,
h: size1,
pos
};
if (videoOrBannerKey === 'video' && bid.params.video) {
Object.keys(bid.params.video)
.filter(param => includes(VIDEO_PARAMS, param) && !isNaN(parseInt(bid.params.video[param], 10)))
.forEach(param => videoOrBannerValue[param] = parseInt(bid.params.video[param], 10));
}
imp[videoOrBannerKey] = videoOrBannerValue;
openRtbBidRequest.imp.push(imp);
});
const videoOrBannerValue = {
w: size0,
h: size1,
pos
};
if (videoOrBannerKey === 'video') {
if (bid.mediaTypes.video) {
this.setValidVideoParams(bid.mediaTypes.video, bid.params.video);
}
if (bid.params.video) {
this.setValidVideoParams(bid.params.video, videoOrBannerValue);
}
}
imp[videoOrBannerKey] = videoOrBannerValue;
openRtbBidRequest.imp.push(imp);
});
});

if (openRtbBidRequest.imp.length && seatId) {
Expand All @@ -99,8 +110,14 @@ export const spec = {
};
}
},

setValidVideoParams: function (sourceObj, destObj) {
Object.keys(sourceObj)
.filter(param => includes(VIDEO_PARAMS, param) && sourceObj[param] !== null && (!isNaN(parseInt(sourceObj[param], 10)) || !(sourceObj[param].length < 1)))
.forEach(param => destObj[param] = Array.isArray(sourceObj[param]) ? sourceObj[param] : parseInt(sourceObj[param], 10));
},
interpretResponse: function(serverResponse) {
var updateMacros = (bid, r) => {
const updateMacros = (bid, r) => {
return r ? r.replace(/\${AUCTION_PRICE}/g, bid.price) : r;
};

Expand All @@ -114,11 +131,11 @@ export const spec = {
if (id && seatbids) {
seatbids.forEach(seatbid => {
seatbid.bid.forEach(bid => {
let creative = updateMacros(bid, bid.adm);
let nurl = updateMacros(bid, bid.nurl);
let [, impType, impid, width, height] = bid.impid.match(/^([vb])(.*)-(.*)x(.*)$/);
let isVideo = impType == 'v';
let bidObj = {
const creative = updateMacros(bid, bid.adm);
const nurl = updateMacros(bid, bid.nurl);
const [, impType, impid, width, height] = bid.impid.match(/^([vb])(.*)-(.*)x(.*)$/);
const isVideo = impType == 'v';
const bidObj = {
requestId: impid,
adId: bid.id.replace(/~/g, '-'),
cpm: parseFloat(bid.price),
Expand All @@ -132,7 +149,7 @@ export const spec = {
ttl: 60
};
if (isVideo) {
let [, uuid] = nurl.match(/ID=([^&]*)&?/);
const [, uuid] = nurl.match(/ID=([^&]*)&?/);
bidObj.videoCacheKey = encodeURIComponent(uuid);
bidObj.vastUrl = nurl;
}
Expand Down
16 changes: 8 additions & 8 deletions modules/synacormediaBidAdapter.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,26 @@ https://track.technoratimedia.com/openrtb/tags?ID=%%PATTERN:hb_cache_id_synacorm
}]
},{
code: 'test-div2',
mediaType: {
mediaTypes: {
video: {
context: 'instream',
playerSizes: [
[300, 250]
],
context: 'instream',
playerSize: [[300, 250]],
}
},
bids: [{
bidder: "synacormedia",
params: {
seatId: "prebid",
placementId: "demo1"
placementId: "demo1",
bidfloor: 0.20,
pos: 1,
video: {
minduration: 15,
maxduration: 30
maxduration: 30,
startdelay: 1,
linearity: 1
}
}
}]
}];
}];
```
129 changes: 129 additions & 0 deletions test/spec/modules/synacormediaBidAdapter_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ describe('synacormediaBidAdapter ', function () {
let bid;
beforeEach(function () {
bid = {
sizes: [300, 250],
params: {
seatId: 'prebid',
placementId: '1234'
Expand All @@ -18,14 +19,26 @@ describe('synacormediaBidAdapter ', function () {
assert(spec.isBidRequestValid(bid));
});

it('should return false when sizes are missing', function () {
delete bid.sizes;
assert.isFalse(spec.isBidRequestValid(bid));
});

it('should return false when the only size is unwanted', function () {
bid.sizes = [[1, 1]];
assert.isFalse(spec.isBidRequestValid(bid));
});

it('should return false when seatId param is missing', function () {
delete bid.params.seatId;
assert.isFalse(spec.isBidRequestValid(bid));
});

it('should return false when placementId param is missing', function () {
delete bid.params.placementId;
assert.isFalse(spec.isBidRequestValid(bid));
});

it('should return false when params is missing or null', function () {
assert.isFalse(spec.isBidRequestValid({ params: null }));
assert.isFalse(spec.isBidRequestValid({}));
Expand Down Expand Up @@ -404,6 +417,122 @@ describe('synacormediaBidAdapter ', function () {
req = spec.buildRequests([validBidReqInvalidSize], bidderRequest);
assert.isUndefined(req);
});
it('should use all the video params in the impression request', function () {
let validBidRequestVideo = {
bidder: 'synacormedia',
params: {
seatId: 'prebid',
placementId: '1234',
video: {
minduration: 30,
maxduration: 45,
startdelay: 1,
linearity: 1,
placement: 1,
mimes: ['video/mp4'],
protocols: [1],
api: 1
}
},
mediaTypes: {
video: {
context: 'instream',
playerSize: [[ 640, 480 ]]
}
},
adUnitCode: 'video1',
transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a',
sizes: [[ 640, 480 ]],
bidId: '2624fabbb078e8',
bidderRequestId: '117954d20d7c9c',
auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706',
src: 'client',
bidRequestsCount: 1
};

let req = spec.buildRequests([validBidRequestVideo], bidderRequest);
expect(req).to.have.property('method', 'POST');
expect(req).to.have.property('url');
expect(req.url).to.contain('//prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$');
expect(req.data.id).to.equal('xyz123');
expect(req.data.imp).to.eql([
{
video: {
h: 480,
pos: 0,
w: 640,
minduration: 30,
maxduration: 45,
startdelay: 1,
linearity: 1,
placement: 1,
mimes: ['video/mp4'],
protocols: [1],
api: 1
},
id: 'v2624fabbb078e8-640x480',
tagid: '1234',
}
]);
});
it('should move any video params in the mediaTypes object to params.video object', function () {
let validBidRequestVideo = {
bidder: 'synacormedia',
params: {
seatId: 'prebid',
placementId: '1234',
video: {
minduration: 30,
maxduration: 45,
protocols: [1],
api: 1
}
},
mediaTypes: {
video: {
context: 'instream',
playerSize: [[ 640, 480 ]],
startdelay: 1,
linearity: 1,
placement: 1,
mimes: ['video/mp4']
}
},
adUnitCode: 'video1',
transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a',
sizes: [[ 640, 480 ]],
bidId: '2624fabbb078e8',
bidderRequestId: '117954d20d7c9c',
auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706',
src: 'client',
bidRequestsCount: 1
};

let req = spec.buildRequests([validBidRequestVideo], bidderRequest);
expect(req).to.have.property('method', 'POST');
expect(req).to.have.property('url');
expect(req.url).to.contain('//prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$');
expect(req.data.id).to.equal('xyz123');
expect(req.data.imp).to.eql([
{
video: {
h: 480,
pos: 0,
w: 640,
minduration: 30,
maxduration: 45,
startdelay: 1,
linearity: 1,
placement: 1,
mimes: ['video/mp4'],
protocols: [1],
api: 1
},
id: 'v2624fabbb078e8-640x480',
tagid: '1234',
}
]);
});
});

describe('interpretResponse', function () {
Expand Down

0 comments on commit 8e2715a

Please sign in to comment.