@xapp/chat-widget 1.110.0 → 1.111.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/dist/index.css +1 -1
- package/dist/index.es.js +131 -12
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +131 -12
- package/dist/index.js.map +1 -1
- package/dist/xapp-chat-widget.css +1 -1
- package/dist/xapp-chat-widget.js +4 -4
- package/dist/xapp-chat-widget.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -3616,6 +3616,115 @@ function stripQueryString(url) {
|
|
|
3616
3616
|
return undefined;
|
|
3617
3617
|
}
|
|
3618
3618
|
}
|
|
3619
|
+
|
|
3620
|
+
/**
|
|
3621
|
+
* Google Analytics 4 ids for chat leads.
|
|
3622
|
+
*
|
|
3623
|
+
* A form lead's `generate_lead` can go out from the browser, but a chat lead is only
|
|
3624
|
+
* ever sent by the backend's Measurement Protocol integration. Without the visitor's
|
|
3625
|
+
* GA client and session ids that event matches no browser session, and GA4 credits
|
|
3626
|
+
* it to Direct / Unassigned. These are sent as chat attributes so the backend can
|
|
3627
|
+
* credit the lead to the traffic source that brought the visitor.
|
|
3628
|
+
*
|
|
3629
|
+
* Only the ids GA itself set are read; nothing here is PII.
|
|
3630
|
+
*/
|
|
3631
|
+
var SESSION_COOKIE_PREFIX = "_ga_";
|
|
3632
|
+
/**
|
|
3633
|
+
* Extracts the GA4 client id from a `_ga` cookie value: `GA1.1.<rand>.<ts>` ->
|
|
3634
|
+
* `<rand>.<ts>`.
|
|
3635
|
+
*/
|
|
3636
|
+
function parseGaClientId(cookie) {
|
|
3637
|
+
var parts = (cookie === null || cookie === void 0 ? void 0 : cookie.split(".")) || [];
|
|
3638
|
+
if (parts.length < 4) {
|
|
3639
|
+
return undefined;
|
|
3640
|
+
}
|
|
3641
|
+
var clientId = parts.slice(-2).join(".");
|
|
3642
|
+
return /^\d+\.\d+$/.test(clientId) ? clientId : undefined;
|
|
3643
|
+
}
|
|
3644
|
+
/**
|
|
3645
|
+
* Extracts the session id from a `_ga_<stream>` cookie value. Handles both the legacy
|
|
3646
|
+
* `GS1.1.<sid>.<n>...` format and the 2025 `GS2.1.s<sid>$o3$...` format.
|
|
3647
|
+
*/
|
|
3648
|
+
function parseGaSessionId(cookie) {
|
|
3649
|
+
var parts = (cookie === null || cookie === void 0 ? void 0 : cookie.split(".")) || [];
|
|
3650
|
+
if (parts.length < 3) {
|
|
3651
|
+
return undefined;
|
|
3652
|
+
}
|
|
3653
|
+
var sessionId;
|
|
3654
|
+
if (parts[0] === "GS2") {
|
|
3655
|
+
var token = parts[2].split("$").find(function (t) { return t.startsWith("s"); });
|
|
3656
|
+
sessionId = token === null || token === void 0 ? void 0 : token.slice(1);
|
|
3657
|
+
}
|
|
3658
|
+
else {
|
|
3659
|
+
sessionId = parts[2];
|
|
3660
|
+
}
|
|
3661
|
+
return sessionId && /^\d+$/.test(sessionId) ? sessionId : undefined;
|
|
3662
|
+
}
|
|
3663
|
+
function hasGlobalPrivacyControlOptOut() {
|
|
3664
|
+
if (typeof navigator === "undefined") {
|
|
3665
|
+
return false;
|
|
3666
|
+
}
|
|
3667
|
+
return (navigator.globalPrivacyControl === true);
|
|
3668
|
+
}
|
|
3669
|
+
function readCookies() {
|
|
3670
|
+
var cookies = {};
|
|
3671
|
+
if (typeof document === "undefined" || !document.cookie) {
|
|
3672
|
+
return cookies;
|
|
3673
|
+
}
|
|
3674
|
+
for (var _i = 0, _a = document.cookie.split(";"); _i < _a.length; _i++) {
|
|
3675
|
+
var pair = _a[_i];
|
|
3676
|
+
var index = pair.indexOf("=");
|
|
3677
|
+
if (index < 0) {
|
|
3678
|
+
continue;
|
|
3679
|
+
}
|
|
3680
|
+
var name_1 = pair.slice(0, index).trim();
|
|
3681
|
+
var raw = pair.slice(index + 1).trim();
|
|
3682
|
+
try {
|
|
3683
|
+
cookies[name_1] = decodeURIComponent(raw);
|
|
3684
|
+
}
|
|
3685
|
+
catch (_b) {
|
|
3686
|
+
// A stray "%" from another script must not break the chat.
|
|
3687
|
+
cookies[name_1] = raw;
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
return cookies;
|
|
3691
|
+
}
|
|
3692
|
+
/**
|
|
3693
|
+
* The GA4 attributes to send with a chat message. Under Global Privacy Control only
|
|
3694
|
+
* the opt-out flag is sent. Never throws.
|
|
3695
|
+
*/
|
|
3696
|
+
function getGa4Attributes() {
|
|
3697
|
+
try {
|
|
3698
|
+
if (hasGlobalPrivacyControlOptOut()) {
|
|
3699
|
+
return { ga4OptOut: true };
|
|
3700
|
+
}
|
|
3701
|
+
var cookies = readCookies();
|
|
3702
|
+
var attributes = {};
|
|
3703
|
+
var gaClientId = parseGaClientId(cookies["_ga"]);
|
|
3704
|
+
if (gaClientId) {
|
|
3705
|
+
attributes.gaClientId = gaClientId;
|
|
3706
|
+
}
|
|
3707
|
+
var gaSessionIds = {};
|
|
3708
|
+
for (var _i = 0, _a = Object.entries(cookies); _i < _a.length; _i++) {
|
|
3709
|
+
var _b = _a[_i], name_2 = _b[0], value = _b[1];
|
|
3710
|
+
if (!name_2.startsWith(SESSION_COOKIE_PREFIX)) {
|
|
3711
|
+
continue;
|
|
3712
|
+
}
|
|
3713
|
+
var stream = name_2.slice(SESSION_COOKIE_PREFIX.length);
|
|
3714
|
+
var sessionId = parseGaSessionId(value);
|
|
3715
|
+
if (/^[A-Z0-9]+$/i.test(stream) && sessionId) {
|
|
3716
|
+
gaSessionIds[stream] = sessionId;
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
if (Object.keys(gaSessionIds).length > 0) {
|
|
3720
|
+
attributes.gaSessionIds = gaSessionIds;
|
|
3721
|
+
}
|
|
3722
|
+
return attributes;
|
|
3723
|
+
}
|
|
3724
|
+
catch (_c) {
|
|
3725
|
+
return {};
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3619
3728
|
/**
|
|
3620
3729
|
* A minimal client for the tenant's homeowner MCP endpoint: one `tools/call` per request, no
|
|
3621
3730
|
* session. The endpoint is public and the server keeps no state we need, so the MCP
|
|
@@ -4001,6 +4110,7 @@ var SuggestionsList_1 = SuggestionsList;
|
|
|
4001
4110
|
var addTestLeadAttribute_1 = addTestLeadAttribute;
|
|
4002
4111
|
var findItemByIndex_1 = findItemByIndex;
|
|
4003
4112
|
var getAttribution_1 = getAttribution;
|
|
4113
|
+
var getGa4Attributes_1 = getGa4Attributes;
|
|
4004
4114
|
var getItemsLength_1 = getItemsLength;
|
|
4005
4115
|
var parseSuggestionsResponse_1 = parseSuggestionsResponse;
|
|
4006
4116
|
var stripQueryString_1 = stripQueryString;
|
|
@@ -6579,16 +6689,25 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
6579
6689
|
StentorDirectChat.prototype.wakeup = function () { };
|
|
6580
6690
|
StentorDirectChat.prototype.postMessage = function (message) {
|
|
6581
6691
|
return __awaiter$1(this, void 0, void 0, function () {
|
|
6582
|
-
var request, userId, sessionId, accessToken, attributes, rwgToken, merchantId, environment, enablePreferredTime, service, origin, now, permissionRequest, expired, text, granted, userProfile, isEmail, configurableMessages, botResponse, successResult, success, fail, i, timeout, responseMessage;
|
|
6692
|
+
var request, userId, sessionId, accessToken, attributes, _i, _a, _b, key, value, rwgToken, merchantId, environment, enablePreferredTime, service, origin, now, permissionRequest, expired, text, granted, userProfile, isEmail, configurableMessages, botResponse, successResult, success, fail, i, timeout, responseMessage;
|
|
6583
6693
|
var _this = this;
|
|
6584
|
-
var
|
|
6585
|
-
return __generator$1(this, function (
|
|
6586
|
-
switch (
|
|
6694
|
+
var _c, _d, _e, _f, _g, _h;
|
|
6695
|
+
return __generator$1(this, function (_j) {
|
|
6696
|
+
switch (_j.label) {
|
|
6587
6697
|
case 0:
|
|
6588
6698
|
userId = this._userId;
|
|
6589
6699
|
sessionId = this._sessionId;
|
|
6590
6700
|
accessToken = this._accessToken;
|
|
6591
6701
|
attributes = mergeAttribution(this._attributes, getAttribution_1());
|
|
6702
|
+
// The visitor's GA client and session ids, so the backend can credit a chat lead
|
|
6703
|
+
// to the traffic source that brought them rather than Direct / Unassigned. Like the
|
|
6704
|
+
// rest of the attribution, a value the host page set itself wins.
|
|
6705
|
+
for (_i = 0, _a = Object.entries(getGa4Attributes_1()); _i < _a.length; _i++) {
|
|
6706
|
+
_b = _a[_i], key = _b[0], value = _b[1];
|
|
6707
|
+
if (((_c = this._attributes) === null || _c === void 0 ? void 0 : _c[key]) === undefined) {
|
|
6708
|
+
attributes[key] = value;
|
|
6709
|
+
}
|
|
6710
|
+
}
|
|
6592
6711
|
rwgToken = localStorage.getItem("xa_rwg_token");
|
|
6593
6712
|
if (rwgToken) {
|
|
6594
6713
|
attributes["rwg_token"] = rwgToken;
|
|
@@ -6618,10 +6737,10 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
6618
6737
|
// Add current time for accurate date/time responses
|
|
6619
6738
|
attributes["currentTime"] = new Date().toISOString();
|
|
6620
6739
|
now = new Date().getTime();
|
|
6621
|
-
if (this.isNewSession && !((
|
|
6740
|
+
if (this.isNewSession && !((_d = message === null || message === void 0 ? void 0 : message.msg) === null || _d === void 0 ? void 0 : _d.text)) {
|
|
6622
6741
|
request = {
|
|
6623
6742
|
type: "LAUNCH_REQUEST",
|
|
6624
|
-
rawQuery: (
|
|
6743
|
+
rawQuery: (_e = message === null || message === void 0 ? void 0 : message.msg) === null || _e === void 0 ? void 0 : _e.text,
|
|
6625
6744
|
sessionId: sessionId,
|
|
6626
6745
|
userId: userId,
|
|
6627
6746
|
isNewSession: true,
|
|
@@ -6633,11 +6752,11 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
6633
6752
|
};
|
|
6634
6753
|
}
|
|
6635
6754
|
else {
|
|
6636
|
-
permissionRequest = (
|
|
6755
|
+
permissionRequest = (_f = message.msg) === null || _f === void 0 ? void 0 : _f.permissionRequest;
|
|
6637
6756
|
if (permissionRequest) {
|
|
6638
6757
|
message = __assign$1(__assign$1({}, message), { msg: __assign$1(__assign$1({}, message.msg), { permissionRequest: undefined }) });
|
|
6639
6758
|
expired = now - permissionRequest.time > PERMISSION_QUESTION_EXPIRATION_MS$1;
|
|
6640
|
-
text = (
|
|
6759
|
+
text = (_g = message.msg.text) === null || _g === void 0 ? void 0 : _g.toLowerCase();
|
|
6641
6760
|
granted = !expired;
|
|
6642
6761
|
userProfile = { id: this._userId };
|
|
6643
6762
|
if (!expired) {
|
|
@@ -6735,7 +6854,7 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
6735
6854
|
});
|
|
6736
6855
|
}); };
|
|
6737
6856
|
i = 1;
|
|
6738
|
-
|
|
6857
|
+
_j.label = 1;
|
|
6739
6858
|
case 1:
|
|
6740
6859
|
if (!(i < configurableMessages.length)) return [3 /*break*/, 4];
|
|
6741
6860
|
timeout = this.config.timeout || 22000;
|
|
@@ -6751,12 +6870,12 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
6751
6870
|
.catch(fail.bind(this, i))];
|
|
6752
6871
|
case 2:
|
|
6753
6872
|
// We don't start typing IF we have a failure message displayed and we are waiting on the timeout
|
|
6754
|
-
|
|
6873
|
+
_j.sent();
|
|
6755
6874
|
// If we have what we want, break the for loop
|
|
6756
6875
|
if (successResult) {
|
|
6757
6876
|
return [3 /*break*/, 4];
|
|
6758
6877
|
}
|
|
6759
|
-
|
|
6878
|
+
_j.label = 3;
|
|
6760
6879
|
case 3:
|
|
6761
6880
|
i++;
|
|
6762
6881
|
return [3 /*break*/, 1];
|
|
@@ -6782,7 +6901,7 @@ var StentorDirectChat = /** @class */ (function () {
|
|
|
6782
6901
|
: "The assistant is not responding right now. Please close the widget and open it again.",
|
|
6783
6902
|
};
|
|
6784
6903
|
}
|
|
6785
|
-
if (typeof ((
|
|
6904
|
+
if (typeof ((_h = this.hooks) === null || _h === void 0 ? void 0 : _h.onResponse) === "function") {
|
|
6786
6905
|
this.hooks.onResponse(botResponse);
|
|
6787
6906
|
}
|
|
6788
6907
|
this.stopTyping();
|