prebid.js 8.5.0 → 8.7.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/adagioBidAdapter.js +1 -1
- package/dist/adbookpspBidAdapter.js +1 -1
- package/dist/adgenerationBidAdapter.js +1 -1
- package/dist/adqueryBidAdapter.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/bidglassBidAdapter.js +1 -1
- package/dist/big-richmediaBidAdapter.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 +6 -0
- 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/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/growthCodeAnalyticsAdapter.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/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/mspa.js +1 -1
- package/dist/newspassidBidAdapter.js +1 -1
- package/dist/nexx360BidAdapter.js +1 -1
- package/dist/not-for-prod/prebid.js +140 -136
- package/dist/oguryBidAdapter.js +1 -1
- package/dist/onetagBidAdapter.js +1 -1
- package/dist/ooloAnalyticsAdapter.js +1 -1
- package/dist/optidigitalBidAdapter.js +1 -1
- package/dist/outbrainBidAdapter.js +1 -1
- package/dist/parrableIdSystem.js +1 -1
- package/dist/pixfutureBidAdapter.js +1 -1
- package/dist/prebid-core.js +1 -1
- package/dist/pubCircleBidAdapter.js +1 -0
- 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/relevadRtdProvider.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/smilewantedBidAdapter.js +1 -1
- package/dist/sonobiBidAdapter.js +1 -1
- package/dist/sovrnAnalyticsAdapter.js +1 -1
- package/dist/sovrnBidAdapter.js +1 -1
- package/dist/ssmasBidAdapter.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/viantOrtbBidAdapter.js +1 -0
- package/dist/vidazooBidAdapter.js +1 -1
- package/dist/videobyteBidAdapter.js +1 -1
- package/dist/videojsVideoProvider.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/videoModule/jwplayer/bidMarkedAsUsed.html +1 -1
- package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +1 -1
- package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +137 -0
- package/integrationExamples/videoModule/jwplayer/eventListeners.html +1 -1
- package/integrationExamples/videoModule/jwplayer/eventsUI.html +1 -1
- package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +1 -1
- package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +1 -1
- package/integrationExamples/videoModule/jwplayer/playlist.html +1 -1
- package/integrationExamples/videoModule/videojs/bidsBackHandlerOverride.html +164 -0
- package/libraries/mspa/activityControls.js +51 -32
- package/modules/adagioBidAdapter.js +15 -1
- package/modules/adgenerationBidAdapter.js +5 -4
- package/modules/adsinteractiveBidAdapter.js +4 -2
- package/modules/alkimiBidAdapter.js +19 -7
- package/modules/appnexusBidAdapter.js +1 -1
- package/modules/automatadAnalyticsAdapter.js +325 -0
- package/modules/automatadAnalyticsAdapter.md +23 -0
- package/modules/connatixBidAdapter.js +185 -0
- package/modules/connatixBidAdapter.md +37 -0
- package/modules/criteoBidAdapter.js +18 -0
- package/modules/cwireBidAdapter.js +19 -0
- package/modules/freepassBidAdapter.js +20 -1
- package/modules/freepassBidAdapter.md +4 -1
- package/modules/gridBidAdapter.js +1 -8
- package/modules/growthCodeAnalyticsAdapter.js +7 -2
- package/modules/medianetBidAdapter.js +7 -4
- package/modules/mediasquareBidAdapter.js +3 -0
- package/modules/newspassid.md +76 -0
- package/modules/newspassidBidAdapter.js +44 -18
- package/modules/optidigitalBidAdapter.js +25 -16
- package/modules/pubCircleBidAdapter.js +231 -0
- package/modules/pubCircleBidAdapter.md +79 -0
- package/modules/relevadRtdProvider.js +6 -7
- package/modules/ssmasBidAdapter.js +2 -2
- package/modules/tappxBidAdapter.js +27 -15
- package/modules/tappxBidAdapter.md +17 -0
- package/modules/topicsFpdModule.js +21 -48
- package/modules/undertoneBidAdapter.md +1 -1
- package/modules/userId/eids.md +7 -0
- package/modules/viantOrtbBidAdapter.js +113 -0
- package/modules/viantOrtbBidAdapter.md +54 -0
- package/modules/vidazooBidAdapter.js +9 -2
- package/modules/videojsVideoProvider.js +9 -2
- package/package.json +1 -1
- package/test/spec/libraries/mspa/activityControls_spec.js +145 -212
- package/test/spec/modules/adagioBidAdapter_spec.js +89 -0
- package/test/spec/modules/adgenerationBidAdapter_spec.js +6 -6
- package/test/spec/modules/alkimiBidAdapter_spec.js +3 -9
- package/test/spec/modules/appnexusBidAdapter_spec.js +12 -1
- package/test/spec/modules/automatadAnalyticsAdapter_spec.js +533 -0
- package/test/spec/modules/connatixBidAdapter_spec.js +366 -0
- package/test/spec/modules/criteoBidAdapter_spec.js +52 -3
- package/test/spec/modules/cwireBidAdapter_spec.js +47 -0
- package/test/spec/modules/freepassBidAdapter_spec.js +44 -0
- package/test/spec/modules/gridBidAdapter_spec.js +68 -0
- package/test/spec/modules/medianetBidAdapter_spec.js +18 -18
- package/test/spec/modules/mediasquareBidAdapter_spec.js +5 -0
- package/test/spec/modules/newspassidBidAdapter_spec.js +6 -0
- package/test/spec/modules/optidigitalBidAdapter_spec.js +9 -2
- package/test/spec/modules/pubCircleBidAdapter_spec.js +399 -0
- package/test/spec/modules/tappxBidAdapter_spec.js +19 -0
- package/test/spec/modules/topicsFpdModule_spec.js +343 -365
- package/test/spec/modules/viantOrtbBidAdapter_spec.js +432 -0
|
@@ -8,7 +8,13 @@ import {
|
|
|
8
8
|
import {gppDataHandler} from '../../src/adapterManager.js';
|
|
9
9
|
|
|
10
10
|
// default interpretation for MSPA consent(s):
|
|
11
|
-
// https://docs.
|
|
11
|
+
// https://docs.prebid.org/features/mspa-usnat.html
|
|
12
|
+
|
|
13
|
+
const SENSITIVE_DATA_GEO = 7;
|
|
14
|
+
|
|
15
|
+
function isApplicable(val) {
|
|
16
|
+
return val != null && val !== 0
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
export function isBasicConsentDenied(cd) {
|
|
14
20
|
// service provider mode is always consent denied
|
|
@@ -18,47 +24,60 @@ export function isBasicConsentDenied(cd) {
|
|
|
18
24
|
// minors 13+ who have not given consent
|
|
19
25
|
cd.KnownChildSensitiveDataConsents[0] === 1 ||
|
|
20
26
|
// minors under 13 cannot consent
|
|
21
|
-
cd.KnownChildSensitiveDataConsents[1]
|
|
22
|
-
// sensitive category consent impossible without notice
|
|
23
|
-
(cd.SensitiveDataProcessing.some(element => element === 2) && (cd.SensitiveDataLimitUseNotice !== 1 || cd.SensitiveDataProcessingOptOutNotice !== 1));
|
|
27
|
+
isApplicable(cd.KnownChildSensitiveDataConsents[1]);
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
export function
|
|
27
|
-
return ['SensitiveDataProcessingOptOutNotice', 'SensitiveDataLimitUseNotice'].some(prop => cd[prop] ===
|
|
30
|
+
export function sensitiveNoticeIs(cd, value) {
|
|
31
|
+
return ['SensitiveDataProcessingOptOutNotice', 'SensitiveDataLimitUseNotice'].some(prop => cd[prop] === value)
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
export function isConsentDenied(cd) {
|
|
31
35
|
return isBasicConsentDenied(cd) ||
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
['Sale', 'Sharing', 'TargetedAdvertising'].some(scope => {
|
|
37
|
+
const oo = cd[`${scope}OptOut`];
|
|
38
|
+
const notice = cd[`${scope}OptOutNotice`];
|
|
39
|
+
// user opted out
|
|
40
|
+
return oo === 1 ||
|
|
41
|
+
// opt-out notice was not given
|
|
42
|
+
notice === 2 ||
|
|
43
|
+
// do not trust CMP if it signals opt-in but no opt-out notice was given
|
|
44
|
+
(oo === 2 && notice === 0);
|
|
45
|
+
}) ||
|
|
46
|
+
// no sharing notice was given ...
|
|
47
|
+
cd.SharingNotice === 2 ||
|
|
48
|
+
// ... or the CMP says it was not applicable, while also claiming it got consent
|
|
49
|
+
(cd.SharingOptOut === 2 && cd.SharingNotice === 0);
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
export
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
export const isTransmitUfpdConsentDenied = (() => {
|
|
53
|
+
// deny anything that smells like: genetic, biometric, state/national ID, financial, union membership,
|
|
54
|
+
// or personal communication data
|
|
55
|
+
const cannotBeInScope = [6, 7, 9, 10, 12].map(el => --el);
|
|
56
|
+
// require consent for everything else (except geo, which is treated separately)
|
|
57
|
+
const allExceptGeo = Array.from(Array(12).keys()).filter((el) => el !== SENSITIVE_DATA_GEO)
|
|
58
|
+
const mustHaveConsent = allExceptGeo.filter(el => !cannotBeInScope.includes(el));
|
|
59
|
+
|
|
60
|
+
return function (cd) {
|
|
61
|
+
return isConsentDenied(cd) ||
|
|
62
|
+
// no notice about sensitive data was given
|
|
63
|
+
sensitiveNoticeIs(cd, 2) ||
|
|
64
|
+
// extra-sensitive data is applicable
|
|
65
|
+
cannotBeInScope.some(i => isApplicable(cd.SensitiveDataProcessing[i])) ||
|
|
66
|
+
// user opted out for not-as-sensitive data
|
|
67
|
+
mustHaveConsent.some(i => cd.SensitiveDataProcessing[i] === 1) ||
|
|
68
|
+
// CMP says it has consent, but did not give notice about it
|
|
69
|
+
(sensitiveNoticeIs(cd, 0) && allExceptGeo.some(i => cd.SensitiveDataProcessing[i] === 2))
|
|
70
|
+
}
|
|
71
|
+
})();
|
|
57
72
|
|
|
58
73
|
export function isTransmitGeoConsentDenied(cd) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
cd
|
|
74
|
+
const geoConsent = cd.SensitiveDataProcessing[SENSITIVE_DATA_GEO];
|
|
75
|
+
return geoConsent === 1 ||
|
|
76
|
+
isBasicConsentDenied(cd) ||
|
|
77
|
+
// no sensitive data notice was given
|
|
78
|
+
sensitiveNoticeIs(cd, 2) ||
|
|
79
|
+
// do not trust CMP if it says it has consent for geo but didn't show a sensitive data notice
|
|
80
|
+
(sensitiveNoticeIs(cd, 0) && geoConsent === 2)
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
const CONSENT_RULES = {
|
|
@@ -399,6 +399,17 @@ function _getUspConsent(bidderRequest) {
|
|
|
399
399
|
return (deepAccess(bidderRequest, 'uspConsent')) ? { uspConsent: bidderRequest.uspConsent } : false;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
+
function _getGppConsent(bidderRequest) {
|
|
403
|
+
let gpp = deepAccess(bidderRequest, 'gppConsent.gppString')
|
|
404
|
+
let gppSid = deepAccess(bidderRequest, 'gppConsent.applicableSections')
|
|
405
|
+
|
|
406
|
+
if (!gpp || !gppSid) {
|
|
407
|
+
gpp = deepAccess(bidderRequest, 'ortb2.regs.gpp', '')
|
|
408
|
+
gppSid = deepAccess(bidderRequest, 'ortb2.regs.gpp_sid', [])
|
|
409
|
+
}
|
|
410
|
+
return { gpp, gppSid }
|
|
411
|
+
}
|
|
412
|
+
|
|
402
413
|
function _getSchain(bidRequest) {
|
|
403
414
|
return deepAccess(bidRequest, 'schain');
|
|
404
415
|
}
|
|
@@ -976,6 +987,7 @@ export const spec = {
|
|
|
976
987
|
const gdprConsent = _getGdprConsent(bidderRequest) || {};
|
|
977
988
|
const uspConsent = _getUspConsent(bidderRequest) || {};
|
|
978
989
|
const coppa = _getCoppa();
|
|
990
|
+
const gppConsent = _getGppConsent(bidderRequest)
|
|
979
991
|
const schain = _getSchain(validBidRequests[0]);
|
|
980
992
|
const eids = _getEids(validBidRequests[0]) || [];
|
|
981
993
|
const syncEnabled = deepAccess(config.getConfig('userSync'), 'syncEnabled')
|
|
@@ -1143,7 +1155,9 @@ export const spec = {
|
|
|
1143
1155
|
regs: {
|
|
1144
1156
|
gdpr: gdprConsent,
|
|
1145
1157
|
coppa: coppa,
|
|
1146
|
-
ccpa: uspConsent
|
|
1158
|
+
ccpa: uspConsent,
|
|
1159
|
+
gpp: gppConsent.gpp,
|
|
1160
|
+
gppSid: gppConsent.gppSid
|
|
1147
1161
|
},
|
|
1148
1162
|
schain: schain,
|
|
1149
1163
|
user: {
|
|
@@ -28,7 +28,7 @@ export const spec = {
|
|
|
28
28
|
buildRequests: function (validBidRequests, bidderRequest) {
|
|
29
29
|
// convert Native ORTB definition to old-style prebid native definition
|
|
30
30
|
validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
|
|
31
|
-
const ADGENE_PREBID_VERSION = '1.6.
|
|
31
|
+
const ADGENE_PREBID_VERSION = '1.6.2';
|
|
32
32
|
let serverRequests = [];
|
|
33
33
|
for (let i = 0, len = validBidRequests.length; i < len; i++) {
|
|
34
34
|
const validReq = validBidRequests[i];
|
|
@@ -41,6 +41,7 @@ export const spec = {
|
|
|
41
41
|
const imuid = deepAccess(validReq, 'userId.imuid');
|
|
42
42
|
const gpid = deepAccess(validReq, 'ortb2Imp.ext.gpid');
|
|
43
43
|
const sua = deepAccess(validReq, 'ortb2.device.sua');
|
|
44
|
+
const uid2 = deepAccess(validReq, 'userId.uid2.id');
|
|
44
45
|
let data = ``;
|
|
45
46
|
data = tryAppendQueryString(data, 'posall', 'SSPLOC');
|
|
46
47
|
const id = getBidIdParameter('id', validReq.params);
|
|
@@ -58,10 +59,10 @@ export const spec = {
|
|
|
58
59
|
data = tryAppendQueryString(data, 'adgext_id5_id', id5id);
|
|
59
60
|
data = tryAppendQueryString(data, 'adgext_id5_id_link_type', id5LinkType);
|
|
60
61
|
data = tryAppendQueryString(data, 'adgext_imuid', imuid);
|
|
61
|
-
data = tryAppendQueryString(data, 'adgext_uid2',
|
|
62
|
-
data = tryAppendQueryString(data, 'gpid', gpid
|
|
62
|
+
data = tryAppendQueryString(data, 'adgext_uid2', uid2);
|
|
63
|
+
data = tryAppendQueryString(data, 'gpid', gpid);
|
|
63
64
|
data = tryAppendQueryString(data, 'uach', sua ? JSON.stringify(sua) : null);
|
|
64
|
-
data = tryAppendQueryString(data, 'schain', validReq.schain ?
|
|
65
|
+
data = tryAppendQueryString(data, 'schain', validReq.schain ? JSON.stringify(validReq.schain) : null);
|
|
65
66
|
|
|
66
67
|
// native以外にvideo等の対応が入った場合は要修正
|
|
67
68
|
if (!validReq.mediaTypes || !validReq.mediaTypes.native) {
|
|
@@ -6,12 +6,14 @@ import { registerBidder } from '../src/adapters/bidderFactory.js';
|
|
|
6
6
|
import { BANNER } from '../src/mediaTypes.js';
|
|
7
7
|
|
|
8
8
|
const ADSINTERACTIVE_CODE = 'adsinteractive';
|
|
9
|
-
const USER_SYNC_URL_IMAGE = 'https://
|
|
10
|
-
const USER_SYNC_URL_IFRAME = 'https://
|
|
9
|
+
const USER_SYNC_URL_IMAGE = 'https://sync.adsinteractive.com/img';
|
|
10
|
+
const USER_SYNC_URL_IFRAME = 'https://sync.adsinteractive.com/sync';
|
|
11
|
+
const GVLID = 1212;
|
|
11
12
|
|
|
12
13
|
export const spec = {
|
|
13
14
|
code: ADSINTERACTIVE_CODE,
|
|
14
15
|
supportedMediaTypes: [BANNER],
|
|
16
|
+
gvlid: GVLID,
|
|
15
17
|
|
|
16
18
|
isBidRequestValid: (bid) => {
|
|
17
19
|
return (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {registerBidder} from '../src/adapters/bidderFactory.js';
|
|
2
|
-
import {deepAccess, deepClone} from '../src/utils.js';
|
|
2
|
+
import {deepAccess, deepClone, getDNT, generateUUID} from '../src/utils.js';
|
|
3
3
|
import {ajax} from '../src/ajax.js';
|
|
4
4
|
import {VIDEO} from '../src/mediaTypes.js';
|
|
5
5
|
import {config} from '../src/config.js';
|
|
@@ -12,7 +12,7 @@ export const spec = {
|
|
|
12
12
|
supportedMediaTypes: ['banner', 'video'],
|
|
13
13
|
|
|
14
14
|
isBidRequestValid: function (bid) {
|
|
15
|
-
return !!(bid.params && bid.params.
|
|
15
|
+
return !!(bid.params && bid.params.token);
|
|
16
16
|
},
|
|
17
17
|
|
|
18
18
|
buildRequests: function (validBidRequests, bidderRequest) {
|
|
@@ -28,12 +28,15 @@ export const spec = {
|
|
|
28
28
|
|
|
29
29
|
bids.push({
|
|
30
30
|
token: bidRequest.params.token,
|
|
31
|
-
|
|
31
|
+
instl: bidRequest.params.instl,
|
|
32
|
+
exp: bidRequest.params.exp,
|
|
32
33
|
bidFloor: getBidFloor(bidRequest, formatTypes),
|
|
33
34
|
sizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes')),
|
|
34
35
|
playerSizes: prepareSizes(deepAccess(bidRequest, 'mediaTypes.video.playerSize')),
|
|
35
36
|
impMediaTypes: formatTypes,
|
|
36
|
-
adUnitCode: bidRequest.adUnitCode
|
|
37
|
+
adUnitCode: bidRequest.adUnitCode,
|
|
38
|
+
video: deepAccess(bidRequest, 'mediaTypes.video'),
|
|
39
|
+
banner: deepAccess(bidRequest, 'mediaTypes.banner')
|
|
37
40
|
})
|
|
38
41
|
bidIds.push(bidRequest.bidId)
|
|
39
42
|
})
|
|
@@ -41,14 +44,23 @@ export const spec = {
|
|
|
41
44
|
const alkimiConfig = config.getConfig('alkimi');
|
|
42
45
|
|
|
43
46
|
let payload = {
|
|
44
|
-
|
|
45
|
-
requestId: bidderRequest.auctionId,
|
|
47
|
+
requestId: generateUUID(),
|
|
46
48
|
signRequest: {bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID},
|
|
47
49
|
bidIds,
|
|
48
50
|
referer: bidderRequest.refererInfo.page,
|
|
49
51
|
signature: alkimiConfig && alkimiConfig.signature,
|
|
50
52
|
schain: validBidRequests[0].schain,
|
|
51
|
-
cpp: config.getConfig('coppa') ? 1 : 0
|
|
53
|
+
cpp: config.getConfig('coppa') ? 1 : 0,
|
|
54
|
+
device: {
|
|
55
|
+
dnt: getDNT() ? 1 : 0,
|
|
56
|
+
w: screen.width,
|
|
57
|
+
h: screen.height
|
|
58
|
+
},
|
|
59
|
+
ortb2: {
|
|
60
|
+
at: bidderRequest.ortb2?.at,
|
|
61
|
+
bcat: bidderRequest.ortb2?.bcat,
|
|
62
|
+
wseat: bidderRequest.ortb2?.wseat
|
|
63
|
+
}
|
|
52
64
|
}
|
|
53
65
|
|
|
54
66
|
if (bidderRequest && bidderRequest.gdprConsent) {
|
|
@@ -788,7 +788,7 @@ function bidToTag(bid) {
|
|
|
788
788
|
tag.keywords = auKeywords;
|
|
789
789
|
}
|
|
790
790
|
|
|
791
|
-
let gpid = deepAccess(bid, 'ortb2Imp.ext.data.pbadslot');
|
|
791
|
+
let gpid = deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot');
|
|
792
792
|
if (gpid) {
|
|
793
793
|
tag.gpid = gpid;
|
|
794
794
|
}
|
|
@@ -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
|
+
```
|