prebid.js 7.23.0 → 7.24.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 (159) 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 -0
  6. package/dist/adrelevantisBidAdapter.js +1 -1
  7. package/dist/adtrgtmeBidAdapter.js +1 -1
  8. package/dist/adxcgBidAdapter.js +1 -1
  9. package/dist/adyoulikeBidAdapter.js +1 -1
  10. package/dist/ajaBidAdapter.js +1 -1
  11. package/dist/amxBidAdapter.js +1 -1
  12. package/dist/amxIdSystem.js +1 -1
  13. package/dist/appierAnalyticsAdapter.js +1 -1
  14. package/dist/appnexusBidAdapter.js +1 -1
  15. package/dist/asoBidAdapter.js +1 -1
  16. package/dist/audiencerunBidAdapter.js +1 -1
  17. package/dist/axonixBidAdapter.js +1 -1
  18. package/dist/bidglassBidAdapter.js +1 -1
  19. package/dist/big-richmediaBidAdapter.js +1 -1
  20. package/dist/bluebillywigBidAdapter.js +1 -1
  21. package/dist/bridgewellBidAdapter.js +1 -1
  22. package/dist/brightMountainMediaBidAdapter.js +1 -1
  23. package/dist/carodaBidAdapter.js +1 -1
  24. package/dist/chtnwBidAdapter.js +1 -1
  25. package/dist/concertBidAdapter.js +1 -1
  26. package/dist/connectIdSystem.js +1 -1
  27. package/dist/connectadBidAdapter.js +1 -1
  28. package/dist/consumableBidAdapter.js +1 -1
  29. package/dist/conversantBidAdapter.js +1 -1
  30. package/dist/craftBidAdapter.js +1 -1
  31. package/dist/criteoBidAdapter.js +1 -1
  32. package/dist/dspxBidAdapter.js +1 -1
  33. package/dist/eplanningBidAdapter.js +1 -1
  34. package/dist/finativeBidAdapter.js +1 -1
  35. package/dist/glimpseBidAdapter.js +1 -1
  36. package/dist/gmosspBidAdapter.js +1 -1
  37. package/dist/goldbachBidAdapter.js +1 -1
  38. package/dist/gridBidAdapter.js +1 -1
  39. package/dist/gridNMBidAdapter.js +1 -1
  40. package/dist/growthCodeIdSystem.js +1 -1
  41. package/dist/gumgumBidAdapter.js +1 -1
  42. package/dist/h12mediaBidAdapter.js +1 -1
  43. package/dist/id5IdSystem.js +1 -1
  44. package/dist/impactifyBidAdapter.js +1 -1
  45. package/dist/improvedigitalBidAdapter.js +1 -1
  46. package/dist/inmarBidAdapter.js +1 -1
  47. package/dist/insticatorBidAdapter.js +1 -1
  48. package/dist/ixBidAdapter.js +1 -1
  49. package/dist/jixieBidAdapter.js +1 -1
  50. package/dist/justpremiumBidAdapter.js +1 -1
  51. package/dist/konduitAnalyticsAdapter.js +1 -1
  52. package/dist/kueezBidAdapter.js +1 -1
  53. package/dist/kueezRtbBidAdapter.js +1 -0
  54. package/dist/lassoBidAdapter.js +1 -1
  55. package/dist/lifestreetBidAdapter.js +1 -1
  56. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  57. package/dist/logicadBidAdapter.js +1 -1
  58. package/dist/loglyliftBidAdapter.js +1 -1
  59. package/dist/magniteAnalyticsAdapter.js +1 -1
  60. package/dist/malltvAnalyticsAdapter.js +1 -1
  61. package/dist/marsmediaBidAdapter.js +1 -1
  62. package/dist/mediafuseBidAdapter.js +1 -1
  63. package/dist/mediakeysBidAdapter.js +1 -1
  64. package/dist/mediasquareBidAdapter.js +1 -1
  65. package/dist/mgidBidAdapter.js +1 -1
  66. package/dist/mgidRtdProvider.js +1 -0
  67. package/dist/minutemediaBidAdapter.js +1 -1
  68. package/dist/not-for-prod/prebid.js +122 -119
  69. package/dist/oguryBidAdapter.js +1 -1
  70. package/dist/onetagBidAdapter.js +1 -1
  71. package/dist/ooloAnalyticsAdapter.js +1 -1
  72. package/dist/outbrainBidAdapter.js +1 -1
  73. package/dist/parrableIdSystem.js +1 -1
  74. package/dist/pbsExtensions.js +1 -1
  75. package/dist/permutiveRtdProvider.js +1 -1
  76. package/dist/pixfutureBidAdapter.js +1 -1
  77. package/dist/prebid-core.js +1 -1
  78. package/dist/publinkIdSystem.js +1 -1
  79. package/dist/pubmaticBidAdapter.js +1 -1
  80. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  81. package/dist/pxyzBidAdapter.js +1 -1
  82. package/dist/quantcastBidAdapter.js +1 -1
  83. package/dist/readpeakBidAdapter.js +1 -1
  84. package/dist/relaidoBidAdapter.js +1 -1
  85. package/dist/rhythmoneBidAdapter.js +1 -1
  86. package/dist/riseBidAdapter.js +1 -1
  87. package/dist/rubiconAnalyticsAdapter.js +1 -1
  88. package/dist/rubiconBidAdapter.js +1 -1
  89. package/dist/seedingAllianceBidAdapter.js +1 -1
  90. package/dist/seedtagBidAdapter.js +1 -1
  91. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  92. package/dist/sharethroughBidAdapter.js +1 -1
  93. package/dist/shinezBidAdapter.js +1 -1
  94. package/dist/smaatoBidAdapter.js +1 -1
  95. package/dist/smartadserverBidAdapter.js +1 -1
  96. package/dist/smartxBidAdapter.js +1 -1
  97. package/dist/smilewantedBidAdapter.js +1 -1
  98. package/dist/sonobiBidAdapter.js +1 -1
  99. package/dist/sovrnAnalyticsAdapter.js +1 -1
  100. package/dist/sovrnBidAdapter.js +1 -1
  101. package/dist/sspBCBidAdapter.js +1 -1
  102. package/dist/sublimeBidAdapter.js +1 -1
  103. package/dist/synacormediaBidAdapter.js +1 -1
  104. package/dist/targetVideoBidAdapter.js +1 -1
  105. package/dist/teadsBidAdapter.js +1 -1
  106. package/dist/trionBidAdapter.js +1 -1
  107. package/dist/tripleliftBidAdapter.js +1 -1
  108. package/dist/ttdBidAdapter.js +1 -1
  109. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  110. package/dist/underdogmediaBidAdapter.js +1 -1
  111. package/dist/undertoneBidAdapter.js +1 -1
  112. package/dist/userId.js +1 -1
  113. package/dist/vidazooBidAdapter.js +1 -1
  114. package/dist/videobyteBidAdapter.js +1 -1
  115. package/dist/visxBidAdapter.js +1 -1
  116. package/dist/vuukleBidAdapter.js +1 -1
  117. package/dist/widespaceBidAdapter.js +1 -1
  118. package/dist/winrBidAdapter.js +1 -1
  119. package/dist/yahoosspBidAdapter.js +1 -1
  120. package/dist/yieldmoBidAdapter.js +1 -1
  121. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  122. package/integrationExamples/gpt/mgidRtdProvider_example.html +143 -0
  123. package/modules/.submodules.json +1 -0
  124. package/modules/admaticBidAdapter.js +147 -0
  125. package/modules/admaticBidAdapter.md +48 -0
  126. package/modules/amxBidAdapter.js +1 -0
  127. package/modules/connectIdSystem.js +36 -23
  128. package/modules/connectIdSystem.md +3 -2
  129. package/modules/growthCodeIdSystem.js +9 -5
  130. package/modules/gumgumBidAdapter.js +4 -0
  131. package/modules/ixBidAdapter.js +30 -7
  132. package/modules/kueezRtbBidAdapter.js +278 -0
  133. package/modules/kueezRtbBidAdapter.md +35 -0
  134. package/modules/magniteAnalyticsAdapter.js +6 -1
  135. package/modules/mgidRtdProvider.js +190 -0
  136. package/modules/mgidRtdProvider.md +51 -0
  137. package/modules/permutiveRtdProvider.js +2 -1
  138. package/modules/permutiveRtdProvider.md +36 -1
  139. package/modules/pubmaticBidAdapter.js +21 -29
  140. package/modules/tripleliftBidAdapter.js +1 -1
  141. package/modules/userId/eids.js +3 -10
  142. package/package.json +8 -8
  143. package/src/adRendering.js +1 -1
  144. package/src/adloader.js +1 -0
  145. package/src/auction.js +1 -1
  146. package/src/prebid.js +83 -79
  147. package/test/spec/auctionmanager_spec.js +9 -0
  148. package/test/spec/modules/admaticBidAdapter_spec.js +46 -0
  149. package/test/spec/modules/connectIdSystem_spec.js +175 -5
  150. package/test/spec/modules/eids_spec.js +10 -7
  151. package/test/spec/modules/ftrackIdSystem_spec.js +34 -22
  152. package/test/spec/modules/gumgumBidAdapter_spec.js +15 -0
  153. package/test/spec/modules/ixBidAdapter_spec.js +203 -0
  154. package/test/spec/modules/kueezRtbBidAdapter_spec.js +396 -0
  155. package/test/spec/modules/magniteAnalyticsAdapter_spec.js +26 -0
  156. package/test/spec/modules/mgidRtdProvider_spec.js +366 -0
  157. package/test/spec/modules/permutiveRtdProvider_spec.js +64 -5
  158. package/test/spec/modules/tripleliftBidAdapter_spec.js +14 -0
  159. package/test/spec/unit/pbjs_api_spec.js +17 -1
@@ -38,7 +38,6 @@ const BANNER_TIME_TO_LIVE = 300;
38
38
  const VIDEO_TIME_TO_LIVE = 3600; // 1hr
39
39
  const NATIVE_TIME_TO_LIVE = 3600; // Since native can have video, use ttl same as video
40
40
  const NET_REVENUE = true;
41
- const MAX_REQUEST_SIZE = 8000;
42
41
  const MAX_REQUEST_LIMIT = 4;
43
42
  const OUTSTREAM_MINIMUM_PLAYER_SIZE = [144, 144];
44
43
  const PRICE_TO_DOLLAR_FACTOR = {
@@ -159,7 +158,7 @@ const MEDIA_TYPES = {
159
158
  * @return {object} A impression object that will be sent to ad server.
160
159
  */
161
160
  function bidToBannerImp(bid) {
162
- const imp = bidToImp(bid);
161
+ const imp = bidToImp(bid, BANNER);
163
162
  imp.banner = {};
164
163
  const impSize = deepAccess(bid, 'params.size');
165
164
  if (impSize) {
@@ -181,7 +180,7 @@ function bidToBannerImp(bid) {
181
180
  * @return {object} A impression object that will be sent to ad server.
182
181
  */
183
182
  function bidToVideoImp(bid) {
184
- const imp = bidToImp(bid);
183
+ const imp = bidToImp(bid, VIDEO);
185
184
  const videoAdUnitRef = deepAccess(bid, 'mediaTypes.video');
186
185
  const videoParamRef = deepAccess(bid, 'params.video');
187
186
  const videoParamErrors = checkVideoParams(videoAdUnitRef, videoParamRef);
@@ -249,7 +248,7 @@ function bidToVideoImp(bid) {
249
248
  * @return {object} A impression object that will be sent to ad server.
250
249
  */
251
250
  function bidToNativeImp(bid) {
252
- const imp = bidToImp(bid);
251
+ const imp = bidToImp(bid, NATIVE);
253
252
 
254
253
  const request = bid.nativeOrtbRequest
255
254
  request.eventtrackers = [{
@@ -276,13 +275,28 @@ function bidToNativeImp(bid) {
276
275
  * @param {object} bid PBJS bid object
277
276
  * @returns {object} IX impression object
278
277
  */
279
- function bidToImp(bid) {
278
+ function bidToImp(bid, mediaType) {
280
279
  const imp = {};
281
280
 
282
281
  imp.id = bid.bidId;
283
282
 
284
283
  imp.ext = {};
285
- imp.ext.siteID = bid.params.siteId.toString();
284
+
285
+ if (deepAccess(bid, `params.${mediaType}.siteId`) && !isNaN(Number(bid.params[mediaType].siteId))) {
286
+ switch (mediaType) {
287
+ case BANNER:
288
+ imp.ext.siteID = bid.params.banner.siteId.toString();
289
+ break;
290
+ case VIDEO:
291
+ imp.ext.siteID = bid.params.video.siteId.toString();
292
+ break;
293
+ case NATIVE:
294
+ imp.ext.siteID = bid.params.native.siteId.toString();
295
+ break;
296
+ }
297
+ } else {
298
+ imp.ext.siteID = bid.params.siteId.toString();
299
+ }
286
300
 
287
301
  // populate imp level sid
288
302
  if (bid.params.hasOwnProperty('id') && (typeof bid.params.id === 'string' || typeof bid.params.id === 'number')) {
@@ -586,6 +600,12 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
586
600
  let userEids = eidInfo.toSend;
587
601
  const pageUrl = deepAccess(bidderRequest, 'refererInfo.page');
588
602
 
603
+ let MAX_REQUEST_SIZE = 8000;
604
+ // Modify request size limit if its FT is enabeld.
605
+ if (FEATURE_TOGGLES.isFeatureEnabled('pbjs_use_32kb_size_limit')) {
606
+ MAX_REQUEST_SIZE = 32000
607
+ }
608
+
589
609
  // RTI ids will be included in the bid request if the function getIdentityInfo() is loaded
590
610
  // and if the data for the partner exist
591
611
  if (window.headertag && typeof window.headertag.getIdentityInfo === 'function') {
@@ -642,6 +662,9 @@ function buildRequest(validBidRequests, bidderRequest, impressions, version) {
642
662
  r.ext.ixdiag.err = cachedErrors;
643
663
  }
644
664
 
665
+ // Add number of available imps to ixDiag.
666
+ r.ext.ixdiag.imps = Object.keys(impressions).length;
667
+
645
668
  // set source.tid to auctionId for outgoing request to Exchange.
646
669
  r.source = {
647
670
  tid: validBidRequests[0].auctionId,
@@ -1418,7 +1441,7 @@ export const spec = {
1418
1441
 
1419
1442
  // Step 1: Create impresssions from IX params
1420
1443
  validBidRequests.forEach((validBidRequest) => {
1421
- const adUnitMediaTypes = Object.keys(deepAccess(validBidRequest, 'mediaTypes', {}))
1444
+ const adUnitMediaTypes = Object.keys(deepAccess(validBidRequest, 'mediaTypes', {}));
1422
1445
 
1423
1446
  for (const type in adUnitMediaTypes) {
1424
1447
  switch (adUnitMediaTypes[type]) {
@@ -0,0 +1,278 @@
1
+ import { _each, deepAccess, parseSizesInput, parseUrl, uniques, isFn } from '../src/utils.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+ import { BANNER } from '../src/mediaTypes.js';
4
+ import { getStorageManager } from '../src/storageManager.js';
5
+
6
+ const GVLID = 1165;
7
+ const DEFAULT_SUB_DOMAIN = 'exchange';
8
+ const BIDDER_CODE = 'kueezrtb';
9
+ const BIDDER_VERSION = '1.0.0';
10
+ const CURRENCY = 'USD';
11
+ const TTL_SECONDS = 60 * 5;
12
+ const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15;
13
+ export const SUPPORTED_ID_SYSTEMS = {
14
+ 'britepoolid': 1,
15
+ 'criteoId': 1,
16
+ 'id5id': 1,
17
+ 'idl_env': 1,
18
+ 'lipb': 1,
19
+ 'netId': 1,
20
+ 'parrableId': 1,
21
+ 'pubcid': 1,
22
+ 'tdid': 1,
23
+ 'pubProvidedId': 1
24
+ };
25
+ const storage = getStorageManager({ gvlid: GVLID, bidderCode: BIDDER_CODE });
26
+
27
+ function getTopWindowQueryParams() {
28
+ try {
29
+ const parsedUrl = parseUrl(window.top.document.URL, { decodeSearchAsString: true });
30
+ return parsedUrl.search;
31
+ } catch (e) {
32
+ return '';
33
+ }
34
+ }
35
+
36
+ export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) {
37
+ return `https://${subDomain}.kueezrtb.com`;
38
+ }
39
+
40
+ export function extractCID(params) {
41
+ return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD;
42
+ }
43
+
44
+ export function extractPID(params) {
45
+ return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD;
46
+ }
47
+
48
+ export function extractSubDomain(params) {
49
+ return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN;
50
+ }
51
+
52
+ function isBidRequestValid(bid) {
53
+ const params = bid.params || {};
54
+ return !!(extractCID(params) && extractPID(params));
55
+ }
56
+
57
+ function buildRequest(bid, topWindowUrl, sizes, bidderRequest) {
58
+ const { params, bidId, userId, adUnitCode, schain } = bid;
59
+ let { bidFloor, ext } = params;
60
+ const hashUrl = hashCode(topWindowUrl);
61
+ const uniqueDealId = getUniqueDealId(hashUrl);
62
+ const cId = extractCID(params);
63
+ const pId = extractPID(params);
64
+ const subDomain = extractSubDomain(params);
65
+
66
+ if (isFn(bid.getFloor)) {
67
+ const floorInfo = bid.getFloor({
68
+ currency: 'USD',
69
+ mediaType: '*',
70
+ size: '*'
71
+ });
72
+
73
+ if (floorInfo.currency === 'USD') {
74
+ bidFloor = floorInfo.floor;
75
+ }
76
+ }
77
+
78
+ let data = {
79
+ url: encodeURIComponent(topWindowUrl),
80
+ uqs: getTopWindowQueryParams(),
81
+ cb: Date.now(),
82
+ bidFloor: bidFloor,
83
+ bidId: bidId,
84
+ referrer: bidderRequest.refererInfo.ref,
85
+ adUnitCode: adUnitCode,
86
+ publisherId: pId,
87
+ sizes: sizes,
88
+ uniqueDealId: uniqueDealId,
89
+ bidderVersion: BIDDER_VERSION,
90
+ prebidVersion: '$prebid.version$',
91
+ res: `${screen.width}x${screen.height}`,
92
+ schain: schain
93
+ };
94
+
95
+ appendUserIdsToRequestPayload(data, userId);
96
+
97
+ if (bidderRequest.gdprConsent) {
98
+ if (bidderRequest.gdprConsent.consentString) {
99
+ data.gdprConsent = bidderRequest.gdprConsent.consentString;
100
+ }
101
+ if (bidderRequest.gdprConsent.gdprApplies !== undefined) {
102
+ data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0;
103
+ }
104
+ }
105
+ if (bidderRequest.uspConsent) {
106
+ data.usPrivacy = bidderRequest.uspConsent;
107
+ }
108
+
109
+ const dto = {
110
+ method: 'POST',
111
+ url: `${createDomain(subDomain)}/prebid/multi/${cId}`,
112
+ data: data
113
+ };
114
+
115
+ _each(ext, (value, key) => {
116
+ dto.data['ext.' + key] = value;
117
+ });
118
+
119
+ return dto;
120
+ }
121
+
122
+ function appendUserIdsToRequestPayload(payloadRef, userIds) {
123
+ let key;
124
+ _each(userIds, (userId, idSystemProviderName) => {
125
+ if (SUPPORTED_ID_SYSTEMS[idSystemProviderName]) {
126
+ key = `uid.${idSystemProviderName}`;
127
+
128
+ switch (idSystemProviderName) {
129
+ case 'digitrustid':
130
+ payloadRef[key] = deepAccess(userId, 'data.id');
131
+ break;
132
+ case 'lipb':
133
+ payloadRef[key] = userId.lipbid;
134
+ break;
135
+ case 'parrableId':
136
+ payloadRef[key] = userId.eid;
137
+ break;
138
+ case 'id5id':
139
+ payloadRef[key] = userId.uid;
140
+ break;
141
+ default:
142
+ payloadRef[key] = userId;
143
+ }
144
+ }
145
+ });
146
+ }
147
+
148
+ function buildRequests(validBidRequests, bidderRequest) {
149
+ const topWindowUrl = bidderRequest.refererInfo.page || bidderRequest.refererInfo.topmostLocation;
150
+ const requests = [];
151
+ validBidRequests.forEach(validBidRequest => {
152
+ const sizes = parseSizesInput(validBidRequest.sizes);
153
+ const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest);
154
+ requests.push(request);
155
+ });
156
+ return requests;
157
+ }
158
+
159
+ function interpretResponse(serverResponse, request) {
160
+ if (!serverResponse || !serverResponse.body) {
161
+ return [];
162
+ }
163
+ const { bidId } = request.data;
164
+ const { results } = serverResponse.body;
165
+
166
+ let output = [];
167
+
168
+ try {
169
+ results.forEach(result => {
170
+ const { creativeId, ad, price, exp, width, height, currency, advertiserDomains } = result;
171
+ if (!ad || !price) {
172
+ return;
173
+ }
174
+ output.push({
175
+ requestId: bidId,
176
+ cpm: price,
177
+ width: width,
178
+ height: height,
179
+ creativeId: creativeId,
180
+ currency: currency || CURRENCY,
181
+ netRevenue: true,
182
+ ttl: exp || TTL_SECONDS,
183
+ ad: ad,
184
+ meta: {
185
+ advertiserDomains: advertiserDomains || []
186
+ }
187
+ })
188
+ });
189
+ return output;
190
+ } catch (e) {
191
+ return [];
192
+ }
193
+ }
194
+
195
+ function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '') {
196
+ let syncs = [];
197
+ const { iframeEnabled, pixelEnabled } = syncOptions;
198
+ const { gdprApplies, consentString = '' } = gdprConsent;
199
+
200
+ const cidArr = responses.filter(resp => deepAccess(resp, 'body.cid')).map(resp => resp.body.cid).filter(uniques);
201
+ const params = `?cid=${encodeURIComponent(cidArr.join(','))}&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}`
202
+ if (iframeEnabled) {
203
+ syncs.push({
204
+ type: 'iframe',
205
+ url: `https://sync.kueezrtb.com/api/sync/iframe/${params}`
206
+ });
207
+ }
208
+ if (pixelEnabled) {
209
+ syncs.push({
210
+ type: 'image',
211
+ url: `https://sync.kueezrtb.com/api/sync/image/${params}`
212
+ });
213
+ }
214
+ return syncs;
215
+ }
216
+
217
+ export function hashCode(s, prefix = '_') {
218
+ const l = s.length;
219
+ let h = 0
220
+ let i = 0;
221
+ if (l > 0) {
222
+ while (i < l) { h = (h << 5) - h + s.charCodeAt(i++) | 0; }
223
+ }
224
+ return prefix + h;
225
+ }
226
+
227
+ export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) {
228
+ const storageKey = `u_${key}`;
229
+ const now = Date.now();
230
+ const data = getStorageItem(storageKey);
231
+ let uniqueId;
232
+
233
+ if (!data || !data.value || now - data.created > expiry) {
234
+ uniqueId = `${key}_${now.toString()}`;
235
+ setStorageItem(storageKey, uniqueId);
236
+ } else {
237
+ uniqueId = data.value;
238
+ }
239
+
240
+ return uniqueId;
241
+ }
242
+
243
+ export function getStorageItem(key) {
244
+ try {
245
+ return tryParseJSON(storage.getDataFromLocalStorage(key));
246
+ } catch (e) { }
247
+
248
+ return null;
249
+ }
250
+
251
+ export function setStorageItem(key, value, timestamp) {
252
+ try {
253
+ const created = timestamp || Date.now();
254
+ const data = JSON.stringify({ value, created });
255
+ storage.setDataInLocalStorage(key, data);
256
+ } catch (e) { }
257
+ }
258
+
259
+ export function tryParseJSON(value) {
260
+ try {
261
+ return JSON.parse(value);
262
+ } catch (e) {
263
+ return value;
264
+ }
265
+ }
266
+
267
+ export const spec = {
268
+ code: BIDDER_CODE,
269
+ version: BIDDER_VERSION,
270
+ gvlid: GVLID,
271
+ supportedMediaTypes: [BANNER],
272
+ isBidRequestValid,
273
+ buildRequests,
274
+ interpretResponse,
275
+ getUserSyncs
276
+ };
277
+
278
+ registerBidder(spec);
@@ -0,0 +1,35 @@
1
+ # Overview
2
+
3
+ **Module Name:** Kueez RTB Bidder Adapter
4
+
5
+ **Module Type:** Bidder Adapter
6
+
7
+ **Maintainer:** rtb@kueez.com
8
+
9
+ # Description
10
+
11
+ Module that connects to Kueez's demand sources.
12
+
13
+ # Test Parameters
14
+ ```js
15
+ var adUnits = [
16
+ {
17
+ code: 'test-ad',
18
+ sizes: [[300, 250]],
19
+ bids: [
20
+ {
21
+ bidder: 'kueezrtb',
22
+ params: {
23
+ cId: '562524b21b1c1f08117fc7f9',
24
+ pId: '59ac17c192832d0011283fe3',
25
+ bidFloor: 0.0001,
26
+ ext: {
27
+ param1: 'loremipsum',
28
+ param2: 'dolorsitamet'
29
+ }
30
+ }
31
+ }
32
+ ]
33
+ }
34
+ ];
35
+ ```
@@ -254,9 +254,14 @@ export const parseBidResponse = (bid, previousBidResponse) => {
254
254
  const validAdomains = Array.isArray(adomains) && adomains.filter(domain => typeof domain === 'string');
255
255
  return validAdomains && validAdomains.length > 0 ? validAdomains.slice(0, 10) : undefined
256
256
  },
257
+ 'networkId', () => {
258
+ const networkId = deepAccess(bid, 'meta.networkId');
259
+ // if not a valid after this, set to undefined so it gets filtered out
260
+ return (networkId && networkId.toString()) || undefined;
261
+ },
257
262
  'conversionError', conversionError => conversionError === true || undefined, // only pass if exactly true
258
263
  'ogCurrency',
259
- 'ogPrice'
264
+ 'ogPrice',
260
265
  ]);
261
266
  }
262
267
 
@@ -0,0 +1,190 @@
1
+ import { submodule } from '../src/hook.js';
2
+ import {ajax} from '../src/ajax.js';
3
+ import {deepAccess, logError, logInfo, mergeDeep} from '../src/utils.js';
4
+ import {getStorageManager} from '../src/storageManager.js';
5
+ import {getRefererInfo} from '../src/refererDetection.js';
6
+
7
+ const MODULE_NAME = 'realTimeData';
8
+ const SUBMODULE_NAME = 'mgid';
9
+ const MGID_RTD_API_URL = 'https://servicer.mgid.com/sda';
10
+ const MGUID_LOCAL_STORAGE_KEY = 'mguid';
11
+ const ORTB2_NAME = 'www.mgid.com'
12
+
13
+ const GVLID = 358;
14
+ /** @type {?Object} */
15
+ export const storage = getStorageManager({
16
+ gvlid: GVLID,
17
+ moduleName: SUBMODULE_NAME
18
+ });
19
+
20
+ function init(moduleConfig) {
21
+ if (!moduleConfig?.params?.clientSiteId) {
22
+ logError('Mgid clientSiteId is not set!');
23
+ return false;
24
+ }
25
+ return true;
26
+ }
27
+
28
+ function getBidRequestData(reqBidsConfigObj, onDone, moduleConfig, userConsent) {
29
+ let mguid;
30
+ try {
31
+ mguid = storage.getDataFromLocalStorage(MGUID_LOCAL_STORAGE_KEY);
32
+ } catch (e) {
33
+ logInfo(`Can't get mguid from localstorage`);
34
+ }
35
+
36
+ const params = [
37
+ {
38
+ name: 'gdprApplies',
39
+ data: typeof userConsent?.gdpr?.gdprApplies !== 'undefined' ? userConsent?.gdpr?.gdprApplies + '' : undefined,
40
+ },
41
+ {
42
+ name: 'consentData',
43
+ data: userConsent?.gdpr?.consentString,
44
+ },
45
+ {
46
+ name: 'uspString',
47
+ data: userConsent?.usp,
48
+ },
49
+ {
50
+ name: 'cxurl',
51
+ data: encodeURIComponent(getContextUrl()),
52
+ },
53
+ {
54
+ name: 'muid',
55
+ data: mguid,
56
+ },
57
+ {
58
+ name: 'clientSiteId',
59
+ data: moduleConfig?.params?.clientSiteId,
60
+ },
61
+ {
62
+ name: 'cxlang',
63
+ data: deepAccess(reqBidsConfigObj.ortb2Fragments.global, 'site.content.language'),
64
+ },
65
+ ];
66
+
67
+ const url = MGID_RTD_API_URL + '?' + params.filter((p) => p.data).map((p) => p.name + '=' + p.data).join('&');
68
+
69
+ let isDone = false;
70
+
71
+ ajax(url, {
72
+ success: (response, req) => {
73
+ if (req.status === 200) {
74
+ try {
75
+ const data = JSON.parse(response);
76
+ const ortb2 = reqBidsConfigObj?.ortb2Fragments?.global || {};
77
+
78
+ mergeDeep(ortb2, getDataForMerge(data));
79
+
80
+ if (data?.muid) {
81
+ try {
82
+ mguid = storage.setDataInLocalStorage(MGUID_LOCAL_STORAGE_KEY, data.muid);
83
+ } catch (e) {
84
+ logInfo(`Can't set mguid to localstorage`);
85
+ }
86
+ }
87
+
88
+ onDone();
89
+ isDone = true;
90
+ } catch (e) {
91
+ onDone();
92
+ isDone = true;
93
+
94
+ logError('Unable to parse Mgid RTD data', e);
95
+ }
96
+ } else {
97
+ onDone();
98
+ isDone = true;
99
+
100
+ logError('Mgid RTD wrong response status');
101
+ }
102
+ },
103
+ error: () => {
104
+ onDone();
105
+ isDone = true;
106
+
107
+ logError('Unable to get Mgid RTD data');
108
+ }
109
+ },
110
+ null, {
111
+ method: 'GET',
112
+ withCredentials: false,
113
+ });
114
+
115
+ setTimeout(function () {
116
+ if (!isDone) {
117
+ onDone();
118
+ logInfo('Mgid RTD timeout');
119
+ isDone = true;
120
+ }
121
+ }, moduleConfig.params.timeout || 1000);
122
+ }
123
+
124
+ function getContextUrl() {
125
+ const refererInfo = getRefererInfo();
126
+
127
+ let resultUrl = refererInfo.canonicalUrl || refererInfo.topmostLocation;
128
+
129
+ const metaElements = document.getElementsByTagName('meta');
130
+ for (let i = 0; i < metaElements.length; i++) {
131
+ if (metaElements[i].getAttribute('property') === 'og:url') {
132
+ resultUrl = metaElements[i].content;
133
+ }
134
+ }
135
+
136
+ return resultUrl;
137
+ }
138
+
139
+ function getDataForMerge(responseData) {
140
+ let siteData = {
141
+ name: ORTB2_NAME
142
+ };
143
+ let userData = {
144
+ name: ORTB2_NAME
145
+ };
146
+
147
+ if (responseData.siteSegments) {
148
+ siteData.segment = responseData.siteSegments.map((segmentId) => ({ id: segmentId }));
149
+ }
150
+ if (responseData.siteSegtax) {
151
+ siteData.ext = {
152
+ segtax: responseData.siteSegtax
153
+ }
154
+ }
155
+
156
+ if (responseData.userSegments) {
157
+ userData.segment = responseData.userSegments.map((segmentId) => ({ id: segmentId }));
158
+ }
159
+ if (responseData.userSegtax) {
160
+ userData.ext = {
161
+ segtax: responseData.userSegtax
162
+ }
163
+ }
164
+
165
+ let result = {};
166
+ if (siteData.segment || siteData.ext) {
167
+ result.site = {
168
+ content: {
169
+ data: [siteData],
170
+ }
171
+ }
172
+ }
173
+
174
+ if (userData.segment || userData.ext) {
175
+ result.user = {
176
+ data: [userData],
177
+ }
178
+ }
179
+
180
+ return result;
181
+ }
182
+
183
+ /** @type {RtdSubmodule} */
184
+ export const mgidSubmodule = {
185
+ name: SUBMODULE_NAME,
186
+ init: init,
187
+ getBidRequestData: getBidRequestData,
188
+ };
189
+
190
+ submodule(MODULE_NAME, mgidSubmodule);
@@ -0,0 +1,51 @@
1
+ # Overview
2
+
3
+ ```
4
+ Module Name: Mgid RTD Provider
5
+ Module Type: RTD Provider
6
+ Maintainer: prebid@mgid.com
7
+ ```
8
+
9
+ # Description
10
+
11
+ Mgid RTD module allows you to enrich bid data with contextual and audience signals, based on IAB taxonomies.
12
+
13
+ ## Configuration
14
+
15
+ This module is configured as part of the `realTimeData.dataProviders` object.
16
+
17
+ {: .table .table-bordered .table-striped }
18
+ | Name | Scope | Description | Example | Type |
19
+ |------------|----------|----------------------------------------|---------------|----------|
20
+ | `name ` | required | Real time data module name | `'mgid'` | `string` |
21
+ | `params` | required | | | `Object` |
22
+ | `params.clientSiteId` | required | The client site id provided by Mgid. | `'123456'` | `string` |
23
+ | `params.timeout` | optional | Maximum amount of milliseconds allowed for module to finish working | `1000` | `number` |
24
+
25
+ #### Example
26
+
27
+ ```javascript
28
+ pbjs.setConfig({
29
+ realTimeData: {
30
+ dataProviders: [{
31
+ name: 'mgid',
32
+ params: {
33
+ clientSiteId: '123456'
34
+ }
35
+ }]
36
+ }
37
+ });
38
+ ```
39
+
40
+ ## Integration
41
+ To install the module, follow these instructions:
42
+
43
+ #### Step 1: Prepare the base Prebid file
44
+
45
+ - Option 1: Use Prebid [Download](/download.html) page to build the prebid package. Ensure that you do check *Mgid Realtime Module* module
46
+
47
+ - Option 2: From the command line, run `gulp build --modules=mgidRtdProvider,...`
48
+
49
+ #### Step 2: Set configuration
50
+
51
+ Enable Mgid Real Time Module using `pbjs.setConfig`. Example is provided in Configuration section.
@@ -238,7 +238,8 @@ function getDefaultBidderFn (bidder) {
238
238
  deepSetValue(bid, 'params.visitor.p_standard', data.ac)
239
239
  }
240
240
  if (data.rubicon && data.rubicon.length) {
241
- deepSetValue(bid, 'params.visitor.permutive', data.rubicon)
241
+ const rubiconCohorts = deepAccess(bid, 'params.video') ? data.rubicon.map(String) : data.rubicon
242
+ deepSetValue(bid, 'params.visitor.permutive', rubiconCohorts)
242
243
  }
243
244
 
244
245
  return bid