@blotoutio/providers-audiohook-sdk 1.53.1 → 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.
Files changed (4) hide show
  1. package/index.cjs.js +156 -1
  2. package/index.js +156 -1
  3. package/index.mjs +156 -1
  4. package/package.json +1 -1
package/index.cjs.js CHANGED
@@ -56,6 +56,40 @@ const init = ({ manifest }) => {
56
56
  initAudiohook(manifest.variables['pixelId']);
57
57
  };
58
58
 
59
+ /**
60
+ * Known ad-network click ID query parameters and the human-readable provider
61
+ * label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
62
+ * and by the analytics API to classify paid-media touch sessions.
63
+ *
64
+ * Keep this list in sync with `defaultParams` in queryParams.ts when new
65
+ * click ID providers are added.
66
+ */
67
+ const CLICK_IDS = [
68
+ { param: 'fbclid', label: 'Facebook' }, // Facebook Ads
69
+ { param: 'gclid', label: 'Google' }, // Google Ads (click)
70
+ { param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
71
+ { param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
72
+ { param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
73
+ { param: 'ttclid', label: 'TikTok' }, // TikTok Ads
74
+ { param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
75
+ { param: 'epik', label: 'Pinterest' }, // Pinterest Ads
76
+ { param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
77
+ { param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
78
+ { param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
79
+ { param: 'aleid', label: 'AppLovin' }, // AppLovin
80
+ { param: 'tabclid', label: 'Taboola' }, // Taboola
81
+ { param: 'obclid', label: 'Outbrain' }, // Outbrain
82
+ { param: 'trybe', label: 'Trybe' }, // Trybe
83
+ { param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
84
+ { param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
85
+ { param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
86
+ { param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
87
+ { param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
88
+ { param: '_raclid', label: 'Rumble' }, // Rumble Ads
89
+ { param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
90
+ { param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
91
+ ];
92
+
59
93
  const expand = (str) => str.split(',').flatMap((entry) => {
60
94
  if (!entry.includes('-')) {
61
95
  return entry;
@@ -441,6 +475,127 @@ const usStates = new Map([
441
475
  ]);
442
476
  new Set([...isoCountries.keys(), ...usStates.keys()]);
443
477
 
478
+ /**
479
+ * Exact utm_source normalization (lowercase key → canonical name).
480
+ *
481
+ * Use exact match when the key is short, generic, or must not accidentally
482
+ * absorb variant spellings (e.g. "impact" must not match "impact_radius").
483
+ *
484
+ * Ordering: Paid (search/social → ad networks → affiliates) →
485
+ * Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
486
+ */
487
+ const UTM_SOURCE_EXACT = {
488
+ // ── Paid – Search & Social ────────────────────────────────────────────────
489
+ google: 'Google',
490
+ adwords: 'Google',
491
+ youtube: 'Google',
492
+ yt: 'Google',
493
+ meta: 'Facebook',
494
+ facebook: 'Facebook',
495
+ instagram: 'Facebook',
496
+ ig: 'Facebook',
497
+ igshopping: 'Facebook',
498
+ threads: 'Facebook',
499
+ twitter: 'Twitter',
500
+ snapchat: 'Snapchat',
501
+ pinterest: 'Pinterest',
502
+ bing: 'Bing',
503
+ microsoft: 'Bing',
504
+ tiktok: 'TikTok',
505
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
506
+ rtbhouse: 'RTB House',
507
+ applovin: 'AppLovin',
508
+ ttd: 'The Trade Desk',
509
+ amazondsp: 'Amazon DSP',
510
+ axon: 'Axon',
511
+ duel: 'Duel',
512
+ // ── Paid – Affiliates ────────────────────────────────────────────────────
513
+ awin: 'Awin',
514
+ 'affiliate-cj': 'CJ Affiliate',
515
+ impact: 'Impact',
516
+ rakuten: 'Rakuten',
517
+ superfiliate: 'Superfiliate',
518
+ // ── Organic – AI & Discovery ─────────────────────────────────────────────
519
+ perplexity: 'Perplexity',
520
+ chatgpt: 'ChatGPT',
521
+ 'chatgpt.com': 'ChatGPT',
522
+ openai: 'ChatGPT',
523
+ 'copilot.com': 'Microsoft Copilot',
524
+ copilot: 'Microsoft Copilot',
525
+ applenews: 'Apple News',
526
+ whatsapp: 'WhatsApp',
527
+ podcast: 'Podcast',
528
+ // ── Retention – Email ────────────────────────────────────────────────────
529
+ mailchimp: 'Mailchimp',
530
+ omnisend: 'Omnisend',
531
+ iterable: 'Iterable',
532
+ listrak: 'Listrak',
533
+ sailthru: 'Sailthru',
534
+ // ── Retention – Push ─────────────────────────────────────────────────────
535
+ pushowl: 'PushOwl',
536
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
537
+ narvar: 'Narvar',
538
+ shop_app: 'Shop App',
539
+ salesforce: 'Salesforce',
540
+ yotpo: 'Yotpo',
541
+ };
542
+ /**
543
+ * Partial utm_source normalization (startsWith prefix check, lowercase).
544
+ *
545
+ * Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
546
+ */
547
+ const UTM_SOURCE_PARTIAL = [
548
+ // ── Paid – Social ─────────────────────────────────────────────────────────
549
+ { prefix: 'tiktok', name: 'TikTok' },
550
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
551
+ { prefix: 'criteo', name: 'Criteo' },
552
+ // ── Retention – Email ────────────────────────────────────────────────────
553
+ { prefix: 'klaviyo', name: 'Klaviyo' },
554
+ // ── Retention – SMS ──────────────────────────────────────────────────────
555
+ { prefix: 'attentive', name: 'Attentive' },
556
+ { prefix: 'postscript', name: 'Postscript' },
557
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
558
+ { prefix: 'afterpay', name: 'Afterpay' },
559
+ { prefix: 'klarna', name: 'Klarna' },
560
+ ];
561
+ const ORGANIC_SEARCH_ENGINES = [
562
+ { match: 'google', name: 'Google' },
563
+ { match: 'bing', name: 'Bing' },
564
+ { match: 'yahoo', name: 'Yahoo' },
565
+ { match: 'duckduckgo', name: 'DuckDuckGo' },
566
+ { match: 'baidu', name: 'Baidu' },
567
+ { match: 'yandex', name: 'Yandex' },
568
+ { match: 'brave', name: 'Brave' },
569
+ ];
570
+ const KNOWN_REFERRAL_PLATFORMS = [
571
+ { match: 'facebook', name: 'Facebook' },
572
+ { match: 'instagram', name: 'Facebook' },
573
+ { match: 'twitter', name: 'Twitter' },
574
+ { match: 'x.com', name: 'Twitter' },
575
+ { match: 'tiktok', name: 'TikTok' },
576
+ { match: 'pinterest', name: 'Pinterest' },
577
+ { match: 'linkedin', name: 'LinkedIn' },
578
+ { match: 'youtube', name: 'YouTube' },
579
+ { match: 'chatgpt', name: 'ChatGPT' },
580
+ { match: 'claude', name: 'Claude' },
581
+ { match: 'perplexity', name: 'Perplexity' },
582
+ { match: 'shop.app', name: 'Shop App' },
583
+ { match: 'amazon', name: 'Amazon' },
584
+ { match: 'attentive', name: 'Attentive' },
585
+ ];
586
+ const OFFLINE_TOUCH = 'Blotout_Offline';
587
+ new Set([
588
+ ...CLICK_IDS.map((c) => c.label),
589
+ ...Object.values(UTM_SOURCE_EXACT),
590
+ ...UTM_SOURCE_PARTIAL.map((e) => e.name),
591
+ ...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
592
+ ...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
593
+ 'Referral - Other',
594
+ 'Direct Traffic',
595
+ 'Other',
596
+ OFFLINE_TOUCH,
597
+ ]);
598
+
444
599
  const prepareData = (data) => {
445
600
  const payload = {};
446
601
  if (data['value'] || data['value'] === 0) {
@@ -486,7 +641,7 @@ const prepareData = (data) => {
486
641
  };
487
642
  const tag = ({ data, eventName, manifestVariables, eventId }) => {
488
643
  const payload = {
489
- sdkVersion: "1.53.1" ,
644
+ sdkVersion: "1.54.0" ,
490
645
  };
491
646
  const windowWithAH = window;
492
647
  if (windowWithAH.ahTrack &&
package/index.js CHANGED
@@ -57,6 +57,40 @@ var ProvidersAudiohookSdk = (function () {
57
57
  initAudiohook(manifest.variables['pixelId']);
58
58
  };
59
59
 
60
+ /**
61
+ * Known ad-network click ID query parameters and the human-readable provider
62
+ * label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
63
+ * and by the analytics API to classify paid-media touch sessions.
64
+ *
65
+ * Keep this list in sync with `defaultParams` in queryParams.ts when new
66
+ * click ID providers are added.
67
+ */
68
+ const CLICK_IDS = [
69
+ { param: 'fbclid', label: 'Facebook' }, // Facebook Ads
70
+ { param: 'gclid', label: 'Google' }, // Google Ads (click)
71
+ { param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
72
+ { param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
73
+ { param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
74
+ { param: 'ttclid', label: 'TikTok' }, // TikTok Ads
75
+ { param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
76
+ { param: 'epik', label: 'Pinterest' }, // Pinterest Ads
77
+ { param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
78
+ { param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
79
+ { param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
80
+ { param: 'aleid', label: 'AppLovin' }, // AppLovin
81
+ { param: 'tabclid', label: 'Taboola' }, // Taboola
82
+ { param: 'obclid', label: 'Outbrain' }, // Outbrain
83
+ { param: 'trybe', label: 'Trybe' }, // Trybe
84
+ { param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
85
+ { param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
86
+ { param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
87
+ { param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
88
+ { param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
89
+ { param: '_raclid', label: 'Rumble' }, // Rumble Ads
90
+ { param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
91
+ { param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
92
+ ];
93
+
60
94
  const expand = (str) => str.split(',').flatMap((entry) => {
61
95
  if (!entry.includes('-')) {
62
96
  return entry;
@@ -442,6 +476,127 @@ var ProvidersAudiohookSdk = (function () {
442
476
  ]);
443
477
  new Set([...isoCountries.keys(), ...usStates.keys()]);
444
478
 
479
+ /**
480
+ * Exact utm_source normalization (lowercase key → canonical name).
481
+ *
482
+ * Use exact match when the key is short, generic, or must not accidentally
483
+ * absorb variant spellings (e.g. "impact" must not match "impact_radius").
484
+ *
485
+ * Ordering: Paid (search/social → ad networks → affiliates) →
486
+ * Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
487
+ */
488
+ const UTM_SOURCE_EXACT = {
489
+ // ── Paid – Search & Social ────────────────────────────────────────────────
490
+ google: 'Google',
491
+ adwords: 'Google',
492
+ youtube: 'Google',
493
+ yt: 'Google',
494
+ meta: 'Facebook',
495
+ facebook: 'Facebook',
496
+ instagram: 'Facebook',
497
+ ig: 'Facebook',
498
+ igshopping: 'Facebook',
499
+ threads: 'Facebook',
500
+ twitter: 'Twitter',
501
+ snapchat: 'Snapchat',
502
+ pinterest: 'Pinterest',
503
+ bing: 'Bing',
504
+ microsoft: 'Bing',
505
+ tiktok: 'TikTok',
506
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
507
+ rtbhouse: 'RTB House',
508
+ applovin: 'AppLovin',
509
+ ttd: 'The Trade Desk',
510
+ amazondsp: 'Amazon DSP',
511
+ axon: 'Axon',
512
+ duel: 'Duel',
513
+ // ── Paid – Affiliates ────────────────────────────────────────────────────
514
+ awin: 'Awin',
515
+ 'affiliate-cj': 'CJ Affiliate',
516
+ impact: 'Impact',
517
+ rakuten: 'Rakuten',
518
+ superfiliate: 'Superfiliate',
519
+ // ── Organic – AI & Discovery ─────────────────────────────────────────────
520
+ perplexity: 'Perplexity',
521
+ chatgpt: 'ChatGPT',
522
+ 'chatgpt.com': 'ChatGPT',
523
+ openai: 'ChatGPT',
524
+ 'copilot.com': 'Microsoft Copilot',
525
+ copilot: 'Microsoft Copilot',
526
+ applenews: 'Apple News',
527
+ whatsapp: 'WhatsApp',
528
+ podcast: 'Podcast',
529
+ // ── Retention – Email ────────────────────────────────────────────────────
530
+ mailchimp: 'Mailchimp',
531
+ omnisend: 'Omnisend',
532
+ iterable: 'Iterable',
533
+ listrak: 'Listrak',
534
+ sailthru: 'Sailthru',
535
+ // ── Retention – Push ─────────────────────────────────────────────────────
536
+ pushowl: 'PushOwl',
537
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
538
+ narvar: 'Narvar',
539
+ shop_app: 'Shop App',
540
+ salesforce: 'Salesforce',
541
+ yotpo: 'Yotpo',
542
+ };
543
+ /**
544
+ * Partial utm_source normalization (startsWith prefix check, lowercase).
545
+ *
546
+ * Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
547
+ */
548
+ const UTM_SOURCE_PARTIAL = [
549
+ // ── Paid – Social ─────────────────────────────────────────────────────────
550
+ { prefix: 'tiktok', name: 'TikTok' },
551
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
552
+ { prefix: 'criteo', name: 'Criteo' },
553
+ // ── Retention – Email ────────────────────────────────────────────────────
554
+ { prefix: 'klaviyo', name: 'Klaviyo' },
555
+ // ── Retention – SMS ──────────────────────────────────────────────────────
556
+ { prefix: 'attentive', name: 'Attentive' },
557
+ { prefix: 'postscript', name: 'Postscript' },
558
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
559
+ { prefix: 'afterpay', name: 'Afterpay' },
560
+ { prefix: 'klarna', name: 'Klarna' },
561
+ ];
562
+ const ORGANIC_SEARCH_ENGINES = [
563
+ { match: 'google', name: 'Google' },
564
+ { match: 'bing', name: 'Bing' },
565
+ { match: 'yahoo', name: 'Yahoo' },
566
+ { match: 'duckduckgo', name: 'DuckDuckGo' },
567
+ { match: 'baidu', name: 'Baidu' },
568
+ { match: 'yandex', name: 'Yandex' },
569
+ { match: 'brave', name: 'Brave' },
570
+ ];
571
+ const KNOWN_REFERRAL_PLATFORMS = [
572
+ { match: 'facebook', name: 'Facebook' },
573
+ { match: 'instagram', name: 'Facebook' },
574
+ { match: 'twitter', name: 'Twitter' },
575
+ { match: 'x.com', name: 'Twitter' },
576
+ { match: 'tiktok', name: 'TikTok' },
577
+ { match: 'pinterest', name: 'Pinterest' },
578
+ { match: 'linkedin', name: 'LinkedIn' },
579
+ { match: 'youtube', name: 'YouTube' },
580
+ { match: 'chatgpt', name: 'ChatGPT' },
581
+ { match: 'claude', name: 'Claude' },
582
+ { match: 'perplexity', name: 'Perplexity' },
583
+ { match: 'shop.app', name: 'Shop App' },
584
+ { match: 'amazon', name: 'Amazon' },
585
+ { match: 'attentive', name: 'Attentive' },
586
+ ];
587
+ const OFFLINE_TOUCH = 'Blotout_Offline';
588
+ new Set([
589
+ ...CLICK_IDS.map((c) => c.label),
590
+ ...Object.values(UTM_SOURCE_EXACT),
591
+ ...UTM_SOURCE_PARTIAL.map((e) => e.name),
592
+ ...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
593
+ ...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
594
+ 'Referral - Other',
595
+ 'Direct Traffic',
596
+ 'Other',
597
+ OFFLINE_TOUCH,
598
+ ]);
599
+
445
600
  const prepareData = (data) => {
446
601
  const payload = {};
447
602
  if (data['value'] || data['value'] === 0) {
@@ -487,7 +642,7 @@ var ProvidersAudiohookSdk = (function () {
487
642
  };
488
643
  const tag = ({ data, eventName, manifestVariables, eventId }) => {
489
644
  const payload = {
490
- sdkVersion: "1.53.1" ,
645
+ sdkVersion: "1.54.0" ,
491
646
  };
492
647
  const windowWithAH = window;
493
648
  if (windowWithAH.ahTrack &&
package/index.mjs CHANGED
@@ -54,6 +54,40 @@ const init = ({ manifest }) => {
54
54
  initAudiohook(manifest.variables['pixelId']);
55
55
  };
56
56
 
57
+ /**
58
+ * Known ad-network click ID query parameters and the human-readable provider
59
+ * label each one maps to. Used by the CDN worker to resolve `inSessionTouch`
60
+ * and by the analytics API to classify paid-media touch sessions.
61
+ *
62
+ * Keep this list in sync with `defaultParams` in queryParams.ts when new
63
+ * click ID providers are added.
64
+ */
65
+ const CLICK_IDS = [
66
+ { param: 'fbclid', label: 'Facebook' }, // Facebook Ads
67
+ { param: 'gclid', label: 'Google' }, // Google Ads (click)
68
+ { param: 'gbraid', label: 'Google' }, // Google Ads (iOS app)
69
+ { param: 'wbraid', label: 'Google' }, // Google Ads (iOS web)
70
+ { param: 'msclkid', label: 'Bing' }, // Microsoft Bing Ads
71
+ { param: 'ttclid', label: 'TikTok' }, // TikTok Ads
72
+ { param: 'ScCid', label: 'Snapchat' }, // Snapchat Ads
73
+ { param: 'epik', label: 'Pinterest' }, // Pinterest Ads
74
+ { param: 'li_fat_id', label: 'LinkedIn' }, // LinkedIn Ads
75
+ { param: 'twclid', label: 'Twitter' }, // X (Twitter) Ads
76
+ { param: 'rdt_cid', label: 'Reddit' }, // Reddit Ads
77
+ { param: 'aleid', label: 'AppLovin' }, // AppLovin
78
+ { param: 'tabclid', label: 'Taboola' }, // Taboola
79
+ { param: 'obclid', label: 'Outbrain' }, // Outbrain
80
+ { param: 'trybe', label: 'Trybe' }, // Trybe
81
+ { param: '_kx', label: 'Klaviyo' }, // Klaviyo email campaigns
82
+ { param: 'mc_eid', label: 'Mailchimp' }, // Mailchimp email campaigns
83
+ { param: 'ttd_id', label: 'The Trade Desk' }, // The Trade Desk programmatic
84
+ { param: 'evsclid', label: 'EvoSearch' }, // EvoSearch
85
+ { param: 'li_did', label: 'Live Intent' }, // LiveIntent device-level ad
86
+ { param: '_raclid', label: 'Rumble' }, // Rumble Ads
87
+ { param: 'ref_id', label: 'StackAdapt' }, // StackAdapt programmatic
88
+ { param: 'duel_a', label: 'Duel' }, // Duel referral/advocacy
89
+ ];
90
+
57
91
  const expand = (str) => str.split(',').flatMap((entry) => {
58
92
  if (!entry.includes('-')) {
59
93
  return entry;
@@ -439,6 +473,127 @@ const usStates = new Map([
439
473
  ]);
440
474
  new Set([...isoCountries.keys(), ...usStates.keys()]);
441
475
 
476
+ /**
477
+ * Exact utm_source normalization (lowercase key → canonical name).
478
+ *
479
+ * Use exact match when the key is short, generic, or must not accidentally
480
+ * absorb variant spellings (e.g. "impact" must not match "impact_radius").
481
+ *
482
+ * Ordering: Paid (search/social → ad networks → affiliates) →
483
+ * Organic (AI/discovery) → Retention (email → SMS → push → post-purchase)
484
+ */
485
+ const UTM_SOURCE_EXACT = {
486
+ // ── Paid – Search & Social ────────────────────────────────────────────────
487
+ google: 'Google',
488
+ adwords: 'Google',
489
+ youtube: 'Google',
490
+ yt: 'Google',
491
+ meta: 'Facebook',
492
+ facebook: 'Facebook',
493
+ instagram: 'Facebook',
494
+ ig: 'Facebook',
495
+ igshopping: 'Facebook',
496
+ threads: 'Facebook',
497
+ twitter: 'Twitter',
498
+ snapchat: 'Snapchat',
499
+ pinterest: 'Pinterest',
500
+ bing: 'Bing',
501
+ microsoft: 'Bing',
502
+ tiktok: 'TikTok',
503
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
504
+ rtbhouse: 'RTB House',
505
+ applovin: 'AppLovin',
506
+ ttd: 'The Trade Desk',
507
+ amazondsp: 'Amazon DSP',
508
+ axon: 'Axon',
509
+ duel: 'Duel',
510
+ // ── Paid – Affiliates ────────────────────────────────────────────────────
511
+ awin: 'Awin',
512
+ 'affiliate-cj': 'CJ Affiliate',
513
+ impact: 'Impact',
514
+ rakuten: 'Rakuten',
515
+ superfiliate: 'Superfiliate',
516
+ // ── Organic – AI & Discovery ─────────────────────────────────────────────
517
+ perplexity: 'Perplexity',
518
+ chatgpt: 'ChatGPT',
519
+ 'chatgpt.com': 'ChatGPT',
520
+ openai: 'ChatGPT',
521
+ 'copilot.com': 'Microsoft Copilot',
522
+ copilot: 'Microsoft Copilot',
523
+ applenews: 'Apple News',
524
+ whatsapp: 'WhatsApp',
525
+ podcast: 'Podcast',
526
+ // ── Retention – Email ────────────────────────────────────────────────────
527
+ mailchimp: 'Mailchimp',
528
+ omnisend: 'Omnisend',
529
+ iterable: 'Iterable',
530
+ listrak: 'Listrak',
531
+ sailthru: 'Sailthru',
532
+ // ── Retention – Push ─────────────────────────────────────────────────────
533
+ pushowl: 'PushOwl',
534
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
535
+ narvar: 'Narvar',
536
+ shop_app: 'Shop App',
537
+ salesforce: 'Salesforce',
538
+ yotpo: 'Yotpo',
539
+ };
540
+ /**
541
+ * Partial utm_source normalization (startsWith prefix check, lowercase).
542
+ *
543
+ * Checked after exact match so short exact keys (e.g. "ig", "yt") win first.
544
+ */
545
+ const UTM_SOURCE_PARTIAL = [
546
+ // ── Paid – Social ─────────────────────────────────────────────────────────
547
+ { prefix: 'tiktok', name: 'TikTok' },
548
+ // ── Paid – Ad Networks ───────────────────────────────────────────────────
549
+ { prefix: 'criteo', name: 'Criteo' },
550
+ // ── Retention – Email ────────────────────────────────────────────────────
551
+ { prefix: 'klaviyo', name: 'Klaviyo' },
552
+ // ── Retention – SMS ──────────────────────────────────────────────────────
553
+ { prefix: 'attentive', name: 'Attentive' },
554
+ { prefix: 'postscript', name: 'Postscript' },
555
+ // ── Retention – Post-purchase / Payment ──────────────────────────────────
556
+ { prefix: 'afterpay', name: 'Afterpay' },
557
+ { prefix: 'klarna', name: 'Klarna' },
558
+ ];
559
+ const ORGANIC_SEARCH_ENGINES = [
560
+ { match: 'google', name: 'Google' },
561
+ { match: 'bing', name: 'Bing' },
562
+ { match: 'yahoo', name: 'Yahoo' },
563
+ { match: 'duckduckgo', name: 'DuckDuckGo' },
564
+ { match: 'baidu', name: 'Baidu' },
565
+ { match: 'yandex', name: 'Yandex' },
566
+ { match: 'brave', name: 'Brave' },
567
+ ];
568
+ const KNOWN_REFERRAL_PLATFORMS = [
569
+ { match: 'facebook', name: 'Facebook' },
570
+ { match: 'instagram', name: 'Facebook' },
571
+ { match: 'twitter', name: 'Twitter' },
572
+ { match: 'x.com', name: 'Twitter' },
573
+ { match: 'tiktok', name: 'TikTok' },
574
+ { match: 'pinterest', name: 'Pinterest' },
575
+ { match: 'linkedin', name: 'LinkedIn' },
576
+ { match: 'youtube', name: 'YouTube' },
577
+ { match: 'chatgpt', name: 'ChatGPT' },
578
+ { match: 'claude', name: 'Claude' },
579
+ { match: 'perplexity', name: 'Perplexity' },
580
+ { match: 'shop.app', name: 'Shop App' },
581
+ { match: 'amazon', name: 'Amazon' },
582
+ { match: 'attentive', name: 'Attentive' },
583
+ ];
584
+ const OFFLINE_TOUCH = 'Blotout_Offline';
585
+ new Set([
586
+ ...CLICK_IDS.map((c) => c.label),
587
+ ...Object.values(UTM_SOURCE_EXACT),
588
+ ...UTM_SOURCE_PARTIAL.map((e) => e.name),
589
+ ...ORGANIC_SEARCH_ENGINES.map((e) => `Organic Search - ${e.name}`),
590
+ ...KNOWN_REFERRAL_PLATFORMS.map((e) => `Referral - ${e.name}`),
591
+ 'Referral - Other',
592
+ 'Direct Traffic',
593
+ 'Other',
594
+ OFFLINE_TOUCH,
595
+ ]);
596
+
442
597
  const prepareData = (data) => {
443
598
  const payload = {};
444
599
  if (data['value'] || data['value'] === 0) {
@@ -484,7 +639,7 @@ const prepareData = (data) => {
484
639
  };
485
640
  const tag = ({ data, eventName, manifestVariables, eventId }) => {
486
641
  const payload = {
487
- sdkVersion: "1.53.1" ,
642
+ sdkVersion: "1.54.0" ,
488
643
  };
489
644
  const windowWithAH = window;
490
645
  if (windowWithAH.ahTrack &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotoutio/providers-audiohook-sdk",
3
- "version": "1.53.1",
3
+ "version": "1.54.0",
4
4
  "description": "Audiohook Browser SDK for EdgeTag",
5
5
  "author": "Blotout",
6
6
  "license": "MIT",