saasco-sdk 0.2.3 → 0.2.5
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/README.md +974 -0
- package/dist/index.cjs +189 -138
- package/dist/index.d.cts +45 -57
- package/dist/index.d.ts +45 -57
- package/dist/index.js +188 -137
- package/dist/{support-chat.cjs → support.cjs} +3579 -2088
- package/dist/{support-chat.d.cts → support.d.cts} +39 -29
- package/dist/{support-chat.d.ts → support.d.ts} +39 -29
- package/dist/{support-chat.js → support.js} +3526 -2035
- package/package.json +34 -9
package/dist/index.cjs
CHANGED
|
@@ -20,9 +20,9 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
BrowserContextSchema: () => BrowserContextSchema,
|
|
23
24
|
IntegrationManager: () => IntegrationManager,
|
|
24
25
|
Saasco: () => Saasco,
|
|
25
|
-
browserContextSchema: () => browserContextSchema,
|
|
26
26
|
createFacebookPixelIntegration: () => createFacebookPixelIntegration,
|
|
27
27
|
createPinterestTagIntegration: () => createPinterestTagIntegration,
|
|
28
28
|
createTikTokPixelIntegration: () => createTikTokPixelIntegration,
|
|
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
38
38
|
var import_psl = require("psl");
|
|
39
39
|
|
|
40
40
|
// package.json
|
|
41
|
-
var version = "0.2.
|
|
41
|
+
var version = "0.2.5";
|
|
42
42
|
|
|
43
43
|
// src/lib/timezones.ts
|
|
44
44
|
var timezones = {
|
|
@@ -487,6 +487,9 @@ var AnalyticsLogger = class {
|
|
|
487
487
|
constructor(config) {
|
|
488
488
|
this.config = config;
|
|
489
489
|
}
|
|
490
|
+
setLevel(level) {
|
|
491
|
+
this.config.level = level;
|
|
492
|
+
}
|
|
490
493
|
debug(...args) {
|
|
491
494
|
if (this.config.level < 3 /* DEBUG */) {
|
|
492
495
|
return;
|
|
@@ -567,9 +570,34 @@ function getIntegrationLoggerLevel(integrationName, debug) {
|
|
|
567
570
|
}
|
|
568
571
|
|
|
569
572
|
// src/lib/utils/uuid.ts
|
|
570
|
-
var
|
|
573
|
+
var HEX = [];
|
|
574
|
+
for (let i = 0; i < 256; i++) {
|
|
575
|
+
HEX[i] = (i + 256).toString(16).slice(1);
|
|
576
|
+
}
|
|
571
577
|
function uuid() {
|
|
572
|
-
|
|
578
|
+
const bytes = randomBytes(16);
|
|
579
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
580
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
581
|
+
let out = "";
|
|
582
|
+
for (let i = 0; i < 16; i++) {
|
|
583
|
+
out += HEX[bytes[i]];
|
|
584
|
+
if (i === 3 || i === 5 || i === 7 || i === 9) {
|
|
585
|
+
out += "-";
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return out;
|
|
589
|
+
}
|
|
590
|
+
function randomBytes(length) {
|
|
591
|
+
const bytes = new Uint8Array(length);
|
|
592
|
+
const webCrypto = globalThis.crypto;
|
|
593
|
+
if (typeof webCrypto?.getRandomValues === "function") {
|
|
594
|
+
webCrypto.getRandomValues(bytes);
|
|
595
|
+
return bytes;
|
|
596
|
+
}
|
|
597
|
+
for (let i = 0; i < length; i++) {
|
|
598
|
+
bytes[i] = Math.random() * 256 | 0;
|
|
599
|
+
}
|
|
600
|
+
return bytes;
|
|
573
601
|
}
|
|
574
602
|
|
|
575
603
|
// src/lib/getBrowserContext.ts
|
|
@@ -1875,6 +1903,41 @@ function normalizeSaascoUrl(url) {
|
|
|
1875
1903
|
return parsed.toString();
|
|
1876
1904
|
}
|
|
1877
1905
|
|
|
1906
|
+
// src/lib/widgetLoader.ts
|
|
1907
|
+
function isEnabledPayload(data2) {
|
|
1908
|
+
return typeof data2 === "object" && data2 !== null && "enabled" in data2 && data2.enabled === true;
|
|
1909
|
+
}
|
|
1910
|
+
function getUrlOrigin(url) {
|
|
1911
|
+
try {
|
|
1912
|
+
return new URL(
|
|
1913
|
+
url,
|
|
1914
|
+
typeof window === "undefined" ? void 0 : window.location.href
|
|
1915
|
+
).origin;
|
|
1916
|
+
} catch {
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
function isLoaderPresent(fileName, injectedFlag) {
|
|
1920
|
+
return Boolean(
|
|
1921
|
+
injectedFlag || document.querySelector(`script[src*="${fileName}"]`)
|
|
1922
|
+
);
|
|
1923
|
+
}
|
|
1924
|
+
function appendLoaderScript({
|
|
1925
|
+
attributes,
|
|
1926
|
+
onLoad,
|
|
1927
|
+
src
|
|
1928
|
+
}) {
|
|
1929
|
+
const script = document.createElement("script");
|
|
1930
|
+
script.async = true;
|
|
1931
|
+
script.src = src;
|
|
1932
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
1933
|
+
script.setAttribute(name, value);
|
|
1934
|
+
}
|
|
1935
|
+
if (onLoad) {
|
|
1936
|
+
script.addEventListener("load", onLoad);
|
|
1937
|
+
}
|
|
1938
|
+
(document.body ?? document.head ?? document.documentElement).append(script);
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1878
1941
|
// src/lib/social-proof/storage.ts
|
|
1879
1942
|
var WIDGET_PAYLOAD_PATH = "/api/social-proof/widget";
|
|
1880
1943
|
var SOCIAL_PROOF_LOADER_FILE = "saasco-social-proof-loader.js";
|
|
@@ -1954,17 +2017,16 @@ async function injectSocialProofLoader({
|
|
|
1954
2017
|
return;
|
|
1955
2018
|
}
|
|
1956
2019
|
window.__saascoSocialProofInjected = true;
|
|
1957
|
-
const
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
script.setAttribute("data-projectId", projectId);
|
|
2020
|
+
const attributes = {
|
|
2021
|
+
"data-projectId": projectId
|
|
2022
|
+
};
|
|
1961
2023
|
if (baseUrlOverride !== void 0) {
|
|
1962
|
-
|
|
1963
|
-
"data-base-url",
|
|
1964
|
-
normalizeSaascoBaseUrl(baseUrlOverride)
|
|
1965
|
-
);
|
|
2024
|
+
attributes["data-base-url"] = normalizeSaascoBaseUrl(baseUrlOverride);
|
|
1966
2025
|
}
|
|
1967
|
-
(
|
|
2026
|
+
appendLoaderScript({
|
|
2027
|
+
attributes,
|
|
2028
|
+
src: normalizeSaascoUrl(scriptUrl)
|
|
2029
|
+
});
|
|
1968
2030
|
}
|
|
1969
2031
|
async function shouldInjectSocialProof({
|
|
1970
2032
|
baseUrl,
|
|
@@ -1993,23 +2055,12 @@ async function shouldInjectSocialProof({
|
|
|
1993
2055
|
writeSession(cacheKey, JSON.stringify({ data: data2, fetchedAt: Date.now() }));
|
|
1994
2056
|
return isEnabledPayload(data2);
|
|
1995
2057
|
}
|
|
1996
|
-
function isEnabledPayload(data2) {
|
|
1997
|
-
return typeof data2 === "object" && data2 !== null && data2.enabled === true;
|
|
1998
|
-
}
|
|
1999
2058
|
function isSocialProofLoaderPresent() {
|
|
2000
|
-
return
|
|
2001
|
-
|
|
2059
|
+
return isLoaderPresent(
|
|
2060
|
+
SOCIAL_PROOF_LOADER_FILE,
|
|
2061
|
+
window.__saascoSocialProofInjected
|
|
2002
2062
|
);
|
|
2003
2063
|
}
|
|
2004
|
-
function getUrlOrigin(url) {
|
|
2005
|
-
try {
|
|
2006
|
-
return new URL(
|
|
2007
|
-
url,
|
|
2008
|
-
typeof window === "undefined" ? void 0 : window.location.href
|
|
2009
|
-
).origin;
|
|
2010
|
-
} catch {
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
2064
|
function isSocialProofQaMode() {
|
|
2014
2065
|
if (typeof window === "undefined") {
|
|
2015
2066
|
return false;
|
|
@@ -2024,19 +2075,81 @@ function isSocialProofQaMode() {
|
|
|
2024
2075
|
}
|
|
2025
2076
|
}
|
|
2026
2077
|
|
|
2078
|
+
// src/lib/support/widgetEnabledCheck.ts
|
|
2079
|
+
var SUPPORT_WIDGET_PATH = "/api/support/widget";
|
|
2080
|
+
var SUPPORT_LOADER_FILE = "saasco-support-loader.js";
|
|
2081
|
+
async function injectSupportLoader({
|
|
2082
|
+
baseUrl: baseUrlOverride,
|
|
2083
|
+
onLoad,
|
|
2084
|
+
placeholder,
|
|
2085
|
+
projectId,
|
|
2086
|
+
scriptUrl
|
|
2087
|
+
}) {
|
|
2088
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2089
|
+
return "skipped";
|
|
2090
|
+
}
|
|
2091
|
+
if (isSupportLoaderPresent()) {
|
|
2092
|
+
return "present";
|
|
2093
|
+
}
|
|
2094
|
+
const baseUrl = normalizeSaascoBaseUrl(
|
|
2095
|
+
baseUrlOverride ?? getUrlOrigin(scriptUrl) ?? SAASCO_ORIGIN
|
|
2096
|
+
);
|
|
2097
|
+
const enabled = await shouldInjectSupport({
|
|
2098
|
+
baseUrl,
|
|
2099
|
+
projectId
|
|
2100
|
+
});
|
|
2101
|
+
if (!enabled) {
|
|
2102
|
+
return "skipped";
|
|
2103
|
+
}
|
|
2104
|
+
if (isSupportLoaderPresent()) {
|
|
2105
|
+
return "present";
|
|
2106
|
+
}
|
|
2107
|
+
window.__saascoSupportInjected = true;
|
|
2108
|
+
const attributes = {
|
|
2109
|
+
"data-projectId": projectId
|
|
2110
|
+
};
|
|
2111
|
+
if (baseUrlOverride !== void 0) {
|
|
2112
|
+
attributes["data-base-url"] = normalizeSaascoBaseUrl(baseUrlOverride);
|
|
2113
|
+
}
|
|
2114
|
+
if (placeholder !== void 0) {
|
|
2115
|
+
attributes["data-placeholder"] = placeholder;
|
|
2116
|
+
}
|
|
2117
|
+
appendLoaderScript({
|
|
2118
|
+
attributes,
|
|
2119
|
+
onLoad,
|
|
2120
|
+
src: normalizeSaascoUrl(scriptUrl)
|
|
2121
|
+
});
|
|
2122
|
+
return "injected";
|
|
2123
|
+
}
|
|
2124
|
+
async function shouldInjectSupport({
|
|
2125
|
+
baseUrl,
|
|
2126
|
+
projectId
|
|
2127
|
+
}) {
|
|
2128
|
+
try {
|
|
2129
|
+
const response = await fetch(
|
|
2130
|
+
`${baseUrl}${SUPPORT_WIDGET_PATH}?projectId=${encodeURIComponent(projectId)}`
|
|
2131
|
+
);
|
|
2132
|
+
if (!response.ok) {
|
|
2133
|
+
return false;
|
|
2134
|
+
}
|
|
2135
|
+
return isEnabledPayload(await response.json());
|
|
2136
|
+
} catch {
|
|
2137
|
+
return false;
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
function isSupportLoaderPresent() {
|
|
2141
|
+
return isLoaderPresent(SUPPORT_LOADER_FILE, window.__saascoSupportInjected);
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2027
2144
|
// src/lib/analytics.ts
|
|
2028
|
-
function
|
|
2029
|
-
return window.
|
|
2145
|
+
function getSupportGlobal() {
|
|
2146
|
+
return window.SaascoSupport;
|
|
2030
2147
|
}
|
|
2031
2148
|
var isBrowser5 = typeof window !== "undefined";
|
|
2032
2149
|
var isServer5 = !isBrowser5;
|
|
2033
2150
|
var PREF = "saasco-sdk";
|
|
2034
2151
|
var SESSION_DURATION = 1e3 * 60 * 30;
|
|
2035
2152
|
var USER_DURATION = 1e3 * 60 * 60 * 24 * 365;
|
|
2036
|
-
var SUPPORT_CHAT_ATTR_MAP = {
|
|
2037
|
-
baseUrl: "data-base-url",
|
|
2038
|
-
placeholder: "data-placeholder"
|
|
2039
|
-
};
|
|
2040
2153
|
var data = {};
|
|
2041
2154
|
function getRootDomain(url) {
|
|
2042
2155
|
if (isServer5) {
|
|
@@ -2204,7 +2317,7 @@ function getUserId() {
|
|
|
2204
2317
|
function setUserId(userId) {
|
|
2205
2318
|
storeData(`user-id`, userId ?? void 0, USER_DURATION);
|
|
2206
2319
|
}
|
|
2207
|
-
function
|
|
2320
|
+
function buildSupportTraits(properties, envelope) {
|
|
2208
2321
|
const traits = {};
|
|
2209
2322
|
const add = (key, value) => {
|
|
2210
2323
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
@@ -2325,7 +2438,7 @@ var Saasco = class {
|
|
|
2325
2438
|
* @param config Configuration options.
|
|
2326
2439
|
* @param config.projectId The unique identifier for the project.
|
|
2327
2440
|
* @param config.proxy The URL of the proxy server to use, if any.
|
|
2328
|
-
* @param config.autoPageTracking Whether to automatically track page views. Default is
|
|
2441
|
+
* @param config.autoPageTracking Whether to automatically track page views. Default is true.
|
|
2329
2442
|
* @param config.enabled Whether analytics is enabled. Default is true. Set to false for development and staging envioronments. Will still allow debug mode to be true, just no events will be sent
|
|
2330
2443
|
* @param config.debug Whether to log debug information. Default is false.
|
|
2331
2444
|
* @param config.trackUrlParams Whether to track URL parameters. Default is true.
|
|
@@ -2374,10 +2487,10 @@ var Saasco = class {
|
|
|
2374
2487
|
integrationManager;
|
|
2375
2488
|
logger;
|
|
2376
2489
|
// Last identity handed to `identify()`, mirrored into the lazily-loaded
|
|
2377
|
-
// support
|
|
2490
|
+
// support widget so chat conversations attach to a CRM contact. Held
|
|
2378
2491
|
// here so an `identify()` that fires before the widget bundle finishes
|
|
2379
2492
|
// loading is replayed once it does.
|
|
2380
|
-
|
|
2493
|
+
lastSupportIdentity = null;
|
|
2381
2494
|
init() {
|
|
2382
2495
|
if (this.isInitialized) {
|
|
2383
2496
|
this.logger.info(
|
|
@@ -2401,52 +2514,20 @@ var Saasco = class {
|
|
|
2401
2514
|
);
|
|
2402
2515
|
}
|
|
2403
2516
|
this.initAutoPageTracking();
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
}
|
|
2407
|
-
if (this.config.socialProof?.enabled !== false) {
|
|
2408
|
-
void this.injectSocialProof();
|
|
2409
|
-
}
|
|
2517
|
+
void this.injectSupport();
|
|
2518
|
+
void this.injectSocialProof();
|
|
2410
2519
|
this.isInitialized = true;
|
|
2411
2520
|
}
|
|
2412
2521
|
disableDebug() {
|
|
2413
2522
|
this.logger.info("Debug mode deactivated.");
|
|
2414
2523
|
this.config.debug = false;
|
|
2524
|
+
this.logger.setLevel(getLoggerLevel(this.config));
|
|
2415
2525
|
}
|
|
2416
2526
|
enableDebug() {
|
|
2417
2527
|
this.config.debug = true;
|
|
2528
|
+
this.logger.setLevel(getLoggerLevel(this.config));
|
|
2418
2529
|
this.logger.info("Debug mode activated.");
|
|
2419
2530
|
}
|
|
2420
|
-
/**
|
|
2421
|
-
* Enables and injects the support chat widget when it was constructed with
|
|
2422
|
-
* `supportChat: { enabled: false }`. Safe to call multiple times.
|
|
2423
|
-
*/
|
|
2424
|
-
enableSupportChat() {
|
|
2425
|
-
if (!this.config.supportChat) {
|
|
2426
|
-
this.logger.warn(
|
|
2427
|
-
"Support chat is not configured; enableSupportChat() was ignored."
|
|
2428
|
-
);
|
|
2429
|
-
return;
|
|
2430
|
-
}
|
|
2431
|
-
this.config.supportChat.enabled = true;
|
|
2432
|
-
this.injectSupportChat();
|
|
2433
|
-
this.pushSupportChatIdentity();
|
|
2434
|
-
}
|
|
2435
|
-
/**
|
|
2436
|
-
* Enables and injects the social-proof widget (e.g. after constructing with
|
|
2437
|
-
* `socialProof: { enabled: false }`, or when no `socialProof` block was
|
|
2438
|
-
* passed). Injection still runs the server check, so the loader only
|
|
2439
|
-
* downloads when the project has the app enabled in the dashboard.
|
|
2440
|
-
* Safe to call multiple times — the loader injection is guarded against
|
|
2441
|
-
* double-injection.
|
|
2442
|
-
*/
|
|
2443
|
-
enableSocialProof() {
|
|
2444
|
-
this.config.socialProof = {
|
|
2445
|
-
...this.config.socialProof,
|
|
2446
|
-
enabled: true
|
|
2447
|
-
};
|
|
2448
|
-
void this.injectSocialProof();
|
|
2449
|
-
}
|
|
2450
2531
|
/**
|
|
2451
2532
|
* Initialize third-party integrations
|
|
2452
2533
|
*/
|
|
@@ -2563,7 +2644,7 @@ var Saasco = class {
|
|
|
2563
2644
|
}
|
|
2564
2645
|
/**
|
|
2565
2646
|
* The page method lets you record page views on your website
|
|
2566
|
-
* This records the page title and path and names the event
|
|
2647
|
+
* This records the page title and path and names the event using the reserved name "Page View"
|
|
2567
2648
|
*
|
|
2568
2649
|
* Before implementing this make sure you have disabled the autoPageTracking in the config or you will get duplicate page views
|
|
2569
2650
|
*/
|
|
@@ -2609,13 +2690,13 @@ var Saasco = class {
|
|
|
2609
2690
|
reset: userIdChangedToNull
|
|
2610
2691
|
});
|
|
2611
2692
|
setUserId(distinctId);
|
|
2612
|
-
this.
|
|
2693
|
+
this.updateSupportIdentity({
|
|
2613
2694
|
distinctId: hasId && distinctId !== null ? distinctId : void 0,
|
|
2614
2695
|
email: typeof properties?.["email"] === "string" ? properties["email"] : void 0,
|
|
2615
2696
|
// Forward the full scalar payload (browser/track context + identify traits
|
|
2616
2697
|
// + session envelope) so the widget can bind them via live context without
|
|
2617
2698
|
// the host mirroring traits into `setStateSnapshot`.
|
|
2618
|
-
traits:
|
|
2699
|
+
traits: buildSupportTraits(properties, { anonymousId, sessionId })
|
|
2619
2700
|
});
|
|
2620
2701
|
this.integrationManager.setContext({
|
|
2621
2702
|
distinctId,
|
|
@@ -2787,51 +2868,25 @@ Request Data: ${JSON.stringify(requestData, null, 2)}`
|
|
|
2787
2868
|
return this.integrationManager.getStats();
|
|
2788
2869
|
}
|
|
2789
2870
|
/**
|
|
2790
|
-
* Lazily injects the support
|
|
2791
|
-
*
|
|
2792
|
-
* config as `data-*` attributes. The loader (no React) injects the
|
|
2793
|
-
* cross-origin embed iframe. Deferred (`async`) and guarded against
|
|
2794
|
-
* double-injection so re-running `init()` is a no-op.
|
|
2871
|
+
* Lazily injects the support **loader** (server-gated). See
|
|
2872
|
+
* {@link injectSupportLoader}. Replays identity once the script loads.
|
|
2795
2873
|
*/
|
|
2796
|
-
|
|
2797
|
-
if (!isBrowser5
|
|
2798
|
-
return;
|
|
2799
|
-
}
|
|
2800
|
-
const chat = this.config.supportChat;
|
|
2801
|
-
if (!chat) {
|
|
2802
|
-
return;
|
|
2803
|
-
}
|
|
2804
|
-
if (window.__saascoSupportChatInjected || document.querySelector('script[src*="saasco-support-chat-loader.js"]')) {
|
|
2805
|
-
return;
|
|
2806
|
-
}
|
|
2807
|
-
const scriptUrl = resolveLoaderScriptUrl(
|
|
2808
|
-
"saasco-support-chat-loader.js",
|
|
2809
|
-
chat.scriptUrl
|
|
2810
|
-
);
|
|
2811
|
-
if (!scriptUrl) {
|
|
2812
|
-
this.logger.warn(
|
|
2813
|
-
"Support chat is enabled but the loader URL could not be resolved. Pass `supportChat.scriptUrl` pointing at your hosted saasco-support-chat-loader.js (or load the analytics SDK from the CDN)."
|
|
2814
|
-
);
|
|
2874
|
+
async injectSupport() {
|
|
2875
|
+
if (!isBrowser5) {
|
|
2815
2876
|
return;
|
|
2816
2877
|
}
|
|
2817
|
-
|
|
2818
|
-
const
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
script.setAttribute(
|
|
2826
|
-
attr,
|
|
2827
|
-
attr === "data-base-url" ? normalizeSaascoBaseUrl(value) : value
|
|
2828
|
-
);
|
|
2829
|
-
}
|
|
2830
|
-
}
|
|
2831
|
-
script.addEventListener("load", () => {
|
|
2832
|
-
this.pushSupportChatIdentity();
|
|
2878
|
+
const { support } = this.config;
|
|
2879
|
+
const scriptUrl = resolveLoaderScriptUrl("saasco-support-loader.js", support?.scriptUrl) ?? `${SAASCO_ORIGIN}/sdk/saasco-support-loader.js`;
|
|
2880
|
+
const result = await injectSupportLoader({
|
|
2881
|
+
baseUrl: support?.baseUrl,
|
|
2882
|
+
onLoad: () => this.pushSupportIdentity(),
|
|
2883
|
+
placeholder: support?.placeholder,
|
|
2884
|
+
projectId: this.config.projectId,
|
|
2885
|
+
scriptUrl
|
|
2833
2886
|
});
|
|
2834
|
-
(
|
|
2887
|
+
if (result === "present") {
|
|
2888
|
+
this.pushSupportIdentity();
|
|
2889
|
+
}
|
|
2835
2890
|
}
|
|
2836
2891
|
/**
|
|
2837
2892
|
* Lazily injects the social-proof loader (server-gated). See
|
|
@@ -2853,42 +2908,38 @@ Request Data: ${JSON.stringify(requestData, null, 2)}`
|
|
|
2853
2908
|
});
|
|
2854
2909
|
}
|
|
2855
2910
|
/**
|
|
2856
|
-
* Records the latest CRM identity and forwards it to the support
|
|
2857
|
-
* No-op when support chat isn't enabled.
|
|
2911
|
+
* Records the latest CRM identity and forwards it to the support widget.
|
|
2858
2912
|
*/
|
|
2859
|
-
|
|
2860
|
-
if (!isBrowser5
|
|
2913
|
+
updateSupportIdentity(identity) {
|
|
2914
|
+
if (!isBrowser5) {
|
|
2861
2915
|
return;
|
|
2862
2916
|
}
|
|
2863
2917
|
const hasTraits = identity.traits && Object.keys(identity.traits).length > 0;
|
|
2864
|
-
this.
|
|
2865
|
-
|
|
2866
|
-
return;
|
|
2867
|
-
}
|
|
2868
|
-
this.pushSupportChatIdentity();
|
|
2918
|
+
this.lastSupportIdentity = identity.distinctId || identity.email || hasTraits ? identity : null;
|
|
2919
|
+
this.pushSupportIdentity();
|
|
2869
2920
|
}
|
|
2870
2921
|
/**
|
|
2871
|
-
* Pushes the current identity onto `window.
|
|
2922
|
+
* Pushes the current identity onto `window.SaascoSupport.identify`. The
|
|
2872
2923
|
* widget bundle publishes that global asynchronously, so this short-polls for
|
|
2873
|
-
* it (same approach as tool registration)
|
|
2874
|
-
*
|
|
2924
|
+
* it (same approach as tool registration). `injectSupport` calls this on
|
|
2925
|
+
* script load (or immediately when the loader is already present).
|
|
2875
2926
|
*/
|
|
2876
|
-
|
|
2877
|
-
if (!isBrowser5
|
|
2927
|
+
pushSupportIdentity() {
|
|
2928
|
+
if (!isBrowser5) {
|
|
2878
2929
|
return;
|
|
2879
2930
|
}
|
|
2880
|
-
const identity = this.
|
|
2931
|
+
const identity = this.lastSupportIdentity ?? {
|
|
2881
2932
|
distinctId: getUserId() ?? void 0,
|
|
2882
2933
|
// Anonymous (pre-identify) page load: still forward browser/track context
|
|
2883
2934
|
// and the session envelope so live context has them from the first turn.
|
|
2884
|
-
traits:
|
|
2935
|
+
traits: buildSupportTraits(void 0, {
|
|
2885
2936
|
anonymousId: getAnonymousId() ?? void 0,
|
|
2886
2937
|
sessionId: getSessionId() ?? void 0
|
|
2887
2938
|
})
|
|
2888
2939
|
};
|
|
2889
2940
|
let attempts = 0;
|
|
2890
2941
|
const tryPush = () => {
|
|
2891
|
-
const api =
|
|
2942
|
+
const api = getSupportGlobal();
|
|
2892
2943
|
if (!api) {
|
|
2893
2944
|
attempts += 1;
|
|
2894
2945
|
if (attempts > 40) {
|
|
@@ -2901,7 +2952,7 @@ Request Data: ${JSON.stringify(requestData, null, 2)}`
|
|
|
2901
2952
|
api.identify(identity);
|
|
2902
2953
|
} catch (error) {
|
|
2903
2954
|
this.logger.warn(
|
|
2904
|
-
"Failed to forward identity to the support
|
|
2955
|
+
"Failed to forward identity to the support widget:",
|
|
2905
2956
|
error
|
|
2906
2957
|
);
|
|
2907
2958
|
}
|
|
@@ -3000,9 +3051,9 @@ function getLoggerLevel(config) {
|
|
|
3000
3051
|
return effectiveDebugVerbose ? 3 /* DEBUG */ : effectiveDebug ? 2 /* INFO */ : 0 /* ERROR */;
|
|
3001
3052
|
}
|
|
3002
3053
|
|
|
3003
|
-
// src/lib/
|
|
3054
|
+
// ../shared/src/lib/types/browserContext.ts
|
|
3004
3055
|
var import_zod = require("zod");
|
|
3005
|
-
var
|
|
3056
|
+
var BrowserContextSchema = import_zod.z.object({
|
|
3006
3057
|
$href: import_zod.z.string(),
|
|
3007
3058
|
$locale: import_zod.z.string(),
|
|
3008
3059
|
$location: import_zod.z.string(),
|
|
@@ -3029,9 +3080,9 @@ var browserContextSchema = import_zod.z.object({
|
|
|
3029
3080
|
});
|
|
3030
3081
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3031
3082
|
0 && (module.exports = {
|
|
3083
|
+
BrowserContextSchema,
|
|
3032
3084
|
IntegrationManager,
|
|
3033
3085
|
Saasco,
|
|
3034
|
-
browserContextSchema,
|
|
3035
3086
|
createFacebookPixelIntegration,
|
|
3036
3087
|
createPinterestTagIntegration,
|
|
3037
3088
|
createTikTokPixelIntegration,
|