@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.
Files changed (78) hide show
  1. package/README.md +48 -1
  2. package/lib/cjs/common/Constants.js +17 -3
  3. package/lib/cjs/common/telemetry/TelemetryConstants.js +2 -0
  4. package/lib/cjs/common/utils.js +27 -2
  5. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  6. package/lib/cjs/components/draggable/DraggableChatWidget.js +16 -1
  7. package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  8. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +54 -1
  9. package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
  10. package/lib/cjs/components/livechatwidget/common/endChat.js +18 -7
  11. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +33 -1
  12. package/lib/cjs/components/livechatwidget/common/liveChatConfigUtils.js +18 -1
  13. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +31 -7
  14. package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +15 -2
  15. package/lib/cjs/components/livechatwidget/common/startChat.js +6 -4
  16. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -12
  17. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +18 -14
  18. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
  19. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +4 -3
  20. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +12 -6
  21. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
  22. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
  23. package/lib/cjs/contexts/common/CustomEventType.js +1 -0
  24. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +3 -1
  25. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +3 -1
  26. package/lib/cjs/contexts/createReducer.js +30 -0
  27. package/lib/cjs/controller/componentController.js +2 -2
  28. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  29. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  30. package/lib/cjs/firstresponselatency/util.js +60 -31
  31. package/lib/cjs/plugins/newMessageEventHandler.js +12 -6
  32. package/lib/esm/common/Constants.js +15 -2
  33. package/lib/esm/common/telemetry/TelemetryConstants.js +2 -0
  34. package/lib/esm/common/utils.js +21 -0
  35. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  36. package/lib/esm/components/draggable/DraggableChatWidget.js +16 -1
  37. package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  38. package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
  39. package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
  40. package/lib/esm/components/livechatwidget/common/endChat.js +18 -7
  41. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +33 -1
  42. package/lib/esm/components/livechatwidget/common/liveChatConfigUtils.js +16 -0
  43. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +33 -9
  44. package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +16 -3
  45. package/lib/esm/components/livechatwidget/common/startChat.js +6 -4
  46. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -12
  47. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +18 -14
  48. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
  49. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.js +4 -4
  50. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.js +12 -6
  51. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
  52. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
  53. package/lib/esm/contexts/common/CustomEventType.js +1 -0
  54. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +3 -1
  55. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +3 -1
  56. package/lib/esm/contexts/createReducer.js +30 -0
  57. package/lib/esm/controller/componentController.js +2 -2
  58. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  59. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  60. package/lib/esm/firstresponselatency/util.js +57 -29
  61. package/lib/esm/plugins/newMessageEventHandler.js +12 -6
  62. package/lib/types/common/Constants.d.ts +14 -2
  63. package/lib/types/common/telemetry/TelemetryConstants.d.ts +2 -0
  64. package/lib/types/common/utils.d.ts +8 -0
  65. package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
  66. package/lib/types/components/livechatwidget/common/liveChatConfigUtils.d.ts +1 -0
  67. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
  68. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/channelDataMiddleware.d.ts +1 -1
  69. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware.d.ts +1 -1
  70. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
  71. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
  72. package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
  73. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +2 -0
  74. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
  75. package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
  76. package/lib/types/firstresponselatency/util.d.ts +17 -0
  77. package/lib/types/plugins/newMessageEventHandler.d.ts +1 -1
  78. 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, "internetConnectionTestUrl", "https://ocsdk-prod.azureedge.net/public/connecttest.txt");
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";
@@ -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(draggableElement) || isNullOrUndefined(positionRelativeToViewport) || isNullOrUndefined(offset.offsetLeft) || isNullOrUndefined(offset.offsetTop)) {
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 isInternetConnected = async () => {
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(Constants.internetConnectionTestUrl);
13
- const text = await response.text();
14
- return text === Constants.internetConnectionTestUrlText;
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
- const connected = await isInternetConnected();
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$domain, _inMemoryState$domain2;
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$domain = inMemoryState.domainStates) === null || _inMemoryState$domain === void 0 ? void 0 : (_inMemoryState$domain2 = _inMemoryState$domain.middlewareLocalizedTexts) === null || _inMemoryState$domain2 === void 0 ? void 0 : _inMemoryState$domain2.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_NO_INTERNET_CONNECTION);
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$domain3, _inMemoryState$domain4;
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$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_INTERNET_BACK_ONLINE) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
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" // Rule to proceess '\n'
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$appStates3;
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$appStates2;
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$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.conversationEndedBy) === ConversationEndEntity.Customer) {
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$appStates3 = state.appStates) !== null && _state$appStates3 !== void 0 && _state$appStates3.conversationEndedBy) {
84
- var _state$appStates4;
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$appStates4 = state.appStates) === null || _state$appStates4 === void 0 ? void 0 : _state$appStates4.conversationEndedBy}.`
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 { isPostChatSurveyEnabled } from "./liveChatConfigUtils";
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 postChatEnabled = await isPostChatSurveyEnabled(facadeChatSDK);
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: context
141
+ payload: mergedContext
118
142
  });
119
- return context;
143
+ return mergedContext;
120
144
  }
121
145
  }
122
146
  } catch (error) {