@blotoutio/providers-google-ads-clicks-sdk 1.53.0 → 1.54.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/index.cjs.js +162 -5
- package/index.js +162 -5
- package/index.mjs +162 -5
- package/package.json +1 -1
package/index.cjs.js
CHANGED
|
@@ -44,6 +44,40 @@ const upsert = (map, key, update, createDefault) => {
|
|
|
44
44
|
return map.set(key, update(currentValue));
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Known ad-network click ID query parameters and the human-readable provider
|
|
49
|
+
* label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
|
|
50
|
+
* and by the analytics API to classify paid-media touch sessions.
|
|
51
|
+
*
|
|
52
|
+
* Keep this list in sync with `defaultParams` in queryParams.ts when new
|
|
53
|
+
* click ID providers are added.
|
|
54
|
+
*/
|
|
55
|
+
const CLICK_IDS = [
|
|
56
|
+
{ param: 'fbclid', label: 'Facebook' }, // Facebook Ads
|
|
57
|
+
{ param: 'gclid', label: 'Google' }, // Google Ads (click)
|
|
58
|
+
{ param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
|
|
59
|
+
{ param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
|
|
60
|
+
{ param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
|
|
61
|
+
{ param: 'ttclid', label: 'TikTok' }, // TikTok Ads
|
|
62
|
+
{ param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
|
|
63
|
+
{ param: 'epik', label: 'Pinterest' }, // Pinterest Ads
|
|
64
|
+
{ param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
|
|
65
|
+
{ param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
|
|
66
|
+
{ param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
|
|
67
|
+
{ param: 'aleid', label: 'AppLovin' }, // AppLovin
|
|
68
|
+
{ param: 'tabclid', label: 'Taboola' }, // Taboola
|
|
69
|
+
{ param: 'obclid', label: 'Outbrain' }, // Outbrain
|
|
70
|
+
{ param: 'trybe', label: 'Trybe' }, // Trybe
|
|
71
|
+
{ param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
|
|
72
|
+
{ param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
|
|
73
|
+
{ param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
|
|
74
|
+
{ param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
|
|
75
|
+
{ param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
|
|
76
|
+
{ param: '_raclid', label: 'Rumble' }, // Rumble Ads
|
|
77
|
+
{ param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
|
|
78
|
+
{ param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
|
|
79
|
+
];
|
|
80
|
+
|
|
47
81
|
const addDaysToDate = (date, days) => {
|
|
48
82
|
const newDate = new Date(date);
|
|
49
83
|
newDate.setDate(newDate.getDate() + days);
|
|
@@ -418,6 +452,127 @@ const usStates = new Map([
|
|
|
418
452
|
]);
|
|
419
453
|
new Set([...isoCountries.keys(), ...usStates.keys()]);
|
|
420
454
|
|
|
455
|
+
/**
|
|
456
|
+
* Exact utm_source normalization (lowercase key → canonical name).
|
|
457
|
+
*
|
|
458
|
+
* Use exact match when the key is short, generic, or must not accidentally
|
|
459
|
+
* absorb variant spellings (e.g. "impact" must not match "impact_radius").
|
|
460
|
+
*
|
|
461
|
+
* Ordering: Paid (search/social → ad networks → affiliates) →
|
|
462
|
+
* Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
|
|
463
|
+
*/
|
|
464
|
+
const UTM_SOURCE_EXACT = {
|
|
465
|
+
// ── Paid – Search & Social ────────────────────────────────────────────────
|
|
466
|
+
google: 'Google',
|
|
467
|
+
adwords: 'Google',
|
|
468
|
+
youtube: 'Google',
|
|
469
|
+
yt: 'Google',
|
|
470
|
+
meta: 'Facebook',
|
|
471
|
+
facebook: 'Facebook',
|
|
472
|
+
instagram: 'Facebook',
|
|
473
|
+
ig: 'Facebook',
|
|
474
|
+
igshopping: 'Facebook',
|
|
475
|
+
threads: 'Facebook',
|
|
476
|
+
twitter: 'Twitter',
|
|
477
|
+
snapchat: 'Snapchat',
|
|
478
|
+
pinterest: 'Pinterest',
|
|
479
|
+
bing: 'Bing',
|
|
480
|
+
microsoft: 'Bing',
|
|
481
|
+
tiktok: 'TikTok',
|
|
482
|
+
// ── Paid – Ad Networks ───────────────────────────────────────────────────
|
|
483
|
+
rtbhouse: 'RTB House',
|
|
484
|
+
applovin: 'AppLovin',
|
|
485
|
+
ttd: 'The Trade Desk',
|
|
486
|
+
amazondsp: 'Amazon DSP',
|
|
487
|
+
axon: 'Axon',
|
|
488
|
+
duel: 'Duel',
|
|
489
|
+
// ── Paid – Affiliates ────────────────────────────────────────────────────
|
|
490
|
+
awin: 'Awin',
|
|
491
|
+
'affiliate-cj': 'CJ Affiliate',
|
|
492
|
+
impact: 'Impact',
|
|
493
|
+
rakuten: 'Rakuten',
|
|
494
|
+
superfiliate: 'Superfiliate',
|
|
495
|
+
// ── Organic – AI & Discovery ─────────────────────────────────────────────
|
|
496
|
+
perplexity: 'Perplexity',
|
|
497
|
+
chatgpt: 'ChatGPT',
|
|
498
|
+
'chatgpt.com': 'ChatGPT',
|
|
499
|
+
openai: 'ChatGPT',
|
|
500
|
+
'copilot.com': 'Microsoft Copilot',
|
|
501
|
+
copilot: 'Microsoft Copilot',
|
|
502
|
+
applenews: 'Apple News',
|
|
503
|
+
whatsapp: 'WhatsApp',
|
|
504
|
+
podcast: 'Podcast',
|
|
505
|
+
// ── Retention – Email ────────────────────────────────────────────────────
|
|
506
|
+
mailchimp: 'Mailchimp',
|
|
507
|
+
omnisend: 'Omnisend',
|
|
508
|
+
iterable: 'Iterable',
|
|
509
|
+
listrak: 'Listrak',
|
|
510
|
+
sailthru: 'Sailthru',
|
|
511
|
+
// ── Retention – Push ─────────────────────────────────────────────────────
|
|
512
|
+
pushowl: 'PushOwl',
|
|
513
|
+
// ── Retention – Post-purchase / Payment ──────────────────────────────────
|
|
514
|
+
narvar: 'Narvar',
|
|
515
|
+
shop_app: 'Shop App',
|
|
516
|
+
salesforce: 'Salesforce',
|
|
517
|
+
yotpo: 'Yotpo',
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Partial utm_source normalization (startsWith prefix check, lowercase).
|
|
521
|
+
*
|
|
522
|
+
* Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
|
|
523
|
+
*/
|
|
524
|
+
const UTM_SOURCE_PARTIAL = [
|
|
525
|
+
// ── Paid – Social ─────────────────────────────────────────────────────────
|
|
526
|
+
{ prefix: 'tiktok', name: 'TikTok' },
|
|
527
|
+
// ── Paid – Ad Networks ───────────────────────────────────────────────────
|
|
528
|
+
{ prefix: 'criteo', name: 'Criteo' },
|
|
529
|
+
// ── Retention – Email ────────────────────────────────────────────────────
|
|
530
|
+
{ prefix: 'klaviyo', name: 'Klaviyo' },
|
|
531
|
+
// ── Retention – SMS ──────────────────────────────────────────────────────
|
|
532
|
+
{ prefix: 'attentive', name: 'Attentive' },
|
|
533
|
+
{ prefix: 'postscript', name: 'Postscript' },
|
|
534
|
+
// ── Retention – Post-purchase / Payment ──────────────────────────────────
|
|
535
|
+
{ prefix: 'afterpay', name: 'Afterpay' },
|
|
536
|
+
{ prefix: 'klarna', name: 'Klarna' },
|
|
537
|
+
];
|
|
538
|
+
const ORGANIC_SEARCH_ENGINES = [
|
|
539
|
+
{ match: 'google', name: 'Google' },
|
|
540
|
+
{ match: 'bing', name: 'Bing' },
|
|
541
|
+
{ match: 'yahoo', name: 'Yahoo' },
|
|
542
|
+
{ match: 'duckduckgo', name: 'DuckDuckGo' },
|
|
543
|
+
{ match: 'baidu', name: 'Baidu' },
|
|
544
|
+
{ match: 'yandex', name: 'Yandex' },
|
|
545
|
+
{ match: 'brave', name: 'Brave' },
|
|
546
|
+
];
|
|
547
|
+
const KNOWN_REFERRAL_PLATFORMS = [
|
|
548
|
+
{ match: 'facebook', name: 'Facebook' },
|
|
549
|
+
{ match: 'instagram', name: 'Facebook' },
|
|
550
|
+
{ match: 'twitter', name: 'Twitter' },
|
|
551
|
+
{ match: 'x.com', name: 'Twitter' },
|
|
552
|
+
{ match: 'tiktok', name: 'TikTok' },
|
|
553
|
+
{ match: 'pinterest', name: 'Pinterest' },
|
|
554
|
+
{ match: 'linkedin', name: 'LinkedIn' },
|
|
555
|
+
{ match: 'youtube', name: 'YouTube' },
|
|
556
|
+
{ match: 'chatgpt', name: 'ChatGPT' },
|
|
557
|
+
{ match: 'claude', name: 'Claude' },
|
|
558
|
+
{ match: 'perplexity', name: 'Perplexity' },
|
|
559
|
+
{ match: 'shop.app', name: 'Shop App' },
|
|
560
|
+
{ match: 'amazon', name: 'Amazon' },
|
|
561
|
+
{ match: 'attentive', name: 'Attentive' },
|
|
562
|
+
];
|
|
563
|
+
const OFFLINE_TOUCH = 'Blotout_Offline';
|
|
564
|
+
new Set([
|
|
565
|
+
...CLICK_IDS.map((c) => c.label),
|
|
566
|
+
...Object.values(UTM_SOURCE_EXACT),
|
|
567
|
+
...UTM_SOURCE_PARTIAL.map((e) => e.name),
|
|
568
|
+
...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
|
|
569
|
+
...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
|
|
570
|
+
'Referral - Other',
|
|
571
|
+
'Direct Traffic',
|
|
572
|
+
'Other',
|
|
573
|
+
OFFLINE_TOUCH,
|
|
574
|
+
]);
|
|
575
|
+
|
|
421
576
|
const getGoogleConsent = (consentData) => {
|
|
422
577
|
const gadsConsent = hasUserConsentForProvider(consentData, 'googleAdsClicks');
|
|
423
578
|
return {
|
|
@@ -705,10 +860,12 @@ const init = ({ manifest, consentData, executionContext, pageUrl, }) => {
|
|
|
705
860
|
customConfig['allow_enhanced_conversions'] = true;
|
|
706
861
|
}
|
|
707
862
|
window.dataLayer = window.dataLayer || [];
|
|
708
|
-
window.gtag =
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
863
|
+
window.gtag =
|
|
864
|
+
window.gtag ||
|
|
865
|
+
function gtag() {
|
|
866
|
+
// eslint-disable-next-line prefer-rest-params
|
|
867
|
+
window.dataLayer.push(arguments);
|
|
868
|
+
};
|
|
712
869
|
if (!window.google_tag_manager ||
|
|
713
870
|
!window.google_tag_manager[manifest.variables['tagId']]) {
|
|
714
871
|
initGAds(manifest.variables['tagId'], consentData, executionContext, (_f = manifest.variables) === null || _f === void 0 ? void 0 : _f['consentSkip']);
|
|
@@ -758,7 +915,7 @@ const tag = ({ data, eventName, manifestVariables, destination, pageUrl, }) => {
|
|
|
758
915
|
var _a;
|
|
759
916
|
const result = {
|
|
760
917
|
isFired: false,
|
|
761
|
-
sdkVersion: "1.
|
|
918
|
+
sdkVersion: "1.54.0" ,
|
|
762
919
|
};
|
|
763
920
|
if (!eventName || !window.gtag || !(manifestVariables === null || manifestVariables === void 0 ? void 0 : manifestVariables['tagId'])) {
|
|
764
921
|
return result;
|
package/index.js
CHANGED
|
@@ -45,6 +45,40 @@ var ProvidersGoogleAdsClicksSdk = (function () {
|
|
|
45
45
|
return map.set(key, update(currentValue));
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Known ad-network click ID query parameters and the human-readable provider
|
|
50
|
+
* label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
|
|
51
|
+
* and by the analytics API to classify paid-media touch sessions.
|
|
52
|
+
*
|
|
53
|
+
* Keep this list in sync with `defaultParams` in queryParams.ts when new
|
|
54
|
+
* click ID providers are added.
|
|
55
|
+
*/
|
|
56
|
+
const CLICK_IDS = [
|
|
57
|
+
{ param: 'fbclid', label: 'Facebook' }, // Facebook Ads
|
|
58
|
+
{ param: 'gclid', label: 'Google' }, // Google Ads (click)
|
|
59
|
+
{ param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
|
|
60
|
+
{ param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
|
|
61
|
+
{ param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
|
|
62
|
+
{ param: 'ttclid', label: 'TikTok' }, // TikTok Ads
|
|
63
|
+
{ param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
|
|
64
|
+
{ param: 'epik', label: 'Pinterest' }, // Pinterest Ads
|
|
65
|
+
{ param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
|
|
66
|
+
{ param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
|
|
67
|
+
{ param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
|
|
68
|
+
{ param: 'aleid', label: 'AppLovin' }, // AppLovin
|
|
69
|
+
{ param: 'tabclid', label: 'Taboola' }, // Taboola
|
|
70
|
+
{ param: 'obclid', label: 'Outbrain' }, // Outbrain
|
|
71
|
+
{ param: 'trybe', label: 'Trybe' }, // Trybe
|
|
72
|
+
{ param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
|
|
73
|
+
{ param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
|
|
74
|
+
{ param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
|
|
75
|
+
{ param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
|
|
76
|
+
{ param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
|
|
77
|
+
{ param: '_raclid', label: 'Rumble' }, // Rumble Ads
|
|
78
|
+
{ param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
|
|
79
|
+
{ param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
|
|
80
|
+
];
|
|
81
|
+
|
|
48
82
|
const addDaysToDate = (date, days) => {
|
|
49
83
|
const newDate = new Date(date);
|
|
50
84
|
newDate.setDate(newDate.getDate() + days);
|
|
@@ -419,6 +453,127 @@ var ProvidersGoogleAdsClicksSdk = (function () {
|
|
|
419
453
|
]);
|
|
420
454
|
new Set([...isoCountries.keys(), ...usStates.keys()]);
|
|
421
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Exact utm_source normalization (lowercase key → canonical name).
|
|
458
|
+
*
|
|
459
|
+
* Use exact match when the key is short, generic, or must not accidentally
|
|
460
|
+
* absorb variant spellings (e.g. "impact" must not match "impact_radius").
|
|
461
|
+
*
|
|
462
|
+
* Ordering: Paid (search/social → ad networks → affiliates) →
|
|
463
|
+
* Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
|
|
464
|
+
*/
|
|
465
|
+
const UTM_SOURCE_EXACT = {
|
|
466
|
+
// ── Paid – Search & Social ────────────────────────────────────────────────
|
|
467
|
+
google: 'Google',
|
|
468
|
+
adwords: 'Google',
|
|
469
|
+
youtube: 'Google',
|
|
470
|
+
yt: 'Google',
|
|
471
|
+
meta: 'Facebook',
|
|
472
|
+
facebook: 'Facebook',
|
|
473
|
+
instagram: 'Facebook',
|
|
474
|
+
ig: 'Facebook',
|
|
475
|
+
igshopping: 'Facebook',
|
|
476
|
+
threads: 'Facebook',
|
|
477
|
+
twitter: 'Twitter',
|
|
478
|
+
snapchat: 'Snapchat',
|
|
479
|
+
pinterest: 'Pinterest',
|
|
480
|
+
bing: 'Bing',
|
|
481
|
+
microsoft: 'Bing',
|
|
482
|
+
tiktok: 'TikTok',
|
|
483
|
+
// ── Paid – Ad Networks ───────────────────────────────────────────────────
|
|
484
|
+
rtbhouse: 'RTB House',
|
|
485
|
+
applovin: 'AppLovin',
|
|
486
|
+
ttd: 'The Trade Desk',
|
|
487
|
+
amazondsp: 'Amazon DSP',
|
|
488
|
+
axon: 'Axon',
|
|
489
|
+
duel: 'Duel',
|
|
490
|
+
// ── Paid – Affiliates ────────────────────────────────────────────────────
|
|
491
|
+
awin: 'Awin',
|
|
492
|
+
'affiliate-cj': 'CJ Affiliate',
|
|
493
|
+
impact: 'Impact',
|
|
494
|
+
rakuten: 'Rakuten',
|
|
495
|
+
superfiliate: 'Superfiliate',
|
|
496
|
+
// ── Organic – AI & Discovery ─────────────────────────────────────────────
|
|
497
|
+
perplexity: 'Perplexity',
|
|
498
|
+
chatgpt: 'ChatGPT',
|
|
499
|
+
'chatgpt.com': 'ChatGPT',
|
|
500
|
+
openai: 'ChatGPT',
|
|
501
|
+
'copilot.com': 'Microsoft Copilot',
|
|
502
|
+
copilot: 'Microsoft Copilot',
|
|
503
|
+
applenews: 'Apple News',
|
|
504
|
+
whatsapp: 'WhatsApp',
|
|
505
|
+
podcast: 'Podcast',
|
|
506
|
+
// ── Retention – Email ────────────────────────────────────────────────────
|
|
507
|
+
mailchimp: 'Mailchimp',
|
|
508
|
+
omnisend: 'Omnisend',
|
|
509
|
+
iterable: 'Iterable',
|
|
510
|
+
listrak: 'Listrak',
|
|
511
|
+
sailthru: 'Sailthru',
|
|
512
|
+
// ── Retention – Push ─────────────────────────────────────────────────────
|
|
513
|
+
pushowl: 'PushOwl',
|
|
514
|
+
// ── Retention – Post-purchase / Payment ──────────────────────────────────
|
|
515
|
+
narvar: 'Narvar',
|
|
516
|
+
shop_app: 'Shop App',
|
|
517
|
+
salesforce: 'Salesforce',
|
|
518
|
+
yotpo: 'Yotpo',
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Partial utm_source normalization (startsWith prefix check, lowercase).
|
|
522
|
+
*
|
|
523
|
+
* Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
|
|
524
|
+
*/
|
|
525
|
+
const UTM_SOURCE_PARTIAL = [
|
|
526
|
+
// ── Paid – Social ─────────────────────────────────────────────────────────
|
|
527
|
+
{ prefix: 'tiktok', name: 'TikTok' },
|
|
528
|
+
// ── Paid – Ad Networks ───────────────────────────────────────────────────
|
|
529
|
+
{ prefix: 'criteo', name: 'Criteo' },
|
|
530
|
+
// ── Retention – Email ────────────────────────────────────────────────────
|
|
531
|
+
{ prefix: 'klaviyo', name: 'Klaviyo' },
|
|
532
|
+
// ── Retention – SMS ──────────────────────────────────────────────────────
|
|
533
|
+
{ prefix: 'attentive', name: 'Attentive' },
|
|
534
|
+
{ prefix: 'postscript', name: 'Postscript' },
|
|
535
|
+
// ── Retention – Post-purchase / Payment ──────────────────────────────────
|
|
536
|
+
{ prefix: 'afterpay', name: 'Afterpay' },
|
|
537
|
+
{ prefix: 'klarna', name: 'Klarna' },
|
|
538
|
+
];
|
|
539
|
+
const ORGANIC_SEARCH_ENGINES = [
|
|
540
|
+
{ match: 'google', name: 'Google' },
|
|
541
|
+
{ match: 'bing', name: 'Bing' },
|
|
542
|
+
{ match: 'yahoo', name: 'Yahoo' },
|
|
543
|
+
{ match: 'duckduckgo', name: 'DuckDuckGo' },
|
|
544
|
+
{ match: 'baidu', name: 'Baidu' },
|
|
545
|
+
{ match: 'yandex', name: 'Yandex' },
|
|
546
|
+
{ match: 'brave', name: 'Brave' },
|
|
547
|
+
];
|
|
548
|
+
const KNOWN_REFERRAL_PLATFORMS = [
|
|
549
|
+
{ match: 'facebook', name: 'Facebook' },
|
|
550
|
+
{ match: 'instagram', name: 'Facebook' },
|
|
551
|
+
{ match: 'twitter', name: 'Twitter' },
|
|
552
|
+
{ match: 'x.com', name: 'Twitter' },
|
|
553
|
+
{ match: 'tiktok', name: 'TikTok' },
|
|
554
|
+
{ match: 'pinterest', name: 'Pinterest' },
|
|
555
|
+
{ match: 'linkedin', name: 'LinkedIn' },
|
|
556
|
+
{ match: 'youtube', name: 'YouTube' },
|
|
557
|
+
{ match: 'chatgpt', name: 'ChatGPT' },
|
|
558
|
+
{ match: 'claude', name: 'Claude' },
|
|
559
|
+
{ match: 'perplexity', name: 'Perplexity' },
|
|
560
|
+
{ match: 'shop.app', name: 'Shop App' },
|
|
561
|
+
{ match: 'amazon', name: 'Amazon' },
|
|
562
|
+
{ match: 'attentive', name: 'Attentive' },
|
|
563
|
+
];
|
|
564
|
+
const OFFLINE_TOUCH = 'Blotout_Offline';
|
|
565
|
+
new Set([
|
|
566
|
+
...CLICK_IDS.map((c) => c.label),
|
|
567
|
+
...Object.values(UTM_SOURCE_EXACT),
|
|
568
|
+
...UTM_SOURCE_PARTIAL.map((e) => e.name),
|
|
569
|
+
...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
|
|
570
|
+
...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
|
|
571
|
+
'Referral - Other',
|
|
572
|
+
'Direct Traffic',
|
|
573
|
+
'Other',
|
|
574
|
+
OFFLINE_TOUCH,
|
|
575
|
+
]);
|
|
576
|
+
|
|
422
577
|
const getGoogleConsent = (consentData) => {
|
|
423
578
|
const gadsConsent = hasUserConsentForProvider(consentData, 'googleAdsClicks');
|
|
424
579
|
return {
|
|
@@ -706,10 +861,12 @@ var ProvidersGoogleAdsClicksSdk = (function () {
|
|
|
706
861
|
customConfig['allow_enhanced_conversions'] = true;
|
|
707
862
|
}
|
|
708
863
|
window.dataLayer = window.dataLayer || [];
|
|
709
|
-
window.gtag =
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
864
|
+
window.gtag =
|
|
865
|
+
window.gtag ||
|
|
866
|
+
function gtag() {
|
|
867
|
+
// eslint-disable-next-line prefer-rest-params
|
|
868
|
+
window.dataLayer.push(arguments);
|
|
869
|
+
};
|
|
713
870
|
if (!window.google_tag_manager ||
|
|
714
871
|
!window.google_tag_manager[manifest.variables['tagId']]) {
|
|
715
872
|
initGAds(manifest.variables['tagId'], consentData, executionContext, (_f = manifest.variables) === null || _f === void 0 ? void 0 : _f['consentSkip']);
|
|
@@ -759,7 +916,7 @@ var ProvidersGoogleAdsClicksSdk = (function () {
|
|
|
759
916
|
var _a;
|
|
760
917
|
const result = {
|
|
761
918
|
isFired: false,
|
|
762
|
-
sdkVersion: "1.
|
|
919
|
+
sdkVersion: "1.54.0" ,
|
|
763
920
|
};
|
|
764
921
|
if (!eventName || !window.gtag || !(manifestVariables === null || manifestVariables === void 0 ? void 0 : manifestVariables['tagId'])) {
|
|
765
922
|
return result;
|
package/index.mjs
CHANGED
|
@@ -42,6 +42,40 @@ const upsert = (map, key, update, createDefault) => {
|
|
|
42
42
|
return map.set(key, update(currentValue));
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Known ad-network click ID query parameters and the human-readable provider
|
|
47
|
+
* label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
|
|
48
|
+
* and by the analytics API to classify paid-media touch sessions.
|
|
49
|
+
*
|
|
50
|
+
* Keep this list in sync with `defaultParams` in queryParams.ts when new
|
|
51
|
+
* click ID providers are added.
|
|
52
|
+
*/
|
|
53
|
+
const CLICK_IDS = [
|
|
54
|
+
{ param: 'fbclid', label: 'Facebook' }, // Facebook Ads
|
|
55
|
+
{ param: 'gclid', label: 'Google' }, // Google Ads (click)
|
|
56
|
+
{ param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
|
|
57
|
+
{ param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
|
|
58
|
+
{ param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
|
|
59
|
+
{ param: 'ttclid', label: 'TikTok' }, // TikTok Ads
|
|
60
|
+
{ param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
|
|
61
|
+
{ param: 'epik', label: 'Pinterest' }, // Pinterest Ads
|
|
62
|
+
{ param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
|
|
63
|
+
{ param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
|
|
64
|
+
{ param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
|
|
65
|
+
{ param: 'aleid', label: 'AppLovin' }, // AppLovin
|
|
66
|
+
{ param: 'tabclid', label: 'Taboola' }, // Taboola
|
|
67
|
+
{ param: 'obclid', label: 'Outbrain' }, // Outbrain
|
|
68
|
+
{ param: 'trybe', label: 'Trybe' }, // Trybe
|
|
69
|
+
{ param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
|
|
70
|
+
{ param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
|
|
71
|
+
{ param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
|
|
72
|
+
{ param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
|
|
73
|
+
{ param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
|
|
74
|
+
{ param: '_raclid', label: 'Rumble' }, // Rumble Ads
|
|
75
|
+
{ param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
|
|
76
|
+
{ param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
|
|
77
|
+
];
|
|
78
|
+
|
|
45
79
|
const addDaysToDate = (date, days) => {
|
|
46
80
|
const newDate = new Date(date);
|
|
47
81
|
newDate.setDate(newDate.getDate() + days);
|
|
@@ -416,6 +450,127 @@ const usStates = new Map([
|
|
|
416
450
|
]);
|
|
417
451
|
new Set([...isoCountries.keys(), ...usStates.keys()]);
|
|
418
452
|
|
|
453
|
+
/**
|
|
454
|
+
* Exact utm_source normalization (lowercase key → canonical name).
|
|
455
|
+
*
|
|
456
|
+
* Use exact match when the key is short, generic, or must not accidentally
|
|
457
|
+
* absorb variant spellings (e.g. "impact" must not match "impact_radius").
|
|
458
|
+
*
|
|
459
|
+
* Ordering: Paid (search/social → ad networks → affiliates) →
|
|
460
|
+
* Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
|
|
461
|
+
*/
|
|
462
|
+
const UTM_SOURCE_EXACT = {
|
|
463
|
+
// ── Paid – Search & Social ────────────────────────────────────────────────
|
|
464
|
+
google: 'Google',
|
|
465
|
+
adwords: 'Google',
|
|
466
|
+
youtube: 'Google',
|
|
467
|
+
yt: 'Google',
|
|
468
|
+
meta: 'Facebook',
|
|
469
|
+
facebook: 'Facebook',
|
|
470
|
+
instagram: 'Facebook',
|
|
471
|
+
ig: 'Facebook',
|
|
472
|
+
igshopping: 'Facebook',
|
|
473
|
+
threads: 'Facebook',
|
|
474
|
+
twitter: 'Twitter',
|
|
475
|
+
snapchat: 'Snapchat',
|
|
476
|
+
pinterest: 'Pinterest',
|
|
477
|
+
bing: 'Bing',
|
|
478
|
+
microsoft: 'Bing',
|
|
479
|
+
tiktok: 'TikTok',
|
|
480
|
+
// ── Paid – Ad Networks ───────────────────────────────────────────────────
|
|
481
|
+
rtbhouse: 'RTB House',
|
|
482
|
+
applovin: 'AppLovin',
|
|
483
|
+
ttd: 'The Trade Desk',
|
|
484
|
+
amazondsp: 'Amazon DSP',
|
|
485
|
+
axon: 'Axon',
|
|
486
|
+
duel: 'Duel',
|
|
487
|
+
// ── Paid – Affiliates ────────────────────────────────────────────────────
|
|
488
|
+
awin: 'Awin',
|
|
489
|
+
'affiliate-cj': 'CJ Affiliate',
|
|
490
|
+
impact: 'Impact',
|
|
491
|
+
rakuten: 'Rakuten',
|
|
492
|
+
superfiliate: 'Superfiliate',
|
|
493
|
+
// ── Organic – AI & Discovery ─────────────────────────────────────────────
|
|
494
|
+
perplexity: 'Perplexity',
|
|
495
|
+
chatgpt: 'ChatGPT',
|
|
496
|
+
'chatgpt.com': 'ChatGPT',
|
|
497
|
+
openai: 'ChatGPT',
|
|
498
|
+
'copilot.com': 'Microsoft Copilot',
|
|
499
|
+
copilot: 'Microsoft Copilot',
|
|
500
|
+
applenews: 'Apple News',
|
|
501
|
+
whatsapp: 'WhatsApp',
|
|
502
|
+
podcast: 'Podcast',
|
|
503
|
+
// ── Retention – Email ────────────────────────────────────────────────────
|
|
504
|
+
mailchimp: 'Mailchimp',
|
|
505
|
+
omnisend: 'Omnisend',
|
|
506
|
+
iterable: 'Iterable',
|
|
507
|
+
listrak: 'Listrak',
|
|
508
|
+
sailthru: 'Sailthru',
|
|
509
|
+
// ── Retention – Push ─────────────────────────────────────────────────────
|
|
510
|
+
pushowl: 'PushOwl',
|
|
511
|
+
// ── Retention – Post-purchase / Payment ──────────────────────────────────
|
|
512
|
+
narvar: 'Narvar',
|
|
513
|
+
shop_app: 'Shop App',
|
|
514
|
+
salesforce: 'Salesforce',
|
|
515
|
+
yotpo: 'Yotpo',
|
|
516
|
+
};
|
|
517
|
+
/**
|
|
518
|
+
* Partial utm_source normalization (startsWith prefix check, lowercase).
|
|
519
|
+
*
|
|
520
|
+
* Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
|
|
521
|
+
*/
|
|
522
|
+
const UTM_SOURCE_PARTIAL = [
|
|
523
|
+
// ── Paid – Social ─────────────────────────────────────────────────────────
|
|
524
|
+
{ prefix: 'tiktok', name: 'TikTok' },
|
|
525
|
+
// ── Paid – Ad Networks ───────────────────────────────────────────────────
|
|
526
|
+
{ prefix: 'criteo', name: 'Criteo' },
|
|
527
|
+
// ── Retention – Email ────────────────────────────────────────────────────
|
|
528
|
+
{ prefix: 'klaviyo', name: 'Klaviyo' },
|
|
529
|
+
// ── Retention – SMS ──────────────────────────────────────────────────────
|
|
530
|
+
{ prefix: 'attentive', name: 'Attentive' },
|
|
531
|
+
{ prefix: 'postscript', name: 'Postscript' },
|
|
532
|
+
// ── Retention – Post-purchase / Payment ──────────────────────────────────
|
|
533
|
+
{ prefix: 'afterpay', name: 'Afterpay' },
|
|
534
|
+
{ prefix: 'klarna', name: 'Klarna' },
|
|
535
|
+
];
|
|
536
|
+
const ORGANIC_SEARCH_ENGINES = [
|
|
537
|
+
{ match: 'google', name: 'Google' },
|
|
538
|
+
{ match: 'bing', name: 'Bing' },
|
|
539
|
+
{ match: 'yahoo', name: 'Yahoo' },
|
|
540
|
+
{ match: 'duckduckgo', name: 'DuckDuckGo' },
|
|
541
|
+
{ match: 'baidu', name: 'Baidu' },
|
|
542
|
+
{ match: 'yandex', name: 'Yandex' },
|
|
543
|
+
{ match: 'brave', name: 'Brave' },
|
|
544
|
+
];
|
|
545
|
+
const KNOWN_REFERRAL_PLATFORMS = [
|
|
546
|
+
{ match: 'facebook', name: 'Facebook' },
|
|
547
|
+
{ match: 'instagram', name: 'Facebook' },
|
|
548
|
+
{ match: 'twitter', name: 'Twitter' },
|
|
549
|
+
{ match: 'x.com', name: 'Twitter' },
|
|
550
|
+
{ match: 'tiktok', name: 'TikTok' },
|
|
551
|
+
{ match: 'pinterest', name: 'Pinterest' },
|
|
552
|
+
{ match: 'linkedin', name: 'LinkedIn' },
|
|
553
|
+
{ match: 'youtube', name: 'YouTube' },
|
|
554
|
+
{ match: 'chatgpt', name: 'ChatGPT' },
|
|
555
|
+
{ match: 'claude', name: 'Claude' },
|
|
556
|
+
{ match: 'perplexity', name: 'Perplexity' },
|
|
557
|
+
{ match: 'shop.app', name: 'Shop App' },
|
|
558
|
+
{ match: 'amazon', name: 'Amazon' },
|
|
559
|
+
{ match: 'attentive', name: 'Attentive' },
|
|
560
|
+
];
|
|
561
|
+
const OFFLINE_TOUCH = 'Blotout_Offline';
|
|
562
|
+
new Set([
|
|
563
|
+
...CLICK_IDS.map((c) => c.label),
|
|
564
|
+
...Object.values(UTM_SOURCE_EXACT),
|
|
565
|
+
...UTM_SOURCE_PARTIAL.map((e) => e.name),
|
|
566
|
+
...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
|
|
567
|
+
...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
|
|
568
|
+
'Referral - Other',
|
|
569
|
+
'Direct Traffic',
|
|
570
|
+
'Other',
|
|
571
|
+
OFFLINE_TOUCH,
|
|
572
|
+
]);
|
|
573
|
+
|
|
419
574
|
const getGoogleConsent = (consentData) => {
|
|
420
575
|
const gadsConsent = hasUserConsentForProvider(consentData, 'googleAdsClicks');
|
|
421
576
|
return {
|
|
@@ -703,10 +858,12 @@ const init = ({ manifest, consentData, executionContext, pageUrl, }) => {
|
|
|
703
858
|
customConfig['allow_enhanced_conversions'] = true;
|
|
704
859
|
}
|
|
705
860
|
window.dataLayer = window.dataLayer || [];
|
|
706
|
-
window.gtag =
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
861
|
+
window.gtag =
|
|
862
|
+
window.gtag ||
|
|
863
|
+
function gtag() {
|
|
864
|
+
// eslint-disable-next-line prefer-rest-params
|
|
865
|
+
window.dataLayer.push(arguments);
|
|
866
|
+
};
|
|
710
867
|
if (!window.google_tag_manager ||
|
|
711
868
|
!window.google_tag_manager[manifest.variables['tagId']]) {
|
|
712
869
|
initGAds(manifest.variables['tagId'], consentData, executionContext, (_f = manifest.variables) === null || _f === void 0 ? void 0 : _f['consentSkip']);
|
|
@@ -756,7 +913,7 @@ const tag = ({ data, eventName, manifestVariables, destination, pageUrl, }) => {
|
|
|
756
913
|
var _a;
|
|
757
914
|
const result = {
|
|
758
915
|
isFired: false,
|
|
759
|
-
sdkVersion: "1.
|
|
916
|
+
sdkVersion: "1.54.0" ,
|
|
760
917
|
};
|
|
761
918
|
if (!eventName || !window.gtag || !(manifestVariables === null || manifestVariables === void 0 ? void 0 : manifestVariables['tagId'])) {
|
|
762
919
|
return result;
|