@highfivve/ad-tag 5.8.17 → 5.8.21
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/lib/ads/labelConfigService.js +14 -1
- package/lib/ads/modules/ad-reload/index.js +146 -142
- package/lib/ads/modules/adex/index.js +106 -104
- package/lib/ads/modules/cleanup/index.js +64 -61
- package/lib/ads/modules/confiant/index.js +29 -29
- package/lib/ads/modules/emetriq/index.js +107 -102
- package/lib/ads/modules/generic-skin/index.js +128 -127
- package/lib/ads/modules/identitylink/index.js +37 -36
- package/lib/ads/modules/moli-analytics/eventTracker.js +43 -0
- package/lib/ads/modules/moli-analytics/events/gptSlotRenderEnded.js +21 -0
- package/lib/ads/modules/moli-analytics/events/index.js +16 -0
- package/lib/ads/modules/moli-analytics/events/pageView.js +31 -0
- package/lib/ads/modules/moli-analytics/events/prebidAuctionEnd.js +39 -0
- package/lib/ads/modules/moli-analytics/events/prebidBidWon.js +23 -0
- package/lib/ads/modules/moli-analytics/index.js +161 -0
- package/lib/ads/modules/moli-analytics/session.js +60 -0
- package/lib/ads/modules/moli-analytics/types.js +1 -0
- package/lib/ads/modules/prebid-first-party-data/index.js +41 -43
- package/lib/ads/modules/pubstack/abTest.js +11 -0
- package/lib/ads/modules/pubstack/index.js +30 -28
- package/lib/ads/modules/sticky-footer-ad/index.js +25 -25
- package/lib/ads/modules/sticky-footer-ad-v2/index.js +25 -25
- package/lib/ads/modules/sticky-header-ad/index.js +44 -42
- package/lib/ads/modules/zeotap/index.js +93 -93
- package/lib/ads/moli.js +35 -22
- package/lib/bundle/adReload.js +2 -2
- package/lib/bundle/adex.js +2 -2
- package/lib/bundle/cleanup.js +2 -2
- package/lib/bundle/confiant.js +2 -2
- package/lib/bundle/emetriq.js +2 -2
- package/lib/bundle/identityLink.js +2 -2
- package/lib/bundle/moliAnalytics.js +2 -0
- package/lib/bundle/prebidFirstPartyData.js +2 -2
- package/lib/bundle/pubstack.js +2 -2
- package/lib/bundle/skin.js +2 -2
- package/lib/bundle/stickyFooterAd.js +2 -2
- package/lib/bundle/stickyFooterAds2.js +2 -2
- package/lib/bundle/stickyHeaderAd.js +2 -2
- package/lib/bundle/zeotap.js +2 -2
- package/lib/gen/packageJson.js +1 -1
- package/lib/types/prebidjs.js +1 -0
- package/lib/util/browserStorageKeys.js +1 -0
- package/package.json +1 -1
|
@@ -11,140 +11,141 @@ export const filterHighestNonSkinBid = (bidResponses, blockedAdSlotDomIds) => {
|
|
|
11
11
|
.sort((bid1, bid2) => bid2.cpm - bid1.cpm)
|
|
12
12
|
.slice(0, 1)));
|
|
13
13
|
};
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
14
|
+
export const createSkin = () => {
|
|
15
|
+
const name = 'skin';
|
|
16
|
+
let skinModuleConfig = null;
|
|
17
|
+
let bidsBackHandler = [];
|
|
18
|
+
const config__ = () => skinModuleConfig;
|
|
19
|
+
const getConfigEffect = (config, bidResponses, log) => {
|
|
20
|
+
const skinBidResponse = bidResponses[config.skinAdSlotDomId];
|
|
21
|
+
const isSkinBid = (bid) => {
|
|
22
|
+
const oneFilterApplied = config.formatFilter.some(filter => {
|
|
23
|
+
switch (filter.bidder) {
|
|
24
|
+
case '*':
|
|
25
|
+
return true;
|
|
26
|
+
case 'gumgum':
|
|
27
|
+
return (bid.bidder === prebidjs.GumGum &&
|
|
28
|
+
(filter.auid === undefined ||
|
|
29
|
+
(typeof bid.ad !== 'string' && bid.ad.auid === filter.auid)));
|
|
30
|
+
default:
|
|
31
|
+
return bid.bidder === filter.bidder;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return bid.cpm > 0 && oneFilterApplied;
|
|
35
|
+
};
|
|
36
|
+
const nonSkinBids = filterHighestNonSkinBid(bidResponses, config.blockedAdSlotDomIds);
|
|
37
|
+
const combinedNonSkinCpm = nonSkinBids.reduce((prev, current) => prev + current.cpm, 0);
|
|
38
|
+
const skinBids = skinBidResponse
|
|
39
|
+
?
|
|
40
|
+
skinBidResponse.bids.filter(isSkinBid).sort((bid1, bid2) => bid2.cpm - bid1.cpm)
|
|
41
|
+
: [];
|
|
42
|
+
const skinConfigEffect = skinBids.length > 0
|
|
43
|
+
? skinBids[0].cpm > combinedNonSkinCpm
|
|
41
44
|
?
|
|
42
|
-
|
|
43
|
-
: [];
|
|
44
|
-
const skinConfigEffect = skinBids.length > 0
|
|
45
|
-
? skinBids[0].cpm > combinedNonSkinCpm
|
|
46
|
-
?
|
|
47
|
-
"BlockOtherSlots"
|
|
48
|
-
:
|
|
49
|
-
"BlockSkinSlot"
|
|
45
|
+
"BlockOtherSlots"
|
|
50
46
|
:
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
47
|
+
"BlockSkinSlot"
|
|
48
|
+
:
|
|
49
|
+
"NoBlocking";
|
|
50
|
+
log.debug(name, 'nonSkinBids', nonSkinBids);
|
|
51
|
+
log.debug(name, 'skinBids', skinBids);
|
|
52
|
+
if (config.enableCpmComparison) {
|
|
53
|
+
return skinConfigEffect;
|
|
54
|
+
}
|
|
55
|
+
return skinBids.length > 0 ? "BlockOtherSlots" : "NoBlocking";
|
|
56
|
+
};
|
|
57
|
+
const selectConfig = (skinModuleConfig, bidResponses, log) => skinModuleConfig.configs
|
|
58
|
+
.map(config => ({
|
|
59
|
+
skinConfig: config,
|
|
60
|
+
configEffect: getConfigEffect(config, bidResponses, log)
|
|
61
|
+
}))
|
|
62
|
+
.find(({ configEffect }) => configEffect !== "NoBlocking");
|
|
63
|
+
const destroyAdSlot = (slotDefinitions, gWindow) => (adSlotDomId) => {
|
|
64
|
+
const adSlots = slotDefinitions
|
|
65
|
+
.map(slot => slot.adSlot)
|
|
66
|
+
.filter((slot) => slot.getSlotElementId() === adSlotDomId);
|
|
67
|
+
gWindow.googletag.destroySlots(adSlots);
|
|
68
|
+
};
|
|
69
|
+
const hideAdSlot = (_window, log) => (domId) => {
|
|
70
|
+
const element = _window.document.getElementById(domId);
|
|
71
|
+
try {
|
|
72
|
+
if (element) {
|
|
73
|
+
log.debug('SkinModule', `Set display:none for ${domId}`);
|
|
74
|
+
element.style.setProperty('display', 'none');
|
|
56
75
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
.
|
|
68
|
-
.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.runSkinConfigs = (skinModuleConfig) => (ctx, bidResponses, slotDefinitions) => {
|
|
72
|
-
const skinConfigWithEffect = this.selectConfig(skinModuleConfig, bidResponses, ctx.logger__);
|
|
73
|
-
if (skinConfigWithEffect) {
|
|
74
|
-
const { skinConfig, configEffect } = skinConfigWithEffect;
|
|
75
|
-
if (configEffect === "BlockOtherSlots") {
|
|
76
|
-
ctx.logger__.debug('SkinModule', 'Skin configuration applied', skinConfig);
|
|
77
|
-
skinConfig.blockedAdSlotDomIds.forEach(this.destroyAdSlot(slotDefinitions, ctx.window__));
|
|
78
|
-
if (skinConfig.hideBlockedSlots) {
|
|
79
|
-
skinConfig.blockedAdSlotDomIds.forEach(this.hideAdSlot(ctx.window__, ctx.logger__));
|
|
80
|
-
}
|
|
81
|
-
if (skinConfig.hideSkinAdSlot) {
|
|
82
|
-
this.hideAdSlot(ctx.window__, ctx.logger__)(skinConfig.skinAdSlotDomId);
|
|
83
|
-
}
|
|
84
|
-
if (skinConfig.hideBlockedSlotsSelector) {
|
|
85
|
-
ctx.window__.document
|
|
86
|
-
.querySelectorAll(skinConfig.hideBlockedSlotsSelector)
|
|
87
|
-
.forEach(node => {
|
|
88
|
-
ctx.logger__.debug('SkinModule', `Set display:none for container with selector ${skinConfig.hideBlockedSlotsSelector}`);
|
|
89
|
-
node.style.setProperty('display', 'none');
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
if (skinConfig.targeting) {
|
|
93
|
-
try {
|
|
94
|
-
ctx.window__.googletag
|
|
95
|
-
.pubads()
|
|
96
|
-
.setTargeting(skinConfig.targeting.key, skinConfig.targeting.value ?? '1');
|
|
97
|
-
}
|
|
98
|
-
catch (e) {
|
|
99
|
-
ctx.logger__.error('SkinModule', e);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
log.error('SkinModule', `Couldn't set the the wallpaper div ${domId} to display:none;`, e);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const runSkinConfigs = (skinModuleConfig) => (ctx, bidResponses, slotDefinitions) => {
|
|
82
|
+
const skinConfigWithEffect = selectConfig(skinModuleConfig, bidResponses, ctx.logger__);
|
|
83
|
+
if (skinConfigWithEffect) {
|
|
84
|
+
const { skinConfig, configEffect } = skinConfigWithEffect;
|
|
85
|
+
if (configEffect === "BlockOtherSlots") {
|
|
86
|
+
ctx.logger__.debug('SkinModule', 'Skin configuration applied', skinConfig);
|
|
87
|
+
skinConfig.blockedAdSlotDomIds.forEach(destroyAdSlot(slotDefinitions, ctx.window__));
|
|
88
|
+
if (skinConfig.hideBlockedSlots) {
|
|
89
|
+
skinConfig.blockedAdSlotDomIds.forEach(hideAdSlot(ctx.window__, ctx.logger__));
|
|
102
90
|
}
|
|
103
|
-
|
|
104
|
-
ctx.logger__
|
|
105
|
-
this.destroyAdSlot(slotDefinitions, ctx.window__)(skinConfig.skinAdSlotDomId);
|
|
91
|
+
if (skinConfig.hideSkinAdSlot) {
|
|
92
|
+
hideAdSlot(ctx.window__, ctx.logger__)(skinConfig.skinAdSlotDomId);
|
|
106
93
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
94
|
+
if (skinConfig.hideBlockedSlotsSelector) {
|
|
95
|
+
ctx.window__.document
|
|
96
|
+
.querySelectorAll(skinConfig.hideBlockedSlotsSelector)
|
|
97
|
+
.forEach(node => {
|
|
98
|
+
ctx.logger__.debug('SkinModule', `Set display:none for container with selector ${skinConfig.hideBlockedSlotsSelector}`);
|
|
99
|
+
node.style.setProperty('display', 'none');
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (skinConfig.targeting) {
|
|
103
|
+
try {
|
|
104
|
+
ctx.window__.googletag
|
|
105
|
+
.pubads()
|
|
106
|
+
.setTargeting(skinConfig.targeting.key, skinConfig.targeting.value ?? '1');
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
ctx.logger__.error('SkinModule', e);
|
|
110
|
+
}
|
|
122
111
|
}
|
|
123
112
|
}
|
|
124
|
-
|
|
125
|
-
|
|
113
|
+
else if (skinConfig.enableCpmComparison) {
|
|
114
|
+
ctx.logger__.debug('SkinModule', 'Skin configuration ignored because cpm was low', skinConfig);
|
|
115
|
+
destroyAdSlot(slotDefinitions, ctx.window__)(skinConfig.skinAdSlotDomId);
|
|
126
116
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
skinModuleConfig.configs
|
|
120
|
+
.filter(skinConfig => skinConfig.destroySkinSlot)
|
|
121
|
+
.map(skinConfig => skinConfig.skinAdSlotDomId)
|
|
122
|
+
.filter(uniquePrimitiveFilter)
|
|
123
|
+
.forEach(destroyAdSlot(slotDefinitions, ctx.window__));
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const configure__ = (moduleConfig) => {
|
|
133
127
|
if (moduleConfig?.skin && moduleConfig.skin.enabled) {
|
|
134
|
-
|
|
135
|
-
|
|
128
|
+
skinModuleConfig = moduleConfig.skin;
|
|
129
|
+
bidsBackHandler.push(runSkinConfigs(moduleConfig.skin));
|
|
136
130
|
}
|
|
137
|
-
}
|
|
138
|
-
initSteps__()
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
131
|
+
};
|
|
132
|
+
const initSteps__ = () => [];
|
|
133
|
+
const configureSteps__ = () => [];
|
|
134
|
+
const prepareRequestAdsSteps__ = () => [];
|
|
135
|
+
const prebidBidsBackHandler__ = () => bidsBackHandler;
|
|
136
|
+
return {
|
|
137
|
+
name,
|
|
138
|
+
description: 'Block other ad slots if a wallpaper has won the auction',
|
|
139
|
+
moduleType: 'prebid',
|
|
140
|
+
config__,
|
|
141
|
+
configure__,
|
|
142
|
+
initSteps__,
|
|
143
|
+
configureSteps__,
|
|
144
|
+
prepareRequestAdsSteps__,
|
|
145
|
+
prebidBidsBackHandler__,
|
|
146
|
+
getConfigEffect,
|
|
147
|
+
selectConfig,
|
|
148
|
+
destroyAdSlot,
|
|
149
|
+
runSkinConfigs
|
|
150
|
+
};
|
|
151
|
+
};
|
|
@@ -1,43 +1,20 @@
|
|
|
1
1
|
import { mkInitStep } from 'ad-tag/ads/adPipeline';
|
|
2
2
|
import { AssetLoadMethod } from 'ad-tag/util/assetLoaderService';
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.identityLinkConfig = null;
|
|
10
|
-
}
|
|
11
|
-
config__() {
|
|
12
|
-
return this.identityLinkConfig;
|
|
13
|
-
}
|
|
14
|
-
configure__(moduleConfig) {
|
|
3
|
+
export const createIdentityLink = () => {
|
|
4
|
+
const name = 'identitylink';
|
|
5
|
+
const gvlid = '97';
|
|
6
|
+
let identityLinkConfig = null;
|
|
7
|
+
const config__ = () => identityLinkConfig;
|
|
8
|
+
const configure__ = (moduleConfig) => {
|
|
15
9
|
if (moduleConfig?.identitylink && moduleConfig.identitylink.enabled) {
|
|
16
|
-
|
|
10
|
+
identityLinkConfig = moduleConfig.identitylink;
|
|
17
11
|
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const config = this.identityLinkConfig;
|
|
21
|
-
return config
|
|
22
|
-
? [
|
|
23
|
-
mkInitStep(this.name, ctx => {
|
|
24
|
-
this.loadAts(ctx, config);
|
|
25
|
-
return Promise.resolve();
|
|
26
|
-
})
|
|
27
|
-
]
|
|
28
|
-
: [];
|
|
29
|
-
}
|
|
30
|
-
configureSteps__() {
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
prepareRequestAdsSteps__() {
|
|
34
|
-
return [];
|
|
35
|
-
}
|
|
36
|
-
loadAts(context, moduleConfig) {
|
|
12
|
+
};
|
|
13
|
+
const loadAts = (context, moduleConfig) => {
|
|
37
14
|
if (context.env__ === 'test') {
|
|
38
15
|
return Promise.resolve();
|
|
39
16
|
}
|
|
40
|
-
if (context.tcData__.gdprApplies && !context.tcData__.vendor.consents[
|
|
17
|
+
if (context.tcData__.gdprApplies && !context.tcData__.vendor.consents[gvlid]) {
|
|
41
18
|
return Promise.resolve();
|
|
42
19
|
}
|
|
43
20
|
const window = context.window__;
|
|
@@ -62,10 +39,34 @@ export class IdentityLink {
|
|
|
62
39
|
});
|
|
63
40
|
return context.assetLoaderService__
|
|
64
41
|
.loadScript({
|
|
65
|
-
name
|
|
42
|
+
name,
|
|
66
43
|
loadMethod: AssetLoadMethod.TAG,
|
|
67
44
|
assetUrl: `https://launchpad-wrapper.privacymanager.io/${moduleConfig.launchPadId}/launchpad-liveramp.js`
|
|
68
45
|
})
|
|
69
46
|
.catch(error => context.logger__.error('failed to load emetriq', error));
|
|
70
|
-
}
|
|
71
|
-
|
|
47
|
+
};
|
|
48
|
+
const initSteps__ = () => {
|
|
49
|
+
const config = identityLinkConfig;
|
|
50
|
+
return config
|
|
51
|
+
? [
|
|
52
|
+
mkInitStep(name, ctx => {
|
|
53
|
+
loadAts(ctx, config);
|
|
54
|
+
return Promise.resolve();
|
|
55
|
+
})
|
|
56
|
+
]
|
|
57
|
+
: [];
|
|
58
|
+
};
|
|
59
|
+
const configureSteps__ = () => [];
|
|
60
|
+
const prepareRequestAdsSteps__ = () => [];
|
|
61
|
+
return {
|
|
62
|
+
name,
|
|
63
|
+
description: "Provides LiveRamp's ATS (authenticated traffic solution) functionality to Moli.",
|
|
64
|
+
moduleType: 'identity',
|
|
65
|
+
config__,
|
|
66
|
+
configure__,
|
|
67
|
+
initSteps__,
|
|
68
|
+
configureSteps__,
|
|
69
|
+
prepareRequestAdsSteps__,
|
|
70
|
+
loadAts
|
|
71
|
+
};
|
|
72
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const createEventTracker = (url, batchSize, batchDelay, logger) => {
|
|
2
|
+
let batch = [];
|
|
3
|
+
let timer = null;
|
|
4
|
+
const processBatch = () => {
|
|
5
|
+
const currentBatch = batch;
|
|
6
|
+
batch = [];
|
|
7
|
+
fetch(url, {
|
|
8
|
+
method: 'POST',
|
|
9
|
+
headers: {
|
|
10
|
+
'Content-Type': 'application/json'
|
|
11
|
+
},
|
|
12
|
+
body: JSON.stringify({ events: currentBatch })
|
|
13
|
+
})
|
|
14
|
+
.then(response => {
|
|
15
|
+
if (response.ok) {
|
|
16
|
+
logger?.debug(`moli-analytics: Successfully sent analytics batch of ${currentBatch.length} events`);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
logger?.error(`moli-analytics: Failed to send analytics batch: ${response.statusText}`);
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
.catch(error => {
|
|
23
|
+
logger?.error(`moli-analytics: Failed to send analytics batch: ${error}`);
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
const track = (event) => {
|
|
27
|
+
logger?.debug('moli-analytics: event', event);
|
|
28
|
+
batch.push(event);
|
|
29
|
+
if (timer != null) {
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
timer = null;
|
|
32
|
+
}
|
|
33
|
+
if (batch.length >= batchSize) {
|
|
34
|
+
processBatch();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
timer = setTimeout(processBatch, batchDelay);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
track
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const mapGPTSlotRenderEnded = (event, context, adContext) => {
|
|
2
|
+
const timestamp = Date.now();
|
|
3
|
+
return {
|
|
4
|
+
v: 1,
|
|
5
|
+
type: 'gpt.slotRenderEnded',
|
|
6
|
+
publisher: context.publisher,
|
|
7
|
+
pageViewId: context.pageViewId,
|
|
8
|
+
userId: adContext.window__.pbjs.getUserIds().pubcid,
|
|
9
|
+
timestamp,
|
|
10
|
+
analyticsLabels: context.analyticsLabels,
|
|
11
|
+
data: {
|
|
12
|
+
auctionId: context.auctionId,
|
|
13
|
+
gpid: context.gpid,
|
|
14
|
+
adUnitPath: event.slot.getAdUnitPath(),
|
|
15
|
+
adUnitName: context.adUnitName,
|
|
16
|
+
adUnitCode: event.slot.getSlotElementId(),
|
|
17
|
+
size: Array.isArray(event.size) ? event.size.join('x') : event.size,
|
|
18
|
+
isEmpty: event.isEmpty
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { mapPrebidAuctionEnd } from 'ad-tag/ads/modules/moli-analytics/events/prebidAuctionEnd';
|
|
2
|
+
import { mapPrebidBidWon } from 'ad-tag/ads/modules/moli-analytics/events/prebidBidWon';
|
|
3
|
+
import { mapGPTSlotRenderEnded } from 'ad-tag/ads/modules/moli-analytics/events/gptSlotRenderEnded';
|
|
4
|
+
import { mapPageView } from 'ad-tag/ads/modules/moli-analytics/events/pageView';
|
|
5
|
+
export const eventMapper = {
|
|
6
|
+
prebid: {
|
|
7
|
+
auctionEnd: mapPrebidAuctionEnd,
|
|
8
|
+
bidWon: mapPrebidBidWon
|
|
9
|
+
},
|
|
10
|
+
gpt: {
|
|
11
|
+
slotRenderEnded: mapGPTSlotRenderEnded
|
|
12
|
+
},
|
|
13
|
+
page: {
|
|
14
|
+
view: mapPageView
|
|
15
|
+
}
|
|
16
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const parseUTM = (search) => {
|
|
2
|
+
const params = new URLSearchParams(search);
|
|
3
|
+
const v = (k) => params.get(k) || null;
|
|
4
|
+
return {
|
|
5
|
+
source: v('utm_source'),
|
|
6
|
+
medium: v('utm_medium'),
|
|
7
|
+
campaign: v('utm_campaign'),
|
|
8
|
+
content: v('utm_content'),
|
|
9
|
+
term: v('utm_term')
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export const mapPageView = (context, adContext) => {
|
|
13
|
+
const timestamp = Date.now();
|
|
14
|
+
const userIds = adContext.window__.pbjs.getUserIds ? adContext.window__.pbjs.getUserIds() : {};
|
|
15
|
+
return {
|
|
16
|
+
v: 1,
|
|
17
|
+
type: 'page.view',
|
|
18
|
+
publisher: context.publisher,
|
|
19
|
+
pageViewId: context.pageViewId,
|
|
20
|
+
userId: userIds?.pubcid,
|
|
21
|
+
timestamp,
|
|
22
|
+
analyticsLabels: context.analyticsLabels,
|
|
23
|
+
data: {
|
|
24
|
+
sessionId: context.session.getId(),
|
|
25
|
+
device: adContext.labelConfigService__.getDeviceLabel(),
|
|
26
|
+
domain: adContext.window__.moli.resolveAdUnitPath('{domain}'),
|
|
27
|
+
ua: adContext.window__.navigator.userAgent,
|
|
28
|
+
utm: parseUTM(adContext.window__.location.search)
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const mapPrebidAuctionEnd = (event, context, adContext) => {
|
|
2
|
+
const timestamp = Date.now();
|
|
3
|
+
return {
|
|
4
|
+
v: 1,
|
|
5
|
+
type: 'prebid.auctionEnd',
|
|
6
|
+
publisher: context.publisher,
|
|
7
|
+
pageViewId: context.pageViewId,
|
|
8
|
+
userId: adContext.window__.pbjs.getUserIds().pubcid,
|
|
9
|
+
timestamp,
|
|
10
|
+
analyticsLabels: context.analyticsLabels,
|
|
11
|
+
data: {
|
|
12
|
+
auctionId: event.auctionId,
|
|
13
|
+
adUnits: Array.from(new Map((event.adUnits || []).map(adUnit => [
|
|
14
|
+
adUnit.code,
|
|
15
|
+
{
|
|
16
|
+
code: adUnit.code,
|
|
17
|
+
adUnitName: adUnit.pubstack?.adUnitName || adUnit.code,
|
|
18
|
+
gpid: adUnit.ortb2Imp?.ext?.gpid
|
|
19
|
+
}
|
|
20
|
+
])).values()),
|
|
21
|
+
bidderRequests: (event.bidderRequests || []).map(request => {
|
|
22
|
+
return {
|
|
23
|
+
bidderCode: request.bidderCode,
|
|
24
|
+
bids: (request.bids || []).map(bid => ({
|
|
25
|
+
adUnitCode: bid.adUnitCode
|
|
26
|
+
}))
|
|
27
|
+
};
|
|
28
|
+
}),
|
|
29
|
+
bidsReceived: (event.bidsReceived || []).map(bid => ({
|
|
30
|
+
bidder: bid.bidder,
|
|
31
|
+
adUnitCode: bid.adUnitCode,
|
|
32
|
+
size: bid.size,
|
|
33
|
+
currency: bid.currency,
|
|
34
|
+
cpm: bid.cpm,
|
|
35
|
+
timeToRespond: bid.timeToRespond
|
|
36
|
+
}))
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const mapPrebidBidWon = (event, context, adContext) => {
|
|
2
|
+
const timestamp = Date.now();
|
|
3
|
+
return {
|
|
4
|
+
v: 1,
|
|
5
|
+
type: 'prebid.bidWon',
|
|
6
|
+
publisher: context.publisher,
|
|
7
|
+
pageViewId: context.pageViewId,
|
|
8
|
+
userId: adContext.window__.pbjs.getUserIds().pubcid,
|
|
9
|
+
timestamp,
|
|
10
|
+
analyticsLabels: context.analyticsLabels,
|
|
11
|
+
data: {
|
|
12
|
+
auctionId: event.auctionId,
|
|
13
|
+
gpid: context.gpid,
|
|
14
|
+
bidderCode: event.bidderCode,
|
|
15
|
+
adUnitCode: event.adUnitCode,
|
|
16
|
+
size: event.size,
|
|
17
|
+
currency: event.currency,
|
|
18
|
+
cpm: event.cpm,
|
|
19
|
+
status: event.status,
|
|
20
|
+
timeToRespond: event.timeToRespond
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
};
|