Skip to content

Commit 664f440

Browse files
jsalisdluxemburg
authored andcommitted
Add banner support to Beachfront adapter (prebid#2117)
* Update Beachfront adapter for v1.0 * Revert Beachfront test endpoint * Add Beachfront markdown file * Add mediaTypes to example * Fix formatting * Remove descriptionUrl from bid response * Add banner support to Beachfront adapter * Fix bid response validation * Update display endpoint * Update display request and response to support multiple bids * Remove console log * Added display example to doc * Add support for dnt * add os version to bid request * Use size from bid response * Add secure to bid request
1 parent ad005a0 commit 664f440

File tree

3 files changed

+424
-132
lines changed

3 files changed

+424
-132
lines changed

modules/beachfrontBidAdapter.js

Lines changed: 147 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,196 @@
11
import * as utils from 'src/utils';
22
import { registerBidder } from 'src/adapters/bidderFactory';
3+
import { VIDEO, BANNER } from 'src/mediaTypes';
4+
import find from 'core-js/library/fn/array/find';
35

4-
export const ENDPOINT = '//reachms.bfmio.com/bid.json?exchange_id=';
6+
const ADAPTER_VERSION = '1.0';
7+
const ADAPTER_NAME = 'BFIO_PREBID';
8+
9+
export const VIDEO_ENDPOINT = '//reachms.bfmio.com/bid.json?exchange_id=';
10+
export const BANNER_ENDPOINT = '//display.bfmio.com/prebid_display';
511

612
export const spec = {
713
code: 'beachfront',
8-
supportedMediaTypes: ['video'],
14+
supportedMediaTypes: [ VIDEO, BANNER ],
915

1016
isBidRequestValid(bid) {
1117
return !!(bid && bid.params && bid.params.appId && bid.params.bidfloor);
1218
},
1319

1420
buildRequests(bids) {
15-
return bids.map(bid => {
16-
return {
21+
let requests = [];
22+
let videoBids = bids.filter(bid => isVideoBid(bid));
23+
let bannerBids = bids.filter(bid => !isVideoBid(bid));
24+
videoBids.forEach(bid => {
25+
requests.push({
1726
method: 'POST',
18-
url: ENDPOINT + bid.params.appId,
19-
data: createRequestParams(bid),
27+
url: VIDEO_ENDPOINT + bid.params.appId,
28+
data: createVideoRequestData(bid),
2029
bidRequest: bid
21-
};
30+
});
2231
});
32+
if (bannerBids.length) {
33+
requests.push({
34+
method: 'POST',
35+
url: BANNER_ENDPOINT,
36+
data: createBannerRequestData(bannerBids),
37+
bidRequest: bannerBids
38+
});
39+
}
40+
return requests;
2341
},
2442

2543
interpretResponse(response, { bidRequest }) {
2644
response = response.body;
27-
if (!response || !response.url || !response.bidPrice) {
28-
utils.logWarn(`No valid bids from ${spec.code} bidder`);
29-
return [];
45+
46+
if (isVideoBid(bidRequest)) {
47+
if (!response || !response.url || !response.bidPrice) {
48+
utils.logWarn(`No valid video bids from ${spec.code} bidder`);
49+
return [];
50+
}
51+
let size = getFirstSize(bidRequest);
52+
return {
53+
requestId: bidRequest.bidId,
54+
bidderCode: spec.code,
55+
vastUrl: response.url,
56+
cpm: response.bidPrice,
57+
width: size.w,
58+
height: size.h,
59+
creativeId: response.cmpId,
60+
mediaType: VIDEO,
61+
currency: 'USD',
62+
netRevenue: true,
63+
ttl: 300
64+
};
65+
} else {
66+
if (!response || !response.length) {
67+
utils.logWarn(`No valid banner bids from ${spec.code} bidder`);
68+
return [];
69+
}
70+
return response.map((bid) => {
71+
let request = find(bidRequest, req => req.adUnitCode === bid.slot);
72+
return {
73+
requestId: request.bidId,
74+
bidderCode: spec.code,
75+
ad: bid.adm,
76+
creativeId: bid.crid,
77+
cpm: bid.price,
78+
width: bid.w,
79+
height: bid.h,
80+
mediaType: BANNER,
81+
currency: 'USD',
82+
netRevenue: true,
83+
ttl: 300
84+
};
85+
});
3086
}
31-
let size = getSize(bidRequest.sizes);
32-
return {
33-
requestId: bidRequest.bidId,
34-
bidderCode: spec.code,
35-
cpm: response.bidPrice,
36-
creativeId: response.cmpId,
37-
vastUrl: response.url,
38-
width: size.width,
39-
height: size.height,
40-
mediaType: 'video',
41-
currency: 'USD',
42-
ttl: 300,
43-
netRevenue: true
44-
};
4587
}
4688
};
4789

48-
function getSize(sizes) {
49-
let parsedSizes = utils.parseSizesInput(sizes);
50-
let [ width, height ] = parsedSizes.length ? parsedSizes[0].split('x') : [];
51-
return {
52-
width: parseInt(width, 10) || undefined,
53-
height: parseInt(height, 10) || undefined
54-
};
90+
function getSizes(bid) {
91+
return utils.parseSizesInput(bid.sizes).map(size => {
92+
let [ width, height ] = size.split('x');
93+
return {
94+
w: parseInt(width, 10) || undefined,
95+
h: parseInt(height, 10) || undefined
96+
};
97+
});
98+
}
99+
100+
function getFirstSize(bid) {
101+
let sizes = getSizes(bid);
102+
return sizes.length ? sizes[0] : { w: undefined, h: undefined };
103+
}
104+
105+
function getOsVersion() {
106+
let clientStrings = [
107+
{ s: 'Android', r: /Android/ },
108+
{ s: 'iOS', r: /(iPhone|iPad|iPod)/ },
109+
{ s: 'Mac OS X', r: /Mac OS X/ },
110+
{ s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ },
111+
{ s: 'Linux', r: /(Linux|X11)/ },
112+
{ s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ },
113+
{ s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ },
114+
{ s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ },
115+
{ s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ },
116+
{ s: 'Windows Vista', r: /Windows NT 6.0/ },
117+
{ s: 'Windows Server 2003', r: /Windows NT 5.2/ },
118+
{ s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ },
119+
{ s: 'UNIX', r: /UNIX/ },
120+
{ s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ }
121+
];
122+
let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent));
123+
return cs ? cs.s : 'unknown';
55124
}
56125

57126
function isMobile() {
58-
return (/(ios|ipod|ipad|iphone|android)/i).test(global.navigator.userAgent);
127+
return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent);
59128
}
60129

61130
function isConnectedTV() {
62-
return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(global.navigator.userAgent);
131+
return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent);
132+
}
133+
134+
function getDoNotTrack() {
135+
return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes';
136+
}
137+
138+
function isVideoBid(bid) {
139+
return bid.mediaTypes && bid.mediaTypes.video;
63140
}
64141

65-
function createRequestParams(bid) {
66-
let size = getSize(bid.sizes);
142+
function createVideoRequestData(bid) {
143+
let size = getFirstSize(bid);
144+
let topLocation = utils.getTopWindowLocation();
67145
return {
68146
isPrebid: true,
69147
appId: bid.params.appId,
70148
domain: document.location.hostname,
149+
id: utils.getUniqueIdentifierStr(),
71150
imp: [{
72151
video: {
73-
w: size.width,
74-
h: size.height
152+
w: size.w,
153+
h: size.h
75154
},
76155
bidfloor: bid.params.bidfloor
77156
}],
78157
site: {
79-
page: utils.getTopWindowLocation().host
158+
page: topLocation.host
80159
},
81160
device: {
82-
ua: global.navigator.userAgent,
83-
devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2
161+
ua: navigator.userAgent,
162+
devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2,
163+
geo: {}
84164
},
85165
cur: ['USD']
86166
};
87167
}
88168

169+
function createBannerRequestData(bids) {
170+
let topLocation = utils.getTopWindowLocation();
171+
let referrer = utils.getTopWindowReferrer();
172+
let slots = bids.map(bid => {
173+
return {
174+
slot: bid.adUnitCode,
175+
id: bid.params.appId,
176+
bidfloor: bid.params.bidfloor,
177+
sizes: getSizes(bid)
178+
};
179+
});
180+
return {
181+
slots: slots,
182+
page: topLocation.href,
183+
domain: topLocation.hostname,
184+
search: topLocation.search,
185+
secure: topLocation.protocol === 'https:' ? 1 : 0,
186+
referrer: referrer,
187+
ua: navigator.userAgent,
188+
deviceOs: getOsVersion(),
189+
isMobile: isMobile() ? 1 : 0,
190+
dnt: getDoNotTrack() ? 1 : 0,
191+
adapterVersion: ADAPTER_VERSION,
192+
adapterName: ADAPTER_NAME
193+
};
194+
}
195+
89196
registerBidder(spec);

modules/beachfrontBidAdapter.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ Module that connects to Beachfront's demand sources
3030
}
3131
}
3232
]
33+
}, {
34+
code: 'test-banner',
35+
sizes: [300, 250],
36+
bids: [
37+
{
38+
bidder: 'beachfront',
39+
params: {
40+
bidfloor: 0.01,
41+
appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3'
42+
}
43+
}
44+
]
3345
}
3446
];
3547
```

0 commit comments

Comments
 (0)