Skip to content
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

Marsmedia Bid Adapter: add support for viewability, floor price module, COPPA & CCPA #6337

Merged
merged 33 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9a9bf04
Change publisherId to zoneId
vladi-mmg Dec 17, 2019
07f5f49
Remove comments
vladi-mmg Dec 17, 2019
154263e
Merge remote-tracking branch 'upstream/master'
vladi-mmg Dec 17, 2019
e5971a7
Merge remote-tracking branch 'upstream/master'
vladi-mmg Dec 18, 2019
c72847b
Merge remote-tracking branch 'upstream/master'
vladi-mmg Dec 19, 2019
b73b7e4
Fix unit test coverage
vladi-mmg Dec 19, 2019
309e247
Merge remote-tracking branch 'upstream/master'
vladi-mmg Mar 31, 2020
51bb539
fix request id bug
vladi-mmg Apr 2, 2020
cf174a4
Remove bid response default sizes
vladi-mmg Apr 5, 2020
7ab347b
Merge remote-tracking branch 'upstream/master'
vladi-mmg Apr 5, 2020
10ff1f9
Merge remote-tracking branch 'upstream/master'
vladi-mmg Apr 13, 2020
4ef0887
Change endpoint url
vladi-mmg Apr 13, 2020
67f9f58
Add unit test for vastXml
vladi-mmg Apr 13, 2020
e430e9e
Merge remote-tracking branch 'upstream/master'
vladi-mmg Apr 23, 2020
063fafb
Change end point
vladi-mmg Apr 23, 2020
b2b764a
Remove trailing-space
vladi-mmg Apr 23, 2020
b087206
Merge branch 'master' of https://github.com/prebid/Prebid.js
vladi-mmg Apr 27, 2020
ee4c472
Add onBidWon function
vladi-mmg Apr 28, 2020
18bb5af
Merge remote-tracking branch 'upstream/master'
vladi-mmg May 12, 2020
1fd57d2
Merge remote-tracking branch 'upstream/master'
vladi-mmg May 19, 2020
5b8e42c
New adapter - videofy
vladi-mmg May 19, 2020
0852882
Merge remote-tracking branch 'upstream/master'
vladi-mmg Jun 8, 2020
45e4213
Merge remote-tracking branch 'upstream/master'
vladi-mmg Jun 9, 2020
ad7b052
Marsmedia & Videofy - Add onTimeout onSetTargeting
vladi-mmg Jun 9, 2020
55cf4ba
Merge remote-tracking branch 'upstream/master'
vladi-mmg Jun 17, 2020
33ac444
Create sendbeacon function
vladi-mmg Jun 17, 2020
96ec104
Merge remote-tracking branch 'upstream/master'
vladi-mmg Jan 13, 2021
b3fdce3
Merge branch 'master' of https://github.com/prebid/Prebid.js
vladi-mmg Feb 3, 2021
625eb9c
Merge branch 'master' of https://github.com/prebid/Prebid.js
vladi-mmg Feb 7, 2021
8384af0
Merge branch 'master' of https://github.com/prebid/Prebid.js
vladi-mmg Feb 21, 2021
b01446d
- add viewability
vladi-mmg Feb 21, 2021
40be118
Merge branch 'master' of https://github.com/prebid/Prebid.js
vladi-mmg Mar 2, 2021
42704d6
remove unnecessary utils.getWindowTop()
vladi-mmg Mar 2, 2021
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
171 changes: 156 additions & 15 deletions modules/marsmediaBidAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import * as utils from '../src/utils.js';
import {registerBidder} from '../src/adapters/bidderFactory.js';
import { BANNER, VIDEO } from '../src/mediaTypes.js';
import {config} from '../src/config.js';

function MarsmediaAdapter() {
this.code = 'marsmedia';
Expand All @@ -16,7 +17,7 @@ function MarsmediaAdapter() {
let SUPPORTED_VIDEO_API = [1, 2, 5];
let slotsToBids = {};
let that = this;
let version = '2.3';
let version = '2.4';

this.isBidRequestValid = function (bid) {
return !!(bid.params && bid.params.zoneId);
Expand Down Expand Up @@ -53,6 +54,7 @@ function MarsmediaAdapter() {
if (!(impObj.banner || impObj.video)) {
continue;
}
impObj.bidfloor = _getFloor(BRs[i]);
impObj.ext = frameExt(BRs[i]);
impList.push(impObj);
}
Expand Down Expand Up @@ -153,9 +155,31 @@ function MarsmediaAdapter() {
}

function frameExt(bid) {
return {
bidder: {
zoneId: bid.params['zoneId']
if ((bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes)) {
let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes;
bidSizes = ((utils.isArray(bidSizes) && utils.isArray(bidSizes[0])) ? bidSizes : [bidSizes]);
bidSizes = bidSizes.filter(size => utils.isArray(size));
const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)}));

const element = document.getElementById(bid.adUnitCode);
const minSize = _getMinSize(processedSizes);
const viewabilityAmount = _isViewabilityMeasurable(element)
? _getViewability(element, utils.getWindowTop(), minSize)
: 'na';
const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount);

return {
bidder: {
zoneId: bid.params['zoneId']
},
viewability: viewabilityAmountRounded
}
} else {
return {
bidder: {
zoneId: bid.params['zoneId']
},
viewability: 'na'
}
}
}
Expand All @@ -180,12 +204,15 @@ function MarsmediaAdapter() {
}
};
if (BRs[0].schain) {
bid.source = {
'ext': {
'schain': BRs[0].schain
}
}
utils.deepSetValue(bid, 'source.ext.schain', BRs[0].schain);
}
if (bidderRequest.uspConsent) {
utils.deepSetValue(bid, 'regs.ext.us_privacy', bidderRequest.uspConsent)
}
if (config.getConfig('coppa') === true) {
utils.deepSetValue(bid, 'regs.coppa', config.getConfig('coppa') & 1)
}

return bid;
}

Expand Down Expand Up @@ -241,12 +268,6 @@ function MarsmediaAdapter() {
sendbeacon(bid, 20)
};

function sendbeacon(bid, type) {
const bidString = JSON.stringify(bid);
const encodedBuf = window.btoa(bidString);
utils.triggerPixel('https://ping-hqx-1.go2speed.media/notification/rtb/beacon/?bt=' + type + '&bid=3mhdom&hb_j=' + encodedBuf, null);
}

this.interpretResponse = function (serverResponse) {
let responses = serverResponse.body || [];
let bids = [];
Expand Down Expand Up @@ -295,6 +316,126 @@ function MarsmediaAdapter() {

return bids;
};

function sendbeacon(bid, type) {
const bidString = JSON.stringify(bid);
const encodedBuf = window.btoa(bidString);
utils.triggerPixel('https://ping-hqx-1.go2speed.media/notification/rtb/beacon/?bt=' + type + '&bid=3mhdom&hb_j=' + encodedBuf, null);
}

/**
* Gets bidfloor
* @param {Object} bid
* @returns {Number} floor
*/
function _getFloor (bid) {
const curMediaType = bid.mediaTypes.video ? 'video' : 'banner';
let floor = 0;

if (typeof bid.getFloor === 'function') {
const floorInfo = bid.getFloor({
currency: 'USD',
mediaType: curMediaType,
size: '*'
});

if (typeof floorInfo === 'object' &&
floorInfo.currency === 'USD' &&
!isNaN(parseFloat(floorInfo.floor))) {
floor = floorInfo.floor;
}
}

return floor;
}

function _getMinSize(sizes) {
return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min);
}

function _isViewabilityMeasurable(element) {
return !_isIframe() && element !== null;
}

function _isIframe() {
try {
return utils.getWindowSelf() !== utils.getWindowTop();
} catch (e) {
return true;
}
}

function _getViewability(element, topWin, { w, h } = {}) {
return utils.getWindowTop().document.visibilityState === 'visible'
vladi-mmg marked this conversation as resolved.
Show resolved Hide resolved
? _getPercentInView(element, topWin, { w, h })
: 0;
}

function _getPercentInView(element, topWin, { w, h } = {}) {
const elementBoundingBox = _getBoundingBox(element, { w, h });

const elementInViewBoundingBox = _getIntersectionOfRects([ {
left: 0,
top: 0,
right: topWin.innerWidth,
bottom: topWin.innerHeight
}, elementBoundingBox ]);

let elementInViewArea, elementTotalArea;

if (elementInViewBoundingBox !== null) {
// Some or all of the element is in view
elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height;
elementTotalArea = elementBoundingBox.width * elementBoundingBox.height;

return ((elementInViewArea / elementTotalArea) * 100);
}

return 0;
}

function _getBoundingBox(element, { w, h } = {}) {
let { width, height, left, top, right, bottom } = element.getBoundingClientRect();

if ((width === 0 || height === 0) && w && h) {
width = w;
height = h;
right = left + w;
bottom = top + h;
}

return { width, height, left, top, right, bottom };
}

function _getIntersectionOfRects(rects) {
const bbox = {
left: rects[0].left,
right: rects[0].right,
top: rects[0].top,
bottom: rects[0].bottom
};

for (let i = 1; i < rects.length; ++i) {
bbox.left = Math.max(bbox.left, rects[i].left);
bbox.right = Math.min(bbox.right, rects[i].right);

if (bbox.left >= bbox.right) {
return null;
}

bbox.top = Math.max(bbox.top, rects[i].top);
bbox.bottom = Math.min(bbox.bottom, rects[i].bottom);

if (bbox.top >= bbox.bottom) {
return null;
}
}

bbox.width = bbox.right - bbox.left;
bbox.height = bbox.bottom - bbox.top;

return bbox;
}
}

export const spec = new MarsmediaAdapter();
Expand Down
Loading