forked from prebid/Prebid.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgetintentBidAdapter.js
224 lines (201 loc) · 6.43 KB
/
getintentBidAdapter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
import {getBidIdParameter, isFn, isInteger} from '../src/utils.js';
import { registerBidder } from '../src/adapters/bidderFactory.js';
/**
* @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest
* @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid
*/
const BIDDER_CODE = 'getintent';
const IS_NET_REVENUE = true;
const BID_HOST = 'px.adhigh.net';
const BID_BANNER_PATH = '/rtb/direct_banner';
const BID_VIDEO_PATH = '/rtb/direct_vast';
const BID_RESPONSE_TTL_SEC = 360;
const FLOOR_PARAM = 'floor';
const CURRENCY_PARAM = 'cur';
const DEFAULT_CURRENCY = 'RUB';
const VIDEO_PROPERTIES = {
'protocols': 'protocols',
'mimes': 'mimes',
'min_dur': 'minduration',
'max_dur': 'maxduration',
'min_btr': 'minbitrate',
'max_btr': 'maxbitrate',
'vi_format': null,
'api': 'api',
'skippable': 'skip',
};
const SKIPPABLE_ALLOW = 'ALLOW';
const SKIPPABLE_NOT_ALLOW = 'NOT_ALLOW';
const OPTIONAL_PROPERTIES = [
'sid'
];
export const spec = {
code: BIDDER_CODE,
aliases: ['getintentAdapter'],
supportedMediaTypes: ['video', 'banner'],
/**
* Determines whether or not the given bid request is valid.
*
* @param {BidRequest} bid The bid to validate.
* @return {boolean} True if this is a valid bid, and false otherwise.
*/
isBidRequestValid: function(bid) {
return !!(bid && bid.params && bid.params.pid && bid.params.tid);
},
/**
* Make a server request from the list of BidRequests.
*
* @param {BidRequest[]} bidRequests - an array of bids.
* @return ServerRequest[]
*/
buildRequests: function(bidRequests) {
return bidRequests.map(bidRequest => {
let giBidRequest = buildGiBidRequest(bidRequest);
return {
method: 'GET',
url: buildUrl(giBidRequest),
data: giBidRequest,
};
});
},
/**
* Callback for bids, after the call to DSP completes.
* Parse the response from the server into a list of bids.
*
* @param {object} serverResponse A response from the GetIntent's server.
* @return {Bid[]} An array of bids which were nested inside the server.
*/
interpretResponse: function(serverResponse) {
let responseBody = serverResponse.body;
const bids = [];
if (responseBody && responseBody.no_bid !== 1) {
let size = parseSize(responseBody.size);
let bid = {
requestId: responseBody.bid_id,
ttl: BID_RESPONSE_TTL_SEC,
netRevenue: IS_NET_REVENUE,
currency: responseBody.currency,
creativeId: responseBody.creative_id,
cpm: responseBody.cpm,
width: size[0],
height: size[1],
meta: {
advertiserDomains: responseBody.adomain || [],
}
};
if (responseBody.vast_url) {
bid.mediaType = 'video';
bid.vastUrl = responseBody.vast_url;
} else {
bid.mediaType = 'banner';
bid.ad = responseBody.ad;
}
bids.push(bid);
}
return bids;
}
};
function buildUrl(bid) {
return 'https://' + BID_HOST + (bid.is_video ? BID_VIDEO_PATH : BID_BANNER_PATH);
}
/**
* Builds GI bid request from BidRequest.
*
* @param {BidRequest} bidRequest
* @return {object} GI bid request
*/
function buildGiBidRequest(bidRequest) {
let giBidRequest = {
bid_id: bidRequest.bidId,
pid: bidRequest.params.pid, // required
tid: bidRequest.params.tid, // required
known: bidRequest.params.known || 1,
is_video: bidRequest.mediaType === 'video',
resp_type: 'JSON',
provider: 'direct.prebidjs'
};
if (bidRequest.sizes) {
giBidRequest.size = produceSize(bidRequest.sizes);
}
const currency = getBidIdParameter(CURRENCY_PARAM, bidRequest.params);
const floorInfo = getBidFloor(bidRequest, currency);
if (floorInfo.floor) {
giBidRequest[FLOOR_PARAM] = floorInfo.floor;
}
if (floorInfo.currency) {
giBidRequest[CURRENCY_PARAM] = floorInfo.currency;
}
if (giBidRequest.is_video) {
addVideo(bidRequest.params.video, bidRequest.mediaTypes.video, giBidRequest);
}
addOptional(bidRequest.params, giBidRequest, OPTIONAL_PROPERTIES);
return giBidRequest;
}
function getBidFloor(bidRequest, currency) {
let floorInfo = {};
if (isFn(bidRequest.getFloor)) {
floorInfo = bidRequest.getFloor({
currency: currency || DEFAULT_CURRENCY,
mediaType: bidRequest.mediaType,
size: bidRequest.sizes || '*'
}) || {};
}
return {
floor: floorInfo.floor || bidRequest.params[FLOOR_PARAM] || 0,
currency: floorInfo.currency || currency || '',
};
}
function addVideo(videoParams, mediaTypesVideoParams, giBidRequest) {
videoParams = videoParams || {};
mediaTypesVideoParams = mediaTypesVideoParams || {};
for (let videoParam in VIDEO_PROPERTIES) {
let paramValue;
const mediaTypesVideoParam = VIDEO_PROPERTIES[videoParam];
if (videoParams.hasOwnProperty(videoParam)) {
paramValue = videoParams[videoParam];
} else if (mediaTypesVideoParam !== null && mediaTypesVideoParams.hasOwnProperty(mediaTypesVideoParam)) {
if (mediaTypesVideoParam === 'skip') {
paramValue = mediaTypesVideoParams[mediaTypesVideoParam] === 1 ? SKIPPABLE_ALLOW : SKIPPABLE_NOT_ALLOW;
} else {
paramValue = mediaTypesVideoParams[mediaTypesVideoParam];
}
}
if (typeof paramValue !== 'undefined') {
giBidRequest[videoParam] = Array.isArray(paramValue) ? paramValue.join(',') : paramValue;
}
}
}
function addOptional(params, request, props) {
for (let i = 0; i < props.length; i++) {
if (params.hasOwnProperty(props[i])) {
request[props[i]] = params[props[i]];
}
}
}
/**
* @param {String} s The string representing a size (e.g. "300x250").
* @return {Number[]} An array with two elements: [width, height] (e.g.: [300, 250]).
*/
function parseSize(s) {
return s.split('x').map(Number);
}
/**
* @param {Array} sizes An array of sizes/numbers to be joined into single string.
* May be an array (e.g. [300, 250]) or array of arrays (e.g. [[300, 250], [640, 480]].
* @return {String} The string with sizes, e.g. array of sizes [[50, 50], [80, 80]] becomes "50x50,80x80" string.
*/
function produceSize (sizes) {
function sizeToStr(s) {
if (Array.isArray(s) && s.length === 2 && isInteger(s[0]) && isInteger(s[1])) {
return s.join('x');
} else {
throw "Malformed parameter 'sizes'";
}
}
if (Array.isArray(sizes) && Array.isArray(sizes[0])) {
return sizes.map(sizeToStr).join(',');
} else {
return sizeToStr(sizes);
}
}
registerBidder(spec);