Skip to content

Commit 34227c8

Browse files
vladi-mmgMike Chowla
authored and
Mike Chowla
committed
Change publisherId to zoneId (#4619)
* Change publisherId to zoneId Add gdpr Add supply chain Add video media type * Remove comments * Fix unit test coverage
1 parent 4b80ae3 commit 34227c8

File tree

3 files changed

+837
-231
lines changed

3 files changed

+837
-231
lines changed

modules/marsmediaBidAdapter.js

+245-106
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,269 @@
1+
'use strict';
2+
13
import * as utils from '../src/utils';
24
import {registerBidder} from '../src/adapters/bidderFactory';
3-
const BIDDER_CODE = 'marsmedia';
5+
import { BANNER, VIDEO } from '../src/mediaTypes';
46

5-
function getDomain() {
6-
if (!utils.inIframe()) {
7-
return window.location.hostname
8-
}
9-
let origins = window.document.location.ancestorOrigins
10-
if (origins && origins.length > 0) {
11-
return origins[origins.length - 1]
12-
}
13-
}
7+
function MarsmediaAdapter() {
8+
this.code = 'marsmedia';
9+
this.aliases = ['mars'];
10+
this.supportedMediaTypes = [VIDEO, BANNER];
11+
12+
let SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6];
13+
let SUPPORTED_VIDEO_MIMES = ['video/mp4'];
14+
let SUPPORTED_VIDEO_PLAYBACK_METHODS = [1, 2, 3, 4];
15+
let SUPPORTED_VIDEO_DELIVERY = [1];
16+
let SUPPORTED_VIDEO_API = [1, 2, 5];
17+
let slotsToBids = {};
18+
let that = this;
19+
let version = '2.1';
1420

15-
export const spec = {
16-
code: BIDDER_CODE,
17-
aliases: ['mars'],
18-
isBidRequestValid: function(bid) {
19-
return (bid.params.publisherID !== null);
20-
},
21-
buildRequests: function(validBidRequests, bidderRequest) {
22-
try {
23-
let protocol = (window.location.protocol === 'https:');
24-
const parse = getSize(validBidRequests[0].sizes);
25-
const publisherId = validBidRequests[0].params.publisherID;
26-
const payload = {
27-
id: validBidRequests[0].bidId,
28-
cur: ['USD'],
29-
30-
language: window.navigator.userLanguage || window.navigator.language,
31-
site: {
32-
id: publisherId,
33-
domain: getDomain(),
34-
page: document.URL,
35-
ref: document.referrer,
36-
publisher: {
37-
id: publisherId,
38-
domain: getDomain()
39-
}
40-
},
41-
imp: [{
42-
id: utils.getUniqueIdentifierStr(),
43-
banner: {
44-
w: parse.width,
45-
h: parse.height,
46-
secure: protocol
47-
},
48-
bidfloor: parseFloat(validBidRequests[0].params.floor) > 0 ? validBidRequests[0].params.floor : 0
49-
}],
50-
device: {
51-
ua: navigator.userAgent
52-
},
53-
user: {
54-
id: publisherId
55-
},
56-
publisher: {
57-
id: publisherId,
58-
domain: getDomain()
21+
this.isBidRequestValid = function (bid) {
22+
return !!(bid.params && bid.params.zoneId);
23+
};
24+
25+
this.getUserSyncs = function (syncOptions, responses, gdprConsent) {
26+
return [];
27+
};
28+
29+
function frameImp(BRs, bidderRequest) {
30+
var impList = [];
31+
var isSecure = 0;
32+
if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.stack.length) {
33+
// clever trick to get the protocol
34+
var el = document.createElement('a');
35+
el.href = bidderRequest.refererInfo.stack[0];
36+
isSecure = (el.protocol == 'https:') ? 1 : 0;
37+
}
38+
for (var i = 0; i < BRs.length; i++) {
39+
slotsToBids[BRs[i].adUnitCode] = BRs[i];
40+
var impObj = {};
41+
impObj.id = BRs[i].adUnitCode;
42+
impObj.secure = isSecure;
43+
44+
if (utils.deepAccess(BRs[i], 'mediaTypes.banner') || utils.deepAccess(BRs[i], 'mediaType') === 'banner') {
45+
let banner = frameBanner(BRs[i]);
46+
if (banner) {
47+
impObj.banner = banner;
5948
}
60-
};
49+
}
50+
if (utils.deepAccess(BRs[i], 'mediaTypes.video') || utils.deepAccess(BRs[i], 'mediaType') === 'video') {
51+
impObj.video = frameVideo(BRs[i]);
52+
}
53+
if (!(impObj.banner || impObj.video)) {
54+
continue;
55+
}
56+
impObj.ext = frameExt(BRs[i]);
57+
impList.push(impObj);
58+
}
59+
return impList;
60+
}
6161

62-
if (bidderRequest && bidderRequest.gdprConsent) {
63-
payload.gdpr = {
64-
applies: bidderRequest.gdprConsent.gdprApplies,
65-
consent: bidderRequest.gdprConsent.consentString
66-
};
62+
function frameSite(bidderRequest) {
63+
var site = {
64+
domain: '',
65+
page: '',
66+
ref: ''
67+
}
68+
if (bidderRequest && bidderRequest.refererInfo) {
69+
var ri = bidderRequest.refererInfo;
70+
site.ref = ri.referer;
71+
72+
if (ri.stack.length) {
73+
site.page = ri.stack[ri.stack.length - 1];
74+
75+
// clever trick to get the domain
76+
var el = document.createElement('a');
77+
el.href = ri.stack[0];
78+
site.domain = el.hostname;
6779
}
80+
}
81+
return site;
82+
}
83+
84+
function frameDevice() {
85+
return {
86+
ua: navigator.userAgent,
87+
ip: '', // Empty Ip string is required, server gets the ip from HTTP header
88+
dnt: utils.getDNT() ? 1 : 0,
89+
}
90+
}
91+
92+
function getValidSizeSet(dimensionList) {
93+
let w = parseInt(dimensionList[0]);
94+
let h = parseInt(dimensionList[1]);
95+
// clever check for NaN
96+
if (! (w !== w || h !== h)) { // eslint-disable-line
97+
return [w, h];
98+
}
99+
return false;
100+
}
68101

102+
function frameBanner(adUnit) {
103+
// adUnit.sizes is scheduled to be deprecated, continue its support but prefer adUnit.mediaTypes.banner
104+
var sizeList = adUnit.sizes;
105+
if (adUnit.mediaTypes && adUnit.mediaTypes.banner) {
106+
sizeList = adUnit.mediaTypes.banner.sizes;
107+
}
108+
var sizeStringList = utils.parseSizesInput(sizeList);
109+
var format = [];
110+
sizeStringList.forEach(function(size) {
111+
if (size) {
112+
var dimensionList = getValidSizeSet(size.split('x'));
113+
if (dimensionList) {
114+
format.push({
115+
'w': dimensionList[0],
116+
'h': dimensionList[1],
117+
});
118+
}
119+
}
120+
});
121+
if (format.length) {
69122
return {
70-
method: 'POST',
71-
url: 'https://bid306.rtbsrv.com/bidder/?bid=3mhdom',
72-
data: JSON.stringify(payload)
123+
'format': format
73124
};
74-
} catch (e) {
75-
utils.logError(e, {validBidRequests, bidderRequest});
76-
}
77-
},
78-
interpretResponse: function(serverResponse, bidRequest) {
79-
const bidResponses = [];
80-
let res = serverResponse.body;
81-
if (!res) {
82-
return []
83-
}
84-
85-
for (let x = 0; x < res.seatbid.length; x++) {
86-
var bidAd = res.seatbid[x].bid[0];
87-
88-
bidResponses.push({
89-
requestId: res.id,
90-
cpm: Number(bidAd.price),
91-
width: bidAd.w,
92-
height: bidAd.h,
93-
ad: bidAd.adm,
94-
ttl: 60,
95-
creativeId: bidAd.cid,
96-
netRevenue: true,
97-
currency: 'USD'
98-
})
99125
}
100126

101-
return bidResponses;
102-
},
103-
getUserSyncs: function(syncOptions, serverResponses) {
104-
return [];
127+
return false;
105128
}
106-
};
107129

108-
function getSize(requestSizes) {
109-
const parsed = {};
110-
const size = utils.parseSizesInput(requestSizes)[0];
130+
function frameVideo(bid) {
131+
var size = [];
132+
if (utils.deepAccess(bid, 'mediaTypes.video.playerSize')) {
133+
var dimensionSet = bid.mediaTypes.video.playerSize;
134+
if (utils.isArray(bid.mediaTypes.video.playerSize[0])) {
135+
dimensionSet = bid.mediaTypes.video.playerSize[0];
136+
}
137+
var validSize = getValidSizeSet(dimensionSet)
138+
if (validSize) {
139+
size = validSize;
140+
}
141+
}
142+
return {
143+
mimes: utils.deepAccess(bid, 'mediaTypes.video.mimes') || SUPPORTED_VIDEO_MIMES,
144+
protocols: utils.deepAccess(bid, 'mediaTypes.video.protocols') || SUPPORTED_VIDEO_PROTOCOLS,
145+
w: size[0],
146+
h: size[1],
147+
startdelay: utils.deepAccess(bid, 'mediaTypes.video.startdelay') || 0,
148+
skip: utils.deepAccess(bid, 'mediaTypes.video.skip') || 0,
149+
playbackmethod: utils.deepAccess(bid, 'mediaTypes.video.playbackmethod') || SUPPORTED_VIDEO_PLAYBACK_METHODS,
150+
delivery: utils.deepAccess(bid, 'mediaTypes.video.delivery') || SUPPORTED_VIDEO_DELIVERY,
151+
api: utils.deepAccess(bid, 'mediaTypes.video.api') || SUPPORTED_VIDEO_API,
152+
}
153+
}
111154

112-
if (typeof size !== 'string') {
113-
return parsed;
155+
function frameExt(bid) {
156+
return {
157+
bidder: {
158+
zoneId: bid.params['zoneId']
159+
}
160+
}
114161
}
115162

116-
const parsedSize = size.toUpperCase().split('X');
117-
const width = parseInt(parsedSize[0], 10);
118-
if (width) {
119-
parsed.width = width;
163+
function frameBid(BRs, bidderRequest) {
164+
let bid = {
165+
id: BRs[0].bidderRequestId,
166+
imp: frameImp(BRs, bidderRequest),
167+
site: frameSite(bidderRequest),
168+
device: frameDevice(),
169+
user: {
170+
ext: {
171+
consent: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? bidderRequest.gdprConsent.consentString : ''
172+
}
173+
},
174+
at: 1,
175+
tmax: 1000,
176+
regs: {
177+
ext: {
178+
gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false
179+
}
180+
}
181+
};
182+
if (BRs[0].schain) {
183+
bid.source = {
184+
'ext': {
185+
'schain': BRs[0].schain
186+
}
187+
}
188+
}
189+
return bid;
120190
}
121191

122-
const height = parseInt(parsedSize[1], 10);
123-
if (height) {
124-
parsed.height = height;
192+
function getFirstParam(key, validBidRequests) {
193+
for (let i = 0; i < validBidRequests.length; i++) {
194+
if (validBidRequests[i].params && validBidRequests[i].params[key]) {
195+
return validBidRequests[i].params[key];
196+
}
197+
}
125198
}
126199

127-
return parsed;
200+
this.buildRequests = function (BRs, bidderRequest) {
201+
let fallbackZoneId = getFirstParam('zoneId', BRs);
202+
if (fallbackZoneId === undefined || BRs.length < 1) {
203+
return [];
204+
}
205+
206+
var uri = 'https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId;
207+
208+
var fat = /(^v|(\.0)+$)/gi;
209+
var prebidVersion = '$prebid.version$';
210+
uri += '&hbv=' + prebidVersion.replace(fat, '') + ',' + version.replace(fat, '');
211+
212+
var bidRequest = frameBid(BRs, bidderRequest);
213+
if (!bidRequest.imp.length) {
214+
return {};
215+
}
216+
217+
return {
218+
method: 'POST',
219+
url: uri,
220+
data: JSON.stringify(bidRequest)
221+
};
222+
};
223+
224+
this.interpretResponse = function (serverResponse) {
225+
let responses = serverResponse.body || [];
226+
let bids = [];
227+
let i = 0;
228+
229+
if (responses.seatbid) {
230+
let temp = [];
231+
for (i = 0; i < responses.seatbid.length; i++) {
232+
for (let j = 0; j < responses.seatbid[i].bid.length; j++) {
233+
temp.push(responses.seatbid[i].bid[j]);
234+
}
235+
}
236+
responses = temp;
237+
}
238+
239+
for (i = 0; i < responses.length; i++) {
240+
let bid = responses[i];
241+
let bidRequest = slotsToBids[bid.impid];
242+
let bidResponse = {
243+
requestId: bidRequest.id,
244+
bidderCode: that.code,
245+
cpm: parseFloat(bid.price),
246+
width: bid.w,
247+
height: bid.h,
248+
creativeId: bid.crid,
249+
currency: 'USD',
250+
netRevenue: true,
251+
ttl: 350
252+
};
253+
254+
if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) {
255+
bidResponse.vastUrl = bid.adm;
256+
bidResponse.mediaType = 'video';
257+
bidResponse.ttl = 600;
258+
} else {
259+
bidResponse.ad = bid.adm;
260+
}
261+
bids.push(bidResponse);
262+
}
263+
264+
return bids;
265+
};
128266
}
129267

268+
export const spec = new MarsmediaAdapter();
130269
registerBidder(spec);

0 commit comments

Comments
 (0)