prebid.js 7.25.0 → 7.26.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 (168) hide show
  1. package/dist/33acrossBidAdapter.js +1 -1
  2. package/dist/adagioBidAdapter.js +1 -1
  3. package/dist/adbookpspBidAdapter.js +1 -1
  4. package/dist/adgenerationBidAdapter.js +1 -1
  5. package/dist/admaticBidAdapter.js +1 -1
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/ajaBidAdapter.js +1 -1
  10. package/dist/amxBidAdapter.js +1 -1
  11. package/dist/amxIdSystem.js +1 -1
  12. package/dist/appierAnalyticsAdapter.js +1 -1
  13. package/dist/appnexusBidAdapter.js +1 -1
  14. package/dist/asoBidAdapter.js +1 -1
  15. package/dist/axonixBidAdapter.js +1 -1
  16. package/dist/beopBidAdapter.js +1 -1
  17. package/dist/bidglassBidAdapter.js +1 -1
  18. package/dist/big-richmediaBidAdapter.js +1 -1
  19. package/dist/bridgewellBidAdapter.js +1 -1
  20. package/dist/brightMountainMediaBidAdapter.js +1 -1
  21. package/dist/captifyRtdProvider.js +1 -0
  22. package/dist/carodaBidAdapter.js +1 -1
  23. package/dist/chtnwBidAdapter.js +1 -1
  24. package/dist/concertBidAdapter.js +1 -1
  25. package/dist/connectadBidAdapter.js +1 -1
  26. package/dist/consumableBidAdapter.js +1 -1
  27. package/dist/conversantBidAdapter.js +1 -1
  28. package/dist/craftBidAdapter.js +1 -1
  29. package/dist/criteoBidAdapter.js +1 -1
  30. package/dist/discoveryBidAdapter.js +1 -1
  31. package/dist/dspxBidAdapter.js +1 -1
  32. package/dist/eplanningBidAdapter.js +1 -1
  33. package/dist/finativeBidAdapter.js +1 -1
  34. package/dist/glimpseBidAdapter.js +1 -1
  35. package/dist/gmosspBidAdapter.js +1 -1
  36. package/dist/goldbachBidAdapter.js +1 -1
  37. package/dist/gridBidAdapter.js +1 -1
  38. package/dist/gridNMBidAdapter.js +1 -1
  39. package/dist/gumgumBidAdapter.js +1 -1
  40. package/dist/h12mediaBidAdapter.js +1 -1
  41. package/dist/id5IdSystem.js +1 -1
  42. package/dist/improvedigitalBidAdapter.js +1 -1
  43. package/dist/inmarBidAdapter.js +1 -1
  44. package/dist/insticatorBidAdapter.js +1 -1
  45. package/dist/ixBidAdapter.js +1 -1
  46. package/dist/justpremiumBidAdapter.js +1 -1
  47. package/dist/konduitAnalyticsAdapter.js +1 -1
  48. package/dist/kueezBidAdapter.js +1 -1
  49. package/dist/kueezRtbBidAdapter.js +1 -1
  50. package/dist/lassoBidAdapter.js +1 -1
  51. package/dist/lifestreetBidAdapter.js +1 -1
  52. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  53. package/dist/logicadBidAdapter.js +1 -1
  54. package/dist/loglyliftBidAdapter.js +1 -1
  55. package/dist/magniteAnalyticsAdapter.js +1 -1
  56. package/dist/malltvAnalyticsAdapter.js +1 -1
  57. package/dist/marsmediaBidAdapter.js +1 -1
  58. package/dist/mediafuseBidAdapter.js +1 -1
  59. package/dist/mediasquareBidAdapter.js +1 -1
  60. package/dist/mgidBidAdapter.js +1 -1
  61. package/dist/minutemediaBidAdapter.js +1 -1
  62. package/dist/nextMillenniumBidAdapter.js +1 -1
  63. package/dist/not-for-prod/prebid.js +152 -118
  64. package/dist/oguryBidAdapter.js +1 -1
  65. package/dist/onetagBidAdapter.js +1 -1
  66. package/dist/ooloAnalyticsAdapter.js +1 -1
  67. package/dist/outbrainBidAdapter.js +1 -1
  68. package/dist/parrableIdSystem.js +1 -1
  69. package/dist/pixfutureBidAdapter.js +1 -1
  70. package/dist/prebid-core.js +1 -1
  71. package/dist/publinkIdSystem.js +1 -1
  72. package/dist/pubmaticBidAdapter.js +1 -1
  73. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  74. package/dist/pxyzBidAdapter.js +1 -1
  75. package/dist/quantcastBidAdapter.js +1 -1
  76. package/dist/readpeakBidAdapter.js +1 -1
  77. package/dist/relaidoBidAdapter.js +1 -1
  78. package/dist/rhythmoneBidAdapter.js +1 -1
  79. package/dist/riseBidAdapter.js +1 -1
  80. package/dist/rubiconAnalyticsAdapter.js +1 -1
  81. package/dist/rubiconBidAdapter.js +1 -1
  82. package/dist/seedingAllianceBidAdapter.js +1 -1
  83. package/dist/seedtagBidAdapter.js +1 -1
  84. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  85. package/dist/sharethroughBidAdapter.js +1 -1
  86. package/dist/shinezBidAdapter.js +1 -1
  87. package/dist/smaatoBidAdapter.js +1 -1
  88. package/dist/smartadserverBidAdapter.js +1 -1
  89. package/dist/smartxBidAdapter.js +1 -1
  90. package/dist/smartytechBidAdapter.js +1 -0
  91. package/dist/smilewantedBidAdapter.js +1 -1
  92. package/dist/sonobiBidAdapter.js +1 -1
  93. package/dist/sovrnAnalyticsAdapter.js +1 -1
  94. package/dist/sovrnBidAdapter.js +1 -1
  95. package/dist/sspBCBidAdapter.js +1 -1
  96. package/dist/sublimeBidAdapter.js +1 -1
  97. package/dist/synacormediaBidAdapter.js +1 -1
  98. package/dist/taboolaBidAdapter.js +1 -1
  99. package/dist/tappxBidAdapter.js +1 -1
  100. package/dist/targetVideoBidAdapter.js +1 -1
  101. package/dist/teadsBidAdapter.js +1 -1
  102. package/dist/trionBidAdapter.js +1 -1
  103. package/dist/tripleliftBidAdapter.js +1 -1
  104. package/dist/ttdBidAdapter.js +1 -1
  105. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  106. package/dist/underdogmediaBidAdapter.js +1 -1
  107. package/dist/undertoneBidAdapter.js +1 -1
  108. package/dist/userId.js +1 -1
  109. package/dist/vidazooBidAdapter.js +1 -1
  110. package/dist/videobyteBidAdapter.js +1 -1
  111. package/dist/viqeoBidAdapter.js +1 -0
  112. package/dist/visxBidAdapter.js +1 -1
  113. package/dist/vuukleBidAdapter.js +1 -1
  114. package/dist/widespaceBidAdapter.js +1 -1
  115. package/dist/winrBidAdapter.js +1 -1
  116. package/dist/yahoosspBidAdapter.js +1 -1
  117. package/dist/yieldlabBidAdapter.js +1 -1
  118. package/dist/yieldmoBidAdapter.js +1 -1
  119. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  120. package/dist/zeta_global_sspBidAdapter.js +1 -1
  121. package/dist/zeusPrimeRtdProvider.js +31 -0
  122. package/integrationExamples/gpt/captifyRtdProvider_example.html +167 -0
  123. package/modules/.submodules.json +3 -1
  124. package/modules/admaticBidAdapter.js +108 -59
  125. package/modules/admaticBidAdapter.md +2 -2
  126. package/modules/beopBidAdapter.js +17 -2
  127. package/modules/captifyRtdProvider.js +146 -0
  128. package/modules/captifyRtdProvider.md +68 -0
  129. package/modules/discoveryBidAdapter.js +38 -17
  130. package/modules/discoveryBidAdapter.md +7 -6
  131. package/modules/gridBidAdapter.js +440 -22
  132. package/modules/nextMillenniumBidAdapter.js +19 -23
  133. package/modules/smartadserverBidAdapter.js +6 -2
  134. package/modules/smartxBidAdapter.js +10 -7
  135. package/modules/smartytechBidAdapter.js +78 -0
  136. package/modules/smartytechBidAdapter.md +44 -0
  137. package/modules/taboolaBidAdapter.js +3 -3
  138. package/modules/taboolaBidAdapter.md +0 -2
  139. package/modules/tappxBidAdapter.js +21 -6
  140. package/modules/ttdBidAdapter.js +4 -3
  141. package/modules/userId/index.js +1 -1
  142. package/modules/vidazooBidAdapter.js +15 -2
  143. package/modules/viqeoBidAdapter.js +180 -0
  144. package/modules/viqeoBidAdapter.md +56 -0
  145. package/modules/yieldlabBidAdapter.js +19 -8
  146. package/modules/yieldoneBidAdapter.js +60 -8
  147. package/modules/yieldoneBidAdapter.md +109 -9
  148. package/modules/zeta_global_sspBidAdapter.js +4 -0
  149. package/modules/zeusPrimeRtdProvider.js +357 -0
  150. package/modules/zeusPrimeRtdProvider.md +60 -0
  151. package/package.json +1 -1
  152. package/src/adloader.js +0 -1
  153. package/test/spec/modules/admaticBidAdapter_spec.js +262 -3
  154. package/test/spec/modules/beopBidAdapter_spec.js +52 -0
  155. package/test/spec/modules/captifyRtdProvider_spec.js +253 -0
  156. package/test/spec/modules/discoveryBidAdapter_spec.js +9 -8
  157. package/test/spec/modules/gridBidAdapter_spec.js +289 -1
  158. package/test/spec/modules/nextMillenniumBidAdapter_spec.js +4 -3
  159. package/test/spec/modules/smartadserverBidAdapter_spec.js +80 -0
  160. package/test/spec/modules/smartxBidAdapter_spec.js +32 -0
  161. package/test/spec/modules/smartytechBidAdapter_spec.js +162 -0
  162. package/test/spec/modules/taboolaBidAdapter_spec.js +0 -77
  163. package/test/spec/modules/ttdBidAdapter_spec.js +13 -0
  164. package/test/spec/modules/viqeoBidAdapter_spec.js +124 -0
  165. package/test/spec/modules/yieldlabBidAdapter_spec.js +125 -0
  166. package/test/spec/modules/yieldoneBidAdapter_spec.js +30 -6
  167. package/test/spec/modules/zeta_global_sspBidAdapter_spec.js +16 -1
  168. package/test/spec/modules/zeusPrimeRtdProvider_spec.js +410 -0
@@ -0,0 +1,78 @@
1
+ import {registerBidder} from '../src/adapters/bidderFactory.js';
2
+ import {buildUrl} from '../src/utils.js'
3
+
4
+ const BIDDER_CODE = 'smartytech';
5
+ export const ENDPOINT_PROTOCOL = 'https';
6
+ export const ENDPOINT_DOMAIN = 'server.smartytech.io';
7
+ export const ENDPOINT_PATH = '/hb/bidder';
8
+
9
+ export const spec = {
10
+ code: BIDDER_CODE,
11
+
12
+ isBidRequestValid: function (bidRequest) {
13
+ return !!parseInt(bidRequest.params.endpointId);
14
+ },
15
+
16
+ buildRequests: function (validBidRequests, bidderRequest) {
17
+ const referer = bidderRequest?.refererInfo?.page || window.location.href;
18
+
19
+ const bidRequests = validBidRequests.map((validBidRequest) => {
20
+ return {
21
+ endpointId: validBidRequest.params.endpointId,
22
+ adUnitCode: validBidRequest.adUnitCode,
23
+ sizes: validBidRequest.sizes,
24
+ bidId: validBidRequest.bidId,
25
+ referer: referer
26
+ };
27
+ });
28
+
29
+ let adPartnerRequestUrl = buildUrl({
30
+ protocol: ENDPOINT_PROTOCOL,
31
+ hostname: ENDPOINT_DOMAIN,
32
+ pathname: ENDPOINT_PATH,
33
+ });
34
+
35
+ return {
36
+ method: 'POST',
37
+ url: adPartnerRequestUrl,
38
+ data: bidRequests
39
+ };
40
+ },
41
+
42
+ interpretResponse: function (serverResponse, bidRequest) {
43
+ if (typeof serverResponse.body === 'undefined') {
44
+ return [];
45
+ }
46
+
47
+ const validBids = bidRequest.data;
48
+ const keys = Object.keys(serverResponse.body)
49
+ const responseBody = serverResponse.body;
50
+
51
+ return keys.filter(key => {
52
+ return responseBody[key].ad
53
+ }).map(key => {
54
+ return {
55
+ bid: validBids.find(b => b.adUnitCode === key),
56
+ response: responseBody[key]
57
+ }
58
+ }).map(item => spec.adResponse(item.bid.bidId, item.response));
59
+ },
60
+
61
+ adResponse: function (requestId, response) {
62
+ const bidObject = {
63
+ requestId,
64
+ ad: response.ad,
65
+ cpm: response.cpm,
66
+ width: response.width,
67
+ height: response.height,
68
+ ttl: 60,
69
+ creativeId: response.creativeId,
70
+ netRevenue: true,
71
+ currency: response.currency,
72
+ }
73
+ return bidObject;
74
+ },
75
+
76
+ }
77
+
78
+ registerBidder(spec);
@@ -0,0 +1,44 @@
1
+ # Overview
2
+
3
+ Module Name: SmartyTech Bidder Adapter
4
+
5
+ Module Type: Bidder Adapter
6
+
7
+ Maintainer: info@adpartner.pro
8
+
9
+ # Description
10
+
11
+ You can use this adapter to get a bid from smartytech.io.
12
+
13
+ About us : https://smartytech.io
14
+
15
+ # Test Parameters
16
+
17
+ ```javascript
18
+ var adUnits = [
19
+ {
20
+ code: 'div-smartytech-example',
21
+ sizes: [[300, 250]],
22
+ bids: [
23
+ {
24
+ bidder: "smartytech",
25
+ params: {
26
+ endpointId: 14
27
+ }
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ code: 'div-smartytech-example-2',
33
+ sizes: [[300, 250]],
34
+ bids: [
35
+ {
36
+ bidder: "smartytech",
37
+ params: {
38
+ endpointId: 14
39
+ }
40
+ }
41
+ ]
42
+ }
43
+ ];
44
+ ```
@@ -9,7 +9,7 @@ import {getStorageManager} from '../src/storageManager.js';
9
9
  const BIDDER_CODE = 'taboola';
10
10
  const GVLID = 42;
11
11
  const CURRENCY = 'USD';
12
- export const END_POINT_URL = 'https://hb.bidder.taboola.com/TaboolaHBOpenRTBRequestHandlerServlet';
12
+ export const END_POINT_URL = 'https://display.bidder.taboola.com/OpenRTB/TaboolaHB/auction';
13
13
  const USER_ID = 'user-id';
14
14
  const STORAGE_KEY = `taboola global:${USER_ID}`;
15
15
  const COOKIE_KEY = 'trc_cookie_storage';
@@ -80,7 +80,7 @@ export const spec = {
80
80
  buildRequests: (validBidRequests, bidderRequest) => {
81
81
  const [bidRequest] = validBidRequests;
82
82
  const {refererInfo, gdprConsent = {}, uspConsent} = bidderRequest;
83
- const {publisherId, endpointUrl} = bidRequest.params;
83
+ const {publisherId} = bidRequest.params;
84
84
  const site = getSiteProperties(bidRequest.params, refererInfo);
85
85
  const device = {ua: navigator.userAgent};
86
86
  const imps = getImps(validBidRequests);
@@ -124,7 +124,7 @@ export const spec = {
124
124
  regs
125
125
  };
126
126
 
127
- const url = [endpointUrl || END_POINT_URL, publisherId].join('/');
127
+ const url = [END_POINT_URL, publisherId].join('/');
128
128
 
129
129
  return {
130
130
  url,
@@ -31,7 +31,6 @@ The Taboola Bidding adapter requires setup before beginning. Please contact us o
31
31
  bidfloor: 0.25, // Optional - default is null
32
32
  bcat: ['IAB1-1'], // Optional - default is []
33
33
  badv: ['example.com'], // Optional - default is []
34
- endpointUrl: ['https://example.com'] // Optional
35
34
  }
36
35
  }]
37
36
  }];
@@ -46,6 +45,5 @@ The Taboola Bidding adapter requires setup before beginning. Please contact us o
46
45
  | `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `Array` |
47
46
  | `badv` | optional | Blocked Advertiser Domains | `'example.com'` | `String Url` |
48
47
  | `bidfloor` | optional | CPM bid floor | `0.25` | `Float` |
49
- | `endpointUrl` | optional | Endpoint Url (only if provided by Taboola) | `https://example.com` | `String` |
50
48
 
51
49
 
@@ -11,7 +11,7 @@ const BIDDER_CODE = 'tappx';
11
11
  const GVLID_CODE = 628;
12
12
  const TTL = 360;
13
13
  const CUR = 'USD';
14
- const TAPPX_BIDDER_VERSION = '0.1.1005';
14
+ const TAPPX_BIDDER_VERSION = '0.1.2';
15
15
  const TYPE_CNN = 'prebidjs';
16
16
  const LOG_PREFIX = '[TAPPX]: ';
17
17
  const VIDEO_SUPPORT = ['instream', 'outstream'];
@@ -271,12 +271,28 @@ function buildOneRequest(validBidRequests, bidderRequest) {
271
271
  api[0] = deepAccess(validBidRequests, 'params.api') ? deepAccess(validBidRequests, 'params.api') : [3, 5];
272
272
  } else {
273
273
  let bundle = _extractPageUrl(validBidRequests, bidderRequest);
274
- let site = {};
274
+ let site = deepAccess(validBidRequests, 'params.site') || {};
275
275
  site.name = bundle;
276
+ site.page = bidderRequest?.refererInfo?.page || deepAccess(validBidRequests, 'params.site.page') || bidderRequest?.refererInfo?.topmostLocation || window.location.href || bundle;
276
277
  site.domain = bundle;
278
+ site.ref = bidderRequest?.refererInfo?.ref || window.top.document.referrer || '';
279
+ site.ext = {};
280
+ site.ext.is_amp = bidderRequest?.refererInfo?.isAmp || 0;
281
+ site.ext.page_da = deepAccess(validBidRequests, 'params.site.page') || '-';
282
+ site.ext.page_rip = bidderRequest?.refererInfo?.page || '-';
283
+ site.ext.page_rit = bidderRequest?.refererInfo?.topmostLocation || '-';
284
+ site.ext.page_wlh = window.location.href || '-';
277
285
  publisher.name = bundle;
278
286
  publisher.domain = bundle;
287
+ let sitename = document.getElementsByTagName('meta')['title'];
288
+ if (sitename && sitename.content) {
289
+ site.name = sitename.content;
290
+ }
279
291
  tagid = `${site.name}_typeAdBanVid_${getOs()}`;
292
+ let keywords = document.getElementsByTagName('meta')['keywords'];
293
+ if (keywords && keywords.content) {
294
+ site.keywords = keywords.content;
295
+ }
280
296
  payload.site = site;
281
297
  }
282
298
  // < App/Site object
@@ -295,9 +311,9 @@ function buildOneRequest(validBidRequests, bidderRequest) {
295
311
  if (
296
312
  ((bannerMediaType.sizes[0].indexOf(480) >= 0) && (bannerMediaType.sizes[0].indexOf(320) >= 0)) ||
297
313
  ((bannerMediaType.sizes[0].indexOf(768) >= 0) && (bannerMediaType.sizes[0].indexOf(1024) >= 0))) {
298
- banner.pos = 7;
314
+ banner.pos = 0;
299
315
  } else {
300
- banner.pos = 4;
316
+ banner.pos = 0;
301
317
  }
302
318
 
303
319
  banner.api = api;
@@ -565,8 +581,7 @@ export function _checkParamDataType(key, value, datatype) {
565
581
  }
566
582
 
567
583
  export function _extractPageUrl(validBidRequests, bidderRequest) {
568
- // TODO: does the fallback make sense?
569
- let url = bidderRequest?.refererInfo?.page || bidderRequest.refererInfo?.topmostLocation;
584
+ let url = bidderRequest?.refererInfo?.page || bidderRequest?.refererInfo?.topmostLocation;
570
585
  return parseDomain(url, {noLeadingWww: true});
571
586
  }
572
587
 
@@ -132,14 +132,15 @@ function getUser(bidderRequest) {
132
132
  }
133
133
 
134
134
  function getSite(bidderRequest, firstPartyData) {
135
- var site = {
135
+ var site = utils.mergeDeep({
136
136
  page: utils.deepAccess(bidderRequest, 'refererInfo.page'),
137
137
  ref: utils.deepAccess(bidderRequest, 'refererInfo.ref'),
138
138
  publisher: {
139
139
  id: utils.deepAccess(bidderRequest, 'bids.0.params.publisherId'),
140
140
  },
141
- ...firstPartyData.site
142
- };
141
+ },
142
+ firstPartyData.site
143
+ );
143
144
 
144
145
  var publisherDomain = bidderRequest.refererInfo.domain;
145
146
  if (publisherDomain) {
@@ -240,7 +240,7 @@ export function setStoredValue(submodule, value) {
240
240
  const valueStr = isPlainObject(value) ? JSON.stringify(value) : value;
241
241
  if (storage.type === COOKIE) {
242
242
  const setCookie = cookieSetter(submodule);
243
- setCookie(null, value, expiresStr);
243
+ setCookie(null, valueStr, expiresStr);
244
244
  if (typeof storage.refreshInSeconds === 'number') {
245
245
  setCookie('_last', new Date().toUTCString(), expiresStr);
246
246
  }
@@ -1,4 +1,4 @@
1
- import {_each, deepAccess, parseSizesInput, parseUrl, uniques} from '../src/utils.js';
1
+ import { _each, deepAccess, parseSizesInput, parseUrl, uniques, isFn } from '../src/utils.js';
2
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
3
3
  import { BANNER } from '../src/mediaTypes.js';
4
4
  import { getStorageManager } from '../src/storageManager.js';
@@ -59,7 +59,8 @@ function isBidRequestValid(bid) {
59
59
 
60
60
  function buildRequest(bid, topWindowUrl, sizes, bidderRequest) {
61
61
  const { params, bidId, userId, adUnitCode, schain } = bid;
62
- const { bidFloor, ext } = params;
62
+ const { ext } = params;
63
+ let { bidFloor } = params;
63
64
  const hashUrl = hashCode(topWindowUrl);
64
65
  const dealId = getNextDealId(hashUrl);
65
66
  const uniqueDealId = getUniqueDealId(hashUrl);
@@ -69,6 +70,18 @@ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) {
69
70
  const subDomain = extractSubDomain(params);
70
71
  const ptrace = getCacheOpt();
71
72
 
73
+ if (isFn(bid.getFloor)) {
74
+ const floorInfo = bid.getFloor({
75
+ currency: 'USD',
76
+ mediaType: '*',
77
+ size: '*'
78
+ });
79
+
80
+ if (floorInfo.currency === 'USD') {
81
+ bidFloor = floorInfo.floor;
82
+ }
83
+ }
84
+
72
85
  let data = {
73
86
  url: encodeURIComponent(topWindowUrl),
74
87
  uqs: getTopWindowQueryParams(),
@@ -0,0 +1,180 @@
1
+ import {registerBidder} from '../src/adapters/bidderFactory.js';
2
+ import {logError, logInfo, _each, mergeDeep, isFn, isNumber, isPlainObject} from '../src/utils.js'
3
+ import {VIDEO} from '../src/mediaTypes.js';
4
+ import {Renderer} from '../src/Renderer.js';
5
+
6
+ const BIDDER_CODE = 'viqeo';
7
+ const DEFAULT_MIMES = ['application/javascript'];
8
+ const VIQEO_ENDPOINT = 'https://ads.betweendigital.com/openrtb_bid';
9
+ const RENDERER_URL = 'https://cdn.viqeo.tv/js/vq_starter.js';
10
+ const DEFAULT_CURRENCY = 'USD';
11
+ const DEFAULT_SSPID = 44697;
12
+
13
+ function getBidFloor(bid) {
14
+ const {floor, currency} = bid.params;
15
+ const curr = currency || DEFAULT_CURRENCY;
16
+ if (!isFn(bid.getFloor)) {
17
+ return {floor: isNumber(floor) ? floor : 0, currency: curr};
18
+ }
19
+ const floorInfo = bid.getFloor({currency: curr, mediaType: VIDEO, size: '*'});
20
+ if (isPlainObject(floorInfo) && isNumber(floorInfo.floor) && floorInfo.currency === curr) {
21
+ return floorInfo;
22
+ }
23
+ return {floor: floor || 0, currency: currency || DEFAULT_CURRENCY};
24
+ }
25
+
26
+ function getVideoTargetingParams({mediaTypes: {video}}) {
27
+ const result = {};
28
+ Object.keys(Object(video))
29
+ .forEach(key => {
30
+ if (key === 'playerSize') {
31
+ result.w = video.playerSize[0][0];
32
+ result.h = video.playerSize[0][1];
33
+ } else if (key !== 'context') {
34
+ result[key] = video[key];
35
+ }
36
+ })
37
+ return result;
38
+ }
39
+
40
+ /**
41
+ * @type {BidderSpec}
42
+ */
43
+ export const spec = {
44
+ code: BIDDER_CODE,
45
+ supportedMediaTypes: [VIDEO],
46
+ /**
47
+ * @param {BidRequest} bidRequest The bid params to validate.
48
+ * @return boolean True if this is a valid bid, and false otherwise.
49
+ */
50
+ isBidRequestValid: ({params}) => {
51
+ if (!params) {
52
+ logError('failed validation: params not declared');
53
+ return false;
54
+ }
55
+ if (!params.user && !params.user?.buyeruid) {
56
+ logError('failed validation: user.buyeruid not declared');
57
+ return false;
58
+ }
59
+ if (!params.playerOptions) {
60
+ logError('failed validation: playerOptions not declared');
61
+ return false;
62
+ }
63
+ const {profileId, videoId, playerId} = params.playerOptions;
64
+ if (!profileId) {
65
+ logError('failed validation: profileId not declared');
66
+ return false;
67
+ }
68
+ if (!videoId && !playerId) {
69
+ logError('failed validation: videoId or playerId not declared');
70
+ return false;
71
+ }
72
+ return true;
73
+ },
74
+ /**
75
+ * @param validBidRequests {BidRequest[]}
76
+ * @returns {ServerRequest[]}
77
+ */
78
+ buildRequests: (validBidRequests) => {
79
+ logInfo('validBidRequests', validBidRequests);
80
+ const bidRequests = [];
81
+ _each(validBidRequests, (bid, i) => {
82
+ const {
83
+ params: {test, sspId, endpointUrl},
84
+ mediaTypes: {video},
85
+ } = bid;
86
+ const ortb2 = bid.ortb2 || {};
87
+ const user = bid.params.user || {};
88
+ const device = bid.params.device || {};
89
+ const site = bid.params.site || {};
90
+ const w = window;
91
+ const floorInfo = getBidFloor(bid);
92
+ const data = {
93
+ id: bid.bidId,
94
+ test,
95
+ imp: [{
96
+ id: `${i}`,
97
+ tagid: bid.adUnitCode,
98
+ video: {
99
+ ...getVideoTargetingParams(bid),
100
+ mimes: video.mimes || DEFAULT_MIMES,
101
+ },
102
+ bidfloor: floorInfo.floor,
103
+ bidfloorcur: floorInfo.currency,
104
+ secure: 1
105
+ }],
106
+ site: test === 1 ? {
107
+ page: 'https://viqeo.tv',
108
+ domain: 'viqeo.tv'
109
+ } : mergeDeep({
110
+ domain: w.location.hostname,
111
+ page: w.location.href
112
+ }, ortb2.site, site),
113
+ device: mergeDeep({
114
+ w: w.screen.width,
115
+ h: w.screen.height,
116
+ ua: w.navigator.userAgent,
117
+ }, ortb2.device, device),
118
+ user: mergeDeep({...user}, ortb2.user),
119
+ app: bid.params.app,
120
+ };
121
+ bidRequests.push({
122
+ url: endpointUrl || `${VIQEO_ENDPOINT}/?sspId=${sspId || DEFAULT_SSPID}`,
123
+ method: 'POST',
124
+ data,
125
+ bids: validBidRequests,
126
+ });
127
+ });
128
+ return bidRequests;
129
+ },
130
+ /**
131
+ * @param {ServerResponse} serverResponse
132
+ * @param {BidRequest} bidRequests
133
+ * @return {Bid[]}
134
+ */
135
+ interpretResponse: (serverResponse, bidRequests) => {
136
+ logInfo('serverResponse', serverResponse);
137
+ const bidResponses = [];
138
+ if (!serverResponse || !serverResponse.body) {
139
+ logError('empty response');
140
+ return [];
141
+ }
142
+ try {
143
+ const {id, seatbid, cur} = serverResponse.body;
144
+ _each(seatbid, (sb) => {
145
+ const {bid} = sb;
146
+ _each(bid, (b) => {
147
+ const bidRequest = bidRequests.bids.find(({bidId}) => bidId === id);
148
+ const renderer = Renderer.install({
149
+ url: bidRequest?.params?.renderUrl || RENDERER_URL,
150
+ });
151
+ renderer.setRender((bid) => {
152
+ if (window.VIQEO) {
153
+ window.VIQEO.renderPrebid(bid);
154
+ } else {
155
+ logError('failed get window.VIQEO');
156
+ }
157
+ });
158
+ bidResponses.push({
159
+ requestId: id,
160
+ currency: cur,
161
+ cpm: b.price,
162
+ ttl: b.exp,
163
+ netRevenue: true,
164
+ creativeId: b.cid,
165
+ width: b.w || bidRequest?.mediaTypes[VIDEO].playerSize[0][0],
166
+ height: b.h || bidRequest?.mediaTypes[VIDEO].playerSize[0][1],
167
+ vastXml: b.adm,
168
+ vastUrl: b.nurl,
169
+ mediaType: VIDEO,
170
+ renderer,
171
+ })
172
+ })
173
+ });
174
+ } catch (error) {
175
+ logError(error);
176
+ }
177
+ return bidResponses;
178
+ },
179
+ }
180
+ registerBidder(spec);
@@ -0,0 +1,56 @@
1
+ # Overview
2
+
3
+ **Module Name**: Viqeo Bidder Adapter
4
+ **Module Type**: Bidder Adapter
5
+ **Maintainer**: muravjovv1@gmail.com
6
+
7
+ # Description
8
+
9
+ Viqeo Bidder Adapter for Prebid.js. About: https://viqeo.tv/
10
+
11
+ ### Bid params
12
+
13
+ {: .table .table-bordered .table-striped }
14
+ | Name | Scope | Description | Example | Type |
15
+ |-----------------------------|----------|----------------------------------------------------------------------------------------------------------------------------|--------------------------|-----------|
16
+ | `user` | required | The object containing user data (See OpenRTB spec) | `user: {}` | `object` |
17
+ | `user.buyeruid` | required | User id | `"12345"` | `string` |
18
+ | `playerOptions` | required | The object containing Viqeo player options | `playerOptions: {}` | `object` |
19
+ | `playerOptions.profileId` | required | Viqeo profile id | `1382` | `number` |
20
+ | `playerOptions.videId` | optional | Viqeo video id | `"ed584da454c7205ca7e4"` | `string` |
21
+ | `playerOptions.playerId` | optional | Viqeo player id | `1` | `number` |
22
+ | `device` | optional | The object containing device data (See OpenRTB spec) | `device: {}` | `object` |
23
+ | `site` | optional | The object containing site data (See OpenRTB spec) | `site: {}` | `object` |
24
+ | `app` | optional | The object containing app data (See OpenRTB spec) | `app: {}` | `object` |
25
+ | `floor` | optional | Bid floor price | `0.5` | `number` |
26
+ | `currency` | optional | 3-letter ISO 4217 code defining the currency of the bid. | `EUR` | `string` |
27
+ | `test` | optional | Flag which will induce a sample bid response when true; only set to true for testing purposes (1 = true, 0 = false) | `1` | `integer` |
28
+ | `sspId` | optional | For debug, request id | `1` | `number` |
29
+ | `renderUrl` | optional | For debug, script player url | `"https://viqeo.tv"` | `string` |
30
+ | `endpointUrl` | optional | For debug, api endpoint | `"https://viqeo.tv"` | `string` |
31
+
32
+ # Test Parameters
33
+ ```
34
+ var adUnits = [{
35
+ code: 'your-slot', // use exactly the same code as your slot div id.
36
+ mediaTypes: {
37
+ video: {
38
+ context: 'outstream',
39
+ playerSize: [640, 480]
40
+ }
41
+ },
42
+ bids: [{
43
+ bidder: 'viqeo',
44
+ params: {
45
+ user: {
46
+ buyeruid: '1',
47
+ },
48
+ playerOptions: {
49
+ videoId: 'ed584da454c7205ca7e4',
50
+ profileId: 1382,
51
+ },
52
+ test: 1,
53
+ }
54
+ }]
55
+ }];
56
+ ```
@@ -370,21 +370,32 @@ function getContentObject(bid) {
370
370
  }
371
371
 
372
372
  /**
373
- * Creates a string for iab_content object
373
+ * Creates a string for iab_content object by
374
+ * 1. flatten the iab content object
375
+ * 2. encoding the values
376
+ * 3. joining array of defined keys ('keyword', 'cat') into one value seperated with '|'
377
+ * 4. encoding the whole string
374
378
  * @param {Object} iabContent
375
379
  * @returns {String}
376
380
  */
377
381
  function createIabContentString(iabContent) {
378
382
  const arrKeys = ['keywords', 'cat']
379
383
  const str = []
380
- for (const key in iabContent) {
381
- if (iabContent.hasOwnProperty(key)) {
382
- const value = (arrKeys.indexOf(key) !== -1 && Array.isArray(iabContent[key]))
383
- ? iabContent[key].map(node => encodeURIComponent(node)).join('|') : encodeURIComponent(iabContent[key])
384
- str.push(''.concat(key, ':', value))
384
+ const transformObjToParam = (obj = {}, extraKey = '') => {
385
+ for (const key in obj) {
386
+ if ((arrKeys.indexOf(key) !== -1 && Array.isArray(obj[key]))) {
387
+ // Array of defined keyword which have to be joined into one value from "key: [value1, value2, value3]" to "key:value1|value2|value3"
388
+ str.push(''.concat(key, ':', obj[key].map(node => encodeURIComponent(node)).join('|')))
389
+ } else if (typeof obj[key] !== 'object') {
390
+ str.push(''.concat(extraKey + key, ':', encodeURIComponent(obj[key])))
391
+ } else {
392
+ // Object has to be further flattened
393
+ transformObjToParam(obj[key], ''.concat(extraKey, key, '.'));
394
+ }
385
395
  }
386
- }
387
- return encodeURIComponent(str.join(','))
396
+ return str.join(',');
397
+ };
398
+ return encodeURIComponent(transformObjToParam(iabContent))
388
399
  }
389
400
 
390
401
  /**