@microsoft/omnichannel-chat-widget 1.8.2-main.5199342 → 1.8.2-main.5a42a08
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 +48 -1
- package/lib/cjs/common/Constants.js +17 -3
- package/lib/cjs/common/telemetry/TelemetryConstants.js +2 -0
- package/lib/cjs/common/utils.js +27 -2
- package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/cjs/components/draggable/DraggableChatWidget.js +16 -1
- package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +54 -1
- package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
- package/lib/cjs/components/livechatwidget/common/endChat.js +18 -7
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +33 -1
- package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +18 -1
- package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +31 -7
- package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +15 -2
- package/lib/cjs/components/livechatwidget/common/startChat.js +6 -4
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -12
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +18 -14
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +4 -3
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +12 -6
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
- package/lib/cjs/contexts/common/CustomEventType.js +1 -0
- package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +3 -1
- package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +3 -1
- package/lib/cjs/contexts/createReducer.js +30 -0
- package/lib/cjs/controller/componentController.js +2 -2
- package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
- package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
- package/lib/cjs/firstresponselatency/util.js +60 -31
- package/lib/cjs/plugins/newMessageEventHandler.js +12 -6
- package/lib/esm/common/Constants.js +15 -2
- package/lib/esm/common/telemetry/TelemetryConstants.js +2 -0
- package/lib/esm/common/utils.js +21 -0
- package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/esm/components/draggable/DraggableChatWidget.js +16 -1
- package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
- package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
- package/lib/esm/components/livechatwidget/common/endChat.js +18 -7
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +33 -1
- package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +16 -0
- package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +33 -9
- package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +16 -3
- package/lib/esm/components/livechatwidget/common/startChat.js +6 -4
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -12
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +18 -14
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +4 -4
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +12 -6
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
- package/lib/esm/contexts/common/CustomEventType.js +1 -0
- package/lib/esm/contexts/common/LiveChatWidgetActionType.js +3 -1
- package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +3 -1
- package/lib/esm/contexts/createReducer.js +30 -0
- package/lib/esm/controller/componentController.js +2 -2
- package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
- package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
- package/lib/esm/firstresponselatency/util.js +57 -29
- package/lib/esm/plugins/newMessageEventHandler.js +12 -6
- package/lib/types/common/Constants.d.ts +14 -2
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +2 -0
- package/lib/types/common/utils.d.ts +8 -0
- package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
- package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +1 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.d.ts +1 -1
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.d.ts +1 -1
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
- package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
- package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +2 -0
- package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
- package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
- package/lib/types/firstresponselatency/util.d.ts +17 -0
- package/lib/types/plugins/newMessageEventHandler.d.ts +1 -1
- package/package.json +4 -4
|
@@ -16,12 +16,16 @@ _defineProperty(Constants, "channelMessageTag", "channel");
|
|
|
16
16
|
_defineProperty(Constants, "historyMessageTag", "history");
|
|
17
17
|
_defineProperty(Constants, "agentEndConversationMessageTag", "agentendconversation");
|
|
18
18
|
_defineProperty(Constants, "supervisorForceCloseMessageTag", "supervisorforceclosedconversation");
|
|
19
|
+
_defineProperty(Constants, "endConversationalSurveyMessageTag", "endconversationalsurvey");
|
|
20
|
+
_defineProperty(Constants, "startConversationalSurveyMessageTag", "startconversationalsurvey");
|
|
21
|
+
_defineProperty(Constants, "c2ConversationalSurveyMessageTag", "c2conversationalsurvey");
|
|
19
22
|
_defineProperty(Constants, "receivedMessageClassName", "ms_lcw_webchat_received_message");
|
|
20
23
|
_defineProperty(Constants, "sentMessageClassName", "ms_lcw_webchat_sent_message");
|
|
21
24
|
_defineProperty(Constants, "webchatChannelId", "webchat");
|
|
22
25
|
_defineProperty(Constants, "markdown", "markdown");
|
|
23
26
|
_defineProperty(Constants, "actionType", "actionType");
|
|
24
27
|
_defineProperty(Constants, "markDownSystemMessageClass", "webchat__basic-transcript__activity-markdown-body");
|
|
28
|
+
_defineProperty(Constants, "MARKDOWN_LIST_INDENTATION", " ");
|
|
25
29
|
_defineProperty(Constants, "String", "string");
|
|
26
30
|
_defineProperty(Constants, "ChatMessagesJson", "chatMessagesJson");
|
|
27
31
|
_defineProperty(Constants, "truePascal", "True");
|
|
@@ -105,8 +109,7 @@ _defineProperty(Constants, "TargetRelationshipAttributes", "noopener noreferrer"
|
|
|
105
109
|
// Markdown icons
|
|
106
110
|
_defineProperty(Constants, "OpenLinkIconCssClass", "webchat__render-markdown__external-link-icon");
|
|
107
111
|
// internet connection test
|
|
108
|
-
_defineProperty(Constants, "
|
|
109
|
-
_defineProperty(Constants, "internetConnectionTestUrlText", "Omnichannel Connect Test");
|
|
112
|
+
_defineProperty(Constants, "internetConnectionTestPath", "/livechatwidget/version.txt");
|
|
110
113
|
_defineProperty(Constants, "ChatWidgetStateChangedPrefix", "ChatWidgetStateChanged");
|
|
111
114
|
_defineProperty(Constants, "PostChatLoadingDurationInMs", 2000);
|
|
112
115
|
_defineProperty(Constants, "BrowserUnloadConfirmationMessage", "Do you want to leave chat?");
|
|
@@ -122,6 +125,12 @@ _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsRespon
|
|
|
122
125
|
_defineProperty(Constants, "OCOriginalMessageId", "OriginalMessageId");
|
|
123
126
|
_defineProperty(Constants, "WebchatSequenceIdAttribute", "webchat:sequence-id");
|
|
124
127
|
_defineProperty(Constants, "MessageSequenceIdOverride", "MessageSequenceIdOverride");
|
|
128
|
+
_defineProperty(Constants, "sendCustomEvent", "sendCustomEvent");
|
|
129
|
+
_defineProperty(Constants, "onCustomEvent", "onCustomEvent");
|
|
130
|
+
_defineProperty(Constants, "customEventName", "customEventName");
|
|
131
|
+
_defineProperty(Constants, "customEventValue", "customEventValue");
|
|
132
|
+
_defineProperty(Constants, "Hidden", "Hidden");
|
|
133
|
+
_defineProperty(Constants, "EndConversationDueToOverflow", "endconversationduetooverflow");
|
|
125
134
|
export const Regex = (_class = /*#__PURE__*/_createClass(function Regex() {
|
|
126
135
|
_classCallCheck(this, Regex);
|
|
127
136
|
}), _defineProperty(_class, "EmailRegex", "^(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\])$"), _class);
|
|
@@ -220,6 +229,10 @@ export let ConversationMode;
|
|
|
220
229
|
ConversationMode["Regular"] = "192350000";
|
|
221
230
|
ConversationMode["Persistent"] = "192350001";
|
|
222
231
|
})(ConversationMode || (ConversationMode = {}));
|
|
232
|
+
export let SurveyProvider;
|
|
233
|
+
(function (SurveyProvider) {
|
|
234
|
+
SurveyProvider["MicrosoftCopilotStudio"] = "600990001";
|
|
235
|
+
})(SurveyProvider || (SurveyProvider = {}));
|
|
223
236
|
export let LiveWorkItemState;
|
|
224
237
|
(function (LiveWorkItemState) {
|
|
225
238
|
LiveWorkItemState["Active"] = "Active";
|
|
@@ -184,6 +184,7 @@ export let TelemetryEvent;
|
|
|
184
184
|
TelemetryEvent["BotAuthActivityUndefinedSignInId"] = "BotAuthActivityUndefinedSignInId";
|
|
185
185
|
TelemetryEvent["ThirdPartyCookiesBlocked"] = "ThirdPartyCookiesBlocked";
|
|
186
186
|
TelemetryEvent["ParticipantsRemovedEvent"] = "ParticipantsRemovedEvent";
|
|
187
|
+
TelemetryEvent["QueueOverflowEvent"] = "QueueOverflowEvent";
|
|
187
188
|
TelemetryEvent["ProcessingHTMLTextMiddlewareFailed"] = "ProcessingHTMLTextMiddlewareFailed";
|
|
188
189
|
TelemetryEvent["ProcessingSanitizationMiddlewareFailed"] = "ProcessingSanitizationMiddlewareFailed";
|
|
189
190
|
TelemetryEvent["FormatTagsMiddlewareJSONStringifyFailed"] = "FormatTagsMiddlewareJSONStringifyFailed";
|
|
@@ -222,6 +223,7 @@ export let TelemetryEvent;
|
|
|
222
223
|
TelemetryEvent["SystemMessageReceived"] = "SystemMessageReceived";
|
|
223
224
|
TelemetryEvent["RehydrateMessageReceived"] = "RehydrateMessageReceived";
|
|
224
225
|
TelemetryEvent["CustomContextReceived"] = "CustomContextReceived";
|
|
226
|
+
TelemetryEvent["CustomEventAction"] = "CustomEventAction";
|
|
225
227
|
TelemetryEvent["NetworkDisconnected"] = "NetworkDisconnected";
|
|
226
228
|
TelemetryEvent["NetworkReconnected"] = "NetworkReconnected";
|
|
227
229
|
TelemetryEvent["LinkModePostChatWorkflowStarted"] = "LinkModePostChatWorkflowStarted";
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -453,4 +453,25 @@ export function getDeviceType() {
|
|
|
453
453
|
} else {
|
|
454
454
|
return "standard";
|
|
455
455
|
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
//Bots expect a payload containing:
|
|
459
|
+
//1. customEventName: this should be string describe the event name
|
|
460
|
+
//2. customEventValue: given the value is from customer with unknown type, it is required to stringify the payload later
|
|
461
|
+
export const isValidCustomEvent = payload => {
|
|
462
|
+
if (Constants.customEventName in payload && payload.customEventName && typeof payload.customEventName === Constants.String && Constants.customEventValue in payload && payload.customEventValue) return true;
|
|
463
|
+
return false;
|
|
464
|
+
};
|
|
465
|
+
export const getCustomEventValue = customEventPayload => {
|
|
466
|
+
let returnVal = "";
|
|
467
|
+
try {
|
|
468
|
+
returnVal = typeof customEventPayload.customEventValue === Constants.String ? customEventPayload.customEventValue : JSON.stringify(customEventPayload.customEventValue);
|
|
469
|
+
} catch (error) {
|
|
470
|
+
console.error(error);
|
|
471
|
+
}
|
|
472
|
+
return returnVal;
|
|
473
|
+
};
|
|
474
|
+
export function isEndConversationDueToOverflowActivity(activity) {
|
|
475
|
+
var _activity$channelData, _activity$channelData2;
|
|
476
|
+
return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(Constants.EndConversationDueToOverflow);
|
|
456
477
|
}
|
|
@@ -65,7 +65,6 @@ export const ChatButtonStateful = props => {
|
|
|
65
65
|
};
|
|
66
66
|
const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeChatButtonStyleProps, outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.styleProps);
|
|
67
67
|
const controlProps = {
|
|
68
|
-
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps),
|
|
69
68
|
id: "oc-lcw-chat-button",
|
|
70
69
|
dir: state.domainStates.globalDir,
|
|
71
70
|
titleText: "Let's Chat!",
|
|
@@ -74,7 +73,8 @@ export const ChatButtonStateful = props => {
|
|
|
74
73
|
unreadMessageCount: state.appStates.unreadMessageCount ? state.appStates.unreadMessageCount > Constants.maximumUnreadMessageCount ? (_props$buttonProps = props.buttonProps) === null || _props$buttonProps === void 0 ? void 0 : (_props$buttonProps$co = _props$buttonProps.controlProps) === null || _props$buttonProps$co === void 0 ? void 0 : _props$buttonProps$co.largeUnreadMessageString : state.appStates.unreadMessageCount.toString() : "0",
|
|
75
74
|
unreadMessageString: (_props$buttonProps2 = props.buttonProps) === null || _props$buttonProps2 === void 0 ? void 0 : (_props$buttonProps2$c = _props$buttonProps2.controlProps) === null || _props$buttonProps2$c === void 0 ? void 0 : _props$buttonProps2$c.unreadMessageString,
|
|
76
75
|
// Regular chat button onClick - this will always take precedence
|
|
77
|
-
onClick: () => ref.current()
|
|
76
|
+
onClick: () => ref.current(),
|
|
77
|
+
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps)
|
|
78
78
|
};
|
|
79
79
|
const outOfOfficeControlProps = {
|
|
80
80
|
// Only take specific properties from outOfOfficeButtonProps, never onClick
|
|
@@ -83,7 +83,6 @@ export const ChatButtonStateful = props => {
|
|
|
83
83
|
titleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro === void 0 ? void 0 : _outOfOfficeButtonPro.titleText) || "We're Offline",
|
|
84
84
|
subtitleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro2 = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro2 === void 0 ? void 0 : _outOfOfficeButtonPro2.subtitleText) || "No agents available",
|
|
85
85
|
unreadMessageString: (_props$buttonProps3 = props.buttonProps) === null || _props$buttonProps3 === void 0 ? void 0 : (_props$buttonProps3$c = _props$buttonProps3.controlProps) === null || _props$buttonProps3$c === void 0 ? void 0 : _props$buttonProps3$c.unreadMessageString,
|
|
86
|
-
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps),
|
|
87
86
|
// Out-of-office specific onClick - this will ALWAYS take precedence
|
|
88
87
|
onClick: () => {
|
|
89
88
|
if (state.appStates.isMinimized) {
|
|
@@ -96,7 +95,8 @@ export const ChatButtonStateful = props => {
|
|
|
96
95
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
97
96
|
payload: ConversationState.OutOfOffice
|
|
98
97
|
});
|
|
99
|
-
}
|
|
98
|
+
},
|
|
99
|
+
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
|
|
100
100
|
};
|
|
101
101
|
useEffect(() => {
|
|
102
102
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
@@ -25,8 +25,11 @@ const DraggableChatWidget = props => {
|
|
|
25
25
|
};
|
|
26
26
|
const calculateOffsetsWithinViewport = useCallback((id, offset, delta) => {
|
|
27
27
|
const draggableElement = document.getElementById(id);
|
|
28
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
28
31
|
const positionRelativeToViewport = draggableElement.getBoundingClientRect();
|
|
29
|
-
if (isNullOrUndefined(
|
|
32
|
+
if (isNullOrUndefined(positionRelativeToViewport) || isNullOrUndefined(offset.offsetLeft) || isNullOrUndefined(offset.offsetTop)) {
|
|
30
33
|
return;
|
|
31
34
|
}
|
|
32
35
|
let offsetLeft = offset.offsetLeft;
|
|
@@ -68,6 +71,9 @@ const DraggableChatWidget = props => {
|
|
|
68
71
|
}
|
|
69
72
|
const cacheInitialPosition = () => {
|
|
70
73
|
const draggableElement = document.getElementById(props.elementId);
|
|
74
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
71
77
|
const offsetLeft = draggableElement.offsetLeft;
|
|
72
78
|
const offsetTop = draggableElement.offsetTop;
|
|
73
79
|
setInitialPosition({
|
|
@@ -77,6 +83,9 @@ const DraggableChatWidget = props => {
|
|
|
77
83
|
};
|
|
78
84
|
const calculateOffsets = () => {
|
|
79
85
|
const draggableElement = document.getElementById(props.elementId);
|
|
86
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
80
89
|
const offsetLeft = draggableElement.offsetLeft;
|
|
81
90
|
const offsetTop = draggableElement.offsetTop;
|
|
82
91
|
|
|
@@ -111,6 +120,9 @@ const DraggableChatWidget = props => {
|
|
|
111
120
|
resetPosition(initialPosition);
|
|
112
121
|
} else if (state.appStates.isMinimized) {
|
|
113
122
|
const draggableElement = document.getElementById(props.elementId);
|
|
123
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
114
126
|
const offsetLeft = draggableElement.offsetLeft;
|
|
115
127
|
const offsetTop = draggableElement.offsetTop;
|
|
116
128
|
if (!cachedPosition) {
|
|
@@ -135,6 +147,9 @@ const DraggableChatWidget = props => {
|
|
|
135
147
|
|
|
136
148
|
// Update position via DOM manipulation to prevent <Stack/> continuously rendering on style change causing high CPU spike
|
|
137
149
|
const draggableElement = document.getElementById(props.elementId);
|
|
150
|
+
if (isNullOrUndefined(draggableElement)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
138
153
|
repositionElement(draggableElement, offsetLeft, offsetTop);
|
|
139
154
|
setPosition({
|
|
140
155
|
offsetLeft,
|
|
@@ -7,34 +7,47 @@ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
|
7
7
|
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
8
8
|
import { executeReducer } from "../../../contexts/createReducer";
|
|
9
9
|
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
10
|
-
const
|
|
10
|
+
const getRegionBasedInternetTestUrl = widgetSnippet => {
|
|
11
|
+
var _widgetSnippet$match;
|
|
12
|
+
if (!widgetSnippet) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const widgetSnippetSourceRegex = new RegExp("src=\"(https:\\/\\/[\\w-.]+)[\\w-.\\/]+\"");
|
|
16
|
+
const baseCdnUrl = (_widgetSnippet$match = widgetSnippet.match(widgetSnippetSourceRegex)) === null || _widgetSnippet$match === void 0 ? void 0 : _widgetSnippet$match[1];
|
|
17
|
+
return baseCdnUrl ? `${baseCdnUrl}${Constants.internetConnectionTestPath}` : null;
|
|
18
|
+
};
|
|
19
|
+
const isInternetConnected = async testUrl => {
|
|
11
20
|
try {
|
|
12
|
-
const response = await fetch(
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
const response = await fetch(testUrl, {
|
|
22
|
+
method: "GET",
|
|
23
|
+
cache: "no-cache"
|
|
24
|
+
});
|
|
25
|
+
return response.ok;
|
|
15
26
|
} catch {
|
|
16
27
|
return false;
|
|
17
28
|
}
|
|
18
29
|
};
|
|
19
30
|
export const createInternetConnectionChangeHandler = async state => {
|
|
20
31
|
const handler = async () => {
|
|
21
|
-
|
|
32
|
+
var _inMemoryState$domain, _inMemoryState$domain2;
|
|
22
33
|
const inMemoryState = executeReducer(state, {
|
|
23
34
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
24
35
|
payload: null
|
|
25
36
|
});
|
|
37
|
+
const testUrl = getRegionBasedInternetTestUrl((_inMemoryState$domain = inMemoryState.domainStates.liveChatConfig) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.LiveWSAndLiveChatEngJoin) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.msdyn_widgetsnippet);
|
|
38
|
+
const connected = testUrl ? await isInternetConnected(testUrl) : false;
|
|
26
39
|
if (!connected) {
|
|
27
|
-
var _inMemoryState$
|
|
40
|
+
var _inMemoryState$domain3, _inMemoryState$domain4;
|
|
28
41
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
29
42
|
Event: TelemetryEvent.NetworkDisconnected
|
|
30
43
|
});
|
|
31
|
-
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
44
|
+
NotificationHandler.notifyError(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain3 = inMemoryState.domainStates) === null || _inMemoryState$domain3 === void 0 ? void 0 : (_inMemoryState$domain4 = _inMemoryState$domain3.middlewareLocalizedTexts) === null || _inMemoryState$domain4 === void 0 ? void 0 : _inMemoryState$domain4.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
|
|
32
45
|
} else {
|
|
33
|
-
var _inMemoryState$
|
|
46
|
+
var _inMemoryState$domain5, _inMemoryState$domain6;
|
|
34
47
|
TelemetryHelper.logActionEvent(LogLevel.WARN, {
|
|
35
48
|
Event: TelemetryEvent.NetworkReconnected
|
|
36
49
|
});
|
|
37
|
-
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$
|
|
50
|
+
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, (inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$domain5 = inMemoryState.domainStates) === null || _inMemoryState$domain5 === void 0 ? void 0 : (_inMemoryState$domain6 = _inMemoryState$domain5.middlewareLocalizedTexts) === null || _inMemoryState$domain6 === void 0 ? void 0 : _inMemoryState$domain6.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
38
51
|
BroadcastService.postMessage({
|
|
39
52
|
eventName: BroadcastEvent.NetworkReconnected
|
|
40
53
|
});
|
|
@@ -28,12 +28,65 @@ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineM
|
|
|
28
28
|
// Rule to process html blocks and paragraphs
|
|
29
29
|
"html_inline",
|
|
30
30
|
// Rule to process html tags
|
|
31
|
-
"newline"
|
|
31
|
+
"newline",
|
|
32
|
+
// Rule to proceess '\n'
|
|
33
|
+
"list" // Enable list parsing rule
|
|
32
34
|
]);
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
markdown.disable(["strikethrough"]);
|
|
36
38
|
|
|
39
|
+
// Custom plugin to fix numbered list continuity
|
|
40
|
+
markdown.use(function (md) {
|
|
41
|
+
const originalRender = md.render.bind(md);
|
|
42
|
+
const originalRenderInline = md.renderInline.bind(md);
|
|
43
|
+
function preprocessText(text) {
|
|
44
|
+
// Handle numbered lists that come with double line breaks (knowledge article format)
|
|
45
|
+
// This ensures proper continuous numbering instead of separate lists
|
|
46
|
+
|
|
47
|
+
let result = text;
|
|
48
|
+
|
|
49
|
+
// Only process if the text contains the double line break pattern
|
|
50
|
+
// But exclude simple numbered lists (where content after \n\n starts with another number)
|
|
51
|
+
if (!/\d+\.\s+.*?\n\n(?!\d+\.\s)[\s\S]*?(?:\n\n\d+\.|\s*$)/.test(text)) {
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Convert "1. Item\n\nContent\n\n2. Item" to proper markdown list format
|
|
56
|
+
// Use improved pattern with negative lookahead to exclude cases where content starts with numbered list
|
|
57
|
+
const listPattern = /(\d+\.\s+[^\n]+)(\n\n(?!\d+\.\s)[\s\S]*?)(?=\n\n\d+\.|\s*$)/g;
|
|
58
|
+
if (listPattern.test(result)) {
|
|
59
|
+
// Reset regex state for actual replacement
|
|
60
|
+
listPattern.lastIndex = 0;
|
|
61
|
+
result = result.replace(listPattern, (match, listItem, content) => {
|
|
62
|
+
if (!content) {
|
|
63
|
+
return match;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Format content with proper indentation
|
|
67
|
+
const cleanContent = content.substring(2); // Remove leading \n\n
|
|
68
|
+
const lines = cleanContent.split("\n");
|
|
69
|
+
const indentedContent = lines.map(line => line.trim() ? `${Constants.MARKDOWN_LIST_INDENTATION}${line}` : "").join("\n");
|
|
70
|
+
const lineBreak = disableNewLineMarkdownSupport ? "\n" : "\n\n";
|
|
71
|
+
return `${listItem}${lineBreak}${indentedContent}`;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
|
+
md.render = function (text, env) {
|
|
79
|
+
const processedText = preprocessText(text);
|
|
80
|
+
return originalRender(processedText, env);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
md.renderInline = function (text, env) {
|
|
85
|
+
const processedText = preprocessText(text);
|
|
86
|
+
return originalRenderInline(processedText, env);
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
|
|
37
90
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
91
|
markdown.use(MarkdownItForInline, "url_new_win", "link_open", function (tokens, idx, env) {
|
|
39
92
|
const targetAttrIndex = tokens[idx].attrIndex(Constants.Target);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Constants } from "../../../common/Constants";
|
|
2
|
+
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
3
|
+
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
4
|
+
import { getCustomEventValue, isValidCustomEvent } from "../../../common/utils";
|
|
5
|
+
export const customEventCallback = facadeChatSDK => event => {
|
|
6
|
+
if (!(Constants.payload in event)) return;
|
|
7
|
+
if (isValidCustomEvent(event.payload)) {
|
|
8
|
+
const customEventPayload = event.payload;
|
|
9
|
+
try {
|
|
10
|
+
const customEventValueStr = getCustomEventValue(customEventPayload);
|
|
11
|
+
const customEventName = customEventPayload.customEventName;
|
|
12
|
+
const messageMeta = {
|
|
13
|
+
customEvent: Constants.true,
|
|
14
|
+
customEventName: customEventName,
|
|
15
|
+
customEventValue: customEventValueStr
|
|
16
|
+
};
|
|
17
|
+
const messagePayload = {
|
|
18
|
+
content: "",
|
|
19
|
+
tags: [Constants.Hidden],
|
|
20
|
+
metadata: messageMeta,
|
|
21
|
+
timestamp: new Date()
|
|
22
|
+
};
|
|
23
|
+
facadeChatSDK.sendMessage(messagePayload);
|
|
24
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.DEBUG, {
|
|
25
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
26
|
+
Description: "Sent customEvent.",
|
|
27
|
+
CustomProperties: {
|
|
28
|
+
customEventName,
|
|
29
|
+
lengthCustomEventValue: customEventValueStr.length
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
|
|
34
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
35
|
+
Description: "Failed to process CustomEvent.",
|
|
36
|
+
ExceptionDetails: {
|
|
37
|
+
error
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const subscribeToSendCustomEvent = (broadcastService, facadeChatSDK, customEventCallback) => {
|
|
44
|
+
broadcastService.getMessageByEventName(Constants.sendCustomEvent).subscribe(customEventCallback(facadeChatSDK));
|
|
45
|
+
};
|
|
@@ -16,7 +16,7 @@ import { uuidv4 } from "@microsoft/omnichannel-chat-sdk";
|
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
17
|
const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter) => {
|
|
18
18
|
try {
|
|
19
|
-
var _conversationDetails$, _state$domainStates, _state$
|
|
19
|
+
var _conversationDetails$, _state$domainStates, _state$appStates5;
|
|
20
20
|
const {
|
|
21
21
|
chatConfig
|
|
22
22
|
} = props;
|
|
@@ -27,7 +27,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
27
27
|
|
|
28
28
|
// Use Case: When post chat is not configured
|
|
29
29
|
if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : (_conversationDetails$ = conversationDetails.canRenderPostChat) === null || _conversationDetails$ === void 0 ? void 0 : _conversationDetails$.toLowerCase()) === Constants.false) {
|
|
30
|
-
var _state$appStates;
|
|
30
|
+
var _state$appStates, _state$appStates2, _state$appStates3;
|
|
31
31
|
// If ended by customer, just close chat
|
|
32
32
|
if ((state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.conversationEndedBy) === ConversationEndEntity.Customer) {
|
|
33
33
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
@@ -38,6 +38,13 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// Use Case: If ended by Agent, stay chat in InActive state
|
|
41
|
+
let isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
|
|
42
|
+
if (isConversationalSurveyEnabled && ((state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.conversationEndedBy) === ConversationEndEntity.Agent || (state === null || state === void 0 ? void 0 : (_state$appStates3 = state.appStates) === null || _state$appStates3 === void 0 ? void 0 : _state$appStates3.conversationEndedBy) === ConversationEndEntity.Bot)) {
|
|
43
|
+
dispatch({
|
|
44
|
+
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
45
|
+
payload: ConversationState.InActive
|
|
46
|
+
});
|
|
47
|
+
}
|
|
41
48
|
return;
|
|
42
49
|
}
|
|
43
50
|
|
|
@@ -53,7 +60,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
53
60
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
61
|
const postchatContext = (await getPostChatContext(facadeChatSDK, state, dispatch)) ?? (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : _state$domainStates.postChatContext);
|
|
55
62
|
if (postchatContext === undefined) {
|
|
56
|
-
var _state$
|
|
63
|
+
var _state$appStates4;
|
|
57
64
|
BroadcastService.postMessage({
|
|
58
65
|
eventName: BroadcastEvent.OnWidgetError,
|
|
59
66
|
payload: {
|
|
@@ -62,7 +69,7 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
62
69
|
});
|
|
63
70
|
|
|
64
71
|
// For Customer intiated conversations, just close chat widget
|
|
65
|
-
if ((state === null || state === void 0 ? void 0 : (_state$
|
|
72
|
+
if ((state === null || state === void 0 ? void 0 : (_state$appStates4 = state.appStates) === null || _state$appStates4 === void 0 ? void 0 : _state$appStates4.conversationEndedBy) === ConversationEndEntity.Customer) {
|
|
66
73
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
67
74
|
Event: TelemetryEvent.PrepareEndChat,
|
|
68
75
|
Description: PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithInvalidPostChat
|
|
@@ -80,11 +87,11 @@ const prepareEndChat = async (props, facadeChatSDK, state, dispatch, setAdapter,
|
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
// Log PrepareEndChat if conversation ended by customer (bot and agent cases are handled in LiveChatWidgetStateful.tsx)
|
|
83
|
-
if (state !== null && state !== void 0 && (_state$
|
|
84
|
-
var _state$
|
|
90
|
+
if (state !== null && state !== void 0 && (_state$appStates5 = state.appStates) !== null && _state$appStates5 !== void 0 && _state$appStates5.conversationEndedBy) {
|
|
91
|
+
var _state$appStates6;
|
|
85
92
|
TelemetryHelper.logSDKEvent(LogLevel.INFO, {
|
|
86
93
|
Event: TelemetryEvent.PrepareEndChat,
|
|
87
|
-
Description: `${PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithInvalidPostChat} ${state === null || state === void 0 ? void 0 : (_state$
|
|
94
|
+
Description: `${PrepareEndChatDescriptionConstants.ConversationEndedByCustomerWithInvalidPostChat} ${state === null || state === void 0 ? void 0 : (_state$appStates6 = state.appStates) === null || _state$appStates6 === void 0 ? void 0 : _state$appStates6.conversationEndedBy}.`
|
|
88
95
|
});
|
|
89
96
|
}
|
|
90
97
|
const persistentEnabled = isPersistentEnabled(chatConfig);
|
|
@@ -256,6 +263,10 @@ export const closeChatStateCleanUp = dispatch => {
|
|
|
256
263
|
payload: undefined
|
|
257
264
|
});
|
|
258
265
|
// dispatch({ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE, payload: ConversationState.Closed });
|
|
266
|
+
dispatch({
|
|
267
|
+
type: LiveChatWidgetActionType.SET_CONVERSATIONAL_SURVEY_DISPLAY,
|
|
268
|
+
payload: false
|
|
269
|
+
});
|
|
259
270
|
dispatch({
|
|
260
271
|
type: LiveChatWidgetActionType.SET_RECONNECT_ID,
|
|
261
272
|
payload: undefined
|
|
@@ -32,6 +32,12 @@ import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller
|
|
|
32
32
|
import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
|
|
33
33
|
import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
|
|
34
34
|
import { Constants } from "../../../common/Constants";
|
|
35
|
+
import createCallActionMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware";
|
|
36
|
+
import createCustomEventMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware";
|
|
37
|
+
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
38
|
+
import { executeReducer } from "../../../contexts/createReducer";
|
|
39
|
+
import { createQueueOverflowMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware";
|
|
40
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
35
41
|
|
|
36
42
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
43
|
export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
@@ -53,6 +59,20 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
53
59
|
let webChatStore = WebChatStoreLoader.store;
|
|
54
60
|
if (!webChatStore) {
|
|
55
61
|
var _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _props$webChatContain7;
|
|
62
|
+
const addConversationalSurveyTagsCallback = action => {
|
|
63
|
+
var _inMemoryState$appSta;
|
|
64
|
+
const inMemoryState = executeReducer(state, {
|
|
65
|
+
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
66
|
+
payload: null
|
|
67
|
+
});
|
|
68
|
+
const isConversationalSurvey = (_inMemoryState$appSta = inMemoryState.appStates) === null || _inMemoryState$appSta === void 0 ? void 0 : _inMemoryState$appSta.isConversationalSurvey;
|
|
69
|
+
if (isConversationalSurvey) {
|
|
70
|
+
if (!action.payload.activity.channelData.tags.includes(Constants.c2ConversationalSurveyMessageTag)) {
|
|
71
|
+
action.payload.activity.channelData.tags.push(Constants.c2ConversationalSurveyMessageTag);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return action;
|
|
75
|
+
};
|
|
56
76
|
const conversationEndCallback = async () => {
|
|
57
77
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
78
|
const conversationDetails = await getConversationDetailsCall(facadeChatSDK);
|
|
@@ -82,9 +102,21 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
82
102
|
});
|
|
83
103
|
}
|
|
84
104
|
};
|
|
105
|
+
const startConversationalSurveyCallback = async () => {
|
|
106
|
+
dispatch({
|
|
107
|
+
type: LiveChatWidgetActionType.SET_CONVERSATIONAL_SURVEY_DISPLAY,
|
|
108
|
+
payload: true
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const endConversationalSurveyCallback = async () => {
|
|
112
|
+
dispatch({
|
|
113
|
+
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
114
|
+
payload: ConversationState.InActive
|
|
115
|
+
});
|
|
116
|
+
};
|
|
85
117
|
webChatStore = createStore({},
|
|
86
118
|
//initial state
|
|
87
|
-
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
119
|
+
preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(),
|
|
88
120
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
89
121
|
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
90
122
|
WebChatStoreLoader.store = webChatStore;
|
|
@@ -6,6 +6,22 @@ export const isPostChatSurveyEnabled = async facadeChatSDK => {
|
|
|
6
6
|
const postChatEnabled = (_chatConfig$LiveWSAnd = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd === void 0 ? void 0 : _chatConfig$LiveWSAnd.msdyn_postconversationsurveyenable.toString().toLowerCase();
|
|
7
7
|
return postChatEnabled === "true";
|
|
8
8
|
};
|
|
9
|
+
export const getPostChatSurveyConfig = async facadeChatSDK => {
|
|
10
|
+
var _chatConfig$LiveWSAnd2, _chatConfig$LiveWSAnd3, _chatConfig$LiveWSAnd4, _chatConfig$LiveWSAnd5, _chatConfig$LiveWSAnd6, _chatConfig$LiveWSAnd7, _chatConfig$LiveWSAnd8, _chatConfig$LiveWSAnd9, _chatConfig$LiveWSAnd10;
|
|
11
|
+
const chatConfig = await facadeChatSDK.getLiveChatConfig();
|
|
12
|
+
const postChatEnabled = (_chatConfig$LiveWSAnd2 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd2 === void 0 ? void 0 : _chatConfig$LiveWSAnd2.msdyn_postconversationsurveyenable.toString().toLowerCase();
|
|
13
|
+
const agentSurveyMode = (_chatConfig$LiveWSAnd3 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd3 === void 0 ? void 0 : (_chatConfig$LiveWSAnd4 = _chatConfig$LiveWSAnd3.msdyn_postconversationsurveymode) === null || _chatConfig$LiveWSAnd4 === void 0 ? void 0 : _chatConfig$LiveWSAnd4.toString();
|
|
14
|
+
const botSurveyMode = (_chatConfig$LiveWSAnd5 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd5 === void 0 ? void 0 : (_chatConfig$LiveWSAnd6 = _chatConfig$LiveWSAnd5.msdyn_postconversationsurveybotsurveymode) === null || _chatConfig$LiveWSAnd6 === void 0 ? void 0 : _chatConfig$LiveWSAnd6.toString();
|
|
15
|
+
const surveyProvider = (_chatConfig$LiveWSAnd7 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd7 === void 0 ? void 0 : (_chatConfig$LiveWSAnd8 = _chatConfig$LiveWSAnd7.msdyn_surveyprovider) === null || _chatConfig$LiveWSAnd8 === void 0 ? void 0 : _chatConfig$LiveWSAnd8.toString();
|
|
16
|
+
const isConversationalSurveyEnabled = (_chatConfig$LiveWSAnd9 = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd9 === void 0 ? void 0 : (_chatConfig$LiveWSAnd10 = _chatConfig$LiveWSAnd9.msdyn_isConversationalPostChatSurveyEnabled) === null || _chatConfig$LiveWSAnd10 === void 0 ? void 0 : _chatConfig$LiveWSAnd10.toString().toLowerCase();
|
|
17
|
+
return {
|
|
18
|
+
postChatEnabled: postChatEnabled === "true",
|
|
19
|
+
agentSurveyMode: agentSurveyMode,
|
|
20
|
+
botSurveyMode: botSurveyMode,
|
|
21
|
+
surveyProvider: surveyProvider,
|
|
22
|
+
isConversationalSurveyEnabled: isConversationalSurveyEnabled === "true"
|
|
23
|
+
};
|
|
24
|
+
};
|
|
9
25
|
export const isPersistentChatEnabled = conversationMode => {
|
|
10
26
|
if (isNullOrUndefined(conversationMode)) {
|
|
11
27
|
return false;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Constants, ParticipantType, PostChatSurveyTelemetryMessage } from "../../../common/Constants";
|
|
1
|
+
import { Constants, ParticipantType, PostChatSurveyTelemetryMessage, SurveyProvider } from "../../../common/Constants";
|
|
2
2
|
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
3
3
|
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
4
4
|
import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
|
|
5
5
|
import { PostChatSurveyMode } from "../../postchatsurveypanestateful/enums/PostChatSurveyMode";
|
|
6
6
|
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
7
7
|
import { addDelayInMs } from "../../../common/utils";
|
|
8
|
-
import {
|
|
8
|
+
import { getPostChatSurveyConfig } from "./liveChatConfigUtils";
|
|
9
9
|
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
11
|
let conversationDetails = undefined;
|
|
@@ -46,23 +46,34 @@ const setSurveyMode = async (props, participantType, state, dispatch) => {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
-
const renderSurvey = async (postChatContext, dispatch) => {
|
|
49
|
+
const renderSurvey = async (postChatContext, state, dispatch) => {
|
|
50
50
|
if (postChatSurveyMode === PostChatSurveyMode.Link) {
|
|
51
51
|
setWidgetStateToInactive(dispatch);
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
if (postChatSurveyMode === PostChatSurveyMode.Embed) {
|
|
55
|
-
await embedModePostChatWorkflow(postChatContext, dispatch);
|
|
55
|
+
await embedModePostChatWorkflow(postChatContext, state, dispatch);
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
// Function for embed mode postchat workflow which is essentially same for both customer and agent
|
|
60
60
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
61
|
-
const embedModePostChatWorkflow = async (postChatContext, dispatch) => {
|
|
61
|
+
const embedModePostChatWorkflow = async (postChatContext, state, dispatch) => {
|
|
62
62
|
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
63
63
|
Event: TelemetryEvent.EmbedModePostChatWorkflowStarted
|
|
64
64
|
});
|
|
65
65
|
if (postChatContext) {
|
|
66
|
+
if (postChatContext.isConversationalSurveyEnabled && postChatContext.surveyProvider === SurveyProvider.MicrosoftCopilotStudio) {
|
|
67
|
+
dispatch({
|
|
68
|
+
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
69
|
+
payload: ConversationState.Postchat
|
|
70
|
+
});
|
|
71
|
+
dispatch({
|
|
72
|
+
type: LiveChatWidgetActionType.SET_CONVERSATIONAL_SURVEY_DISPLAY,
|
|
73
|
+
payload: true
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
66
77
|
dispatch({
|
|
67
78
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
68
79
|
payload: ConversationState.PostchatLoading
|
|
@@ -89,7 +100,7 @@ const initiatePostChat = async (props, conversationDetailsParam, state, dispatch
|
|
|
89
100
|
conversationDetails = conversationDetailsParam;
|
|
90
101
|
const participantType = ((_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType) ?? postchatContext.participantType;
|
|
91
102
|
await setSurveyMode(props, participantType, state, dispatch);
|
|
92
|
-
await renderSurvey(postchatContext, dispatch);
|
|
103
|
+
await renderSurvey(postchatContext, state, dispatch);
|
|
93
104
|
};
|
|
94
105
|
|
|
95
106
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -102,7 +113,14 @@ const isPostChatEnabled = (props, state) => {
|
|
|
102
113
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
103
114
|
const getPostChatContext = async (facadeChatSDK, state, dispatch) => {
|
|
104
115
|
try {
|
|
105
|
-
const
|
|
116
|
+
const postChatConfig = await getPostChatSurveyConfig(facadeChatSDK);
|
|
117
|
+
const postChatEnabled = postChatConfig.postChatEnabled;
|
|
118
|
+
if (postChatConfig.isConversationalSurveyEnabled) {
|
|
119
|
+
dispatch({
|
|
120
|
+
type: LiveChatWidgetActionType.SET_CONVERSATIONAL_SURVEY_ENABLED,
|
|
121
|
+
payload: true
|
|
122
|
+
});
|
|
123
|
+
}
|
|
106
124
|
if (postChatEnabled) {
|
|
107
125
|
var _state$domainStates2;
|
|
108
126
|
if ((state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.postChatContext) === undefined) {
|
|
@@ -112,11 +130,17 @@ const getPostChatContext = async (facadeChatSDK, state, dispatch) => {
|
|
|
112
130
|
Event: TelemetryEvent.PostChatContextCallSucceed,
|
|
113
131
|
Description: PostChatSurveyTelemetryMessage.PostChatContextCallSucceed
|
|
114
132
|
});
|
|
133
|
+
|
|
134
|
+
// Merge postChatConfig with postChatSurveyContext
|
|
135
|
+
const mergedContext = {
|
|
136
|
+
...context,
|
|
137
|
+
...postChatConfig
|
|
138
|
+
};
|
|
115
139
|
dispatch({
|
|
116
140
|
type: LiveChatWidgetActionType.SET_POST_CHAT_CONTEXT,
|
|
117
|
-
payload:
|
|
141
|
+
payload: mergedContext
|
|
118
142
|
});
|
|
119
|
-
return
|
|
143
|
+
return mergedContext;
|
|
120
144
|
}
|
|
121
145
|
}
|
|
122
146
|
} catch (error) {
|