Skip to content

Commit 381d885

Browse files
GeneGeniesa1omon
authored andcommitted
add viewdeosDX whitelabel (prebid#4231)
* add viewdeosDX hitelabel * Fixed tests and support for sizes * Fix strings * Fix strings * remove only * Fix tests * fix codereview * Fix test + Code review * code review + tests
1 parent 02df81f commit 381d885

File tree

3 files changed

+611
-0
lines changed

3 files changed

+611
-0
lines changed

modules/viewdeosDXBidAdapter.js

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
import * as utils from '../src/utils';
2+
import {registerBidder} from '../src/adapters/bidderFactory';
3+
import {VIDEO, BANNER} from '../src/mediaTypes';
4+
import {Renderer} from '../src/Renderer';
5+
import findIndex from 'core-js/library/fn/array/find-index';
6+
7+
const URL = '//hb.sync.viewdeos.com/auction/';
8+
const OUTSTREAM_SRC = '//player.sync.viewdeos.com/outstream-unit/2.01/outstream.min.js';
9+
const BIDDER_CODE = 'viewdeosDX';
10+
const OUTSTREAM = 'outstream';
11+
const DISPLAY = 'display';
12+
13+
export const spec = {
14+
code: BIDDER_CODE,
15+
aliases: ['viewdeos'],
16+
supportedMediaTypes: [VIDEO, BANNER],
17+
isBidRequestValid: function (bid) {
18+
return !!utils.deepAccess(bid, 'params.aid');
19+
},
20+
getUserSyncs: function (syncOptions, serverResponses) {
21+
const syncs = [];
22+
23+
function addSyncs(bid) {
24+
const uris = bid.cookieURLs;
25+
const types = bid.cookieURLSTypes || [];
26+
27+
if (Array.isArray(uris)) {
28+
uris.forEach((uri, i) => {
29+
const type = types[i] || 'image';
30+
31+
if ((!syncOptions.pixelEnabled && type === 'image') ||
32+
(!syncOptions.iframeEnabled && type === 'iframe')) {
33+
return;
34+
}
35+
36+
syncs.push({
37+
type: type,
38+
url: uri
39+
})
40+
})
41+
}
42+
}
43+
44+
if (syncOptions.pixelEnabled || syncOptions.iframeEnabled) {
45+
utils.isArray(serverResponses) && serverResponses.forEach((response) => {
46+
if (response.body) {
47+
if (utils.isArray(response.body)) {
48+
response.body.forEach(b => {
49+
addSyncs(b);
50+
})
51+
} else {
52+
addSyncs(response.body)
53+
}
54+
}
55+
})
56+
}
57+
return syncs;
58+
},
59+
/**
60+
* Make a server request from the list of BidRequests
61+
* @param bidRequests
62+
* @param bidderRequest
63+
*/
64+
buildRequests: function (bidRequests, bidderRequest) {
65+
return {
66+
data: bidToTag(bidRequests, bidderRequest),
67+
bidderRequest,
68+
method: 'GET',
69+
url: URL
70+
};
71+
},
72+
73+
/**
74+
* Unpack the response from the server into a list of bids
75+
* @param serverResponse
76+
* @param bidderRequest
77+
* @return {Bid[]} An array of bids which were nested inside the server
78+
*/
79+
interpretResponse: function (serverResponse, {bidderRequest}) {
80+
serverResponse = serverResponse.body;
81+
let bids = [];
82+
83+
if (!utils.isArray(serverResponse)) {
84+
return parseRTBResponse(serverResponse, bidderRequest);
85+
}
86+
87+
serverResponse.forEach(serverBidResponse => {
88+
bids = utils.flatten(bids, parseRTBResponse(serverBidResponse, bidderRequest));
89+
});
90+
91+
return bids;
92+
}
93+
};
94+
95+
function parseRTBResponse(serverResponse, bidderRequest) {
96+
const isInvalidValidResp = !serverResponse || !utils.isArray(serverResponse.bids);
97+
98+
const bids = [];
99+
100+
if (isInvalidValidResp) {
101+
const extMessage = serverResponse && serverResponse.ext && serverResponse.ext.message ? `: ${serverResponse.ext.message}` : '';
102+
const errorMessage = `in response for ${bidderRequest.bidderCode} adapter ${extMessage}`;
103+
104+
utils.logError(errorMessage);
105+
106+
return bids;
107+
}
108+
109+
serverResponse.bids.forEach(serverBid => {
110+
const requestId = findIndex(bidderRequest.bids, (bidRequest) => {
111+
return bidRequest.bidId === serverBid.requestId;
112+
});
113+
114+
if (serverBid.cpm !== 0 && requestId !== -1) {
115+
const bid = createBid(serverBid, getMediaType(bidderRequest.bids[requestId]));
116+
117+
bids.push(bid);
118+
}
119+
});
120+
121+
return bids;
122+
}
123+
124+
function bidToTag(bidRequests, bidderRequest) {
125+
const tag = {
126+
domain: utils.deepAccess(bidderRequest, 'refererInfo.referer')
127+
};
128+
129+
if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) {
130+
tag.gdpr = 1;
131+
tag.gdpr_consent = utils.deepAccess(bidderRequest, 'gdprConsent.consentString');
132+
}
133+
134+
for (let i = 0, length = bidRequests.length; i < length; i++) {
135+
Object.assign(tag, prepareRTBRequestParams(i, bidRequests[i]));
136+
}
137+
138+
return tag;
139+
}
140+
141+
/**
142+
* Parse mediaType
143+
* @param _index {number}
144+
* @param bid {object}
145+
* @returns {object}
146+
*/
147+
function prepareRTBRequestParams(_index, bid) {
148+
const mediaType = utils.deepAccess(bid, 'mediaTypes.video') ? VIDEO : DISPLAY;
149+
const index = !_index ? '' : `${_index + 1}`;
150+
const sizes = bid.sizes ? bid.sizes : (mediaType === VIDEO ? utils.deepAccess(bid, 'mediaTypes.video.playerSize') : utils.deepAccess(bid, 'mediaTypes.banner.sizes'));
151+
return {
152+
['callbackId' + index]: bid.bidId,
153+
['aid' + index]: bid.params.aid,
154+
['ad_type' + index]: mediaType,
155+
['sizes' + index]: utils.parseSizesInput(sizes).join()
156+
};
157+
}
158+
159+
/**
160+
* Prepare all parameters for request
161+
* @param bidderRequest {object}
162+
* @returns {object}
163+
*/
164+
function getMediaType(bidderRequest) {
165+
const videoMediaType = utils.deepAccess(bidderRequest, 'mediaTypes.video');
166+
const context = utils.deepAccess(bidderRequest, 'mediaTypes.video.context');
167+
168+
return !videoMediaType ? DISPLAY : context === OUTSTREAM ? OUTSTREAM : VIDEO;
169+
}
170+
171+
/**
172+
* Configure new bid by response
173+
* @param bidResponse {object}
174+
* @param mediaType {Object}
175+
* @returns {object}
176+
*/
177+
function createBid(bidResponse, mediaType) {
178+
const bid = {
179+
requestId: bidResponse.requestId,
180+
creativeId: bidResponse.cmpId,
181+
height: bidResponse.height,
182+
currency: bidResponse.cur,
183+
width: bidResponse.width,
184+
cpm: bidResponse.cpm,
185+
netRevenue: true,
186+
mediaType,
187+
ttl: 3600
188+
};
189+
190+
if (mediaType === DISPLAY) {
191+
return Object.assign(bid, {
192+
ad: bidResponse.ad
193+
});
194+
}
195+
196+
Object.assign(bid, {
197+
vastUrl: bidResponse.vastUrl
198+
});
199+
200+
if (mediaType === OUTSTREAM) {
201+
Object.assign(bid, {
202+
mediaType: 'video',
203+
adResponse: bidResponse,
204+
renderer: newRenderer(bidResponse.requestId)
205+
});
206+
}
207+
208+
return bid;
209+
}
210+
211+
/**
212+
* Create renderer
213+
* @param requestId
214+
* @returns {*}
215+
*/
216+
function newRenderer(requestId) {
217+
const renderer = Renderer.install({
218+
id: requestId,
219+
url: OUTSTREAM_SRC,
220+
loaded: false
221+
});
222+
223+
renderer.setRender(outstreamRender);
224+
225+
return renderer;
226+
}
227+
228+
/**
229+
* Initialise outstream
230+
* @param bid
231+
*/
232+
function outstreamRender(bid) {
233+
bid.renderer.push(() => {
234+
window.VOutstreamAPI.initOutstreams([{
235+
width: bid.width,
236+
height: bid.height,
237+
vastUrl: bid.vastUrl,
238+
elId: bid.adUnitCode
239+
}]);
240+
});
241+
}
242+
243+
registerBidder(spec);

modules/viewdeosDXBidAdapter.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Overview
2+
3+
**Module Name**: Viewdeos DX Bidder Adapter
4+
**Module Type**: Bidder Adapter
5+
6+
# Description
7+
8+
Get access to multiple demand partners across Viewdeos and maximize your yield with Viewdeos header bidding adapter.
9+
10+
# Test Parameters
11+
```
12+
var adUnits = [
13+
14+
// Video instream adUnit
15+
{
16+
code: 'div-test-div',
17+
sizes: [[640, 480]],
18+
mediaTypes: {
19+
video: {
20+
context: 'instream'
21+
}
22+
},
23+
bids: [{
24+
bidder: 'viewdeosDX',
25+
params: {
26+
aid: 331133
27+
}
28+
}]
29+
},
30+
31+
// Video outstream adUnit
32+
{
33+
code: 'outstream-test-div',
34+
sizes: [[640, 480]],
35+
mediaTypes: {
36+
video: {
37+
context: 'outstream'
38+
}
39+
},
40+
bids: [{
41+
bidder: 'viewdeosDX',
42+
params: {
43+
aid: 331133
44+
}
45+
}]
46+
},
47+
48+
// Banner adUnit
49+
{
50+
code: 'div-test-div',
51+
sizes: [[300, 250]],
52+
bids: [{
53+
bidder: 'viewdeosDX',
54+
params: {
55+
aid: 350975
56+
}
57+
}]
58+
}
59+
];
60+
```

0 commit comments

Comments
 (0)