prebid.js 5.16.0 → 5.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/.devcontainer/Dockerfile +11 -0
  2. package/.devcontainer/devcontainer.json +27 -0
  3. package/.devcontainer/postCreate.sh +6 -0
  4. package/browsers.json +1 -0
  5. package/integrationExamples/gpt/akamaidap_segments_example.html +132 -0
  6. package/modules/.submodules.json +1 -0
  7. package/modules/adfBidAdapter.js +21 -16
  8. package/modules/adgenerationBidAdapter.js +28 -4
  9. package/modules/adkernelBidAdapter.js +3 -1
  10. package/modules/admixerBidAdapter.js +11 -0
  11. package/modules/adnuntiusBidAdapter.js +1 -0
  12. package/modules/adtelligentBidAdapter.js +2 -1
  13. package/modules/airgridRtdProvider.js +1 -1
  14. package/modules/akamaiDapRtdProvider.js +474 -0
  15. package/modules/akamaiDapRtdProvider.md +47 -0
  16. package/modules/aolBidAdapter.js +2 -1
  17. package/modules/appnexusBidAdapter.js +5 -3
  18. package/modules/atsAnalyticsAdapter.js +89 -63
  19. package/modules/atsAnalyticsAdapter.md +1 -0
  20. package/modules/betweenBidAdapter.js +20 -3
  21. package/modules/bliinkBidAdapter.js +58 -32
  22. package/modules/bliinkBidAdapter.md +29 -6
  23. package/modules/browsiRtdProvider.js +106 -18
  24. package/modules/cleanioRtdProvider.js +192 -0
  25. package/modules/cleanioRtdProvider.md +59 -0
  26. package/modules/codefuelBidAdapter.js +183 -0
  27. package/modules/codefuelBidAdapter.md +111 -0
  28. package/modules/connectIdSystem.js +104 -0
  29. package/modules/connectIdSystem.md +33 -0
  30. package/modules/cwireBidAdapter.js +272 -0
  31. package/modules/cwireBidAdapter.md +43 -0
  32. package/modules/deepintentBidAdapter.js +106 -9
  33. package/modules/deepintentBidAdapter.md +36 -1
  34. package/modules/deltaprojectsBidAdapter.js +252 -0
  35. package/modules/deltaprojectsBidAdapter.md +32 -0
  36. package/modules/dgkeywordRtdProvider.js +0 -1
  37. package/modules/engageyaBidAdapter.js +157 -0
  38. package/modules/glimpseBidAdapter.js +160 -48
  39. package/modules/glimpseBidAdapter.md +11 -74
  40. package/modules/gridBidAdapter.js +1 -0
  41. package/modules/gridNMBidAdapter.js +7 -6
  42. package/modules/gumgumBidAdapter.js +16 -2
  43. package/modules/iasRtdProvider.js +83 -67
  44. package/modules/inskinBidAdapter.js +7 -3
  45. package/modules/ixBidAdapter.js +8 -1
  46. package/modules/jixieBidAdapter.js +8 -2
  47. package/modules/justpremiumBidAdapter.js +6 -1
  48. package/modules/kargoBidAdapter.js +14 -7
  49. package/modules/kargoBidAdapter.md +20 -0
  50. package/modules/limelightDigitalBidAdapter.js +22 -2
  51. package/modules/livewrappedAnalyticsAdapter.js +53 -3
  52. package/modules/mediakeysBidAdapter.js +405 -14
  53. package/modules/mediakeysBidAdapter.md +108 -0
  54. package/modules/multibid/index.js +3 -3
  55. package/modules/mytargetBidAdapter.js +112 -0
  56. package/modules/nativoBidAdapter.js +48 -29
  57. package/modules/nativoBidAdapter.md +0 -1
  58. package/modules/nextMillenniumBidAdapter.js +12 -3
  59. package/modules/nextrollBidAdapter.js +375 -0
  60. package/modules/nobidBidAdapter.js +2 -1
  61. package/modules/oguryBidAdapter.js +36 -7
  62. package/modules/openxBidAdapter.js +34 -22
  63. package/modules/operaadsBidAdapter.js +21 -1
  64. package/modules/otmBidAdapter.js +146 -0
  65. package/modules/otmBidAdapter.md +27 -26
  66. package/modules/outbrainBidAdapter.js +5 -0
  67. package/modules/pixfutureBidAdapter.js +24 -4
  68. package/modules/pixfutureBidAdapter.md +127 -0
  69. package/modules/playwireBidAdapter.md +61 -0
  70. package/modules/prebidServerBidAdapter/index.js +1 -1
  71. package/modules/proxistoreBidAdapter.js +4 -6
  72. package/modules/publinkIdSystem.js +17 -7
  73. package/modules/publinkIdSystem.md +7 -2
  74. package/modules/pubmaticBidAdapter.js +22 -6
  75. package/modules/pubmaticBidAdapter.md +1 -1
  76. package/modules/relaidoBidAdapter.js +8 -2
  77. package/modules/rtdModule/index.js +2 -2
  78. package/modules/sharethroughBidAdapter.js +12 -19
  79. package/modules/slimcutBidAdapter.js +121 -0
  80. package/modules/sonobiBidAdapter.js +7 -0
  81. package/modules/sortableBidAdapter.js +1 -0
  82. package/modules/spotxBidAdapter.js +15 -1
  83. package/modules/sspBCBidAdapter.js +207 -12
  84. package/modules/sspBCBidAdapter.md +1 -1
  85. package/modules/talkadsBidAdapter.js +129 -0
  86. package/modules/talkadsBidAdapter.md +60 -0
  87. package/modules/tappxBidAdapter.js +6 -5
  88. package/modules/teadsBidAdapter.js +3 -0
  89. package/modules/tripleliftBidAdapter.js +22 -5
  90. package/modules/trustxBidAdapter.js +17 -11
  91. package/modules/undertoneBidAdapter.js +9 -5
  92. package/modules/undertoneBidAdapter.md +5 -1
  93. package/modules/unicornBidAdapter.js +3 -3
  94. package/modules/userId/eids.js +18 -0
  95. package/modules/userId/eids.md +7 -0
  96. package/modules/userId/userId.md +12 -0
  97. package/modules/ventesBidAdapter.js +370 -0
  98. package/modules/ventesBidAdapter.md +94 -0
  99. package/modules/videobyteBidAdapter.js +13 -6
  100. package/modules/videobyteBidAdapter.md +49 -0
  101. package/modules/vidoomyBidAdapter.js +20 -12
  102. package/modules/visxBidAdapter.js +15 -22
  103. package/modules/yahoosspBidAdapter.js +637 -0
  104. package/modules/yahoosspBidAdapter.md +795 -0
  105. package/modules/yieldlabBidAdapter.js +48 -3
  106. package/modules/yieldlabBidAdapter.md +16 -1
  107. package/modules/yieldmoBidAdapter.js +20 -6
  108. package/modules/yieldmoSyntheticInventoryModule.js +46 -0
  109. package/modules/yieldmoSyntheticInventoryModule.md +68 -0
  110. package/package.json +1 -1
  111. package/src/adapterManager.js +5 -0
  112. package/src/adapters/bidderFactory.js +4 -3
  113. package/src/auction.js +11 -11
  114. package/src/constants.json +1 -0
  115. package/src/secureCreatives.js +6 -7
  116. package/src/targeting.js +11 -9
  117. package/test/.eslintrc.js +2 -1
  118. package/test/spec/modules/adfBidAdapter_spec.js +83 -29
  119. package/test/spec/modules/adgenerationBidAdapter_spec.js +121 -50
  120. package/test/spec/modules/adnuntiusBidAdapter_spec.js +68 -0
  121. package/test/spec/modules/adtelligentBidAdapter_spec.js +1 -0
  122. package/test/spec/modules/akamaiDapRtdProvider_spec.js +246 -0
  123. package/test/spec/modules/appnexusBidAdapter_spec.js +2 -1
  124. package/test/spec/modules/atsAnalyticsAdapter_spec.js +77 -9
  125. package/test/spec/modules/betweenBidAdapter_spec.js +41 -0
  126. package/test/spec/modules/bliinkBidAdapter_spec.js +87 -36
  127. package/test/spec/modules/browsiRtdProvider_spec.js +62 -7
  128. package/test/spec/modules/cleanioRtdProvider_spec.js +188 -0
  129. package/test/spec/modules/codefuelBidAdapter_spec.js +316 -0
  130. package/test/spec/modules/connectIdSystem_spec.js +189 -0
  131. package/test/spec/modules/cwireBidAdapter_spec.js +246 -0
  132. package/test/spec/modules/deepintentBidAdapter_spec.js +153 -3
  133. package/test/spec/modules/deltaprojectsBidAdapter_spec.js +399 -0
  134. package/test/spec/modules/engageyaBidAdapter_spec.js +286 -0
  135. package/test/spec/modules/glimpseBidAdapter_spec.js +302 -204
  136. package/test/spec/modules/gridNMBidAdapter_spec.js +40 -1
  137. package/test/spec/modules/gumgumBidAdapter_spec.js +23 -6
  138. package/test/spec/modules/iasRtdProvider_spec.js +71 -6
  139. package/test/spec/modules/ixBidAdapter_spec.js +13 -3
  140. package/test/spec/modules/jixieBidAdapter_spec.js +13 -11
  141. package/test/spec/modules/justpremiumBidAdapter_spec.js +9 -2
  142. package/test/spec/modules/limelightDigitalBidAdapter_spec.js +155 -1
  143. package/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +67 -12
  144. package/test/spec/modules/mediakeysBidAdapter_spec.js +406 -51
  145. package/test/spec/modules/multibid_spec.js +31 -31
  146. package/test/spec/modules/mytargetBidAdapter_spec.js +199 -0
  147. package/test/spec/modules/nativoBidAdapter_spec.js +50 -3
  148. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +13 -1
  149. package/test/spec/modules/nextrollBidAdapter_spec.js +290 -0
  150. package/test/spec/modules/nobidBidAdapter_spec.js +65 -1
  151. package/test/spec/modules/oguryBidAdapter_spec.js +125 -37
  152. package/test/spec/modules/openxBidAdapter_spec.js +85 -13
  153. package/test/spec/modules/operaadsBidAdapter_spec.js +38 -6
  154. package/test/spec/modules/otmBidAdapter_spec.js +67 -0
  155. package/test/spec/modules/outbrainBidAdapter_spec.js +18 -0
  156. package/test/spec/modules/publinkIdSystem_spec.js +34 -15
  157. package/test/spec/modules/pubmaticBidAdapter_spec.js +217 -1
  158. package/test/spec/modules/relaidoBidAdapter_spec.js +21 -20
  159. package/test/spec/modules/sharethroughBidAdapter_spec.js +156 -136
  160. package/test/spec/modules/slimcutBidAdapter_spec.js +200 -0
  161. package/test/spec/modules/sonobiBidAdapter_spec.js +34 -1
  162. package/test/spec/modules/sortableBidAdapter_spec.js +11 -0
  163. package/test/spec/modules/spotxBidAdapter_spec.js +36 -0
  164. package/test/spec/modules/sspBCBidAdapter_spec.js +210 -62
  165. package/test/spec/modules/talkadsBidAdapter_spec.js +231 -0
  166. package/test/spec/modules/teadsBidAdapter_spec.js +132 -0
  167. package/test/spec/modules/tripleliftBidAdapter_spec.js +128 -0
  168. package/test/spec/modules/trustxBidAdapter_spec.js +38 -5
  169. package/test/spec/modules/undertoneBidAdapter_spec.js +52 -0
  170. package/test/spec/modules/unicornBidAdapter_spec.js +4 -4
  171. package/test/spec/modules/ventesBidAdapter_spec.js +845 -0
  172. package/test/spec/modules/videobyteBidAdapter_spec.js +2 -2
  173. package/test/spec/modules/visxBidAdapter_spec.js +48 -4
  174. package/test/spec/modules/yahoosspBidAdapter_spec.js +1332 -0
  175. package/test/spec/modules/yieldlabBidAdapter_spec.js +65 -1
  176. package/test/spec/modules/yieldmoBidAdapter_spec.js +30 -9
  177. package/test/spec/modules/yieldmoSyntheticInventoryModule_spec.js +89 -0
  178. package/test/spec/unit/core/adapterManager_spec.js +32 -0
  179. package/test/spec/unit/core/bidderFactory_spec.js +61 -1
  180. package/test/spec/unit/pbjs_api_spec.js +37 -2
  181. package/test/spec/unit/secureCreatives_spec.js +54 -25
  182. package/modules/turktelekomBidAdapter.md +0 -49
@@ -1,7 +1,7 @@
1
1
  import { isArray, deepAccess, logWarn, parseUrl } from '../src/utils.js';
2
2
  import { ajax } from '../src/ajax.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
- import { BANNER } from '../src/mediaTypes.js';
4
+ import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
5
5
  import strIncludes from 'core-js-pure/features/string/includes.js';
6
6
 
7
7
  const BIDDER_CODE = 'sspBC';
@@ -9,7 +9,7 @@ const BIDDER_URL = 'https://ssp.wp.pl/bidder/';
9
9
  const SYNC_URL = 'https://ssp.wp.pl/bidder/usersync';
10
10
  const NOTIFY_URL = 'https://ssp.wp.pl/bidder/notify';
11
11
  const TMAX = 450;
12
- const BIDDER_VERSION = '5.0';
12
+ const BIDDER_VERSION = '5.2';
13
13
  const W = window;
14
14
  const { navigator } = W;
15
15
  const oneCodeDetection = {};
@@ -155,6 +155,108 @@ const mapBanner = slot => {
155
155
  }
156
156
  }
157
157
 
158
+ /**
159
+ * @param {string} paramName Native parameter name
160
+ * @param {object} paramValue Native parameter value
161
+ * @returns {object} native asset object that conforms to ortb native ads spec
162
+ */
163
+ const mapAsset = (paramName, paramValue) => {
164
+ let asset;
165
+ switch (paramName) {
166
+ case 'title':
167
+ asset = {
168
+ id: 0,
169
+ required: paramValue.required,
170
+ title: { len: paramValue.len }
171
+ }
172
+ break;
173
+ case 'cta':
174
+ asset = {
175
+ id: 1,
176
+ required: paramValue.required,
177
+ data: { type: 12 }
178
+ }
179
+ break;
180
+ case 'icon':
181
+ asset = {
182
+ id: 2,
183
+ required: paramValue.required,
184
+ img: { type: 1, w: paramValue.sizes[0], h: paramValue.sizes[1] }
185
+ }
186
+ break;
187
+ case 'image':
188
+ asset = {
189
+ id: 3,
190
+ required: paramValue.required,
191
+ img: { type: 3, w: paramValue.sizes[0], h: paramValue.sizes[1] }
192
+ }
193
+ break;
194
+ case 'body':
195
+ asset = {
196
+ id: 4,
197
+ required: paramValue.required,
198
+ data: { type: 2 }
199
+ }
200
+ break;
201
+ case 'sponsoredBy':
202
+ asset = {
203
+ id: 5,
204
+ required: paramValue.required,
205
+ data: { type: 1 }
206
+ }
207
+ break;
208
+ }
209
+ return asset;
210
+ }
211
+
212
+ /**
213
+ * @param {object} slot Ad Unit Params by Prebid
214
+ * @returns {object} native object that conforms to ortb native ads spec
215
+ */
216
+ const mapNative = slot => {
217
+ const native = deepAccess(slot, 'mediaTypes.native');
218
+ let assets;
219
+ if (native) {
220
+ const nativeParams = Object.keys(native);
221
+ assets = [];
222
+ nativeParams.forEach(par => {
223
+ const newAsset = mapAsset(par, native[par]);
224
+ if (newAsset) { assets.push(newAsset) };
225
+ });
226
+ }
227
+ return assets ? { request: JSON.stringify({ native: { assets } }) } : undefined;
228
+ }
229
+
230
+ var mapVideo = slot => {
231
+ var video = deepAccess(slot, 'mediaTypes.video');
232
+ var videoParamsUsed = ['api', 'context', 'linearity', 'maxduration', 'mimes', 'protocols'];
233
+ var videoAssets;
234
+
235
+ if (video) {
236
+ var videoParams = Object.keys(video);
237
+ var playerSize = video.playerSize;
238
+ videoAssets = {}; // player width / height
239
+
240
+ if (playerSize) {
241
+ var maxSize = playerSize.reduce(function (prev, next) {
242
+ return next[0] >= prev[0] && next[1] >= prev[1] ? next : prev;
243
+ }, [1, 1]);
244
+ videoAssets.w = maxSize[0];
245
+ videoAssets.h = maxSize[1];
246
+ } // remaining supported params
247
+
248
+ videoParams.forEach(function (par) {
249
+ if (videoParamsUsed.indexOf(par) >= 0) {
250
+ videoAssets[par] = video[par];
251
+ }
252
+
253
+ ;
254
+ });
255
+ }
256
+
257
+ return videoAssets;
258
+ };
259
+
158
260
  const mapImpression = slot => {
159
261
  const { adUnitCode, bidId, params = {}, ortb2Imp = {} } = slot;
160
262
  const { id, siteId } = params;
@@ -165,32 +267,100 @@ const mapImpression = slot => {
165
267
  send this info as ext.pbsize
166
268
  */
167
269
  const slotSize = slot.sizes.length ? slot.sizes.reduce((prev, next) => prev[0] * prev[1] <= next[0] * next[1] ? next : prev).join('x') : '1x1';
168
- adSizesCalled[slotSize] = adSizesCalled[slotSize] ? adSizesCalled[slotSize] + 1 : 1;
270
+ adSizesCalled[slotSize] = adSizesCalled[slotSize] ? adSizesCalled[slotSize] += 1 : 1;
169
271
  ext.data = Object.assign({ pbsize: `${slotSize}_${adSizesCalled[slotSize]}` }, ext.data);
170
272
 
171
273
  const imp = {
172
274
  id: id && siteId ? id : 'bidid-' + bidId,
173
275
  banner: mapBanner(slot),
174
- // native: mapNative(slot),
276
+ native: mapNative(slot),
277
+ video: mapVideo(slot),
175
278
  tagid: adUnitCode,
176
279
  ext,
177
280
  };
178
281
 
179
282
  // Check floorprices for this imp
180
283
  if (typeof slot.getFloor === 'function') {
181
- let bannerFloor = 0;
182
- // sspBC adapter accepts only floor per imp - check for maximum value for requested ad types and sizes
284
+ var bannerFloor = 0;
285
+ var nativeFloor = 0;
286
+ var videoFloor = 0; // sspBC adapter accepts only floor per imp - check for maximum value for requested ad types and sizes
287
+
183
288
  if (slot.sizes.length) {
184
- bannerFloor = slot.sizes.reduce((prev, next) => {
185
- const currentFloor = slot.getFloor({ mediaType: 'banner', size: next }).floor;
289
+ bannerFloor = slot.sizes.reduce(function (prev, next) {
290
+ var currentFloor = slot.getFloor({
291
+ mediaType: 'banner',
292
+ size: next
293
+ }).floor;
186
294
  return prev > currentFloor ? prev : currentFloor;
187
295
  }, 0);
188
296
  }
189
- imp.bidfloor = bannerFloor;
297
+
298
+ nativeFloor = slot.getFloor({
299
+ mediaType: 'native'
300
+ });
301
+ videoFloor = slot.getFloor({
302
+ mediaType: 'video'
303
+ });
304
+ imp.bidfloor = Math.max(bannerFloor, nativeFloor, videoFloor);
190
305
  }
191
306
  return imp;
192
307
  }
193
308
 
309
+ const isVideoAd = bid => {
310
+ const xmlTester = new RegExp(/^<\?xml/);
311
+ return bid.adm && bid.adm.match(xmlTester);
312
+ }
313
+
314
+ const isNativeAd = bid => {
315
+ const xmlTester = new RegExp(/^{['"]native['"]/);
316
+
317
+ return bid.adm && bid.adm.match(xmlTester);
318
+ }
319
+
320
+ const parseNative = nativeData => {
321
+ const result = {};
322
+ nativeData.assets.forEach(asset => {
323
+ const id = parseInt(asset.id);
324
+ switch (id) {
325
+ case 0:
326
+ result.title = asset.title.text;
327
+ break;
328
+ case 2:
329
+ result.icon = {
330
+ url: asset.img.url,
331
+ width: asset.img.w,
332
+ height: asset.img.h,
333
+ };
334
+ break;
335
+ case 3:
336
+ result.image = {
337
+ url: asset.img.url,
338
+ width: asset.img.w,
339
+ height: asset.img.h,
340
+ };
341
+ break;
342
+ case 4:
343
+ result.body = asset.data.value;
344
+ break;
345
+ case 5:
346
+ result.sponsoredBy = asset.data.value;
347
+ break;
348
+
349
+ default:
350
+ logWarn('Unrecognized native asset', asset);
351
+ }
352
+ });
353
+ result.clickUrl = nativeData.link.url;
354
+ result.impressionTrackers = nativeData.imptrackers;
355
+
356
+ if (isArray(nativeData.jstracker)) {
357
+ result.javascriptTrackers = nativeData.jstracker;
358
+ } else if (nativeData.jstracker) {
359
+ result.javascriptTrackers = [nativeData.jstracker];
360
+ }
361
+ return result;
362
+ }
363
+
194
364
  const renderCreative = (site, auctionId, bid, seat, request) => {
195
365
  let gam;
196
366
 
@@ -243,6 +413,7 @@ const renderCreative = (site, auctionId, bid, seat, request) => {
243
413
  <script>
244
414
  window.rekid = ${site.id};
245
415
  window.slot = ${parseInt(site.slot, 10)};
416
+ window.responseTimestamp = ${Date.now()};
246
417
  window.wp_sn = "${site.sn}";
247
418
  window.mcad = JSON.parse(decodeURI(atob("${mcbase}")));
248
419
  window.gdpr = ${JSON.stringify(request.gdprConsent)};
@@ -268,7 +439,7 @@ const renderCreative = (site, auctionId, bid, seat, request) => {
268
439
  const spec = {
269
440
  code: BIDDER_CODE,
270
441
  aliases: [],
271
- supportedMediaTypes: [BANNER],
442
+ supportedMediaTypes: [BANNER, NATIVE, VIDEO],
272
443
  isBidRequestValid(bid) {
273
444
  // as per OneCode integration, bids without params are valid
274
445
  return true;
@@ -377,15 +548,39 @@ const spec = {
377
548
  width: w,
378
549
  height: h,
379
550
  bidderCode: BIDDER_CODE,
380
- mediaType: 'banner',
381
551
  meta: {
382
552
  advertiserDomains: adomain,
383
553
  networkName: seat,
384
554
  },
385
555
  netRevenue: true,
386
- ad: renderCreative(site, response.id, serverBid, seat, bidderRequest),
387
556
  };
388
557
 
558
+ // mediaType and ad data for instream / native / banner
559
+ if (isVideoAd(serverBid)) {
560
+ // video
561
+ bid.adType = 'instream';
562
+ bid.mediaType = 'video';
563
+ bid.vastXml = serverBid.adm;
564
+ bid.vastContent = serverBid.adm;
565
+ } else if (isNativeAd(serverBid)) {
566
+ // native
567
+ bid.mediaType = 'native';
568
+ // check native object
569
+ try {
570
+ const nativeData = JSON.parse(serverBid.adm).native;
571
+ bid.native = parseNative(nativeData);
572
+ bid.width = 1;
573
+ bid.height = 1;
574
+ } catch (err) {
575
+ logWarn('Could not parse native data', serverBid.adm);
576
+ bid.cpm = 0;
577
+ }
578
+ } else {
579
+ // banner ad (default)
580
+ bid.mediaType = 'banner';
581
+ bid.ad = renderCreative(site, response.id, serverBid, seat, bidderRequest);
582
+ }
583
+
389
584
  if (bid.cpm > 0) {
390
585
  bids.push(bid);
391
586
  }
@@ -7,7 +7,7 @@ Maintainer: wojciech.bialy@grupawp.pl
7
7
  # Description
8
8
 
9
9
  Module that connects to Wirtualna Polska Media header bidding endpoint to fetch bids.
10
- Only banner format is supported.
10
+ Supports Banner, Video (instream) and Native formats
11
11
  Supported currencies: USD, EUR, PLN
12
12
 
13
13
  Required parameters:
@@ -0,0 +1,129 @@
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
2
+ import { NATIVE, BANNER } from '../src/mediaTypes.js';
3
+ import * as utils from '../src/utils.js';
4
+ import {ajax} from '../src/ajax.js';
5
+
6
+ const CURRENCY = 'EUR';
7
+ const BIDDER_CODE = 'talkads';
8
+
9
+ export const spec = {
10
+ code: BIDDER_CODE,
11
+ supportedMediaTypes: [ NATIVE, BANNER ],
12
+ params: null,
13
+
14
+ /**
15
+ * Determines whether or not the given bid request is valid.
16
+ *
17
+ * @param poBid The bid params to validate.
18
+ * @return boolean True if this is a valid bid, and false otherwise.
19
+ */
20
+ isBidRequestValid: (poBid) => {
21
+ utils.logInfo('isBidRequestValid : ', poBid);
22
+ if (poBid.params === undefined) {
23
+ utils.logError('VALIDATION FAILED : the parameters must be defined');
24
+ return false;
25
+ }
26
+ if (poBid.params.tag_id === undefined) {
27
+ utils.logError('VALIDATION FAILED : the parameter "tag_id" must be defined');
28
+ return false;
29
+ }
30
+ if (poBid.params.bidder_url === undefined) {
31
+ utils.logError('VALIDATION FAILED : the parameter "bidder_url" must be defined');
32
+ return false;
33
+ }
34
+ this.params = poBid.params;
35
+ return !!(poBid.nativeParams || poBid.sizes);
36
+ }, // isBidRequestValid
37
+
38
+ /**
39
+ * Make a server request from the list of BidRequests.
40
+ *
41
+ * @param paValidBidRequests An array of bids
42
+ * @param poBidderRequest
43
+ * @return ServerRequest Info describing the request to the server.
44
+ */
45
+ buildRequests: (paValidBidRequests, poBidderRequest) => {
46
+ utils.logInfo('buildRequests : ', paValidBidRequests, poBidderRequest);
47
+ const laBids = paValidBidRequests.map((poBid, piId) => {
48
+ const loOne = { id: piId, ad_unit: poBid.adUnitCode, bid_id: poBid.bidId, type: '', size: [] };
49
+ if (poBid.nativeParams) {
50
+ loOne.type = 'native';
51
+ } else {
52
+ loOne.type = 'banner';
53
+ loOne.size = poBid.sizes;
54
+ }
55
+ return loOne;
56
+ });
57
+ const loServerRequest = {
58
+ cur: CURRENCY,
59
+ timeout: poBidderRequest.timeout,
60
+ auction_id: paValidBidRequests[0].auctionId,
61
+ transaction_id: paValidBidRequests[0].transactionId,
62
+ bids: laBids,
63
+ gdpr: { applies: false, consent: false },
64
+ };
65
+ if (poBidderRequest && poBidderRequest.gdprConsent) {
66
+ const loGdprConsent = poBidderRequest.gdprConsent;
67
+ if ((typeof loGdprConsent.gdprApplies === 'boolean') && loGdprConsent.gdprApplies) {
68
+ loServerRequest.gdpr.applies = true;
69
+ }
70
+ if ((typeof loGdprConsent.consentString === 'string') && loGdprConsent.consentString) {
71
+ loServerRequest.gdpr.consent = poBidderRequest.gdprConsent.consentString;
72
+ }
73
+ }
74
+ const lsUrl = this.params.bidder_url + '/' + this.params.tag_id;
75
+ return {
76
+ method: 'POST',
77
+ url: lsUrl,
78
+ data: JSON.stringify(loServerRequest),
79
+ };
80
+ }, // buildRequests
81
+
82
+ /**
83
+ * Unpack the response from the server into a list of bids.
84
+ *
85
+ * @param poServerResponse A successful response from the server.
86
+ * @param poPidRequest Request original server request
87
+ * @return An array of bids which were nested inside the server.
88
+ */
89
+ interpretResponse: (poServerResponse, poPidRequest) => {
90
+ utils.logInfo('interpretResponse : ', poServerResponse);
91
+ if (!poServerResponse.body) {
92
+ return [];
93
+ }
94
+ let laResponse = [];
95
+ if (poServerResponse.body.status !== 'ok') {
96
+ utils.logInfo('Error : ', poServerResponse.body.error);
97
+ return laResponse;
98
+ }
99
+ poServerResponse.body.bids.forEach((poResponse) => {
100
+ laResponse[laResponse.length] = {
101
+ requestId: poResponse.requestId,
102
+ cpm: poResponse.cpm,
103
+ currency: poResponse.currency,
104
+ width: poResponse.width,
105
+ height: poResponse.height,
106
+ ad: poResponse.ad,
107
+ ttl: poResponse.ttl,
108
+ creativeId: poResponse.creativeId,
109
+ netRevenue: poResponse.netRevenue,
110
+ pbid: poServerResponse.body.pbid,
111
+ };
112
+ });
113
+ return laResponse;
114
+ }, // interpretResponse
115
+
116
+ /**
117
+ * Register bidder specific code, which will execute if a bid from this bidder won the auction.
118
+ *
119
+ * @param poBid The bid that won the auction
120
+ */
121
+ onBidWon: (poBid) => {
122
+ utils.logInfo('onBidWon : ', poBid);
123
+ if (poBid.pbid) {
124
+ ajax(this.params.bidder_url + 'won/' + poBid.pbid);
125
+ }
126
+ }, // onBidWon
127
+ };
128
+
129
+ registerBidder(spec);
@@ -0,0 +1,60 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: TalkAds Adapter
5
+ Module Type: Bidder Adapter
6
+ Maintainer: technical_team@natexo.com
7
+ ```
8
+
9
+ # Description
10
+
11
+ Module that connects to TalkAds bidder to fetch bids.
12
+ Both native and banner formats are supported but not at the same time.
13
+ The only currently supported currency is EUR.
14
+
15
+ This adapter requires setup and approval from the Natexo programmatic team.
16
+
17
+ # Configuration
18
+
19
+
20
+
21
+
22
+ # Test parameters
23
+
24
+ ## Test banner Parameters
25
+
26
+ ```
27
+ var adUnits = [
28
+ code: 'prebid_banner_test',
29
+ mediaTypes: {
30
+ banner: {
31
+ sizes: [[300, 250], [300, 600]],
32
+ }
33
+ },
34
+ bids: [{
35
+ bidder: 'talkads',
36
+ params: {
37
+ tag_id: 0,
38
+ bidder_url: 'https://d.natexo-programmatic.com/tad/tag/testbid',
39
+ },
40
+ }]
41
+ ];
42
+ ```
43
+
44
+ ## Test native parameters
45
+
46
+ ```
47
+ var adUnits = [
48
+ code: 'prebid_native_test',
49
+ mediaTypes: {
50
+ native: {}
51
+ },
52
+ bids: [{
53
+ bidder: 'talkads',
54
+ params: {
55
+ tag_id: 0,
56
+ bidder_url: 'https://d.natexo-programmatic.com/tad/tag/testbid',
57
+ },
58
+ }]
59
+ ];
60
+ ```
@@ -9,7 +9,7 @@ import { Renderer } from '../src/Renderer.js';
9
9
  const BIDDER_CODE = 'tappx';
10
10
  const TTL = 360;
11
11
  const CUR = 'USD';
12
- const TAPPX_BIDDER_VERSION = '0.1.0921';
12
+ const TAPPX_BIDDER_VERSION = '0.1.1004';
13
13
  const TYPE_CNN = 'prebidjs';
14
14
  const LOG_PREFIX = '[TAPPX]: ';
15
15
  const VIDEO_SUPPORT = ['instream', 'outstream'];
@@ -495,15 +495,16 @@ export function _getHostInfo(validBidRequests) {
495
495
  }
496
496
 
497
497
  function outstreamRender(bid, request) {
498
+ let rendererOptions = {};
499
+ rendererOptions = (typeof bid.params[0].video != 'undefined') ? bid.params[0].video : {};
500
+ rendererOptions.content = bid.vastXml;
501
+
498
502
  bid.renderer.push(() => {
499
503
  window.tappxOutstream.renderAd({
500
504
  sizes: [bid.width, bid.height],
501
505
  targetId: bid.adUnitCode,
502
506
  adResponse: bid.adResponse,
503
- rendererOptions: {
504
- content: bid.vastXml,
505
- skip: (typeof bid.params[0].video.skip != 'undefined' && bid.params[0].video.skip > 0) ? bid.params[0].video.skip : 0
506
- }
507
+ rendererOptions: rendererOptions
507
508
  });
508
509
  });
509
510
  }
@@ -190,6 +190,8 @@ function buildRequestObject(bid) {
190
190
  const reqObj = {};
191
191
  let placementId = getValue(bid.params, 'placementId');
192
192
  let pageId = getValue(bid.params, 'pageId');
193
+ const impressionData = deepAccess(bid, 'ortb2Imp.ext.data');
194
+ const gpid = deepAccess(impressionData, 'pbadslot') || deepAccess(impressionData, 'adserver.adslot');
193
195
 
194
196
  reqObj.sizes = getSizes(bid);
195
197
  reqObj.bidId = getBidIdParameter('bidId', bid);
@@ -199,6 +201,7 @@ function buildRequestObject(bid) {
199
201
  reqObj.adUnitCode = getBidIdParameter('adUnitCode', bid);
200
202
  reqObj.auctionId = getBidIdParameter('auctionId', bid);
201
203
  reqObj.transactionId = getBidIdParameter('transactionId', bid);
204
+ if (gpid) { reqObj.gpid = gpid; }
202
205
  return reqObj;
203
206
  }
204
207
 
@@ -1,4 +1,4 @@
1
- import { tryAppendQueryString, logMessage, isEmpty } from '../src/utils.js';
1
+ import { tryAppendQueryString, logMessage, isEmpty, isStr, isPlainObject, isArray, logWarn } from '../src/utils.js';
2
2
  import { BANNER, VIDEO } from '../src/mediaTypes.js';
3
3
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
4
  import { config } from '../src/config.js';
@@ -262,19 +262,36 @@ function getPubCommonEids(bidRequest) {
262
262
  function getEids(bidRequest, type, source, rtiPartner) {
263
263
  return bidRequest
264
264
  .map(getUserId(type)) // bids -> userIds of a certain type
265
- .filter((x) => !!x) // filter out null userIds
265
+ .filter(filterEids(type)) // filter out unqualified userIds
266
266
  .map(formatEid(source, rtiPartner)); // userIds -> eid objects
267
267
  }
268
268
 
269
+ const filterEids = type => (userId, i, arr) => {
270
+ let isValidUserId =
271
+ !!userId && // is not null nor empty
272
+ (isStr(userId)
273
+ ? !!userId
274
+ : isPlainObject(userId) && // or, is object
275
+ !isArray(userId) && // not an array
276
+ !isEmpty(userId) && // is not empty
277
+ userId.id && // contains nested id field
278
+ isStr(userId.id) && // nested id field is a string
279
+ !!userId.id); // that is not empty
280
+ if (!isValidUserId && arr[0] !== undefined) {
281
+ logWarn(`Triplelift: invalid ${type} userId format`);
282
+ }
283
+ return isValidUserId;
284
+ };
285
+
269
286
  function getUserId(type) {
270
- return (bid) => (bid && bid.userId && bid.userId[type]);
287
+ return bid => bid && bid.userId && bid.userId[type];
271
288
  }
272
289
 
273
290
  function formatEid(source, rtiPartner) {
274
- return (id) => ({
291
+ return (userId) => ({
275
292
  source,
276
293
  uids: [{
277
- id,
294
+ id: userId.id ? userId.id : userId,
278
295
  ext: { rtiPartner }
279
296
  }]
280
297
  });
@@ -315,7 +315,7 @@ function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst) {
315
315
  if (!serverBid) return;
316
316
  let errorMessage;
317
317
  if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid);
318
- if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
318
+ if (!serverBid.adm && !serverBid.nurl) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid);
319
319
  else {
320
320
  const { bidsMap } = bidRequest;
321
321
  const bid = bidsMap[serverBid.impid];
@@ -336,11 +336,15 @@ function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst) {
336
336
  },
337
337
  };
338
338
  if (serverBid.content_type === 'video') {
339
- bidResponse.vastXml = serverBid.adm;
339
+ if (serverBid.adm) {
340
+ bidResponse.vastXml = serverBid.adm;
341
+ bidResponse.adResponse = {
342
+ content: bidResponse.vastXml
343
+ };
344
+ } else if (serverBid.nurl) {
345
+ bidResponse.vastUrl = serverBid.nurl;
346
+ }
340
347
  bidResponse.mediaType = VIDEO;
341
- bidResponse.adResponse = {
342
- content: bidResponse.vastXml
343
- };
344
348
  if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) {
345
349
  bidResponse.renderer = createRenderer(bidResponse, {
346
350
  id: bid.bidId,
@@ -425,9 +429,10 @@ function addSegments(name, segName, segments, data, bidConfigName) {
425
429
  if (segments && segments.length) {
426
430
  data.push({
427
431
  name: name,
428
- segment: segments.map((seg) => {
429
- return {name: segName, value: seg};
430
- })
432
+ segment: segments
433
+ .map((seg) => seg && (seg.id || seg))
434
+ .filter((seg) => seg && (typeof seg === 'string' || typeof seg === 'number'))
435
+ .map((seg) => ({ name: segName, value: seg.toString() }))
431
436
  });
432
437
  } else if (bidConfigName) {
433
438
  const configData = config.getConfig('ortb2.user.data');
@@ -441,9 +446,10 @@ function addSegments(name, segName, segments, data, bidConfigName) {
441
446
  if (segData && segData.length) {
442
447
  data.push({
443
448
  name: name,
444
- segment: segData.map((seg) => {
445
- return {name: segName, value: seg};
446
- })
449
+ segment: segData
450
+ .map((seg) => seg && (seg.id || seg))
451
+ .filter((seg) => seg && (typeof seg === 'string' || typeof seg === 'number'))
452
+ .map((seg) => ({ name: segName, value: seg.toString() }))
447
453
  });
448
454
  }
449
455
  }
@@ -85,13 +85,17 @@ export const spec = {
85
85
  const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
86
86
  const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
87
87
  const pageSizeArray = vw == 0 || vh == 0 ? null : [vw, vh];
88
+ const commons = {
89
+ 'adapterVersion': '$prebid.version$',
90
+ 'uids': validBidRequests[0].userId,
91
+ 'pageSize': pageSizeArray
92
+ };
93
+ if (validBidRequests[0].schain) {
94
+ commons.schain = validBidRequests[0].schain;
95
+ }
88
96
  const payload = {
89
97
  'x-ut-hb-params': [],
90
- 'commons': {
91
- 'adapterVersion': '$prebid.version$',
92
- 'uids': validBidRequests[0].userId,
93
- 'pageSize': pageSizeArray
94
- }
98
+ 'commons': commons
95
99
  };
96
100
  const referer = bidderRequest.refererInfo.referer;
97
101
  const hostname = parseUrl(referer).hostname;
@@ -1,9 +1,13 @@
1
1
  # Overview
2
2
 
3
3
  ```
4
- Module Name: Example Bidder Adapter
4
+ Module Name: Undertone Bidder Adapter
5
5
  Module Type: Bidder Adapter
6
6
  Maintainer: RampProgrammatic@perion.com
7
+ gdpr_supported: true
8
+ usp_supported: true
9
+ schain_supported: true
10
+ media_types: video, native
7
11
  ```
8
12
  # Description
9
13