@blotoutio/providers-universal-ads-sdk 1.66.0 → 1.66.2
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/index.cjs.js +405 -91
- package/index.js +405 -91
- package/index.mjs +405 -91
- package/package.json +1 -1
package/index.cjs.js
CHANGED
|
@@ -1,6 +1,159 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* The Universal Ads pixel vocabulary.
|
|
5
|
+
*
|
|
6
|
+
* Every name here is taken verbatim from Universal Ads' own tooling — the
|
|
7
|
+
* event-level snippets the UA dashboard generates and the official GTM
|
|
8
|
+
* community template (`Universal-Ads/universal-ads-pixel-gtm`, `template.tpl`).
|
|
9
|
+
* uap.js lower-cases the conversion name before it posts it (`eventName:
|
|
10
|
+
* name.toLowerCase()`) but validates nothing else and aliases nothing, so a
|
|
11
|
+
* near-miss (`start_checkout` instead of `checkout_start`) is accepted by the
|
|
12
|
+
* pixel and then silently records nothing. Do not "tidy" these strings.
|
|
13
|
+
*/
|
|
14
|
+
/** All 18 conversions the pixel accepts, including the two custom slots. */
|
|
15
|
+
const UA_CONVERSIONS = [
|
|
16
|
+
'page_view',
|
|
17
|
+
'content_view',
|
|
18
|
+
'product_view',
|
|
19
|
+
'search',
|
|
20
|
+
'sign_in',
|
|
21
|
+
'sign_up',
|
|
22
|
+
'schedule_appointment',
|
|
23
|
+
'start_trial',
|
|
24
|
+
'view_cart',
|
|
25
|
+
'wish_list',
|
|
26
|
+
'purchase',
|
|
27
|
+
'checkout_start',
|
|
28
|
+
'add_to_cart',
|
|
29
|
+
'add_payment_info',
|
|
30
|
+
'add_address_info',
|
|
31
|
+
'subscribe',
|
|
32
|
+
'custom_event_1',
|
|
33
|
+
'custom_event_2',
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Which parameters UA offers per event, mirroring the event-level snippets the
|
|
37
|
+
* dashboard generates. `page_view` is carried by the base code and takes none.
|
|
38
|
+
*/
|
|
39
|
+
const UA_EVENT_PARAMS = {
|
|
40
|
+
page_view: [],
|
|
41
|
+
content_view: ['description', 'content_id', 'user_id'],
|
|
42
|
+
product_view: ['price', 'currency', 'description', 'content_id', 'user_id'],
|
|
43
|
+
search: ['price', 'currency', 'description', 'content_id', 'user_id'],
|
|
44
|
+
sign_in: ['description', 'user_id', 'user_name'],
|
|
45
|
+
sign_up: ['description', 'user_id', 'user_name'],
|
|
46
|
+
schedule_appointment: ['description', 'user_id', 'user_name'],
|
|
47
|
+
start_trial: ['price', 'currency', 'description', 'user_id', 'user_name'],
|
|
48
|
+
subscribe: ['price', 'currency', 'description', 'user_id', 'user_name'],
|
|
49
|
+
view_cart: [
|
|
50
|
+
'price',
|
|
51
|
+
'currency',
|
|
52
|
+
'description',
|
|
53
|
+
'content_id',
|
|
54
|
+
'item_quantity',
|
|
55
|
+
'user_id',
|
|
56
|
+
],
|
|
57
|
+
wish_list: [
|
|
58
|
+
'price',
|
|
59
|
+
'currency',
|
|
60
|
+
'description',
|
|
61
|
+
'content_id',
|
|
62
|
+
'item_quantity',
|
|
63
|
+
'user_id',
|
|
64
|
+
],
|
|
65
|
+
checkout_start: [
|
|
66
|
+
'price',
|
|
67
|
+
'currency',
|
|
68
|
+
'description',
|
|
69
|
+
'content_id',
|
|
70
|
+
'item_quantity',
|
|
71
|
+
'user_id',
|
|
72
|
+
],
|
|
73
|
+
add_to_cart: [
|
|
74
|
+
'price',
|
|
75
|
+
'currency',
|
|
76
|
+
'description',
|
|
77
|
+
'content_id',
|
|
78
|
+
'item_quantity',
|
|
79
|
+
'user_id',
|
|
80
|
+
],
|
|
81
|
+
add_payment_info: [
|
|
82
|
+
'price',
|
|
83
|
+
'currency',
|
|
84
|
+
'description',
|
|
85
|
+
'content_id',
|
|
86
|
+
'item_quantity',
|
|
87
|
+
'user_id',
|
|
88
|
+
],
|
|
89
|
+
add_address_info: [
|
|
90
|
+
'price',
|
|
91
|
+
'currency',
|
|
92
|
+
'description',
|
|
93
|
+
'content_id',
|
|
94
|
+
'item_quantity',
|
|
95
|
+
'user_id',
|
|
96
|
+
],
|
|
97
|
+
purchase: [
|
|
98
|
+
'price',
|
|
99
|
+
'currency',
|
|
100
|
+
'order_id',
|
|
101
|
+
'description',
|
|
102
|
+
'content_id',
|
|
103
|
+
'item_quantity',
|
|
104
|
+
'user_id',
|
|
105
|
+
'user_name',
|
|
106
|
+
],
|
|
107
|
+
custom_event_1: [
|
|
108
|
+
'price',
|
|
109
|
+
'currency',
|
|
110
|
+
'order_id',
|
|
111
|
+
'description',
|
|
112
|
+
'content_id',
|
|
113
|
+
'item_quantity',
|
|
114
|
+
'user_id',
|
|
115
|
+
'user_name',
|
|
116
|
+
],
|
|
117
|
+
custom_event_2: [
|
|
118
|
+
'price',
|
|
119
|
+
'currency',
|
|
120
|
+
'order_id',
|
|
121
|
+
'description',
|
|
122
|
+
'content_id',
|
|
123
|
+
'item_quantity',
|
|
124
|
+
'user_id',
|
|
125
|
+
'user_name',
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* EdgeTag event -> UA conversion, applied when a tag configures no override.
|
|
130
|
+
*
|
|
131
|
+
* `RemoveFromCart` and `SessionStart` are absent on purpose: UA has no
|
|
132
|
+
* equivalent, so they are dropped rather than mapped onto something adjacent.
|
|
133
|
+
* The UA conversions with no EdgeTag twin (sign_in, product_view, start_trial,
|
|
134
|
+
* view_cart, wish_list, schedule_appointment, custom_event_1/2) are reachable
|
|
135
|
+
* through the per-tag event mapping.
|
|
136
|
+
*/
|
|
137
|
+
const DEFAULT_EVENT_MAP = {
|
|
138
|
+
PageView: 'page_view',
|
|
139
|
+
ViewContent: 'content_view',
|
|
140
|
+
AddToCart: 'add_to_cart',
|
|
141
|
+
InitiateCheckout: 'checkout_start',
|
|
142
|
+
AddPaymentInfo: 'add_payment_info',
|
|
143
|
+
AddShippingInfo: 'add_address_info',
|
|
144
|
+
Purchase: 'purchase',
|
|
145
|
+
Subscribe: 'subscribe',
|
|
146
|
+
Search: 'search',
|
|
147
|
+
Lead: 'sign_up',
|
|
148
|
+
};
|
|
149
|
+
|
|
3
150
|
const packageName = 'universalAds';
|
|
151
|
+
// The pixel library UA serves; it aliases itself onto `window[data-sdk-name]`.
|
|
152
|
+
const SDK_URL = 'https://connect.universalads.com/uap.js';
|
|
153
|
+
// The global the pixel is reachable through once loaded with our script tag.
|
|
154
|
+
const SDK_NAME = 'uapx';
|
|
155
|
+
|
|
156
|
+
const keyPrefix = `_worker`;
|
|
4
157
|
|
|
5
158
|
const canLog = () => {
|
|
6
159
|
try {
|
|
@@ -34,6 +187,176 @@ const logger = {
|
|
|
34
187
|
},
|
|
35
188
|
};
|
|
36
189
|
|
|
190
|
+
const initKey = `${keyPrefix}StoreMultiple`;
|
|
191
|
+
const getData = (destination, persistType, key = initKey) => {
|
|
192
|
+
let data;
|
|
193
|
+
if (persistType === 'session') {
|
|
194
|
+
data = getSession(key);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
data = getLocal(key);
|
|
198
|
+
}
|
|
199
|
+
return (data === null || data === void 0 ? void 0 : data[destination]) || {};
|
|
200
|
+
};
|
|
201
|
+
const getLocal = (key) => {
|
|
202
|
+
try {
|
|
203
|
+
if (!localStorage) {
|
|
204
|
+
return {};
|
|
205
|
+
}
|
|
206
|
+
const data = localStorage.getItem(key);
|
|
207
|
+
if (!data) {
|
|
208
|
+
return {};
|
|
209
|
+
}
|
|
210
|
+
return JSON.parse(data) || {};
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return {};
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
const getSession = (key) => {
|
|
217
|
+
try {
|
|
218
|
+
if (!sessionStorage) {
|
|
219
|
+
return {};
|
|
220
|
+
}
|
|
221
|
+
const data = sessionStorage.getItem(key);
|
|
222
|
+
if (!data) {
|
|
223
|
+
return {};
|
|
224
|
+
}
|
|
225
|
+
return JSON.parse(data) || {};
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return {};
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const SCRIPT_ID = 'uapx-sdk';
|
|
233
|
+
/**
|
|
234
|
+
* Conversions raised before uap.js finished loading.
|
|
235
|
+
*
|
|
236
|
+
* The pixel script is async, so EdgeTag's PageView routinely reaches `tag`
|
|
237
|
+
* before `window.uapx` exists. UA's own snippet dodges this by sending
|
|
238
|
+
* page_view from inside `onload`; we send from the tag handler instead, so we
|
|
239
|
+
* buffer here rather than dropping the event.
|
|
240
|
+
*/
|
|
241
|
+
const pending = [];
|
|
242
|
+
/**
|
|
243
|
+
* Cap on the queue. An ad blocker blocking `connect.universalads.com` is the
|
|
244
|
+
* expected failure for an ad pixel, and an SPA session can raise events for
|
|
245
|
+
* hours — the queue must not grow with them.
|
|
246
|
+
*
|
|
247
|
+
* @internal Exported for the cap assertion in `pixel.test.ts` only.
|
|
248
|
+
*/
|
|
249
|
+
const MAX_PENDING = 50;
|
|
250
|
+
/**
|
|
251
|
+
* Set once the pixel can never arrive: the script errored, or it loaded without
|
|
252
|
+
* exposing the global. From then on conversions are dropped instead of queued
|
|
253
|
+
* for a flush that will never come.
|
|
254
|
+
*/
|
|
255
|
+
let unavailable = false;
|
|
256
|
+
/** Give up for the rest of the page: release the queue and say why once. */
|
|
257
|
+
const abandon = (message) => {
|
|
258
|
+
unavailable = true;
|
|
259
|
+
pending.length = 0;
|
|
260
|
+
logger.log(message);
|
|
261
|
+
};
|
|
262
|
+
const flush = () => {
|
|
263
|
+
var _a;
|
|
264
|
+
while (pending.length) {
|
|
265
|
+
const next = pending.shift();
|
|
266
|
+
if (!next) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
// One rejected conversion must not strand the rest of the queue.
|
|
270
|
+
try {
|
|
271
|
+
(_a = window.uapx) === null || _a === void 0 ? void 0 : _a.sendConversion(next.conversion, next.params);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
logger.error(error);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
const start = (productId, accessToken) => {
|
|
279
|
+
if (!window.uapx) {
|
|
280
|
+
abandon('Universal Ads pixel loaded but window.uapx is missing; conversions will not be sent.');
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const config = {
|
|
284
|
+
general: {
|
|
285
|
+
install_id_enabled: true,
|
|
286
|
+
pers_tr: true,
|
|
287
|
+
collect_page_info: true,
|
|
288
|
+
collect_ga: true,
|
|
289
|
+
product_id: productId,
|
|
290
|
+
access_token: accessToken,
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
// This runs from the script's `onload`, outside init's try/catch, so a throw
|
|
294
|
+
// here would surface as an uncaught error on the customer's page.
|
|
295
|
+
try {
|
|
296
|
+
window.uapx.startWithConfig(config);
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
logger.error(error);
|
|
300
|
+
}
|
|
301
|
+
flush();
|
|
302
|
+
};
|
|
303
|
+
const loadPixel = (productId, accessToken) => {
|
|
304
|
+
// Already present, either from a previous init or a hand-placed base snippet.
|
|
305
|
+
// Starting twice would re-run session bookkeeping inside uap.js.
|
|
306
|
+
if (window.uapx || document.getElementById(SCRIPT_ID)) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const script = document.createElement('script');
|
|
310
|
+
script.id = SCRIPT_ID;
|
|
311
|
+
script.type = 'text/javascript';
|
|
312
|
+
script.async = true;
|
|
313
|
+
// uap.js reads this off `document.currentScript` to decide which global to
|
|
314
|
+
// alias itself onto. Without it the pixel is only reachable as
|
|
315
|
+
// `window.pubSuite` and every sendConversion call below silently no-ops.
|
|
316
|
+
script.setAttribute('data-sdk-name', SDK_NAME);
|
|
317
|
+
script.src = SDK_URL;
|
|
318
|
+
script.onload = () => {
|
|
319
|
+
start(productId, accessToken);
|
|
320
|
+
};
|
|
321
|
+
script.onerror = () => {
|
|
322
|
+
script.remove();
|
|
323
|
+
abandon(`Universal Ads pixel failed to load from ${SDK_URL}.`);
|
|
324
|
+
};
|
|
325
|
+
document.head.appendChild(script);
|
|
326
|
+
};
|
|
327
|
+
const sendConversion = (conversion, params) => {
|
|
328
|
+
if (window.uapx) {
|
|
329
|
+
window.uapx.sendConversion(conversion, params);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (unavailable || pending.length >= MAX_PENDING) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
pending.push({ conversion, params });
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
const init = ({ manifest }) => {
|
|
339
|
+
var _a;
|
|
340
|
+
try {
|
|
341
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (((_a = manifest.variables) === null || _a === void 0 ? void 0 : _a['enableBrowser']) !== '1') {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
const productId = manifest.variables['productId'];
|
|
348
|
+
const accessToken = manifest.variables['accessToken'];
|
|
349
|
+
if (!productId || !accessToken) {
|
|
350
|
+
logger.log('Universal Ads pixel is not loaded. Configure UNIVERSAL_ADS_PRODUCT_ID and UNIVERSAL_ADS_ACCESS_TOKEN.');
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
loadPixel(productId, accessToken);
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
logger.error(error);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
|
|
37
360
|
/**
|
|
38
361
|
* Known ad-network click ID query parameters and the human-readable provider
|
|
39
362
|
* label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
|
|
@@ -460,26 +783,6 @@ new Set([
|
|
|
460
783
|
...caProvinces.keys(),
|
|
461
784
|
]);
|
|
462
785
|
|
|
463
|
-
const normalize = (urlString) => {
|
|
464
|
-
try {
|
|
465
|
-
const cleanUrl = urlString.replace(/\t/g, '');
|
|
466
|
-
const urlObj = new URL(cleanUrl);
|
|
467
|
-
const pathname = urlObj.pathname.replace(/\/+$/, ''); // Remove trailing slash
|
|
468
|
-
return `${urlObj.origin}${pathname}`;
|
|
469
|
-
}
|
|
470
|
-
catch (e) {
|
|
471
|
-
// Fallback for non-URL values
|
|
472
|
-
return urlString.replace(/\t/g, '').replace(/\/+$/, '');
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
// Convert wildcard URL pattern to RegExp (e.g. * becomes .+?)
|
|
476
|
-
const wildcardToRegex = (pattern) => {
|
|
477
|
-
const escaped = pattern
|
|
478
|
-
.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&') // Escape regex special characters
|
|
479
|
-
.replace(/\*/g, '[^/]+'); // Wildcard * matches one path segment
|
|
480
|
-
return new RegExp(`^${escaped}$`, 'i'); // Case-insensitive match
|
|
481
|
-
};
|
|
482
|
-
|
|
483
786
|
/**
|
|
484
787
|
* Exact utm_source normalization (lowercase key → canonical name).
|
|
485
788
|
*
|
|
@@ -601,94 +904,105 @@ new Set([
|
|
|
601
904
|
OFFLINE_TOUCH,
|
|
602
905
|
]);
|
|
603
906
|
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
//
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
if (normalizedPattern.includes('*')) {
|
|
618
|
-
const regex = wildcardToRegex(normalizedPattern);
|
|
619
|
-
return regex.test(normalizedUrl);
|
|
907
|
+
const isConversion = (value) => UA_CONVERSIONS.includes(value);
|
|
908
|
+
// A configured row wins for the event it names; every other event keeps its default.
|
|
909
|
+
const resolveConversion = (eventName, eventMapping) => {
|
|
910
|
+
var _a;
|
|
911
|
+
const configured = tryParse(eventMapping, []);
|
|
912
|
+
if (Array.isArray(configured)) {
|
|
913
|
+
const override = configured.find((row) => (row === null || row === void 0 ? void 0 : row.event) === eventName);
|
|
914
|
+
// A row naming a conversion UA does not accept is ignored rather than
|
|
915
|
+
// dropping the event: the form's conversion select is not creatable, so this
|
|
916
|
+
// only reaches us from a legacy or hand-edited worker value, and the default
|
|
917
|
+
// conversion is a better outcome there than silently sending nothing.
|
|
918
|
+
if (override && isConversion(override.conversion)) {
|
|
919
|
+
return override.conversion;
|
|
620
920
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
return match ? { tagId: match.tagId, segmentKey: match.segmentKey } : null;
|
|
921
|
+
}
|
|
922
|
+
return (_a = DEFAULT_EVENT_MAP[eventName]) !== null && _a !== void 0 ? _a : null;
|
|
624
923
|
};
|
|
625
|
-
|
|
626
|
-
const
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
url.searchParams.set('ord', cacheBuster.toString());
|
|
635
|
-
return url.toString();
|
|
924
|
+
const contentsOf = (data) => Array.isArray(data['contents']) ? data['contents'] : [];
|
|
925
|
+
const asParam = (value) => {
|
|
926
|
+
if (value === undefined || value === null || value === '') {
|
|
927
|
+
return undefined;
|
|
928
|
+
}
|
|
929
|
+
if (typeof value === 'number') {
|
|
930
|
+
return Number.isFinite(value) ? String(value) : undefined;
|
|
931
|
+
}
|
|
932
|
+
return typeof value === 'string' ? value : undefined;
|
|
636
933
|
};
|
|
637
|
-
const
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
return;
|
|
934
|
+
const itemQuantity = (contents) => {
|
|
935
|
+
if (!contents.length) {
|
|
936
|
+
return undefined;
|
|
641
937
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
938
|
+
const total = contents.reduce((sum, item) => {
|
|
939
|
+
const quantity = Number(item === null || item === void 0 ? void 0 : item.quantity);
|
|
940
|
+
return sum + (Number.isFinite(quantity) ? quantity : 0);
|
|
941
|
+
}, 0);
|
|
942
|
+
return total || undefined;
|
|
943
|
+
};
|
|
944
|
+
// Only the parameters UA allows for that conversion; empty values are dropped.
|
|
945
|
+
const buildParams = (conversion, data, userId, kvEmail) => {
|
|
946
|
+
var _a, _b, _c;
|
|
947
|
+
const contents = contentsOf(data);
|
|
948
|
+
const available = {
|
|
949
|
+
price: asParam(data['value']),
|
|
950
|
+
currency: asParam(data['currency']),
|
|
951
|
+
order_id: asParam(data['orderId']),
|
|
952
|
+
description: (_a = asParam(data['name'])) !== null && _a !== void 0 ? _a : asParam((_b = contents[0]) === null || _b === void 0 ? void 0 : _b.title),
|
|
953
|
+
// UA's snippets carry a single content id, so a multi-item cart reports the
|
|
954
|
+
// first usable one rather than a list UA would not parse.
|
|
955
|
+
content_id: contents.map((item) => asParam(item === null || item === void 0 ? void 0 : item.id)).find(Boolean),
|
|
956
|
+
item_quantity: asParam(itemQuantity(contents)),
|
|
957
|
+
user_id: asParam(userId),
|
|
958
|
+
// UA labels `user_name` "User Email" in both the dashboard and the GTM
|
|
959
|
+
// template — it carries the email, not a display name. It goes out in the
|
|
960
|
+
// clear on purpose: UA's dashboard snippets and their GTM template both pass
|
|
961
|
+
// the plain address and uap.js normalizes it on their side, so a sha256'd
|
|
962
|
+
// value (as criteo/spotify need) would simply fail to match. Same shape as
|
|
963
|
+
// facebook's `em` and tiktok's `email` here.
|
|
964
|
+
//
|
|
965
|
+
// The event rarely carries it — email usually arrives through the data API
|
|
966
|
+
// and lands in session KV — so fall back to the KV value.
|
|
967
|
+
user_name: (_c = asParam(data['email'])) !== null && _c !== void 0 ? _c : asParam(kvEmail),
|
|
968
|
+
};
|
|
969
|
+
const params = {};
|
|
970
|
+
for (const key of UA_EVENT_PARAMS[conversion]) {
|
|
971
|
+
const value = available[key];
|
|
972
|
+
if (value !== undefined) {
|
|
973
|
+
params[key] = value;
|
|
650
974
|
}
|
|
651
975
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
976
|
+
return params;
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
const tag = ({ eventName, data, userId, manifestVariables, destination, }) => {
|
|
655
980
|
try {
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
const pixel = document.createElement('img');
|
|
659
|
-
pixel.src = getUrl(mapping, buzzKey, accountId);
|
|
660
|
-
pixel.width = 0;
|
|
661
|
-
pixel.height = 0;
|
|
662
|
-
pixel.style.position = 'absolute';
|
|
663
|
-
pixel.style.visibility = 'hidden';
|
|
664
|
-
pixel.setAttribute('border', '0');
|
|
665
|
-
const firstScript = document.getElementsByTagName('script')[0];
|
|
666
|
-
(_a = firstScript.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(pixel, firstScript);
|
|
981
|
+
if (typeof window === 'undefined') {
|
|
982
|
+
return {};
|
|
667
983
|
}
|
|
668
|
-
|
|
669
|
-
|
|
984
|
+
const conversion = resolveConversion(eventName, manifestVariables === null || manifestVariables === void 0 ? void 0 : manifestVariables['eventMapping']);
|
|
985
|
+
// UA has no conversion for this event (RemoveFromCart, SessionStart, or an
|
|
986
|
+
// unmapped custom event) — sending an invented name would record nothing.
|
|
987
|
+
if (!conversion) {
|
|
988
|
+
return {};
|
|
670
989
|
}
|
|
990
|
+
// The email UA wants for `user_name` usually arrives via the data API and is
|
|
991
|
+
// held in session KV rather than on the event payload.
|
|
992
|
+
const kv = getData(destination, 'session')['kv'];
|
|
993
|
+
sendConversion(conversion, buildParams(conversion, data, userId, kv === null || kv === void 0 ? void 0 : kv['email']));
|
|
671
994
|
}
|
|
672
|
-
catch {
|
|
673
|
-
logger.
|
|
674
|
-
}
|
|
675
|
-
};
|
|
676
|
-
const init = ({ manifest, pageUrl }) => {
|
|
677
|
-
if (typeof window == 'undefined' ||
|
|
678
|
-
!manifest.variables ||
|
|
679
|
-
manifest.variables['enableBrowser'] !== '1' ||
|
|
680
|
-
!manifest.variables['accountId'] ||
|
|
681
|
-
!manifest.variables['buzzKey'] ||
|
|
682
|
-
!manifest.variables['urlMapping']) {
|
|
683
|
-
return;
|
|
995
|
+
catch (error) {
|
|
996
|
+
logger.error(error);
|
|
684
997
|
}
|
|
685
|
-
|
|
998
|
+
return {};
|
|
686
999
|
};
|
|
687
1000
|
|
|
688
1001
|
// eslint-disable-next-line @nx/enforce-module-boundaries
|
|
689
1002
|
const data = {
|
|
690
1003
|
name: packageName,
|
|
691
1004
|
init,
|
|
1005
|
+
tag,
|
|
692
1006
|
};
|
|
693
1007
|
try {
|
|
694
1008
|
if (window) {
|