prebid.js 6.29.2 → 6.29.3

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 (112) 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/adrelevantisBidAdapter.js +1 -1
  6. package/dist/adxcgBidAdapter.js +1 -1
  7. package/dist/ajaBidAdapter.js +1 -1
  8. package/dist/amxBidAdapter.js +1 -1
  9. package/dist/amxIdSystem.js +1 -1
  10. package/dist/appierAnalyticsAdapter.js +1 -1
  11. package/dist/appnexusBidAdapter.js +1 -1
  12. package/dist/asoBidAdapter.js +1 -1
  13. package/dist/axonixBidAdapter.js +1 -1
  14. package/dist/bidglassBidAdapter.js +1 -1
  15. package/dist/bidwatchAnalyticsAdapter.js +1 -1
  16. package/dist/big-richmediaBidAdapter.js +1 -1
  17. package/dist/bridgewellBidAdapter.js +1 -1
  18. package/dist/brightMountainMediaBidAdapter.js +1 -1
  19. package/dist/concertBidAdapter.js +1 -1
  20. package/dist/connectadBidAdapter.js +1 -1
  21. package/dist/consumableBidAdapter.js +1 -1
  22. package/dist/conversantBidAdapter.js +1 -1
  23. package/dist/craftBidAdapter.js +1 -1
  24. package/dist/criteoBidAdapter.js +1 -1
  25. package/dist/dspxBidAdapter.js +1 -1
  26. package/dist/eplanningBidAdapter.js +1 -1
  27. package/dist/glimpseBidAdapter.js +1 -1
  28. package/dist/gmosspBidAdapter.js +1 -1
  29. package/dist/goldbachBidAdapter.js +1 -1
  30. package/dist/gridBidAdapter.js +1 -1
  31. package/dist/gridNMBidAdapter.js +1 -1
  32. package/dist/gumgumBidAdapter.js +1 -1
  33. package/dist/h12mediaBidAdapter.js +1 -1
  34. package/dist/id5IdSystem.js +1 -1
  35. package/dist/improvedigitalBidAdapter.js +1 -1
  36. package/dist/inmarBidAdapter.js +1 -1
  37. package/dist/insticatorBidAdapter.js +1 -1
  38. package/dist/ixBidAdapter.js +1 -1
  39. package/dist/justpremiumBidAdapter.js +1 -1
  40. package/dist/konduitAnalyticsAdapter.js +1 -1
  41. package/dist/lassoBidAdapter.js +1 -1
  42. package/dist/liveyieldAnalyticsAdapter.js +1 -1
  43. package/dist/logicadBidAdapter.js +1 -1
  44. package/dist/loglyliftBidAdapter.js +1 -1
  45. package/dist/malltvAnalyticsAdapter.js +1 -1
  46. package/dist/marsmediaBidAdapter.js +1 -1
  47. package/dist/mediafuseBidAdapter.js +1 -1
  48. package/dist/mediasquareBidAdapter.js +1 -1
  49. package/dist/mgidBidAdapter.js +1 -1
  50. package/dist/minutemediaBidAdapter.js +1 -1
  51. package/dist/not-for-prod/prebid.js +105 -105
  52. package/dist/oguryBidAdapter.js +1 -1
  53. package/dist/oneVideoBidAdapter.js +1 -1
  54. package/dist/onetagBidAdapter.js +1 -1
  55. package/dist/ooloAnalyticsAdapter.js +1 -1
  56. package/dist/openxAnalyticsAdapter.js +1 -1
  57. package/dist/outbrainBidAdapter.js +1 -1
  58. package/dist/parrableIdSystem.js +1 -1
  59. package/dist/pixfutureBidAdapter.js +1 -1
  60. package/dist/prebid-core.js +3 -3
  61. package/dist/publinkIdSystem.js +1 -1
  62. package/dist/pubmaticBidAdapter.js +1 -1
  63. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  64. package/dist/pxyzBidAdapter.js +1 -1
  65. package/dist/quantcastBidAdapter.js +1 -1
  66. package/dist/readpeakBidAdapter.js +1 -1
  67. package/dist/relaidoBidAdapter.js +1 -1
  68. package/dist/rhythmoneBidAdapter.js +1 -1
  69. package/dist/riseBidAdapter.js +1 -1
  70. package/dist/rubiconAnalyticsAdapter.js +1 -1
  71. package/dist/rubiconBidAdapter.js +1 -1
  72. package/dist/seedingAllianceBidAdapter.js +1 -1
  73. package/dist/seedtagBidAdapter.js +1 -1
  74. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  75. package/dist/sharethroughBidAdapter.js +1 -1
  76. package/dist/smaatoBidAdapter.js +1 -1
  77. package/dist/smartadserverBidAdapter.js +1 -1
  78. package/dist/smartxBidAdapter.js +1 -1
  79. package/dist/smilewantedBidAdapter.js +1 -1
  80. package/dist/sonobiBidAdapter.js +1 -1
  81. package/dist/sortableBidAdapter.js +1 -1
  82. package/dist/sovrnAnalyticsAdapter.js +1 -1
  83. package/dist/sovrnBidAdapter.js +1 -1
  84. package/dist/sspBCBidAdapter.js +1 -1
  85. package/dist/sublimeBidAdapter.js +1 -1
  86. package/dist/synacormediaBidAdapter.js +1 -1
  87. package/dist/targetVideoBidAdapter.js +1 -1
  88. package/dist/teadsBidAdapter.js +1 -1
  89. package/dist/trionBidAdapter.js +1 -1
  90. package/dist/tripleliftBidAdapter.js +1 -1
  91. package/dist/trustxBidAdapter.js +1 -1
  92. package/dist/ttdBidAdapter.js +1 -1
  93. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  94. package/dist/underdogmediaBidAdapter.js +1 -1
  95. package/dist/undertoneBidAdapter.js +1 -1
  96. package/dist/vidazooBidAdapter.js +1 -1
  97. package/dist/videobyteBidAdapter.js +1 -1
  98. package/dist/visxBidAdapter.js +1 -1
  99. package/dist/vuukleBidAdapter.js +1 -1
  100. package/dist/widespaceBidAdapter.js +1 -1
  101. package/dist/winrBidAdapter.js +1 -1
  102. package/dist/yahoosspBidAdapter.js +1 -1
  103. package/dist/yieldmoBidAdapter.js +1 -1
  104. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  105. package/modules/bidwatchAnalyticsAdapter.js +132 -20
  106. package/modules/openxAnalyticsAdapter.js +7 -746
  107. package/modules/openxAnalyticsAdapter.md +3 -0
  108. package/modules/yahoosspBidAdapter.js +2 -1
  109. package/package.json +1 -1
  110. package/test/spec/modules/bidwatchAnalyticsAdapter_spec.js +37 -5
  111. package/test/spec/modules/openxAnalyticsAdapter_spec.js +6 -638
  112. package/test/spec/modules/yahoosspBidAdapter_spec.js +13 -0
@@ -1,128 +1,19 @@
1
1
  import {
2
- _each,
3
- _map,
4
- deepAccess,
5
- flatten,
6
- getWindowLocation,
7
- isEmpty,
8
- logError,
9
- logInfo,
10
- logMessage,
11
- logWarn,
12
- parseQS,
13
- parseSizesInput,
14
- uniques
2
+ logWarn
15
3
  } from '../src/utils.js';
16
- import adapter from '../src/AnalyticsAdapter.js';
17
- import CONSTANTS from '../src/constants.json';
18
- import adapterManager from '../src/adapterManager.js';
19
- import {ajax} from '../src/ajax.js';
20
- import {find, includes} from '../src/polyfill.js';
4
+ import adapter from '../src/AnalyticsAdapter.js'
5
+ import adapterManager from '../src/adapterManager.js'
21
6
 
22
- export const AUCTION_STATES = {
23
- INIT: 'initialized', // auction has initialized
24
- ENDED: 'ended', // all auction requests have been accounted for
25
- COMPLETED: 'completed' // all slots have rendered
26
- };
27
-
28
- const ADAPTER_VERSION = '0.1';
29
- const SCHEMA_VERSION = '0.1';
30
-
31
- const AUCTION_END_WAIT_TIME = 1000;
32
- const URL_PARAM = '';
33
- const ANALYTICS_TYPE = 'endpoint';
34
- const ENDPOINT = 'https://prebid.openx.net/ox/analytics/';
35
-
36
- // Event Types
37
- const {
38
- EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, BID_TIMEOUT, AUCTION_END, BID_WON }
39
- } = CONSTANTS;
40
- const SLOT_LOADED = 'slotOnload';
41
-
42
- const UTM_TAGS = [
43
- 'utm_campaign',
44
- 'utm_source',
45
- 'utm_medium',
46
- 'utm_term',
47
- 'utm_content'
48
- ];
49
- const UTM_TO_CAMPAIGN_PROPERTIES = {
50
- 'utm_campaign': 'name',
51
- 'utm_source': 'source',
52
- 'utm_medium': 'medium',
53
- 'utm_term': 'term',
54
- 'utm_content': 'content'
55
- };
56
-
57
- /**
58
- * @typedef {Object} OxAnalyticsConfig
59
- * @property {string} orgId
60
- * @property {string} publisherPlatformId
61
- * @property {number} publisherAccountId
62
- * @property {string} configId
63
- * @property {string} optimizerConfig
64
- * @property {number} sampling
65
- * @property {Object} campaign
66
- * @property {number} payloadWaitTime
67
- * @property {number} payloadWaitTimePadding
68
- * @property {Array<string>} adUnits
69
- */
70
-
71
- /**
72
- * @type {OxAnalyticsConfig}
73
- */
74
- const DEFAULT_ANALYTICS_CONFIG = {
75
- orgId: void (0),
76
- publisherPlatformId: void (0),
77
- publisherAccountId: void (0),
78
- sampling: 0.05, // default sampling rate of 5%
79
- testCode: 'default',
80
- campaign: {},
81
- adUnits: [],
82
- payloadWaitTime: AUCTION_END_WAIT_TIME,
83
- payloadWaitTimePadding: 2000
84
- };
85
-
86
- // Initialization
87
- /**
88
- * @type {OxAnalyticsConfig}
89
- */
90
- let analyticsConfig;
91
- let auctionMap = {};
92
- let auctionOrder = 1; // tracks the number of auctions ran on the page
93
-
94
- let googletag = window.googletag || {};
95
- googletag.cmd = googletag.cmd || [];
96
-
97
- let openxAdapter = Object.assign(adapter({ urlParam: URL_PARAM, analyticsType: ANALYTICS_TYPE }));
7
+ let openxAdapter = Object.assign(adapter({ urlParam: '', analyticsType: 'endpoint' }));
98
8
 
99
9
  openxAdapter.originEnableAnalytics = openxAdapter.enableAnalytics;
100
10
 
101
11
  openxAdapter.enableAnalytics = function(adapterConfig = {options: {}}) {
102
- if (isValidConfig(adapterConfig)) {
103
- analyticsConfig = {...DEFAULT_ANALYTICS_CONFIG, ...adapterConfig.options};
104
-
105
- // campaign properties defined by config will override utm query parameters
106
- analyticsConfig.campaign = {...buildCampaignFromUtmCodes(), ...analyticsConfig.campaign};
107
-
108
- logInfo('OpenX Analytics enabled with config', analyticsConfig);
12
+ logWarn('OpenX Analytics has been deprecated, this adapter will be removed in Prebid 8');
109
13
 
110
- // override track method with v2 handlers
111
- openxAdapter.track = prebidAnalyticsEventHandler;
14
+ openxAdapter.track = prebidAnalyticsEventHandler;
112
15
 
113
- googletag.cmd.push(function () {
114
- let pubads = googletag.pubads();
115
-
116
- if (pubads.addEventListener) {
117
- pubads.addEventListener(SLOT_LOADED, args => {
118
- openxAdapter.track({eventType: SLOT_LOADED, args});
119
- logInfo('OX: SlotOnLoad event triggered');
120
- });
121
- }
122
- });
123
-
124
- openxAdapter.originEnableAnalytics(adapterConfig);
125
- }
16
+ openxAdapter.originEnableAnalytics(adapterConfig);
126
17
  };
127
18
 
128
19
  adapterManager.registerAnalyticsAdapter({
@@ -132,635 +23,5 @@ adapterManager.registerAnalyticsAdapter({
132
23
 
133
24
  export default openxAdapter;
134
25
 
135
- /**
136
- * Test Helper Functions
137
- */
138
-
139
- // reset the cache for unit tests
140
- openxAdapter.reset = function() {
141
- auctionMap = {};
142
- auctionOrder = 1;
143
- };
144
-
145
- /**
146
- * Private Functions
147
- */
148
-
149
- function isValidConfig({options: analyticsOptions}) {
150
- let hasOrgId = analyticsOptions && analyticsOptions.orgId !== void (0);
151
-
152
- const fieldValidations = [
153
- // tuple of property, type, required
154
- ['orgId', 'string', hasOrgId],
155
- ['publisherPlatformId', 'string', !hasOrgId],
156
- ['publisherAccountId', 'number', !hasOrgId],
157
- ['configId', 'string', false],
158
- ['optimizerConfig', 'string', false],
159
- ['sampling', 'number', false],
160
- ['adIdKey', 'string', false],
161
- ['payloadWaitTime', 'number', false],
162
- ['payloadWaitTimePadding', 'number', false],
163
- ];
164
-
165
- let failedValidation = find(fieldValidations, ([property, type, required]) => {
166
- // if required, the property has to exist
167
- // if property exists, type check value
168
- return (required && !analyticsOptions.hasOwnProperty(property)) ||
169
- /* eslint-disable valid-typeof */
170
- (analyticsOptions.hasOwnProperty(property) && typeof analyticsOptions[property] !== type);
171
- });
172
- if (failedValidation) {
173
- let [property, type, required] = failedValidation;
174
-
175
- if (required) {
176
- logError(`OpenXAnalyticsAdapter: Expected '${property}' to exist and of type '${type}'`);
177
- } else {
178
- logError(`OpenXAnalyticsAdapter: Expected '${property}' to be type '${type}'`);
179
- }
180
- }
181
-
182
- return !failedValidation;
183
- }
184
-
185
- function buildCampaignFromUtmCodes() {
186
- const location = getWindowLocation();
187
- const queryParams = parseQS(location && location.search);
188
- let campaign = {};
189
-
190
- UTM_TAGS.forEach(function(utmKey) {
191
- let utmValue = queryParams[utmKey];
192
- if (utmValue) {
193
- let key = UTM_TO_CAMPAIGN_PROPERTIES[utmKey];
194
- campaign[key] = decodeURIComponent(utmValue);
195
- }
196
- });
197
- return campaign;
198
- }
199
-
200
- function detectMob() {
201
- if (
202
- navigator.userAgent.match(/Android/i) ||
203
- navigator.userAgent.match(/webOS/i) ||
204
- navigator.userAgent.match(/iPhone/i) ||
205
- navigator.userAgent.match(/iPad/i) ||
206
- navigator.userAgent.match(/iPod/i) ||
207
- navigator.userAgent.match(/BlackBerry/i) ||
208
- navigator.userAgent.match(/Windows Phone/i)
209
- ) {
210
- return true;
211
- } else {
212
- return false;
213
- }
214
- }
215
-
216
- function detectOS() {
217
- if (navigator.userAgent.indexOf('Android') != -1) return 'Android';
218
- if (navigator.userAgent.indexOf('like Mac') != -1) return 'iOS';
219
- if (navigator.userAgent.indexOf('Win') != -1) return 'Windows';
220
- if (navigator.userAgent.indexOf('Mac') != -1) return 'Macintosh';
221
- if (navigator.userAgent.indexOf('Linux') != -1) return 'Linux';
222
- if (navigator.appVersion.indexOf('X11') != -1) return 'Unix';
223
- return 'Others';
224
- }
225
-
226
- function detectBrowser() {
227
- var isChrome =
228
- /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
229
- var isCriOS = navigator.userAgent.match('CriOS');
230
- var isSafari =
231
- /Safari/.test(navigator.userAgent) &&
232
- /Apple Computer/.test(navigator.vendor);
233
- var isFirefox = /Firefox/.test(navigator.userAgent);
234
- var isIE =
235
- /Trident/.test(navigator.userAgent) || /MSIE/.test(navigator.userAgent);
236
- var isEdge = /Edge/.test(navigator.userAgent);
237
- if (isIE) return 'Internet Explorer';
238
- if (isEdge) return 'Microsoft Edge';
239
- if (isCriOS) return 'Chrome';
240
- if (isSafari) return 'Safari';
241
- if (isFirefox) return 'Firefox';
242
- if (isChrome) return 'Chrome';
243
- return 'Others';
244
- }
245
-
246
26
  function prebidAnalyticsEventHandler({eventType, args}) {
247
- logMessage(eventType, Object.assign({}, args));
248
- switch (eventType) {
249
- case AUCTION_INIT:
250
- onAuctionInit(args);
251
- break;
252
- case BID_REQUESTED:
253
- onBidRequested(args);
254
- break;
255
- case BID_RESPONSE:
256
- onBidResponse(args);
257
- break;
258
- case BID_TIMEOUT:
259
- onBidTimeout(args);
260
- break;
261
- case AUCTION_END:
262
- onAuctionEnd(args);
263
- break;
264
- case BID_WON:
265
- onBidWon(args);
266
- break;
267
- case SLOT_LOADED:
268
- onSlotLoadedV2(args);
269
- break;
270
- }
271
- }
272
-
273
- /**
274
- * @typedef {Object} PbAuction
275
- * @property {string} auctionId - Auction ID of the request this bid responded to
276
- * @property {number} timestamp //: 1586675964364
277
- * @property {number} auctionEnd - timestamp of when auction ended //: 1586675964364
278
- * @property {string} auctionStatus //: "inProgress"
279
- * @property {Array<Adunit>} adUnits //: [{…}]
280
- * @property {string} adUnitCodes //: ["video1"]
281
- * @property {string} labels //: undefined
282
- * @property {Array<BidRequest>} bidderRequests //: (2) [{…}, {…}]
283
- * @property {Array<BidRequest>} noBids //: []
284
- * @property {Array<BidResponse>} bidsReceived //: []
285
- * @property {Array<BidResponse>} winningBids //: []
286
- * @property {number} timeout //: 3000
287
- * @property {Object} config //: {publisherPlatformId: "a3aece0c-9e80-4316-8deb-faf804779bd1", publisherAccountId: 537143056, sampling: 1}/*
288
- */
289
-
290
- function onAuctionInit({auctionId, timestamp: startTime, timeout, adUnitCodes}) {
291
- auctionMap[auctionId] = {
292
- id: auctionId,
293
- startTime,
294
- endTime: void (0),
295
- timeout,
296
- auctionOrder,
297
- userIds: [],
298
- adUnitCodesCount: adUnitCodes.length,
299
- adunitCodesRenderedCount: 0,
300
- state: AUCTION_STATES.INIT,
301
- auctionSendDelayTimer: void (0),
302
- };
303
-
304
- // setup adunit properties in map
305
- auctionMap[auctionId].adUnitCodeToAdUnitMap = adUnitCodes.reduce((obj, adunitCode) => {
306
- obj[adunitCode] = {
307
- code: adunitCode,
308
- adPosition: void (0),
309
- bidRequestsMap: {}
310
- };
311
- return obj;
312
- }, {});
313
-
314
- auctionOrder++;
315
- }
316
-
317
- /**
318
- * @typedef {Object} PbBidRequest
319
- * @property {string} auctionId - Auction ID of the request this bid responded to
320
- * @property {number} auctionStart //: 1586675964364
321
- * @property {Object} refererInfo
322
- * @property {PbBidderRequest} bids
323
- * @property {number} start - Start timestamp of the bidder request
324
- *
325
- */
326
-
327
- /**
328
- * @typedef {Object} PbBidderRequest
329
- * @property {string} adUnitCode - Name of div or google adunit path
330
- * @property {string} bidder - Bame of bidder
331
- * @property {string} bidId - Identifies the bid request
332
- * @property {Object} mediaTypes
333
- * @property {Object} params
334
- * @property {string} src
335
- * @property {Object} userId - Map of userId module to module object
336
- */
337
-
338
- /**
339
- * Tracks the bid request
340
- * @param {PbBidRequest} bidRequest
341
- */
342
- function onBidRequested(bidRequest) {
343
- const {auctionId, bids: bidderRequests, start, timeout} = bidRequest;
344
- const auction = auctionMap[auctionId];
345
- const adUnitCodeToAdUnitMap = auction.adUnitCodeToAdUnitMap;
346
-
347
- bidderRequests.forEach(bidderRequest => {
348
- const { adUnitCode, bidder, bidId: requestId, mediaTypes, params, src, userId } = bidderRequest;
349
-
350
- auction.userIds.push(userId);
351
- adUnitCodeToAdUnitMap[adUnitCode].bidRequestsMap[requestId] = {
352
- bidder,
353
- params,
354
- mediaTypes,
355
- source: src,
356
- startTime: start,
357
- timedOut: false,
358
- timeLimit: timeout,
359
- bids: {}
360
- };
361
- });
362
- }
363
-
364
- /**
365
- *
366
- * @param {BidResponse} bidResponse
367
- */
368
- function onBidResponse(bidResponse) {
369
- let {
370
- auctionId,
371
- adUnitCode,
372
- requestId,
373
- cpm,
374
- creativeId,
375
- requestTimestamp,
376
- responseTimestamp,
377
- ts,
378
- mediaType,
379
- dealId,
380
- ttl,
381
- netRevenue,
382
- currency,
383
- originalCpm,
384
- originalCurrency,
385
- width,
386
- height,
387
- timeToRespond: latency,
388
- adId,
389
- meta
390
- } = bidResponse;
391
-
392
- auctionMap[auctionId].adUnitCodeToAdUnitMap[adUnitCode].bidRequestsMap[requestId].bids[adId] = {
393
- cpm,
394
- creativeId,
395
- requestTimestamp,
396
- responseTimestamp,
397
- ts,
398
- adId,
399
- meta,
400
- mediaType,
401
- dealId,
402
- ttl,
403
- netRevenue,
404
- currency,
405
- originalCpm,
406
- originalCurrency,
407
- width,
408
- height,
409
- latency,
410
- winner: false,
411
- rendered: false,
412
- renderTime: 0,
413
- };
414
- }
415
-
416
- function onBidTimeout(args) {
417
- _each(args, ({auctionId, adUnitCode, bidId: requestId}) => {
418
- let timedOutRequest = deepAccess(auctionMap,
419
- `${auctionId}.adUnitCodeToAdUnitMap.${adUnitCode}.bidRequestsMap.${requestId}`);
420
-
421
- if (timedOutRequest) {
422
- timedOutRequest.timedOut = true;
423
- }
424
- });
425
- }
426
- /**
427
- *
428
- * @param {PbAuction} endedAuction
429
- */
430
- function onAuctionEnd(endedAuction) {
431
- let auction = auctionMap[endedAuction.auctionId];
432
-
433
- if (!auction) {
434
- return;
435
- }
436
-
437
- clearAuctionTimer(auction);
438
- auction.endTime = endedAuction.auctionEnd;
439
- auction.state = AUCTION_STATES.ENDED;
440
- delayedSend(auction);
441
- }
442
-
443
- /**
444
- *
445
- * @param {BidResponse} bidResponse
446
- */
447
- function onBidWon(bidResponse) {
448
- const { auctionId, adUnitCode, requestId, adId } = bidResponse;
449
- let winningBid = deepAccess(auctionMap,
450
- `${auctionId}.adUnitCodeToAdUnitMap.${adUnitCode}.bidRequestsMap.${requestId}.bids.${adId}`);
451
-
452
- if (winningBid) {
453
- winningBid.winner = true;
454
- const auction = auctionMap[auctionId];
455
- if (auction.sent) {
456
- const endpoint = (analyticsConfig.endpoint || ENDPOINT) + 'event';
457
- const bidder = auction.adUnitCodeToAdUnitMap[adUnitCode].bidRequestsMap[requestId].bidder;
458
- ajax(`${endpoint}?t=win&b=${adId}&a=${analyticsConfig.orgId}&bidder=${bidder}&ts=${auction.startTime}`,
459
- () => {
460
- logInfo(`Openx Analytics - Sending complete impression event for ${adId} at ${Date.now()}`)
461
- });
462
- } else {
463
- logInfo(`Openx Analytics - impression event for ${adId} will be sent with auction data`)
464
- }
465
- }
466
- }
467
-
468
- /**
469
- *
470
- * @param {GoogleTagSlot} slot
471
- * @param {string} serviceName
472
- */
473
- function onSlotLoadedV2({ slot }) {
474
- const renderTime = Date.now();
475
- const elementId = slot.getSlotElementId();
476
- const bidId = slot.getTargeting('hb_adid')[0];
477
-
478
- let [auction, adUnit, bid] = getPathToBidResponseByBidId(bidId);
479
-
480
- if (!auction) {
481
- // attempt to get auction by adUnitCode
482
- auction = getAuctionByGoogleTagSLot(slot);
483
-
484
- if (!auction) {
485
- return; // slot is not participating in an active prebid auction
486
- }
487
- }
488
-
489
- clearAuctionTimer(auction);
490
-
491
- // track that an adunit code has completed within an auction
492
- auction.adunitCodesRenderedCount++;
493
-
494
- // mark adunit as rendered
495
- if (bid) {
496
- let {x, y} = getPageOffset();
497
- bid.rendered = true;
498
- bid.renderTime = renderTime;
499
- adUnit.adPosition = isAtf(elementId, x, y) ? 'ATF' : 'BTF';
500
- }
501
-
502
- if (auction.adunitCodesRenderedCount === auction.adUnitCodesCount) {
503
- auction.state = AUCTION_STATES.COMPLETED;
504
- }
505
-
506
- // prepare to send regardless if auction is complete or not as a failsafe in case not all events are tracked
507
- // add additional padding when not all slots are rendered
508
- delayedSend(auction);
509
- }
510
-
511
- function isAtf(elementId, scrollLeft = 0, scrollTop = 0) {
512
- let elem = document.querySelector('#' + elementId);
513
- let isAtf = false;
514
- if (elem) {
515
- let bounding = elem.getBoundingClientRect();
516
- if (bounding) {
517
- let windowWidth = (window.innerWidth || document.documentElement.clientWidth);
518
- let windowHeight = (window.innerHeight || document.documentElement.clientHeight);
519
-
520
- // intersection coordinates
521
- let left = Math.max(0, bounding.left + scrollLeft);
522
- let right = Math.min(windowWidth, bounding.right + scrollLeft);
523
- let top = Math.max(0, bounding.top + scrollTop);
524
- let bottom = Math.min(windowHeight, bounding.bottom + scrollTop);
525
-
526
- let intersectionWidth = right - left;
527
- let intersectionHeight = bottom - top;
528
-
529
- let intersectionArea = (intersectionHeight > 0 && intersectionWidth > 0) ? (intersectionHeight * intersectionWidth) : 0;
530
- let adSlotArea = (bounding.right - bounding.left) * (bounding.bottom - bounding.top);
531
-
532
- if (adSlotArea > 0) {
533
- // Atleast 50% of intersection in window
534
- isAtf = intersectionArea * 2 >= adSlotArea;
535
- }
536
- }
537
- } else {
538
- logWarn('OX: DOM element not for id ' + elementId);
539
- }
540
- return isAtf;
541
- }
542
-
543
- // backwards compatible pageOffset from https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollX
544
- function getPageOffset() {
545
- var x = (window.pageXOffset !== undefined)
546
- ? window.pageXOffset
547
- : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
548
-
549
- var y = (window.pageYOffset !== undefined)
550
- ? window.pageYOffset
551
- : (document.documentElement || document.body.parentNode || document.body).scrollTop;
552
- return {x, y};
553
- }
554
-
555
- function delayedSend(auction) {
556
- if (auction.sent) {
557
- return;
558
- }
559
- const delayTime = auction.adunitCodesRenderedCount === auction.adUnitCodesCount
560
- ? analyticsConfig.payloadWaitTime
561
- : analyticsConfig.payloadWaitTime + analyticsConfig.payloadWaitTimePadding;
562
-
563
- auction.auctionSendDelayTimer = setTimeout(() => {
564
- auction.sent = true; // any BidWon emitted after this will be recorded separately
565
- let payload = JSON.stringify([buildAuctionPayload(auction)]);
566
-
567
- ajax(analyticsConfig.endpoint || ENDPOINT, () => {
568
- logInfo(`OpenX Analytics - Sending complete auction at ${Date.now()}`);
569
- }, payload, { contentType: 'application/json' });
570
- }, delayTime);
571
- }
572
-
573
- function clearAuctionTimer(auction) {
574
- // reset the delay timer to send the auction data
575
- if (auction.auctionSendDelayTimer) {
576
- clearTimeout(auction.auctionSendDelayTimer);
577
- auction.auctionSendDelayTimer = void (0);
578
- }
579
- }
580
-
581
- /**
582
- * Returns the path to a bid (auction, adunit, bidRequest, and bid) based on a bidId
583
- * @param {string} bidId
584
- * @returns {Array<*>}
585
- */
586
- function getPathToBidResponseByBidId(bidId) {
587
- let auction;
588
- let adUnit;
589
- let bidResponse;
590
-
591
- if (!bidId) {
592
- return [];
593
- }
594
-
595
- _each(auctionMap, currentAuction => {
596
- // skip completed auctions
597
- if (currentAuction.state === AUCTION_STATES.COMPLETED) {
598
- return;
599
- }
600
-
601
- _each(currentAuction.adUnitCodeToAdUnitMap, (currentAdunit) => {
602
- _each(currentAdunit.bidRequestsMap, currentBiddRequest => {
603
- _each(currentBiddRequest.bids, (currentBidResponse, bidResponseId) => {
604
- if (bidId === bidResponseId) {
605
- auction = currentAuction;
606
- adUnit = currentAdunit;
607
- bidResponse = currentBidResponse;
608
- }
609
- });
610
- });
611
- });
612
- });
613
- return [auction, adUnit, bidResponse];
614
- }
615
-
616
- function getAuctionByGoogleTagSLot(slot) {
617
- let slotAdunitCodes = [slot.getSlotElementId(), slot.getAdUnitPath()];
618
- let slotAuction;
619
-
620
- _each(auctionMap, auction => {
621
- if (auction.state === AUCTION_STATES.COMPLETED) {
622
- return;
623
- }
624
-
625
- _each(auction.adUnitCodeToAdUnitMap, (bidderRequestIdMap, adUnitCode) => {
626
- if (includes(slotAdunitCodes, adUnitCode)) {
627
- slotAuction = auction;
628
- }
629
- });
630
- });
631
-
632
- return slotAuction;
633
- }
634
-
635
- function buildAuctionPayload(auction) {
636
- let {startTime, endTime, state, timeout, auctionOrder, userIds, adUnitCodeToAdUnitMap, id} = auction;
637
- const auctionId = id;
638
- let {orgId, publisherPlatformId, publisherAccountId, campaign, testCode, configId, optimizerConfig} = analyticsConfig;
639
-
640
- return {
641
- auctionId,
642
- adapterVersion: ADAPTER_VERSION,
643
- schemaVersion: SCHEMA_VERSION,
644
- orgId,
645
- publisherPlatformId,
646
- publisherAccountId,
647
- configId,
648
- optimizerConfig,
649
- campaign,
650
- state,
651
- startTime,
652
- endTime,
653
- timeLimit: timeout,
654
- auctionOrder,
655
- deviceType: detectMob() ? 'Mobile' : 'Desktop',
656
- deviceOSType: detectOS(),
657
- browser: detectBrowser(),
658
- testCode: testCode,
659
- // return an array of module name that have user data
660
- userIdProviders: buildUserIdProviders(userIds),
661
- adUnits: buildAdUnitsPayload(adUnitCodeToAdUnitMap),
662
- };
663
-
664
- function buildAdUnitsPayload(adUnitCodeToAdUnitMap) {
665
- return _map(adUnitCodeToAdUnitMap, (adUnit) => {
666
- let {code, adPosition} = adUnit;
667
-
668
- return {
669
- code,
670
- adPosition,
671
- bidRequests: buildBidRequestPayload(adUnit.bidRequestsMap)
672
- };
673
-
674
- function buildBidRequestPayload(bidRequestsMap) {
675
- return _map(bidRequestsMap, (bidRequest) => {
676
- let {bidder, source, bids, mediaTypes, timeLimit, timedOut} = bidRequest;
677
- return {
678
- bidder,
679
- source,
680
- hasBidderResponded: Object.keys(bids).length > 0,
681
- availableAdSizes: getMediaTypeSizes(mediaTypes),
682
- availableMediaTypes: getMediaTypes(mediaTypes),
683
- timeLimit,
684
- timedOut,
685
- bidResponses: _map(bidRequest.bids, (bidderBidResponse) => {
686
- let {
687
- adId,
688
- cpm,
689
- creativeId,
690
- ts,
691
- meta,
692
- mediaType,
693
- dealId,
694
- ttl,
695
- netRevenue,
696
- currency,
697
- width,
698
- height,
699
- latency,
700
- winner,
701
- rendered,
702
- renderTime
703
- } = bidderBidResponse;
704
-
705
- return {
706
- bidId: adId,
707
- microCpm: cpm * 1000000,
708
- netRevenue,
709
- currency,
710
- mediaType,
711
- height,
712
- width,
713
- size: `${width}x${height}`,
714
- dealId,
715
- latency,
716
- ttl,
717
- winner,
718
- creativeId,
719
- ts,
720
- rendered,
721
- renderTime,
722
- meta
723
- }
724
- })
725
- }
726
- });
727
- }
728
- });
729
- }
730
-
731
- function buildUserIdProviders(userIds) {
732
- return _map(userIds, (userId) => {
733
- return _map(userId, (id, module) => {
734
- return hasUserData(module, id) ? module : false
735
- }).filter(module => module);
736
- }).reduce(flatten, []).filter(uniques).sort();
737
- }
738
-
739
- function hasUserData(module, idOrIdObject) {
740
- let normalizedId;
741
-
742
- switch (module) {
743
- case 'digitrustid':
744
- normalizedId = deepAccess(idOrIdObject, 'data.id');
745
- break;
746
- case 'lipb':
747
- normalizedId = idOrIdObject.lipbid;
748
- break;
749
- default:
750
- normalizedId = idOrIdObject;
751
- }
752
-
753
- return !isEmpty(normalizedId);
754
- }
755
-
756
- function getMediaTypeSizes(mediaTypes) {
757
- return _map(mediaTypes, (mediaTypeConfig, mediaType) => {
758
- return parseSizesInput(mediaTypeConfig.sizes)
759
- .map(size => `${mediaType}_${size}`);
760
- }).reduce(flatten, []);
761
- }
762
-
763
- function getMediaTypes(mediaTypes) {
764
- return _map(mediaTypes, (mediaTypeConfig, mediaType) => mediaType);
765
- }
766
27
  }