prebid.js 8.6.0 → 8.8.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.
- package/dist/33acrossBidAdapter.js +1 -1
- package/dist/33acrossIdSystem.js +1 -1
- package/dist/a1MediaRtdProvider.js +1 -1
- package/dist/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/admaticBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.js +1 -1
- package/dist/adqueryIdSystem.js +1 -1
- package/dist/adrelevantisBidAdapter.js +1 -1
- package/dist/adsinteractiveBidAdapter.js +1 -1
- package/dist/adtrgtmeBidAdapter.js +1 -1
- package/dist/adxcgBidAdapter.js +1 -1
- package/dist/adyoulikeBidAdapter.js +1 -1
- package/dist/ajaBidAdapter.js +1 -1
- package/dist/alkimiBidAdapter.js +1 -1
- package/dist/amxBidAdapter.js +1 -1
- package/dist/amxIdSystem.js +1 -1
- package/dist/appierAnalyticsAdapter.js +1 -1
- package/dist/appnexusBidAdapter.js +1 -1
- package/dist/asoBidAdapter.js +1 -1
- package/dist/automatadAnalyticsAdapter.js +1 -0
- package/dist/axonixBidAdapter.js +1 -1
- package/dist/bidViewability.js +1 -1
- package/dist/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.js +1 -1
- package/dist/brandmetricsRtdProvider.js +1 -1
- package/dist/bridBidAdapter.js +1 -1
- package/dist/bridgewellBidAdapter.js +1 -1
- package/dist/brightMountainMediaBidAdapter.js +1 -1
- package/dist/carodaBidAdapter.js +1 -1
- package/dist/chtnwBidAdapter.js +1 -1
- package/dist/concertBidAdapter.js +1 -1
- package/dist/connatixBidAdapter.js +1 -0
- package/dist/connectadBidAdapter.js +1 -1
- package/dist/consumableBidAdapter.js +1 -1
- package/dist/conversantAnalyticsAdapter.js +1 -1
- package/dist/conversantBidAdapter.js +1 -1
- package/dist/craftBidAdapter.js +1 -1
- package/dist/criteoBidAdapter.js +1 -1
- package/dist/cwireBidAdapter.js +1 -1
- package/dist/dependencies.json +7 -1
- package/dist/dspxBidAdapter.js +1 -1
- package/dist/eplanningBidAdapter.js +1 -1
- package/dist/euidIdSystem.js +1 -1
- package/dist/feedadBidAdapter.js +1 -1
- package/dist/finativeBidAdapter.js +1 -1
- package/dist/freepassBidAdapter.js +1 -1
- package/dist/freewheel-sspBidAdapter.js +1 -1
- package/dist/geoedgeRtdProvider.js +1 -1
- package/dist/gmosspBidAdapter.js +1 -1
- package/dist/goldbachBidAdapter.js +1 -1
- package/dist/greenbidsAnalyticsAdapter.js +1 -1
- package/dist/greenbidsRtdProvider.js +1 -1
- package/dist/gridBidAdapter.js +1 -1
- package/dist/gumgumBidAdapter.js +1 -1
- package/dist/h12mediaBidAdapter.js +1 -1
- package/dist/hypelabBidAdapter.js +1 -1
- package/dist/id5IdSystem.js +1 -1
- package/dist/imdsBidAdapter.js +1 -1
- package/dist/improvedigitalBidAdapter.js +1 -1
- package/dist/insticatorBidAdapter.js +1 -1
- package/dist/ixBidAdapter.js +1 -1
- package/dist/justpremiumBidAdapter.js +1 -1
- package/dist/kargoBidAdapter.js +1 -1
- package/dist/konduitAnalyticsAdapter.js +1 -1
- package/dist/kueezBidAdapter.js +1 -1
- package/dist/kueezRtbBidAdapter.js +1 -1
- package/dist/kulturemediaBidAdapter.js +1 -1
- package/dist/lassoBidAdapter.js +1 -1
- package/dist/lifestreetBidAdapter.js +1 -1
- package/dist/liveIntentIdSystem.js +1 -1
- package/dist/logicadBidAdapter.js +1 -1
- package/dist/loglyliftBidAdapter.js +1 -1
- package/dist/magniteAnalyticsAdapter.js +1 -1
- package/dist/malltvAnalyticsAdapter.js +1 -1
- package/dist/marsmediaBidAdapter.js +1 -1
- package/dist/mediafuseBidAdapter.js +1 -1
- package/dist/medianetBidAdapter.js +1 -1
- package/dist/mediasquareBidAdapter.js +1 -1
- package/dist/mgidBidAdapter.js +1 -1
- package/dist/minutemediaBidAdapter.js +1 -1
- package/dist/minutemediaplusBidAdapter.js +1 -1
- package/dist/nativoBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +145 -142
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/operaadsBidAdapter.js +1 -1
- package/dist/operaadsIdSystem.js +1 -0
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/oxxionAnalyticsAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/publinkIdSystem.js +1 -1
- package/dist/pubmaticBidAdapter.js +1 -1
- package/dist/pubwiseAnalyticsAdapter.js +1 -1
- package/dist/pxyzBidAdapter.js +1 -1
- package/dist/quantcastBidAdapter.js +1 -1
- package/dist/readpeakBidAdapter.js +1 -1
- package/dist/relaidoBidAdapter.js +1 -1
- package/dist/retailspotBidAdapter.js +1 -1
- package/dist/rhythmoneBidAdapter.js +1 -1
- package/dist/riseBidAdapter.js +1 -1
- package/dist/rubiconBidAdapter.js +1 -1
- package/dist/seedingAllianceBidAdapter.js +1 -1
- package/dist/seedtagBidAdapter.js +1 -1
- package/dist/sharethroughAnalyticsAdapter.js +1 -1
- package/dist/sharethroughBidAdapter.js +1 -1
- package/dist/shinezBidAdapter.js +1 -1
- package/dist/smaatoBidAdapter.js +1 -1
- package/dist/smartadserverBidAdapter.js +1 -1
- package/dist/smartxBidAdapter.js +1 -1
- package/dist/smartyadsBidAdapter.js +1 -1
- package/dist/smilewantedBidAdapter.js +1 -1
- package/dist/snigelBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/sspBCBidAdapter.js +1 -1
- package/dist/stvBidAdapter.js +1 -1
- package/dist/sublimeBidAdapter.js +1 -1
- package/dist/tappxBidAdapter.js +1 -1
- package/dist/targetVideoBidAdapter.js +1 -1
- package/dist/teadsBidAdapter.js +1 -1
- package/dist/topicsFpdModule.js +1 -1
- package/dist/trionBidAdapter.js +1 -1
- package/dist/tripleliftBidAdapter.js +1 -1
- package/dist/ttdBidAdapter.js +1 -1
- package/dist/ucfunnelAnalyticsAdapter.js +1 -1
- package/dist/uid2IdSystem.js +1 -1
- package/dist/underdogmediaBidAdapter.js +1 -1
- package/dist/undertoneBidAdapter.js +1 -1
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/visxBidAdapter.js +1 -1
- package/dist/vuukleBidAdapter.js +1 -1
- package/dist/widespaceBidAdapter.js +1 -1
- package/dist/winrBidAdapter.js +1 -1
- package/dist/yahoosspBidAdapter.js +1 -1
- package/dist/yieldmoBidAdapter.js +1 -1
- package/dist/yieldoneAnalyticsAdapter.js +1 -1
- package/integrationExamples/topics/topics-server.js +72 -0
- package/modules/.submodules.json +2 -1
- package/modules/a1MediaRtdProvider.js +1 -1
- package/modules/adagioBidAdapter.js +15 -1
- package/modules/adgenerationBidAdapter.js +4 -3
- package/modules/admaticBidAdapter.js +5 -0
- package/modules/adqueryBidAdapter.js +23 -21
- package/modules/adqueryIdSystem.js +45 -30
- package/modules/adrelevantisBidAdapter.js +2 -0
- package/modules/adsinteractiveBidAdapter.js +2 -0
- package/modules/alkimiBidAdapter.js +19 -7
- package/modules/automatadAnalyticsAdapter.js +325 -0
- package/modules/automatadAnalyticsAdapter.md +23 -0
- package/modules/bidViewability.js +7 -0
- package/modules/bidViewability.md +9 -8
- package/modules/brandmetricsRtdProvider.js +30 -27
- package/modules/connatixBidAdapter.js +185 -0
- package/modules/connatixBidAdapter.md +37 -0
- package/modules/criteoBidAdapter.js +73 -50
- package/modules/freepassBidAdapter.js +20 -1
- package/modules/freepassBidAdapter.md +4 -1
- package/modules/geoedgeRtdProvider.js +43 -13
- package/modules/geoedgeRtdProvider.md +2 -1
- package/modules/gridBidAdapter.js +1 -8
- package/modules/liveIntentIdSystem.js +16 -1
- package/modules/medianetBidAdapter.js +7 -4
- package/modules/mediasquareBidAdapter.js +3 -0
- package/modules/nativoBidAdapter.js +21 -3
- package/modules/onetagBidAdapter.js +3 -0
- package/modules/operaadsBidAdapter.js +5 -0
- package/modules/operaadsBidAdapter.md +5 -5
- package/modules/operaadsIdSystem.js +106 -0
- package/modules/operaadsIdSystem.md +52 -0
- package/modules/optidigitalBidAdapter.js +25 -16
- package/modules/oxxionAnalyticsAdapter.js +22 -5
- package/modules/rubiconBidAdapter.js +2 -2
- package/modules/smartyadsBidAdapter.js +18 -1
- package/modules/snigelBidAdapter.js +69 -16
- package/modules/snigelBidAdapter.md +9 -3
- package/modules/tappxBidAdapter.js +17 -14
- package/modules/topicsFpdModule.js +35 -9
- package/modules/undertoneBidAdapter.md +1 -1
- package/modules/userId/eids.md +7 -0
- package/modules/visxBidAdapter.js +51 -1
- package/package.json +2 -2
- package/src/adloader.js +1 -0
- package/src/native.js +2 -2
- package/test/spec/modules/adagioBidAdapter_spec.js +89 -0
- package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
- package/test/spec/modules/admaticBidAdapter_spec.js +5 -0
- package/test/spec/modules/adqueryIdSystem_spec.js +13 -24
- package/test/spec/modules/alkimiBidAdapter_spec.js +3 -9
- package/test/spec/modules/automatadAnalyticsAdapter_spec.js +533 -0
- package/test/spec/modules/bidViewability_spec.js +32 -1
- package/test/spec/modules/brandmetricsRtdProvider_spec.js +6 -0
- package/test/spec/modules/connatixBidAdapter_spec.js +366 -0
- package/test/spec/modules/criteoBidAdapter_spec.js +249 -0
- package/test/spec/modules/eids_spec.js +48 -0
- package/test/spec/modules/freepassBidAdapter_spec.js +44 -0
- package/test/spec/modules/geoedgeRtdProvider_spec.js +44 -24
- package/test/spec/modules/gridBidAdapter_spec.js +68 -0
- package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +5 -0
- package/test/spec/modules/liveIntentIdSystem_spec.js +5 -0
- package/test/spec/modules/medianetBidAdapter_spec.js +18 -18
- package/test/spec/modules/mediasquareBidAdapter_spec.js +5 -0
- package/test/spec/modules/nativoBidAdapter_spec.js +6 -1
- package/test/spec/modules/onetagBidAdapter_spec.js +69 -0
- package/test/spec/modules/operaadsIdSystem_spec.js +53 -0
- package/test/spec/modules/optidigitalBidAdapter_spec.js +9 -2
- package/test/spec/modules/oxxionAnalyticsAdapter_spec.js +6 -1
- package/test/spec/modules/rubiconBidAdapter_spec.js +24 -0
- package/test/spec/modules/smartyadsBidAdapter_spec.js +49 -0
- package/test/spec/modules/snigelBidAdapter_spec.js +57 -6
- package/test/spec/modules/tappxBidAdapter_spec.js +19 -0
- package/test/spec/modules/topicsFpdModule_spec.js +102 -1
- package/test/spec/modules/visxBidAdapter_spec.js +151 -1
- package/test/spec/native_spec.js +5 -3
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logError,
|
|
3
|
+
logInfo,
|
|
4
|
+
logMessage
|
|
5
|
+
} from '../src/utils.js';
|
|
6
|
+
|
|
7
|
+
import CONSTANTS from '../src/constants.json';
|
|
8
|
+
import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js';
|
|
9
|
+
import adapterManager from '../src/adapterManager.js';
|
|
10
|
+
import { config } from '../src/config.js'
|
|
11
|
+
|
|
12
|
+
/** Prebid Event Handlers */
|
|
13
|
+
|
|
14
|
+
const ADAPTER_CODE = 'automatadAnalytics'
|
|
15
|
+
const trialCountMilsMapping = [1500, 3000, 5000, 10000];
|
|
16
|
+
|
|
17
|
+
var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = [];
|
|
18
|
+
|
|
19
|
+
const prettyLog = (level, text, isGroup = false, cb = () => {}) => {
|
|
20
|
+
if (self.isLoggingEnabled === undefined) {
|
|
21
|
+
if (window.localStorage.getItem('__aggLoggingEnabled')) {
|
|
22
|
+
self.isLoggingEnabled = true
|
|
23
|
+
} else {
|
|
24
|
+
const queryParams = new URLSearchParams(new URL(window.location.href).search)
|
|
25
|
+
self.isLoggingEnabled = queryParams.has('aggLoggingEnabled')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (self.isLoggingEnabled) {
|
|
30
|
+
if (isGroup) {
|
|
31
|
+
logInfo(`ATD Analytics Adapter: ${level.toUpperCase()}: ${text} --- Group Start ---`)
|
|
32
|
+
try {
|
|
33
|
+
cb();
|
|
34
|
+
} catch (error) {
|
|
35
|
+
logError(`ATD Analytics Adapter: ERROR: ${'Error during cb function in prettyLog'}`)
|
|
36
|
+
}
|
|
37
|
+
logInfo(`ATD Analytics Adapter: ${level.toUpperCase()}: ${text} --- Group End ---`)
|
|
38
|
+
} else {
|
|
39
|
+
logInfo(`ATD Analytics Adapter: ${level.toUpperCase()}: ${text}`)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const processEvents = () => {
|
|
45
|
+
if (self.retryCount === trialCountMilsMapping.length) {
|
|
46
|
+
self.prettyLog('error', `Aggregator still hasn't loaded. Processing que stopped`, trialCountMilsMapping, self.retryCount)
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
self.prettyLog('status', `Que has been inactive for a while. Adapter starting to process que now... Trial Count = ${self.retryCount + 1}`)
|
|
51
|
+
|
|
52
|
+
let shouldTryAgain = false
|
|
53
|
+
|
|
54
|
+
while (self.queuePointer < self.__atmtdAnalyticsQueue.length) {
|
|
55
|
+
const eventType = self.__atmtdAnalyticsQueue[self.queuePointer][0]
|
|
56
|
+
const args = self.__atmtdAnalyticsQueue[self.queuePointer][1]
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
switch (eventType) {
|
|
60
|
+
case CONSTANTS.EVENTS.AUCTION_INIT:
|
|
61
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler) {
|
|
62
|
+
window.atmtdAnalytics.auctionInitHandler(args);
|
|
63
|
+
} else {
|
|
64
|
+
shouldTryAgain = true
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case CONSTANTS.EVENTS.BID_REQUESTED:
|
|
68
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler) {
|
|
69
|
+
window.atmtdAnalytics.bidRequestedHandler(args);
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case CONSTANTS.EVENTS.BID_RESPONSE:
|
|
73
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler) {
|
|
74
|
+
window.atmtdAnalytics.bidResponseHandler(args);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
case CONSTANTS.EVENTS.BID_REJECTED:
|
|
78
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler) {
|
|
79
|
+
window.atmtdAnalytics.bidRejectedHandler(args);
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case CONSTANTS.EVENTS.BIDDER_DONE:
|
|
83
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler) {
|
|
84
|
+
window.atmtdAnalytics.bidderDoneHandler(args);
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
case CONSTANTS.EVENTS.BID_WON:
|
|
88
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler) {
|
|
89
|
+
window.atmtdAnalytics.bidWonHandler(args);
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
case CONSTANTS.EVENTS.NO_BID:
|
|
93
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler) {
|
|
94
|
+
window.atmtdAnalytics.noBidHandler(args);
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
case CONSTANTS.EVENTS.BID_TIMEOUT:
|
|
98
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler) {
|
|
99
|
+
window.atmtdAnalytics.bidderTimeoutHandler(args);
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
case CONSTANTS.EVENTS.AUCTION_DEBUG:
|
|
103
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler) {
|
|
104
|
+
window.atmtdAnalytics.auctionDebugHandler(args);
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
case 'slotRenderEnded':
|
|
108
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler) {
|
|
109
|
+
window.atmtdAnalytics.slotRenderEndedGPTHandler(args);
|
|
110
|
+
} else {
|
|
111
|
+
shouldTryAgain = true
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
case 'impressionViewable':
|
|
115
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler) {
|
|
116
|
+
window.atmtdAnalytics.impressionViewableHandler(args);
|
|
117
|
+
} else {
|
|
118
|
+
shouldTryAgain = true
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (shouldTryAgain) break;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
self.prettyLog('error', `Unhandled Error while processing ${eventType} of ${self.queuePointer}th index in the que. Will not be retrying this raw event ...`, true, () => {
|
|
126
|
+
logError(`The error is `, error)
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
self.queuePointer = self.queuePointer + 1
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (shouldTryAgain) {
|
|
134
|
+
if (trialCountMilsMapping[self.retryCount]) self.prettyLog('warn', `Adapter failed to process event as aggregator has not loaded. Retrying in ${trialCountMilsMapping[self.retryCount]}ms ...`);
|
|
135
|
+
setTimeout(self.processEvents, trialCountMilsMapping[self.retryCount])
|
|
136
|
+
self.retryCount = self.retryCount + 1
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const addGPTHandlers = () => {
|
|
141
|
+
const googletag = window.googletag || {}
|
|
142
|
+
googletag.cmd = googletag.cmd || []
|
|
143
|
+
googletag.cmd.push(() => {
|
|
144
|
+
googletag.pubads().addEventListener('slotRenderEnded', (event) => {
|
|
145
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.slotRenderEndedGPTHandler) {
|
|
146
|
+
if (window.__atmtdAggregatorFirstAuctionInitialized === true) {
|
|
147
|
+
window.atmtdAnalytics.slotRenderEndedGPTHandler(event)
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
self.__atmtdAnalyticsQueue.push(['slotRenderEnded', event])
|
|
152
|
+
self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting slotRenderEnded handler and pushing to que instead`)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
googletag.pubads().addEventListener('impressionViewable', (event) => {
|
|
156
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.impressionViewableHandler) {
|
|
157
|
+
if (window.__atmtdAggregatorFirstAuctionInitialized === true) {
|
|
158
|
+
window.atmtdAnalytics.impressionViewableHandler(event)
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
self.__atmtdAnalyticsQueue.push(['impressionViewable', event])
|
|
163
|
+
self.prettyLog(`warn`, `Aggregator not initialised at auctionInit, exiting impressionViewable handler and pushing to que instead`)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const initializeQueue = () => {
|
|
169
|
+
self.__atmtdAnalyticsQueue.push = (args) => {
|
|
170
|
+
Array.prototype.push.apply(self.__atmtdAnalyticsQueue, [args]);
|
|
171
|
+
if (timer) {
|
|
172
|
+
clearTimeout(timer);
|
|
173
|
+
timer = null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (args[0] === CONSTANTS.EVENTS.AUCTION_INIT) {
|
|
177
|
+
const timeout = parseInt(config.getConfig('bidderTimeout')) + 1500
|
|
178
|
+
timer = setTimeout(() => {
|
|
179
|
+
self.processEvents()
|
|
180
|
+
}, timeout);
|
|
181
|
+
} else {
|
|
182
|
+
timer = setTimeout(() => {
|
|
183
|
+
self.processEvents()
|
|
184
|
+
}, 1500);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// ANALYTICS ADAPTER
|
|
190
|
+
|
|
191
|
+
let baseAdapter = adapter({analyticsType: 'bundle'});
|
|
192
|
+
let atmtdAdapter = Object.assign({}, baseAdapter, {
|
|
193
|
+
|
|
194
|
+
disableAnalytics() {
|
|
195
|
+
baseAdapter.disableAnalytics.apply(this, arguments);
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
track({eventType, args}) {
|
|
199
|
+
switch (eventType) {
|
|
200
|
+
case CONSTANTS.EVENTS.AUCTION_INIT:
|
|
201
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionInitHandler) {
|
|
202
|
+
self.prettyLog('status', 'Aggregator loaded, initialising auction through handlers');
|
|
203
|
+
window.atmtdAnalytics.auctionInitHandler(args);
|
|
204
|
+
} else {
|
|
205
|
+
self.prettyLog('warn', 'Aggregator not loaded, initialising auction through que ...');
|
|
206
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
case CONSTANTS.EVENTS.BID_REQUESTED:
|
|
210
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRequestedHandler) {
|
|
211
|
+
window.atmtdAnalytics.bidRequestedHandler(args);
|
|
212
|
+
} else {
|
|
213
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
214
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
217
|
+
case CONSTANTS.EVENTS.BID_REJECTED:
|
|
218
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidRejectedHandler) {
|
|
219
|
+
window.atmtdAnalytics.bidRejectedHandler(args);
|
|
220
|
+
} else {
|
|
221
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
222
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
223
|
+
}
|
|
224
|
+
break;
|
|
225
|
+
case CONSTANTS.EVENTS.BID_RESPONSE:
|
|
226
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidResponseHandler) {
|
|
227
|
+
window.atmtdAnalytics.bidResponseHandler(args);
|
|
228
|
+
} else {
|
|
229
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
230
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
231
|
+
}
|
|
232
|
+
break;
|
|
233
|
+
case CONSTANTS.EVENTS.BIDDER_DONE:
|
|
234
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderDoneHandler) {
|
|
235
|
+
window.atmtdAnalytics.bidderDoneHandler(args);
|
|
236
|
+
} else {
|
|
237
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
238
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
239
|
+
}
|
|
240
|
+
break;
|
|
241
|
+
case CONSTANTS.EVENTS.BID_WON:
|
|
242
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidWonHandler) {
|
|
243
|
+
window.atmtdAnalytics.bidWonHandler(args);
|
|
244
|
+
} else {
|
|
245
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
246
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
case CONSTANTS.EVENTS.NO_BID:
|
|
250
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.noBidHandler) {
|
|
251
|
+
window.atmtdAnalytics.noBidHandler(args);
|
|
252
|
+
} else {
|
|
253
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
254
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
case CONSTANTS.EVENTS.AUCTION_DEBUG:
|
|
258
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.auctionDebugHandler) {
|
|
259
|
+
window.atmtdAnalytics.auctionDebugHandler(args);
|
|
260
|
+
} else {
|
|
261
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
262
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
case CONSTANTS.EVENTS.BID_TIMEOUT:
|
|
266
|
+
if (window.atmtdAnalytics && window.atmtdAnalytics.bidderTimeoutHandler) {
|
|
267
|
+
window.atmtdAnalytics.bidderTimeoutHandler(args);
|
|
268
|
+
} else {
|
|
269
|
+
self.prettyLog('warn', `Aggregator not loaded, pushing ${eventType} to que instead ...`);
|
|
270
|
+
self.__atmtdAnalyticsQueue.push([eventType, args])
|
|
271
|
+
}
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
atmtdAdapter.originEnableAnalytics = atmtdAdapter.enableAnalytics
|
|
278
|
+
|
|
279
|
+
atmtdAdapter.enableAnalytics = function (configuration) {
|
|
280
|
+
if ((configuration === undefined && typeof configuration !== 'object') || configuration.options === undefined) {
|
|
281
|
+
logError('A valid configuration must be passed to the Atmtd Analytics Adapter.');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const conf = configuration.options
|
|
286
|
+
|
|
287
|
+
if (conf === undefined || typeof conf !== 'object' || conf.siteID === undefined || conf.publisherID === undefined) {
|
|
288
|
+
logError('A valid publisher ID and siteID must be passed to the Atmtd Analytics Adapter.');
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
self.initializeQueue()
|
|
293
|
+
self.addGPTHandlers()
|
|
294
|
+
|
|
295
|
+
window.__atmtdSDKConfig = {
|
|
296
|
+
publisherID: conf.publisherID,
|
|
297
|
+
siteID: conf.siteID,
|
|
298
|
+
collectDebugMessages: conf.logDebug ? conf.logDebug : false
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
logMessage(`Automatad Analytics Adapter enabled with sdk config`, window.__atmtdSDKConfig)
|
|
302
|
+
|
|
303
|
+
// eslint-disable-next-line
|
|
304
|
+
atmtdAdapter.originEnableAnalytics(configuration)
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
/// /////////// ADAPTER REGISTRATION //////////////
|
|
308
|
+
|
|
309
|
+
adapterManager.registerAnalyticsAdapter({
|
|
310
|
+
adapter: atmtdAdapter,
|
|
311
|
+
code: ADAPTER_CODE
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
export var self = {
|
|
315
|
+
__atmtdAnalyticsQueue,
|
|
316
|
+
processEvents,
|
|
317
|
+
initializeQueue,
|
|
318
|
+
addGPTHandlers,
|
|
319
|
+
prettyLog,
|
|
320
|
+
queuePointer,
|
|
321
|
+
retryCount,
|
|
322
|
+
isLoggingEnabled
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export default atmtdAdapter;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
# Overview
|
|
3
|
+
|
|
4
|
+
Module Name: Automatad Analytics Adapter
|
|
5
|
+
Module Type: Analytics Adapter
|
|
6
|
+
Maintainer: tech@automatad.com
|
|
7
|
+
|
|
8
|
+
# Description
|
|
9
|
+
|
|
10
|
+
Analytics adapter for automatad.com. Contact tech@automatad.com for information.
|
|
11
|
+
|
|
12
|
+
# Test Parameters
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
{
|
|
16
|
+
provider: 'automatadAnalytics',
|
|
17
|
+
options: {
|
|
18
|
+
publisherID: 'N8vZLx',
|
|
19
|
+
siteID: 'PXfvBq'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
```
|
|
@@ -67,6 +67,8 @@ export let logWinningBidNotFound = (slot) => {
|
|
|
67
67
|
|
|
68
68
|
export let impressionViewableHandler = (globalModuleConfig, slot, event) => {
|
|
69
69
|
let respectiveBid = getMatchingWinningBidForGPTSlot(globalModuleConfig, slot);
|
|
70
|
+
let respectiveDeferredAdUnit = getGlobal().adUnits.find(adUnit => adUnit.deferBilling && respectiveBid.adUnitCode === adUnit.code);
|
|
71
|
+
|
|
70
72
|
if (respectiveBid === null) {
|
|
71
73
|
logWinningBidNotFound(slot);
|
|
72
74
|
} else {
|
|
@@ -74,6 +76,11 @@ export let impressionViewableHandler = (globalModuleConfig, slot, event) => {
|
|
|
74
76
|
fireViewabilityPixels(globalModuleConfig, respectiveBid);
|
|
75
77
|
// trigger respective bidder's onBidViewable handler
|
|
76
78
|
adapterManager.callBidViewableBidder(respectiveBid.adapterCode || respectiveBid.bidder, respectiveBid);
|
|
79
|
+
|
|
80
|
+
if (respectiveDeferredAdUnit) {
|
|
81
|
+
adapterManager.callBidBillableBidder(respectiveBid);
|
|
82
|
+
}
|
|
83
|
+
|
|
77
84
|
// emit the BID_VIEWABLE event with bid details, this event can be consumed by bidders and analytics pixels
|
|
78
85
|
events.emit(CONSTANTS.EVENTS.BID_VIEWABLE, respectiveBid);
|
|
79
86
|
}
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Module Name: bidViewability
|
|
4
4
|
|
|
5
|
-
Purpose: Track when a bid is viewable
|
|
5
|
+
Purpose: Track when a bid is viewable (and also ready for billing)
|
|
6
6
|
|
|
7
7
|
Maintainer: harshad.mane@pubmatic.com
|
|
8
8
|
|
|
9
9
|
# Description
|
|
10
|
-
- This module, when included, will trigger a BID_VIEWABLE event which can be consumed by Analytics adapters, bidders will need to implement `onBidViewable` method to capture this event
|
|
11
|
-
-
|
|
10
|
+
- This module, when included, will trigger a BID_VIEWABLE event which can be consumed by Analytics adapters, bidders will need to implement the `onBidViewable` method to capture this event
|
|
11
|
+
- Bidders can check if this module is part of the final build and whether it is enabled or not by accessing ```pbjs.getConfig('bidViewability')```
|
|
12
12
|
- GPT API is used to find when a bid is viewable, https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent . This event is fired when an impression becomes viewable, according to the Active View criteria.
|
|
13
13
|
Refer: https://support.google.com/admanager/answer/4524488
|
|
14
|
-
-
|
|
14
|
+
- This module does not work with any adserver's other than GAM with GPT integration
|
|
15
15
|
- Logic used to find a matching pbjs-bid for a GPT slot is ``` (slot.getAdUnitPath() === bid.adUnitCode || slot.getSlotElementId() === bid.adUnitCode) ``` this logic can be changed by using param ```customMatchFunction```
|
|
16
|
-
- When a rendered PBJS bid is viewable the module will trigger BID_VIEWABLE event, which can be consumed by bidders and analytics adapters
|
|
17
|
-
-
|
|
16
|
+
- When a rendered PBJS bid is viewable the module will trigger a BID_VIEWABLE event, which can be consumed by bidders and analytics adapters
|
|
17
|
+
- If the viewable bid contains a ```vurls``` param containing URL's and the Bid Viewability module is configured with ``` firePixels: true ``` then the URLs mentioned in bid.vurls will be called. Please note that GDPR and USP related parameters will be added to the given URLs
|
|
18
|
+
- This module is also compatible with Prebid core's billing deferral logic, this means that bids linked to an ad unit marked with `deferBilling: true` will trigger a bid adapter's `onBidBillable` function (if present) indicating an ad slot was viewed and also billing ready (if it were deferred).
|
|
18
19
|
|
|
19
20
|
# Params
|
|
20
21
|
- enabled [required] [type: boolean, default: false], when set to true, the module will emit BID_VIEWABLE when applicable
|
|
@@ -44,6 +45,6 @@ Refer: https://support.google.com/admanager/answer/4524488
|
|
|
44
45
|
```
|
|
45
46
|
|
|
46
47
|
# Please Note:
|
|
47
|
-
-
|
|
48
|
-
- Works with Banner, Outsteam
|
|
48
|
+
- This module doesn't seem to work with Instream Video, https://docs.prebid.org/dev-docs/examples/instream-banner-mix.html as GPT's impressionViewable event is not triggered for instream-video-creative
|
|
49
|
+
- Works with Banner, Outsteam and Native creatives
|
|
49
50
|
|
|
@@ -21,13 +21,14 @@ let billableEventsInitialized = false
|
|
|
21
21
|
|
|
22
22
|
function init (config, userConsent) {
|
|
23
23
|
const hasConsent = checkConsent(userConsent)
|
|
24
|
+
const initialize = hasConsent !== false
|
|
24
25
|
|
|
25
|
-
if (
|
|
26
|
+
if (initialize) {
|
|
26
27
|
const moduleConfig = getMergedConfig(config)
|
|
27
28
|
initializeBrandmetrics(moduleConfig.params.scriptId)
|
|
28
29
|
initializeBillableEvents()
|
|
29
30
|
}
|
|
30
|
-
return
|
|
31
|
+
return initialize
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -36,33 +37,35 @@ function init (config, userConsent) {
|
|
|
36
37
|
* @returns {boolean}
|
|
37
38
|
*/
|
|
38
39
|
function checkConsent (userConsent) {
|
|
39
|
-
let consent
|
|
40
|
-
|
|
41
|
-
if (userConsent
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
let consent
|
|
41
|
+
|
|
42
|
+
if (userConsent) {
|
|
43
|
+
if (userConsent.gdpr && userConsent.gdpr.gdprApplies) {
|
|
44
|
+
const gdpr = userConsent.gdpr
|
|
45
|
+
|
|
46
|
+
if (gdpr.vendorData) {
|
|
47
|
+
const vendor = gdpr.vendorData.vendor
|
|
48
|
+
const purpose = gdpr.vendorData.purpose
|
|
49
|
+
|
|
50
|
+
let vendorConsent = false
|
|
51
|
+
if (vendor.consents) {
|
|
52
|
+
vendorConsent = vendor.consents[GVL_ID]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (vendor.legitimateInterests) {
|
|
56
|
+
vendorConsent = vendorConsent || vendor.legitimateInterests[GVL_ID]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const purposes = TCF_PURPOSES.map(id => {
|
|
60
|
+
return (purpose.consents && purpose.consents[id]) || (purpose.legitimateInterests && purpose.legitimateInterests[id])
|
|
61
|
+
})
|
|
62
|
+
const purposesValid = purposes.filter(p => p === true).length === TCF_PURPOSES.length
|
|
63
|
+
consent = vendorConsent && purposesValid
|
|
51
64
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const purposes = TCF_PURPOSES.map(id => {
|
|
58
|
-
return (purpose.consents && purpose.consents[id]) || (purpose.legitimateInterests && purpose.legitimateInterests[id])
|
|
59
|
-
})
|
|
60
|
-
const purposesValid = purposes.filter(p => p === true).length === TCF_PURPOSES.length
|
|
61
|
-
consent = vendorConsent && purposesValid
|
|
65
|
+
} else if (userConsent.usp) {
|
|
66
|
+
const usp = userConsent.usp
|
|
67
|
+
consent = usp[1] !== 'N' && usp[2] !== 'Y'
|
|
62
68
|
}
|
|
63
|
-
} else if (userConsent.usp) {
|
|
64
|
-
const usp = userConsent.usp
|
|
65
|
-
consent = usp[1] !== 'N' && usp[2] !== 'Y'
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
return consent
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
registerBidder
|
|
3
|
+
} from '../src/adapters/bidderFactory.js';
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
deepAccess,
|
|
7
|
+
isFn,
|
|
8
|
+
logError,
|
|
9
|
+
isArray,
|
|
10
|
+
formatQS
|
|
11
|
+
} from '../src/utils.js';
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
BANNER,
|
|
15
|
+
} from '../src/mediaTypes.js';
|
|
16
|
+
|
|
17
|
+
const BIDDER_CODE = 'connatix';
|
|
18
|
+
const AD_URL = 'https://capi.connatix.com/rtb/hba';
|
|
19
|
+
const DEFAULT_MAX_TTL = '3600';
|
|
20
|
+
const DEFAULT_CURRENCY = 'USD';
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* Get the bid floor value from the bid object, either using the getFloor function or by accessing the 'params.bidfloor' property.
|
|
24
|
+
* If the bid floor cannot be determined, return 0 as a fallback value.
|
|
25
|
+
*/
|
|
26
|
+
export function getBidFloor(bid) {
|
|
27
|
+
if (!isFn(bid.getFloor)) {
|
|
28
|
+
return deepAccess(bid, 'params.bidfloor', 0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const bidFloor = bid.getFloor({
|
|
33
|
+
currency: DEFAULT_CURRENCY,
|
|
34
|
+
mediaType: '*',
|
|
35
|
+
size: '*',
|
|
36
|
+
});
|
|
37
|
+
return bidFloor.floor;
|
|
38
|
+
} catch (err) {
|
|
39
|
+
logError(err);
|
|
40
|
+
return 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const spec = {
|
|
45
|
+
code: BIDDER_CODE,
|
|
46
|
+
gvlid: 143,
|
|
47
|
+
supportedMediaTypes: [BANNER],
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
* Validate the bid request.
|
|
51
|
+
* If the request is valid, Connatix is trying to obtain at least one bid.
|
|
52
|
+
* Otherwise, the request to the Connatix server is not made
|
|
53
|
+
*/
|
|
54
|
+
isBidRequestValid: (bid = {}) => {
|
|
55
|
+
const bidId = deepAccess(bid, 'bidId');
|
|
56
|
+
const mediaTypes = deepAccess(bid, 'mediaTypes', {});
|
|
57
|
+
const params = deepAccess(bid, 'params', {});
|
|
58
|
+
const bidder = deepAccess(bid, 'bidder');
|
|
59
|
+
|
|
60
|
+
const banner = deepAccess(mediaTypes, BANNER, {});
|
|
61
|
+
|
|
62
|
+
const hasBidId = Boolean(bidId);
|
|
63
|
+
const isValidBidder = (bidder === BIDDER_CODE);
|
|
64
|
+
const isValidSize = (Boolean(banner.sizes) && isArray(mediaTypes[BANNER].sizes) && mediaTypes[BANNER].sizes.length > 0);
|
|
65
|
+
const hasSizes = mediaTypes[BANNER] ? isValidSize : false;
|
|
66
|
+
const hasRequiredBidParams = Boolean(params.placementId);
|
|
67
|
+
|
|
68
|
+
const isValid = isValidBidder && hasBidId && hasSizes && hasRequiredBidParams;
|
|
69
|
+
if (!isValid) {
|
|
70
|
+
logError(`Invalid bid request: isValidBidder: ${isValidBidder} hasBidId: ${hasBidId}, hasSizes: ${hasSizes}, hasRequiredBidParams: ${hasRequiredBidParams}`);
|
|
71
|
+
}
|
|
72
|
+
return isValid;
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
/*
|
|
76
|
+
* Build the request payload by processing valid bid requests and extracting the necessary information.
|
|
77
|
+
* Determine the host and page from the bidderRequest's refferUrl, and include ccpa and gdpr consents.
|
|
78
|
+
* Return an object containing the request method, url, and the constructed payload.
|
|
79
|
+
*/
|
|
80
|
+
buildRequests: (validBidRequests = [], bidderRequest = {}) => {
|
|
81
|
+
const bidRequests = validBidRequests.map(bid => {
|
|
82
|
+
const {
|
|
83
|
+
bidId,
|
|
84
|
+
mediaTypes,
|
|
85
|
+
params,
|
|
86
|
+
sizes,
|
|
87
|
+
} = bid;
|
|
88
|
+
return {
|
|
89
|
+
bidId,
|
|
90
|
+
mediaTypes,
|
|
91
|
+
sizes,
|
|
92
|
+
placementId: params.placementId,
|
|
93
|
+
floor: getBidFloor(bid),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const requestPayload = {
|
|
98
|
+
ortb2: bidderRequest.ortb2,
|
|
99
|
+
gdprConsent: bidderRequest.gdprConsent,
|
|
100
|
+
uspConsent: bidderRequest.uspConsent,
|
|
101
|
+
refererInfo: bidderRequest.refererInfo,
|
|
102
|
+
bidRequests,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
url: AD_URL,
|
|
108
|
+
data: requestPayload
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* Interpret the server response and create an array of bid responses by extracting and formatting
|
|
114
|
+
* relevant information such as requestId, cpm, ttl, width, height, creativeId, referrer and ad
|
|
115
|
+
* Returns an array of bid responses by extracting and formatting the server response
|
|
116
|
+
*/
|
|
117
|
+
interpretResponse: (serverResponse) => {
|
|
118
|
+
const responseBody = serverResponse.body;
|
|
119
|
+
const bids = responseBody.Bids;
|
|
120
|
+
const playerId = responseBody.PlayerId;
|
|
121
|
+
const customerId = responseBody.CustomerId;
|
|
122
|
+
|
|
123
|
+
if (!isArray(bids) || !playerId || !customerId) {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return bids.map(bidResponse => ({
|
|
128
|
+
requestId: bidResponse.RequestId,
|
|
129
|
+
cpm: bidResponse.Cpm,
|
|
130
|
+
ttl: bidResponse.Ttl || DEFAULT_MAX_TTL,
|
|
131
|
+
currency: 'USD',
|
|
132
|
+
mediaType: BANNER,
|
|
133
|
+
netRevenue: true,
|
|
134
|
+
width: bidResponse.Width,
|
|
135
|
+
height: bidResponse.Height,
|
|
136
|
+
creativeId: bidResponse.CreativeId,
|
|
137
|
+
referrer: bidResponse.Referrer,
|
|
138
|
+
ad: bidResponse.Ad,
|
|
139
|
+
}));
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* Determine the user sync type (either 'iframe' or 'image') based on syncOptions.
|
|
144
|
+
* Construct the sync URL by appending required query parameters such as gdpr, ccpa, and coppa consents.
|
|
145
|
+
* Return an array containing an object with the sync type and the constructed URL.
|
|
146
|
+
*/
|
|
147
|
+
getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => {
|
|
148
|
+
if (!syncOptions.iframeEnabled) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!serverResponses || !serverResponses.length) {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const params = {};
|
|
157
|
+
|
|
158
|
+
if (gdprConsent) {
|
|
159
|
+
if (typeof gdprConsent.gdprApplies === 'boolean') {
|
|
160
|
+
params['gdpr'] = Number(gdprConsent.gdprApplies);
|
|
161
|
+
} else {
|
|
162
|
+
params['gdpr'] = 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (typeof gdprConsent.consentString === 'string') {
|
|
166
|
+
params['gdpr_consent'] = encodeURIComponent(gdprConsent.consentString);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (typeof uspConsent === 'string') {
|
|
171
|
+
params['us_privacy'] = encodeURIComponent(uspConsent);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const syncUrl = serverResponses[0].body.UserSyncEndpoint;
|
|
175
|
+
const queryParams = Object.keys(params).length > 0 ? formatQS(params) : '';
|
|
176
|
+
|
|
177
|
+
const url = queryParams ? `${syncUrl}?${queryParams}` : syncUrl;
|
|
178
|
+
return [{
|
|
179
|
+
type: 'iframe',
|
|
180
|
+
url
|
|
181
|
+
}];
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
registerBidder(spec);
|