@microsoft/omnichannel-chat-widget 1.8.2-main.fc93d3d → 1.8.3-main.3445895

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 (66) hide show
  1. package/README.md +46 -1
  2. package/lib/cjs/common/Constants.js +8 -2
  3. package/lib/cjs/common/telemetry/TelemetryConstants.js +3 -0
  4. package/lib/cjs/common/telemetry/TelemetryHelper.js +7 -5
  5. package/lib/cjs/common/utils.js +27 -2
  6. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  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 +13 -2
  11. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +8 -3
  12. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
  13. package/lib/cjs/components/livechatwidget/common/startChat.js +5 -4
  14. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -6
  15. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +1 -2
  16. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +3 -1
  17. package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +27 -2
  18. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
  19. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +72 -0
  20. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
  21. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
  22. package/lib/cjs/contexts/common/CustomEventType.js +1 -0
  23. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  24. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  25. package/lib/cjs/firstresponselatency/util.js +24 -10
  26. package/lib/cjs/plugins/createChatTranscript.js +13 -0
  27. package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
  28. package/lib/esm/common/Constants.js +8 -2
  29. package/lib/esm/common/telemetry/TelemetryConstants.js +3 -0
  30. package/lib/esm/common/telemetry/TelemetryHelper.js +7 -5
  31. package/lib/esm/common/utils.js +21 -0
  32. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  33. package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  34. package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
  35. package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
  36. package/lib/esm/components/livechatwidget/common/endChat.js +13 -2
  37. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +9 -4
  38. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
  39. package/lib/esm/components/livechatwidget/common/startChat.js +5 -4
  40. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -6
  41. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +1 -2
  42. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +4 -2
  43. package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +23 -0
  44. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
  45. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +65 -0
  46. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
  47. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
  48. package/lib/esm/contexts/common/CustomEventType.js +1 -0
  49. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  50. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  51. package/lib/esm/firstresponselatency/util.js +21 -8
  52. package/lib/esm/plugins/createChatTranscript.js +13 -0
  53. package/lib/esm/plugins/newMessageEventHandler.js +3 -3
  54. package/lib/types/common/Constants.d.ts +8 -2
  55. package/lib/types/common/telemetry/TelemetryConstants.d.ts +3 -0
  56. package/lib/types/common/utils.d.ts +8 -0
  57. package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
  58. package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +2 -0
  59. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
  60. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +5 -0
  61. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
  62. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
  63. package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
  64. package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
  65. package/lib/types/firstresponselatency/util.d.ts +1 -0
  66. package/package.json +5 -4
@@ -1,6 +1,9 @@
1
1
  import { ConversationEndEntity, ParticipantType } from "../../../common/Constants";
2
2
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
3
3
  import { changeLanguageCodeFormatForWebChat, getConversationDetailsCall } from "../../../common/utils";
4
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
5
+ import { Constants } from "../../../common/Constants";
6
+ import { ConversationState } from "../../../contexts/common/ConversationState";
4
7
  import DOMPurify from "dompurify";
5
8
  import HyperlinkTextOverrideRenderer from "../../webchatcontainerstateful/webchatcontroller/markdownrenderers/HyperlinkTextOverrideRenderer";
6
9
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
@@ -12,28 +15,30 @@ import { createActivityMiddleware } from "../../webchatcontainerstateful/webchat
12
15
  import { createAttachmentMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware";
13
16
  import createAttachmentUploadValidatorMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/attachmentUploadValidatorMiddleware";
14
17
  import { createAvatarMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/avatarMiddleware";
18
+ import createCallActionMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware";
15
19
  import { createCardActionMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/cardActionMiddleware";
20
+ import { createCitationsMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware";
16
21
  import createConversationEndMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/conversationEndMiddleware";
22
+ import createCustomEventMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware";
17
23
  import createDataMaskingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/dataMaskingMiddleware";
18
24
  import { createMarkdown } from "./createMarkdown";
19
25
  import createMaxMessageSizeValidator from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/maxMessageSizeValidator";
20
26
  import { createMessageSequenceIdOverrideMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware";
21
27
  import { createMessageTimeStampMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageTimestampMiddleware";
28
+ import { createQueueOverflowMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware";
22
29
  import { createStore } from "botframework-webchat";
23
30
  import { createToastMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/toastMiddleware";
24
31
  import { createWebChatTelemetry } from "../../webchatcontainerstateful/webchatcontroller/webchattelemetry/WebChatLogger";
25
32
  import { defaultAttachmentProps } from "../../webchatcontainerstateful/common/defaultProps/defaultAttachmentProps";
26
33
  import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
27
34
  import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
35
+ import { executeReducer } from "../../../contexts/createReducer";
28
36
  import { getLocaleStringFromId } from "@microsoft/omnichannel-chat-sdk";
29
37
  import gifUploadMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/gifUploadMiddleware";
30
38
  import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlPlayerMiddleware";
31
39
  import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
32
40
  import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
33
41
  import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
34
- import { Constants } from "../../../common/Constants";
35
- import { ConversationState } from "../../../contexts/common/ConversationState";
36
- import { executeReducer } from "../../../contexts/createReducer";
37
42
 
38
43
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
44
  export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
@@ -112,7 +117,7 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
112
117
  };
113
118
  webChatStore = createStore({},
114
119
  //initial state
115
- 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(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,
120
+ 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, createCitationsMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware, createCallActionMiddleware(),
116
121
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
117
122
  ...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
118
123
  WebChatStoreLoader.store = webChatStore;
@@ -6,6 +6,7 @@ import { PostChatSurveyMode } from "../../postchatsurveypanestateful/enums/PostC
6
6
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
7
7
  import { addDelayInMs } from "../../../common/utils";
8
8
  import { getPostChatSurveyConfig } from "./liveChatConfigUtils";
9
+ import { executeReducer } from "../../../contexts/createReducer";
9
10
 
10
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
12
  let conversationDetails = undefined;
@@ -59,6 +60,13 @@ const renderSurvey = async (postChatContext, state, dispatch) => {
59
60
  // Function for embed mode postchat workflow which is essentially same for both customer and agent
60
61
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
62
  const embedModePostChatWorkflow = async (postChatContext, state, dispatch) => {
63
+ const inMemoryState = executeReducer(state, {
64
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
65
+ payload: null
66
+ });
67
+ if (inMemoryState.appStates.conversationState === ConversationState.Closed) {
68
+ return;
69
+ }
62
70
  TelemetryHelper.logActionEvent(LogLevel.INFO, {
63
71
  Event: TelemetryEvent.EmbedModePostChatWorkflowStarted
64
72
  });
@@ -79,6 +87,13 @@ const embedModePostChatWorkflow = async (postChatContext, state, dispatch) => {
79
87
  payload: ConversationState.PostchatLoading
80
88
  });
81
89
  await addDelayInMs(Constants.PostChatLoadingDurationInMs);
90
+ const inMemoryState = executeReducer(state, {
91
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
92
+ payload: null
93
+ });
94
+ if (inMemoryState.appStates.conversationState === ConversationState.Closed) {
95
+ return;
96
+ }
82
97
  dispatch({
83
98
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
84
99
  payload: ConversationState.Postchat
@@ -97,6 +112,14 @@ const embedModePostChatWorkflow = async (postChatContext, state, dispatch) => {
97
112
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
98
113
  const initiatePostChat = async (props, conversationDetailsParam, state, dispatch, postchatContext) => {
99
114
  var _conversationDetails;
115
+ const inMemoryState = executeReducer(state, {
116
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
117
+ payload: null
118
+ });
119
+ if (inMemoryState.appStates.conversationState === ConversationState.Closed) {
120
+ // If the conversation is closed, we need to reset the state
121
+ return;
122
+ }
100
123
  conversationDetails = conversationDetailsParam;
101
124
  const participantType = ((_conversationDetails = conversationDetails) === null || _conversationDetails === void 0 ? void 0 : _conversationDetails.participantType) ?? postchatContext.participantType;
102
125
  await setSurveyMode(props, participantType, state, dispatch);
@@ -1,5 +1,6 @@
1
1
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
2
  import { Constants, LiveWorkItemState, WidgetLoadTelemetryMessage } from "../../../common/Constants";
3
+ import { TelemetryManager, TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
3
4
  import { checkContactIdError, createTimer, getConversationDetailsCall, getStateFromCache, getWidgetCacheIdfromProps, isNullOrEmptyString, isNullOrUndefined, isUndefinedOrEmpty } from "../../../common/utils";
4
5
  import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "./reconnectChatHelper";
5
6
  import { handleStartChatError, logWidgetLoadComplete } from "./startChatErrorHandler";
@@ -8,7 +9,6 @@ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
8
9
  import { ConversationState } from "../../../contexts/common/ConversationState";
9
10
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
10
11
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
11
- import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
12
12
  import { chatSDKStateCleanUp } from "./endChat";
13
13
  import { createAdapter } from "./createAdapter";
14
14
  import { createOnNewAdapterActivityHandler } from "../../../plugins/newMessageEventHandler";
@@ -131,7 +131,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
131
131
  * This is because a new change to control OOH as closed event when a widget is coming from chat.
132
132
  */
133
133
  if ((state === null || state === void 0 ? void 0 : state.appStates.isMinimized) === undefined || (state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.isMinimized) === true) {
134
- var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6$;
134
+ var _state$domainStates5, _state$domainStates5$, _state$domainStates6, _state$domainStates6$, _TelemetryManager$Int;
135
135
  dispatch({
136
136
  type: LiveChatWidgetActionType.SET_MINIMIZED,
137
137
  payload: false
@@ -141,14 +141,14 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
141
141
  eventName: BroadcastEvent.MaximizeChat,
142
142
  payload: {
143
143
  height: state === null || state === void 0 ? void 0 : (_state$domainStates5 = state.domainStates) === null || _state$domainStates5 === void 0 ? void 0 : (_state$domainStates5$ = _state$domainStates5.widgetSize) === null || _state$domainStates5$ === void 0 ? void 0 : _state$domainStates5$.height,
144
- width: state === null || state === void 0 ? void 0 : (_state$domainStates6 = state.domainStates) === null || _state$domainStates6 === void 0 ? void 0 : (_state$domainStates6$ = _state$domainStates6.widgetSize) === null || _state$domainStates6$ === void 0 ? void 0 : _state$domainStates6$.width
144
+ width: state === null || state === void 0 ? void 0 : (_state$domainStates6 = state.domainStates) === null || _state$domainStates6 === void 0 ? void 0 : (_state$domainStates6$ = _state$domainStates6.widgetSize) === null || _state$domainStates6$ === void 0 ? void 0 : _state$domainStates6$.width,
145
+ runtimeId: TelemetryManager === null || TelemetryManager === void 0 ? void 0 : (_TelemetryManager$Int = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.lcwRuntimeId
145
146
  }
146
147
  });
147
148
  }
148
149
  const optionalParams = {
149
150
  isProactiveChat
150
151
  };
151
- createTrackingForFirstMessage();
152
152
  await initStartChat(facadeChatSDK, dispatch, setAdapter, state, props, optionalParams);
153
153
  };
154
154
 
@@ -199,6 +199,7 @@ const initStartChat = async (facadeChatSDK, dispatch, setAdapter, state, props,
199
199
  const startChatOptionalParams = Object.assign({}, params, optionalParams, defaultOptionalParams);
200
200
  // startTime is used to determine if a message is history or new, better to be set before creating the adapter to get bandwidth
201
201
  const startTime = new Date().getTime();
202
+ createTrackingForFirstMessage();
202
203
  await facadeChatSDK.startChat(startChatOptionalParams);
203
204
  isStartChatSuccessful = true;
204
205
  await createAdapterAndSubscribe(facadeChatSDK, dispatch, setAdapter, startTime, props);
@@ -9,6 +9,7 @@ import { TelemetryManager, TelemetryTimers } from "../../../common/telemetry/Tel
9
9
  import { chatSDKStateCleanUp, endChat, endChatStateCleanUp, prepareEndChat } from "../common/endChat";
10
10
  import { checkIfConversationStillValid, initStartChat, prepareStartChat, setPreChatAndInitiateChat } from "../common/startChat";
11
11
  import { createTimer, getBroadcastChannelName, getConversationDetailsCall, getLocaleDirection, getStateFromCache, getWidgetCacheIdfromProps, getWidgetEndChatEventName, isNullOrEmptyString, isNullOrUndefined, isThisSessionPopout, isUndefinedOrEmpty, setOcUserAgent } from "../../../common/utils";
12
+ import { customEventCallback, subscribeToSendCustomEvent } from "../common/customEventHandler";
12
13
  import { defaultClientDataStoreProvider, isCookieAllowed } from "../../../common/storage/default/defaultClientDataStoreProvider";
13
14
  import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "../common/reconnectChatHelper";
14
15
  import { shouldShowCallingContainer, shouldShowChatButton, shouldShowConfirmationPane, shouldShowEmailTranscriptPane, shouldShowHeader, shouldShowLoadingPane, shouldShowOutOfOfficeHoursPane, shouldShowPostChatLoadingPane, shouldShowPostChatSurveyPane, shouldShowPreChatSurveyPane, shouldShowProactiveChatPane, shouldShowReconnectChatPane, shouldShowStartChatErrorPane, shouldShowWebChatContainer } from "../../../controller/componentController";
@@ -413,7 +414,7 @@ export const LiveChatWidgetStateful = props => {
413
414
  BroadcastService.getMessageByEventName(BroadcastEvent.StartChat).subscribe(msg => {
414
415
  var _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3, _inMemoryState$appSta4;
415
416
  // If chat is out of operating hours chat widget sets the conversation state to OutOfOffice.
416
- if (state.appStates.outsideOperatingHours === true) {
417
+ if (state.appStates.outsideOperatingHours && state.appStates.conversationState !== ConversationState.Active) {
417
418
  dispatch({
418
419
  type: LiveChatWidgetActionType.SET_MINIMIZED,
419
420
  payload: false
@@ -580,6 +581,9 @@ export const LiveChatWidgetStateful = props => {
580
581
  }
581
582
  });
582
583
 
584
+ // subscribe custom event
585
+ subscribeToSendCustomEvent(BroadcastService, facadeChatSDK, customEventCallback);
586
+
583
587
  // Check for TPC and log in telemetry if blocked
584
588
  isCookieAllowed();
585
589
  return () => {
@@ -715,11 +719,7 @@ export const LiveChatWidgetStateful = props => {
715
719
  endChat(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
716
720
  return;
717
721
  }
718
- const inMemoryState = executeReducer(state, {
719
- type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
720
- payload: null
721
- });
722
- let isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
722
+ const isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
723
723
 
724
724
  // In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
725
725
  // Hence setting ConversationState to InActive will be done later in the post chat flows
@@ -892,11 +892,21 @@ export const LiveChatWidgetStateful = props => {
892
892
  .webchat__basic-transcript__activity-markdown-body > :first-child {
893
893
  margin-top: 0px;
894
894
  }
895
+
895
896
  .webchat__basic-transcript__activity-markdown-body img.webchat__render-markdown__external-link-icon {
896
897
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==) !important;
897
898
  height: .75em;
898
899
  margin-left: .25em;
899
900
  }
901
+
902
+ .webchat__link-definitions__header-text {
903
+ color: ${bubbleBackground}
904
+ }
905
+
906
+ .webchat__link-definitions__header-chevron {
907
+ color: ${bubbleBackground}
908
+ }
909
+
900
910
  ${(sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight) && `
901
911
  .webchat__auto-resize-textarea.webchat__send-box-text-box__text-area {
902
912
  min-height: ${sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight} !important;
@@ -178,7 +178,7 @@ export const WebChatContainerStateful = props => {
178
178
  }
179
179
 
180
180
  .webchat__bubble__content>div#ms_lcw_webchat_adaptive_card .ac-textBlock {
181
- color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp2 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp2 === void 0 ? void 0 : _webChatContainerProp2.color) ?? defaultAdaptiveCardStyles.color} !important;
181
+ color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp2 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp2 === void 0 ? void 0 : _webChatContainerProp2.color) ?? defaultAdaptiveCardStyles.color};
182
182
  }
183
183
 
184
184
  .webchat__stacked-layout__content div.webchat__stacked-layout__message-row div.webchat__bubble--from-user {
@@ -287,7 +287,6 @@ export const WebChatContainerStateful = props => {
287
287
  overflow-y: unset;
288
288
  }
289
289
 
290
-
291
290
  `), /*#__PURE__*/React.createElement(Stack, {
292
291
  styles: containerStyles,
293
292
  className: "webchat__stacked-layout_container"
@@ -12,7 +12,7 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
12
12
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
13
13
  import { Observable } from "rxjs/Observable";
14
14
  import MockAdapter from "./mockadapter";
15
- import { customerUser, postBotMessageActivity, postEchoActivity, postSystemMessageActivity } from "./utils/chatAdapterUtils";
15
+ import { customerUser, postAgentMessageActivity, postBotMessageActivity, postEchoActivity, postSystemMessageActivity } from "./utils/chatAdapterUtils";
16
16
  export let DesignerChatAdapter = /*#__PURE__*/function (_MockAdapter) {
17
17
  _inherits(DesignerChatAdapter, _MockAdapter);
18
18
  var _super = _createSuper(DesignerChatAdapter);
@@ -22,10 +22,12 @@ export let DesignerChatAdapter = /*#__PURE__*/function (_MockAdapter) {
22
22
  _this = _super.call(this);
23
23
  setTimeout(() => {
24
24
  postBotMessageActivity(_this.activityObserver, "Thank you for contacting us! How can I help you today?", undefined, 0);
25
+ postBotMessageActivity(_this.activityObserver, "Please accept terms and conditions to proceed. Visit the link for terms and conditions <a href=\"\">here</a>.", undefined, 0);
25
26
  _this.postUserActivity("I need to change my address.", 0);
26
27
  postBotMessageActivity(_this.activityObserver, "Okay, let me connect you with a live agent.", undefined, 100);
27
28
  postSystemMessageActivity(_this.activityObserver, "John has joined the chat", 100);
28
- postBotMessageActivity(_this.activityObserver, "I'd be happy to help you update your account.", undefined, 100);
29
+ postAgentMessageActivity(_this.activityObserver, "I'd be happy to help you update your account.", undefined, 100);
30
+ _this.postUserActivity("I have trouble visiting the signin page <a href=\"\">signin</a>.", 0);
29
31
  }, 1000);
30
32
  return _this;
31
33
  }
@@ -9,6 +9,11 @@ export const botUser = {
9
9
  name: "Bot",
10
10
  role: "bot"
11
11
  };
12
+ export const agentUser = {
13
+ id: "AgentId",
14
+ name: "John",
15
+ role: "bot"
16
+ };
12
17
 
13
18
  // WebChat expects an "echo" activity to confirm the message has been sent successfully
14
19
  export const postEchoActivity = function (activityObserver, activity, user) {
@@ -44,6 +49,24 @@ export const postBotMessageActivity = function (activityObserver, text) {
44
49
  });
45
50
  }, delay);
46
51
  };
52
+ export const postAgentMessageActivity = function (activityObserver, text) {
53
+ let tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
54
+ let delay = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
55
+ setTimeout(() => {
56
+ activityObserver === null || activityObserver === void 0 ? void 0 : activityObserver.next({
57
+ id: uuidv4(),
58
+ from: {
59
+ ...agentUser
60
+ },
61
+ text,
62
+ type: "message",
63
+ channelData: {
64
+ tags
65
+ },
66
+ timestamp: new Date().toISOString()
67
+ });
68
+ }, delay);
69
+ };
47
70
  export const postSystemMessageActivity = function (activityObserver, text) {
48
71
  let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
49
72
  postBotMessageActivity(activityObserver, text, "system", delay);
@@ -0,0 +1,36 @@
1
+ /******
2
+ * CallActionMiddleware
3
+ *
4
+ * Intercepts custom call actions and handles tel: URL navigation
5
+ ******/
6
+
7
+ import { WebChatActionType } from "../../enums/WebChatActionType";
8
+
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
10
+ const createCallActionMiddleware = () => () => next => action => {
11
+ // Intercept incoming activities to modify suggested actions with call type
12
+ if (action.type === WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY) {
13
+ var _action$payload, _activity$suggestedAc;
14
+ const activity = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : _action$payload.activity;
15
+
16
+ // Check if activity has suggested actions with call type
17
+ if (activity !== null && activity !== void 0 && (_activity$suggestedAc = activity.suggestedActions) !== null && _activity$suggestedAc !== void 0 && _activity$suggestedAc.actions) {
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ activity.suggestedActions.actions = activity.suggestedActions.actions.map(suggestedAction => {
20
+ if (suggestedAction.type === "call") {
21
+ // Convert call action to openUrl with encoded tel URL scheme
22
+ const telUrl = suggestedAction.value;
23
+ const convertedAction = {
24
+ ...suggestedAction,
25
+ type: "openUrl",
26
+ value: `tel:${telUrl}`
27
+ };
28
+ return convertedAction;
29
+ }
30
+ return suggestedAction;
31
+ });
32
+ }
33
+ }
34
+ return next(action);
35
+ };
36
+ export default createCallActionMiddleware;
@@ -0,0 +1,65 @@
1
+ import { LogLevel, TelemetryEvent } from "../../../../../common/telemetry/TelemetryConstants";
2
+ import { TelemetryHelper } from "../../../../../common/telemetry/TelemetryHelper";
3
+ export const createCitationsMiddleware = _ref => {
4
+ let {
5
+ dispatch
6
+ } = _ref;
7
+ return next => action => {
8
+ var _action$payload;
9
+ if ((_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
10
+ if (isApplicable(action)) {
11
+ try {
12
+ const gptFeedback = JSON.parse(action.payload.activity.channelData.metadata["pva:gpt-feedback"]);
13
+ // Replace citations in the text
14
+ const updatedText = replaceCitations(action.payload.activity.text, gptFeedback.summarizationOpenAIResponse.result.textCitations);
15
+ action.payload.activity.text = updatedText;
16
+ } catch (error) {
17
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
18
+ Event: TelemetryEvent.CitationMiddlewareFailed,
19
+ ExceptionDetails: {
20
+ ErrorData: "Error while converting citation labels",
21
+ Exception: error
22
+ }
23
+ });
24
+ }
25
+ }
26
+ }
27
+ return next(action);
28
+ };
29
+ };
30
+ const isApplicable = action => {
31
+ var _action$payload2, _action$payload2$acti, _action$payload3, _action$payload3$acti;
32
+ if ((action === null || action === void 0 ? void 0 : (_action$payload2 = action.payload) === null || _action$payload2 === void 0 ? void 0 : (_action$payload2$acti = _action$payload2.activity) === null || _action$payload2$acti === void 0 ? void 0 : _action$payload2$acti.actionType) === "DIRECT_LINE/INCOMING_ACTIVITY" && (action === null || action === void 0 ? void 0 : (_action$payload3 = action.payload) === null || _action$payload3 === void 0 ? void 0 : (_action$payload3$acti = _action$payload3.activity) === null || _action$payload3$acti === void 0 ? void 0 : _action$payload3$acti.channelId) === "ACS_CHANNEL") {
33
+ var _action$payload4, _action$payload4$acti, _action$payload4$acti2, _action$payload4$acti3;
34
+ // Validate if pva:gpt-feedback exists and is not null
35
+ if (action !== null && action !== void 0 && (_action$payload4 = action.payload) !== null && _action$payload4 !== void 0 && (_action$payload4$acti = _action$payload4.activity) !== null && _action$payload4$acti !== void 0 && (_action$payload4$acti2 = _action$payload4$acti.channelData) !== null && _action$payload4$acti2 !== void 0 && (_action$payload4$acti3 = _action$payload4$acti2.metadata) !== null && _action$payload4$acti3 !== void 0 && _action$payload4$acti3["pva:gpt-feedback"]) {
36
+ return true;
37
+ }
38
+ }
39
+ return false;
40
+ };
41
+ const replaceCitations = (text, citations) => {
42
+ if (!citations || !Array.isArray(citations)) {
43
+ return text;
44
+ }
45
+ try {
46
+ return text.replace(/\[(\d+)\]:\s(cite:\d+)\s"([^"]+)"/g, (match, number, citeId) => {
47
+ const citation = citations.find(c => c.id === citeId);
48
+ if (citation) {
49
+ // Replace only the citation label while preserving the original format
50
+ return `[${number}]: ${citeId} "${citation.title}"`;
51
+ }
52
+ return match; // Keep the original match if no replacement is found
53
+ });
54
+ } catch (error) {
55
+ TelemetryHelper.logActionEvent(LogLevel.ERROR, {
56
+ Event: TelemetryEvent.CitationMiddlewareFailed,
57
+ ExceptionDetails: {
58
+ ErrorData: "Error while finding citations references",
59
+ Exception: error
60
+ }
61
+ });
62
+ // Return the original text in case of issues
63
+ return text;
64
+ }
65
+ };
@@ -0,0 +1,33 @@
1
+ /******
2
+ * CustomEventMiddleware
3
+ *
4
+ * This middleware is invoked when a custom event is received.
5
+ * The callback is then invoked to handle the custom event.
6
+ ******/
7
+
8
+ import { Constants } from "../../../../../common/Constants";
9
+ import { WebChatActionType } from "../../enums/WebChatActionType";
10
+ export const isValidCustomEvent = activity => {
11
+ var _activity$channelData, _activity$channelData2, _activity$channelData3, _activity$channelData4, _activity$channelData5, _activity$channelData6, _activity$channelData7, _activity$from, _activity$channelData8, _activity$channelData9, _activity$channelData10, _activity$channelData11;
12
+ return !!(activity !== null && activity !== void 0 && (_activity$channelData = activity.channelData) !== null && _activity$channelData !== void 0 && (_activity$channelData2 = _activity$channelData.metadata) !== null && _activity$channelData2 !== void 0 && _activity$channelData2.customEvent && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : (_activity$channelData4 = _activity$channelData3.metadata) === null || _activity$channelData4 === void 0 ? void 0 : _activity$channelData4.customEvent) === Constants.String && (activity === null || activity === void 0 ? void 0 : (_activity$channelData5 = activity.channelData) === null || _activity$channelData5 === void 0 ? void 0 : (_activity$channelData6 = _activity$channelData5.metadata) === null || _activity$channelData6 === void 0 ? void 0 : (_activity$channelData7 = _activity$channelData6.customEvent) === null || _activity$channelData7 === void 0 ? void 0 : _activity$channelData7.toLowerCase()) === Constants.true && (activity === null || activity === void 0 ? void 0 : (_activity$from = activity.from) === null || _activity$from === void 0 ? void 0 : _activity$from.role) !== Constants.userMessageTag && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData8 = activity.channelData) === null || _activity$channelData8 === void 0 ? void 0 : (_activity$channelData9 = _activity$channelData8.metadata) === null || _activity$channelData9 === void 0 ? void 0 : _activity$channelData9.customEventName) === Constants.String && activity !== null && activity !== void 0 && (_activity$channelData10 = activity.channelData) !== null && _activity$channelData10 !== void 0 && (_activity$channelData11 = _activity$channelData10.metadata) !== null && _activity$channelData11 !== void 0 && _activity$channelData11.customEventValue);
13
+ };
14
+ const createCustomEventMiddleware = broadcastservice => () => next => action => {
15
+ var _action$payload;
16
+ if ((action === null || action === void 0 ? void 0 : action.type) == WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && (_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
17
+ const activity = action.payload.activity;
18
+ if (isValidCustomEvent(activity)) {
19
+ const customEvent = {
20
+ eventName: Constants.onCustomEvent,
21
+ payload: {
22
+ messageId: activity.messageid ?? activity.id,
23
+ customEventName: activity.channelData.metadata.customEventName,
24
+ customEventValue: activity.channelData.metadata.customEventValue
25
+ }
26
+ };
27
+ broadcastservice.postMessage(customEvent);
28
+ return;
29
+ }
30
+ }
31
+ return next(action);
32
+ };
33
+ export default createCustomEventMiddleware;
@@ -0,0 +1,38 @@
1
+ import { WebChatActionType } from "../../enums/WebChatActionType";
2
+ import { LogLevel, TelemetryEvent } from "../../../../../common/telemetry/TelemetryConstants";
3
+ import { TelemetryHelper } from "../../../../../common/telemetry/TelemetryHelper";
4
+ import { LiveChatWidgetActionType } from "../../../../../contexts/common/LiveChatWidgetActionType";
5
+ import { executeReducer } from "../../../../../contexts/createReducer";
6
+ import { isEndConversationDueToOverflowActivity } from "../../../../../common/utils";
7
+ const queueOverflowHandlingHelper = async (state, dispatch) => {
8
+ const {
9
+ appStates
10
+ } = executeReducer(state, {
11
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
12
+ payload: undefined
13
+ });
14
+ if (!appStates.chatDisconnectEventReceived) {
15
+ dispatch({
16
+ type: LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
17
+ payload: true
18
+ });
19
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
20
+ Event: TelemetryEvent.QueueOverflowEvent,
21
+ Description: "Set chat disconnect event received."
22
+ });
23
+ }
24
+ };
25
+ export const createQueueOverflowMiddleware = (state, dispatch) => () => next => action => {
26
+ var _action$payload;
27
+ if ((action === null || action === void 0 ? void 0 : action.type) == WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && (_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
28
+ const activity = action.payload.activity;
29
+ if (isEndConversationDueToOverflowActivity(activity)) {
30
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
31
+ Event: TelemetryEvent.QueueOverflowEvent,
32
+ Description: "Queue overflow event received."
33
+ });
34
+ queueOverflowHandlingHelper(state, dispatch);
35
+ }
36
+ }
37
+ return next(action);
38
+ };
@@ -0,0 +1 @@
1
+ export {};