@microsoft/omnichannel-chat-widget 0.1.0-main.3d1c026 → 0.1.0-main.7338c17

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 (58) hide show
  1. package/README.md +235 -0
  2. package/lib/cjs/common/Constants.js +2 -0
  3. package/lib/cjs/common/contextDataStore/DataStoreManager.js +14 -0
  4. package/lib/cjs/common/interfaces/IContextDataStore.js +1 -0
  5. package/lib/cjs/common/telemetry/TelemetryConstants.js +5 -1
  6. package/lib/cjs/components/confirmationpanestateful/ConfirmationPaneStateful.js +15 -28
  7. package/lib/cjs/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +2 -2
  8. package/lib/cjs/components/livechatwidget/common/endChat.js +7 -3
  9. package/lib/cjs/components/livechatwidget/common/initCallingSdk.js +5 -0
  10. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +6 -12
  11. package/lib/cjs/components/livechatwidget/common/registerTelemetryLoggers.js +20 -3
  12. package/lib/cjs/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +23 -22
  13. package/lib/cjs/components/livechatwidget/common/startChat.js +72 -26
  14. package/lib/cjs/components/livechatwidget/common/startProactiveChat.js +3 -3
  15. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +27 -11
  16. package/lib/cjs/components/loadingpanestateful/LoadingPaneStateful.js +1 -1
  17. package/lib/cjs/components/ooohpanestateful/OOOHPaneStateful.js +8 -0
  18. package/lib/cjs/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +28 -11
  19. package/lib/cjs/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +10 -4
  20. package/lib/cjs/components/proactivechatpanestateful/interfaces/IProactiveChatNotificationConfig.js +1 -0
  21. package/lib/cjs/contexts/common/LiveChatWidgetActionType.js +2 -0
  22. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +2 -1
  23. package/lib/cjs/contexts/createReducer.js +13 -0
  24. package/lib/esm/common/Constants.js +2 -0
  25. package/lib/esm/common/contextDataStore/DataStoreManager.js +5 -0
  26. package/lib/esm/common/interfaces/IContextDataStore.js +1 -0
  27. package/lib/esm/common/telemetry/TelemetryConstants.js +5 -1
  28. package/lib/esm/components/confirmationpanestateful/ConfirmationPaneStateful.js +15 -28
  29. package/lib/esm/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.js +2 -2
  30. package/lib/esm/components/livechatwidget/common/endChat.js +7 -3
  31. package/lib/esm/components/livechatwidget/common/initCallingSdk.js +3 -0
  32. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +6 -12
  33. package/lib/esm/components/livechatwidget/common/registerTelemetryLoggers.js +18 -3
  34. package/lib/esm/components/livechatwidget/common/setPostChatContextAndLoadSurvey.js +22 -22
  35. package/lib/esm/components/livechatwidget/common/startChat.js +67 -22
  36. package/lib/esm/components/livechatwidget/common/startProactiveChat.js +5 -5
  37. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +26 -11
  38. package/lib/esm/components/loadingpanestateful/LoadingPaneStateful.js +1 -1
  39. package/lib/esm/components/ooohpanestateful/OOOHPaneStateful.js +6 -0
  40. package/lib/esm/components/prechatsurveypanestateful/PreChatSurveyPaneStateful.js +26 -10
  41. package/lib/esm/components/proactivechatpanestateful/ProactiveChatPaneStateful.js +8 -4
  42. package/lib/esm/components/proactivechatpanestateful/interfaces/IProactiveChatNotificationConfig.js +1 -0
  43. package/lib/esm/contexts/common/LiveChatWidgetActionType.js +2 -0
  44. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +2 -1
  45. package/lib/esm/contexts/createReducer.js +13 -0
  46. package/lib/types/common/Constants.d.ts +1 -0
  47. package/lib/types/common/contextDataStore/DataStoreManager.d.ts +4 -0
  48. package/lib/types/common/interfaces/IContextDataStore.d.ts +14 -0
  49. package/lib/types/common/telemetry/TelemetryConstants.d.ts +4 -0
  50. package/lib/types/components/livechatwidget/common/setPostChatContextAndLoadSurvey.d.ts +1 -1
  51. package/lib/types/components/livechatwidget/common/startChat.d.ts +1 -1
  52. package/lib/types/components/livechatwidget/common/startProactiveChat.d.ts +2 -1
  53. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +3 -1
  54. package/lib/types/components/prechatsurveypanestateful/interfaces/IPreChatSurveyPaneStatefulParams.d.ts +1 -1
  55. package/lib/types/components/proactivechatpanestateful/interfaces/IProactiveChatNotificationConfig.d.ts +3 -0
  56. package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -0
  57. package/lib/types/contexts/common/LiveChatWidgetActionType.d.ts +3 -1
  58. package/package.json +1 -1
@@ -1,18 +1,18 @@
1
1
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
2
3
  import { ConversationState } from "../../../contexts/common/ConversationState";
3
4
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
4
5
  import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
5
6
  import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
6
7
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
7
8
  import { WebChatStoreLoader } from "../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader";
8
- import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps";
9
- import { BroadcastService } from "@microsoft/omnichannel-chat-components"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ import { defaultWebChatContainerStatefulProps } from "../../webchatcontainerstateful/common/defaultProps/defaultWebChatContainerStatefulProps"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
10
 
11
11
  export const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter) => {
12
12
  try {
13
13
  var _props$webChatContain;
14
14
 
15
- TelemetryHelper.logConfigDataEvent(LogLevel.INFO, {
15
+ TelemetryHelper.logSDKEvent(LogLevel.INFO, {
16
16
  Event: TelemetryEvent.EndChatSDKCall
17
17
  });
18
18
  await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.endChat());
@@ -42,6 +42,10 @@ export const endChat = async (props, chatSDK, setAdapter, setWebChatStyles, disp
42
42
  type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
43
43
  payload: undefined
44
44
  });
45
+ dispatch({
46
+ type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
47
+ payload: undefined
48
+ });
45
49
  BroadcastService.postMessage({
46
50
  eventName: "EndChat"
47
51
  });
@@ -8,6 +8,9 @@ export const initCallingSdk = async (chatSDK, setVoiceVideoCallingSDK) => {
8
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
9
  const callingSDK = await chatSDK.getVoiceVideoCalling();
10
10
  setVoiceVideoCallingSDK(callingSDK);
11
+ TelemetryHelper.logCallingEvent(LogLevel.ERROR, {
12
+ Event: TelemetryEvent.CallingSDKLoadSuccess
13
+ });
11
14
  return true;
12
15
  }
13
16
 
@@ -1,5 +1,4 @@
1
1
  import { createStore } from "botframework-webchat";
2
- import { ConversationState } from "../../../contexts/common/ConversationState";
3
2
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
4
3
  import { PostChatSurveyMode } from "../../postchatsurveypanestateful/enums/PostChatSurveyMode";
5
4
  import { WebChatStoreLoader } from "../../webchatcontainerstateful/webchatcontroller/WebChatStoreLoader";
@@ -23,8 +22,8 @@ import htmlPlayerMiddleware from "../../webchatcontainerstateful/webchatcontroll
23
22
  import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware";
24
23
  import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
25
24
  import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
26
- import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
-
25
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
27
  export const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatStyles) => {
29
28
  var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3, _state$domainStates$l4, _state$domainStates$l8, _state$domainStates$l9, _props$webChatContain7, _props$webChatContain8, _state$domainStates$r, _state$domainStates$r2, _props$webChatContain9, _props$webChatContain10, _state$domainStates$r3, _state$domainStates$r4, _props$webChatContain11, _props$webChatContain12, _defaultWebChatContai, _props$webChatContain13, _props$webChatContain14, _props$webChatContain15, _props$webChatContain16, _state$domainStates$r5, _state$domainStates$r6, _props$webChatContain17, _props$webChatContain18, _defaultWebChatContai2, _props$webChatContain19, _props$webChatContain20, _defaultWebChatContai3, _props$webChatContain21;
30
29
 
@@ -54,15 +53,10 @@ export const initWebChatComposer = (props, chatSDK, state, dispatch, setWebChatS
54
53
  }
55
54
 
56
55
  if (isPostChatEnabled === "true" && postChatSurveyMode === PostChatSurveyMode.Embed) {
57
- dispatch({
58
- type: LiveChatWidgetActionType.SET_SHOULD_SHOW_POST_CHAT,
59
- payload: true
60
- });
61
- dispatch({
62
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
63
- payload: ConversationState.Loading
64
- });
65
- await setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
56
+ const loadPostChatEvent = {
57
+ eventName: "LoadPostChatSurvey"
58
+ };
59
+ BroadcastService.postMessage(loadPostChatEvent);
66
60
  } else {
67
61
  dispatch({
68
62
  type: LiveChatWidgetActionType.SET_CONVERSATION_ENDED_BY_AGENT,
@@ -4,9 +4,19 @@ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
4
4
  import { defaultAriaConfig } from "../../../common/telemetry/defaultConfigs/defaultAriaConfig";
5
5
  import { defaultInternalTelemetryData } from "../../../common/telemetry/defaultConfigs/defaultTelemetryInternalData";
6
6
  import { defaultTelemetryConfiguration } from "../../../common/telemetry/defaultConfigs/defaultTelemetryConfiguration";
7
+ import { version as chatComponentVersion } from "@microsoft/omnichannel-chat-components/package.json";
8
+ import { version as chatSdkVersion } from "@microsoft/omnichannel-chat-sdk/package.json";
7
9
  export const registerTelemetryLoggers = (props, dispatch) => {
8
10
  var _props$liveChatContex, _props$liveChatContex2;
9
11
 
12
+ let widgetPackageInfo;
13
+
14
+ try {
15
+ widgetPackageInfo = require("@microsoft/omnichannel-chat-widget/package.json");
16
+ } catch (error) {
17
+ widgetPackageInfo = "0.0.0-0";
18
+ }
19
+
10
20
  const telemetryConfig = { ...defaultTelemetryConfiguration,
11
21
  ...props.telemetryConfig
12
22
  };
@@ -16,6 +26,8 @@ export const registerTelemetryLoggers = (props, dispatch) => {
16
26
 
17
27
  TelemetryManager.InternalTelemetryData = (_props$liveChatContex3 = props.liveChatContextFromCache) === null || _props$liveChatContex3 === void 0 ? void 0 : (_props$liveChatContex4 = _props$liveChatContex3.domainStates) === null || _props$liveChatContex4 === void 0 ? void 0 : _props$liveChatContex4.telemetryInternalData;
18
28
  } else {
29
+ var _props$chatSDK, _props$chatSDK$omnich, _props$chatSDK2, _props$chatSDK2$omnic, _props$chatSDK3, _props$chatSDK3$omnic;
30
+
19
31
  let telemetryData = { ...defaultInternalTelemetryData,
20
32
  telemetryConfig: Object.assign({}, defaultTelemetryConfiguration, telemetryConfig),
21
33
  ariaConfig: Object.assign({}, defaultAriaConfig, telemetryConfig === null || telemetryConfig === void 0 ? void 0 : telemetryConfig.ariaConfigurations)
@@ -26,9 +38,12 @@ export const registerTelemetryLoggers = (props, dispatch) => {
26
38
  }
27
39
 
28
40
  telemetryData = TelemetryHelper.addWidgetDataToTelemetry(telemetryConfig, telemetryData);
29
- telemetryData.OCChatSDKVersion = telemetryConfig === null || telemetryConfig === void 0 ? void 0 : telemetryConfig.OCChatSDKVersion;
30
- telemetryData.chatComponentVersion = telemetryConfig === null || telemetryConfig === void 0 ? void 0 : telemetryConfig.chatComponentVersion;
31
- telemetryData.chatWidgetVersion = telemetryConfig === null || telemetryConfig === void 0 ? void 0 : telemetryConfig.chatWidgetVersion;
41
+ telemetryData.OCChatSDKVersion = chatSdkVersion;
42
+ telemetryData.chatComponentVersion = chatComponentVersion;
43
+ telemetryData.chatWidgetVersion = widgetPackageInfo;
44
+ telemetryData.orgId = (_props$chatSDK = props.chatSDK) === null || _props$chatSDK === void 0 ? void 0 : (_props$chatSDK$omnich = _props$chatSDK.omnichannelConfig) === null || _props$chatSDK$omnich === void 0 ? void 0 : _props$chatSDK$omnich.orgId;
45
+ telemetryData.widgetId = (_props$chatSDK2 = props.chatSDK) === null || _props$chatSDK2 === void 0 ? void 0 : (_props$chatSDK2$omnic = _props$chatSDK2.omnichannelConfig) === null || _props$chatSDK2$omnic === void 0 ? void 0 : _props$chatSDK2$omnic.widgetId;
46
+ telemetryData.orgUrl = (_props$chatSDK3 = props.chatSDK) === null || _props$chatSDK3 === void 0 ? void 0 : (_props$chatSDK3$omnic = _props$chatSDK3.omnichannelConfig) === null || _props$chatSDK3$omnic === void 0 ? void 0 : _props$chatSDK3$omnic.orgUrl;
32
47
  dispatch({
33
48
  type: LiveChatWidgetActionType.SET_TELEMETRY_DATA,
34
49
  payload: telemetryData
@@ -1,20 +1,23 @@
1
1
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
2
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
3
3
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
4
- import { ConversationState } from "../../../contexts/common/ConversationState"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
-
6
- export const setPostChatContextAndLoadSurvey = async (chatSDK, dispatch, loadSurvey) => {
4
+ import { ConversationState } from "../../../contexts/common/ConversationState";
5
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ export const setPostChatContextAndLoadSurvey = async (chatSDK, dispatch, persistedChat) => {
7
8
  try {
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- const context = await chatSDK.getPostChatSurveyContext();
10
- TelemetryHelper.logSDKEvent(LogLevel.INFO, {
11
- Event: TelemetryEvent.PostChatContextCallSucceed,
12
- Description: "Postchat context call succeed."
13
- });
14
- dispatch({
15
- type: LiveChatWidgetActionType.SET_POST_CHAT_CONTEXT,
16
- payload: context
17
- });
9
+ if (!persistedChat) {
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ const context = await chatSDK.getPostChatSurveyContext();
12
+ TelemetryHelper.logSDKEvent(LogLevel.INFO, {
13
+ Event: TelemetryEvent.PostChatContextCallSucceed,
14
+ Description: "Postchat context call succeed."
15
+ });
16
+ dispatch({
17
+ type: LiveChatWidgetActionType.SET_POST_CHAT_CONTEXT,
18
+ payload: context
19
+ });
20
+ }
18
21
  } catch (ex) {
19
22
  TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
20
23
  Event: TelemetryEvent.PostChatContextCallFailed,
@@ -23,18 +26,15 @@ export const setPostChatContextAndLoadSurvey = async (chatSDK, dispatch, loadSur
23
26
  }
24
27
  });
25
28
  }
26
- /* -true: setPostChatContextAndLoadSurvey is called after passing all checks from ConfirmationPane and endChatMiddleware in usual scenario.
27
- -false: Below if condition is needed for multi-tab scenarios. So when agent ends a chat and customer has opened chat in multiple tabs,
28
- all tabs should show post chat survey as per existing functionality. But when an agent end a conversation, Omnichannel SDK
29
- getPostChatSurveyContext returns as invalid conversation. To avoid that, caching the survey url is needed after chat starts and
30
- in this case loadSurvey is false
31
- */
32
-
33
29
 
34
- if (loadSurvey) {
30
+ BroadcastService.getMessageByEventName("LoadPostChatSurvey").subscribe(msg => {
31
+ dispatch({
32
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
33
+ payload: ConversationState.Loading
34
+ });
35
35
  dispatch({
36
36
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
37
37
  payload: ConversationState.Postchat
38
38
  });
39
- }
39
+ });
40
40
  };
@@ -1,6 +1,7 @@
1
+ import { ChatSDKError, Constants } from "../../../common/Constants";
1
2
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
- import { ChatSDKError } from "../../../common/Constants";
3
3
  import { ConversationState } from "../../../contexts/common/ConversationState";
4
+ import { DataStoreManager } from "../../../common/contextDataStore/DataStoreManager";
4
5
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
5
6
  import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
6
7
  import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
@@ -9,11 +10,15 @@ import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
9
10
  import { createAdapter } from "./createAdapter";
10
11
  import { createTimer } from "../../../common/utils";
11
12
  import { getReconnectIdForAuthenticatedChat } from "./reconnectChatHelper";
12
- import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry";
13
- import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey";
14
+ import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry"; // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
15
 
15
16
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
16
- // Getting PreChat Survey Context
17
+ if (await canConnectToExistingChat(props, chatSDK, state, dispatch, setAdapter)) {
18
+ return;
19
+ } // Getting PreChat Survey Context
20
+
21
+
17
22
  const parseToJson = false;
18
23
  const preChatSurveyResponse = await chatSDK.getPreChatSurvey(parseToJson);
19
24
  const showPrechat = state.appStates.conversationState === ConversationState.ProactiveChat ? preChatSurveyResponse && state.appStates.proactiveChatStates.proactiveChatEnablePrechat : preChatSurveyResponse; // Getting reconnectId for authenticated chat
@@ -48,18 +53,18 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
48
53
  }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
54
 
50
55
 
51
- const initStartChat = async (chatSDK, dispatch, setAdapter, params) => {
56
+ const initStartChat = async (chatSDK, dispatch, setAdapter, params, persistedState) => {
52
57
  try {
53
58
  var _TelemetryTimers$Widg;
54
59
 
55
60
  try {
56
- TelemetryHelper.logConfigDataEvent(LogLevel.INFO, {
61
+ TelemetryTimers.WidgetLoadTimer = createTimer();
62
+ TelemetryHelper.logSDKEvent(LogLevel.INFO, {
57
63
  Event: TelemetryEvent.StartChatSDKCall
58
64
  });
59
65
  await chatSDK.startChat(params);
60
- TelemetryTimers.WidgetLoadTimer = createTimer();
61
66
  } catch (error) {
62
- TelemetryHelper.logLoadingEvent(LogLevel.ERROR, {
67
+ TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
63
68
  Event: TelemetryEvent.StartChatMethodException,
64
69
  ExceptionDetails: {
65
70
  exception: `Failed to setup startChat: ${error}`
@@ -68,24 +73,40 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params) => {
68
73
  }
69
74
 
70
75
  const newAdapter = await createAdapter(chatSDK);
71
- setAdapter(newAdapter); // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ setAdapter(newAdapter);
72
77
 
73
- if (chatSDK !== null && chatSDK !== void 0 && chatSDK.getVoiceVideoCalling) {
78
+ if (!persistedState) {
74
79
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
- const chatToken = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getChatToken());
80
+ if (chatSDK !== null && chatSDK !== void 0 && chatSDK.getVoiceVideoCalling) {
81
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
82
+ const chatToken = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getChatToken());
83
+ dispatch({
84
+ type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
85
+ payload: chatToken
86
+ });
87
+ } // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
+
89
+
90
+ const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
76
91
  dispatch({
77
- type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
78
- payload: chatToken
92
+ type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
93
+ payload: liveChatContext
79
94
  });
80
- }
95
+ await setPostChatContextAndLoadSurvey(chatSDK, dispatch);
96
+ await updateSessionDataForTelemetry(chatSDK, dispatch); // Set app state to Active
81
97
 
82
- await setPostChatContextAndLoadSurvey(chatSDK, dispatch, false);
83
- await updateSessionDataForTelemetry(chatSDK, dispatch); // Set app state to Active
98
+ dispatch({
99
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
100
+ payload: ConversationState.Active
101
+ });
102
+ } else {
103
+ dispatch({
104
+ type: LiveChatWidgetActionType.SET_WIDGET_STATE,
105
+ payload: persistedState
106
+ });
107
+ await setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
108
+ }
84
109
 
85
- dispatch({
86
- type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
87
- payload: ConversationState.Active
88
- });
89
110
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
90
111
  Event: TelemetryEvent.WidgetLoadComplete,
91
112
  Description: "Widget load complete",
@@ -93,9 +114,9 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params) => {
93
114
  });
94
115
  } catch (ex) {
95
116
  TelemetryHelper.logLoadingEvent(LogLevel.ERROR, {
96
- Event: TelemetryEvent.StartChatFailed,
117
+ Event: TelemetryEvent.WidgetLoadFailed,
97
118
  ExceptionDetails: {
98
- Exception: `Start Chat Failed: ${ex}`
119
+ Exception: `Widget load Failed: ${ex}`
99
120
  }
100
121
  });
101
122
  NotificationHandler.notifyError(NotificationScenarios.Connection, "Start Chat Failed: " + ex); // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -111,6 +132,30 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, params) => {
111
132
  });
112
133
  }
113
134
  }
135
+ }; // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+
137
+
138
+ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdapter) => {
139
+ var _DataStoreManager$cli, _persistedState$domai;
140
+
141
+ const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(Constants.widgetStateDataKey, "localStorage");
142
+ const persistedState = widgetStateFromCache ? JSON.parse(widgetStateFromCache) : undefined;
143
+
144
+ if (persistedState !== null && persistedState !== void 0 && (_persistedState$domai = persistedState.domainStates) !== null && _persistedState$domai !== void 0 && _persistedState$domai.liveChatContext) {
145
+ var _persistedState$domai2;
146
+
147
+ dispatch({
148
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
149
+ payload: ConversationState.Loading
150
+ });
151
+ const optionalParams = {
152
+ liveChatContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai2 = persistedState.domainStates) === null || _persistedState$domai2 === void 0 ? void 0 : _persistedState$domai2.liveChatContext
153
+ };
154
+ await initStartChat(chatSDK, dispatch, setAdapter, optionalParams, persistedState);
155
+ return true;
156
+ } else {
157
+ return false;
158
+ }
114
159
  };
115
160
 
116
161
  export { prepareStartChat, initStartChat };
@@ -2,14 +2,14 @@ import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryCon
2
2
  import { ConversationState } from "../../../contexts/common/ConversationState";
3
3
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
4
4
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
5
- import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager"; // Defines startProactiveChat callback
6
-
7
- export const startProactiveChat = (dispatch, bodyTitle, showPrechat, inNewWindow) => {
5
+ import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
6
+ // Defines startProactiveChat callback
7
+ export const startProactiveChat = (dispatch, notificationConfig, enablePreChat, inNewWindow) => {
8
8
  dispatch({
9
9
  type: LiveChatWidgetActionType.SET_PROACTIVE_CHAT_PARAMS,
10
10
  payload: {
11
- proactiveChatBodyTitle: bodyTitle ?? "",
12
- proactiveChatEnablePrechat: showPrechat ?? false,
11
+ proactiveChatBodyTitle: notificationConfig && notificationConfig.message ? notificationConfig.message : "",
12
+ proactiveChatEnablePrechat: enablePreChat ?? false,
13
13
  proactiveChatInNewWindow: inNewWindow ?? false
14
14
  }
15
15
  });
@@ -39,8 +39,10 @@ import { startProactiveChat } from "../common/startProactiveChat";
39
39
  import useChatAdapterStore from "../../../hooks/useChatAdapterStore";
40
40
  import useChatContextStore from "../../../hooks/useChatContextStore";
41
41
  import useChatSDKStore from "../../../hooks/useChatSDKStore";
42
- import { TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
42
+ import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
43
43
  import { disposeTelemetryLoggers } from "../common/disposeTelemetryLoggers";
44
+ import { DataStoreManager } from "../../../common/contextDataStore/DataStoreManager";
45
+ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
44
46
  export const LiveChatWidgetStateful = props => {
45
47
  var _props$webChatContain, _props$styleProps, _props$controlProps, _props$webChatContain3, _props$webChatContain4, _props$styleProps2, _props$controlProps5, _props$componentOverr, _props$controlProps6, _props$componentOverr2, _props$controlProps7, _props$componentOverr3, _props$controlProps8, _props$componentOverr4, _props$controlProps9, _props$componentOverr5, _props$controlProps10, _props$componentOverr6, _props$controlProps11, _props$controlProps12, _props$controlProps13, _props$componentOverr7, _props$controlProps14, _props$componentOverr8, _props$controlProps15, _props$componentOverr9, _props$componentOverr10, _props$componentOverr11;
46
48
 
@@ -69,6 +71,7 @@ export const LiveChatWidgetStateful = props => {
69
71
 
70
72
  registerTelemetryLoggers(props, dispatch);
71
73
  createInternetConnectionChangeHandler();
74
+ DataStoreManager.clientDataStore = props.contextDataStore ?? undefined;
72
75
  dispatch({
73
76
  type: LiveChatWidgetActionType.SET_WIDGET_ELEMENT_ID,
74
77
  payload: widgetElementId
@@ -140,10 +143,20 @@ export const LiveChatWidgetStateful = props => {
140
143
  }, [state.appStates.skipChatButtonRendering]);
141
144
  useEffect(() => {
142
145
  BroadcastService.getMessageByEventName("StartProactiveChat").subscribe(msg => {
146
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
147
+ Event: TelemetryEvent.StartProactiveChatEventReceived,
148
+ Description: "Start proactive chat event received."
149
+ });
150
+
143
151
  if (canStartProactiveChat.current) {
144
152
  var _msg$payload, _msg$payload2, _msg$payload3;
145
153
 
146
- startProactiveChat(dispatch, msg === null || msg === void 0 ? void 0 : (_msg$payload = msg.payload) === null || _msg$payload === void 0 ? void 0 : _msg$payload.bodyTitle, msg === null || msg === void 0 ? void 0 : (_msg$payload2 = msg.payload) === null || _msg$payload2 === void 0 ? void 0 : _msg$payload2.showPrechat, msg === null || msg === void 0 ? void 0 : (_msg$payload3 = msg.payload) === null || _msg$payload3 === void 0 ? void 0 : _msg$payload3.inNewWindow);
154
+ startProactiveChat(dispatch, msg === null || msg === void 0 ? void 0 : (_msg$payload = msg.payload) === null || _msg$payload === void 0 ? void 0 : _msg$payload.notificationConfig, msg === null || msg === void 0 ? void 0 : (_msg$payload2 = msg.payload) === null || _msg$payload2 === void 0 ? void 0 : _msg$payload2.enablePreChat, msg === null || msg === void 0 ? void 0 : (_msg$payload3 = msg.payload) === null || _msg$payload3 === void 0 ? void 0 : _msg$payload3.inNewWindow);
155
+ } else {
156
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
157
+ Event: TelemetryEvent.ChatAlreadyTriggered,
158
+ Description: "Start proactive chat method called, when chat was already triggered."
159
+ });
147
160
  }
148
161
  });
149
162
  window.addEventListener("beforeunload", event => {
@@ -166,7 +179,7 @@ export const LiveChatWidgetStateful = props => {
166
179
  } // Track the message count
167
180
 
168
181
 
169
- if (state.appStates.conversationState == ConversationState.Active) {
182
+ if (state.appStates.conversationState === ConversationState.Active) {
170
183
  chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.onNewMessage(() => {
171
184
  currentMessageCountRef.current++;
172
185
  dispatch({
@@ -210,23 +223,25 @@ export const LiveChatWidgetStateful = props => {
210
223
  }, [(_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : _props$webChatContain3.webChatStyles]);
211
224
  const webChatProps = initWebChatComposer(props, chatSDK, state, dispatch, setWebChatStyles);
212
225
 
213
- const setPostChatContextRelay = () => setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
226
+ const setPostChatContextRelay = () => setPostChatContextAndLoadSurvey(chatSDK, dispatch);
214
227
 
215
228
  const endChatRelay = () => endChat(props, chatSDK, setAdapter, setWebChatStyles, dispatch, adapter);
216
229
 
217
230
  const prepareStartChatRelay = () => prepareStartChat(props, chatSDK, state, dispatch, setAdapter); // eslint-disable-next-line @typescript-eslint/no-explicit-any
218
231
 
219
232
 
220
- const initStartChatRelay = optionalParams => initStartChat(chatSDK, dispatch, setAdapter, optionalParams);
233
+ const initStartChatRelay = (optionalParams, persistedState) => initStartChat(chatSDK, dispatch, setAdapter, optionalParams, persistedState);
221
234
 
222
235
  const confirmationPaneProps = initConfirmationPropsComposer(props); // publish chat widget state
223
236
 
224
- const chatWidgetStateChangeEvent = {
225
- eventName: TelemetryEvent.ChatWidgetStateChanged,
226
- payload: { ...state
227
- }
228
- };
229
- BroadcastService.postMessage(chatWidgetStateChangeEvent);
237
+ useEffect(() => {
238
+ const chatWidgetStateChangeEvent = {
239
+ eventName: TelemetryEvent.ChatWidgetStateChanged,
240
+ payload: { ...state
241
+ }
242
+ };
243
+ BroadcastService.postMessage(chatWidgetStateChangeEvent);
244
+ }, [state]);
230
245
  return /*#__PURE__*/React.createElement(Composer, _extends({}, webChatProps, {
231
246
  styleOptions: webChatStyles,
232
247
  directLine: ((_props$webChatContain4 = props.webChatContainerProps) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.directLine) ?? adapter ?? defaultWebChatContainerStatefulProps.directLine
@@ -26,7 +26,7 @@ export const LoadingPaneStateful = props => {
26
26
  firstElement[0].focus();
27
27
  }
28
28
 
29
- TelemetryHelper.logActionEvent(LogLevel.INFO, {
29
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
30
30
  Event: TelemetryEvent.LoadingPaneLoaded,
31
31
  Description: "Loading pane loaded."
32
32
  });
@@ -1,5 +1,7 @@
1
+ import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
1
2
  import React, { useEffect } from "react";
2
3
  import { OutOfOfficeHoursPane } from "@microsoft/omnichannel-chat-components";
4
+ import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
3
5
  import { defaultGeneralStyleProps } from "./common/defaultStyleProps/defaultgeneralOOOHPaneStyleProps";
4
6
  import { findAllFocusableElement } from "../../common/utils";
5
7
  import useChatContextStore from "../../hooks/useChatContextStore";
@@ -23,6 +25,10 @@ export const OutOfOfficeHoursPaneStateful = props => {
23
25
  if (firstElement && firstElement[0]) {
24
26
  firstElement[0].focus();
25
27
  }
28
+
29
+ TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
30
+ Event: TelemetryEvent.OutOfOfficePaneLoaded
31
+ });
26
32
  }, []);
27
33
  return /*#__PURE__*/React.createElement(OutOfOfficeHoursPane, {
28
34
  componentOverrides: props.componentOverrides,
@@ -1,10 +1,11 @@
1
+ import { Constants, HtmlAttributeNames, Regex } from "../../common/Constants";
1
2
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
2
3
  import React, { useEffect } from "react";
3
4
  import { extractPreChatSurveyResponseValues, findAllFocusableElement, parseAdaptiveCardPayload } from "../../common/utils";
4
5
  import { ConversationState } from "../../contexts/common/ConversationState";
6
+ import { DataStoreManager } from "../../common/contextDataStore/DataStoreManager";
5
7
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
6
8
  import { PreChatSurveyPane } from "@microsoft/omnichannel-chat-components";
7
- import { HtmlAttributeNames, Regex } from "../../common/Constants";
8
9
  import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
9
10
  import { defaultGeneralPreChatSurveyPaneStyleProps } from "./common/defaultStyles/defaultGeneralPreChatSurveyPaneStyleProps";
10
11
  import { defaultPreChatSurveyLocalizedTexts } from "./common/defaultProps/defaultPreChatSurveyLocalizedTexts";
@@ -39,7 +40,7 @@ export const PreChatSurveyPaneStateful = props => {
39
40
  try {
40
41
  return parseAdaptiveCardPayload(payload, requiredFieldMissingMessage);
41
42
  } catch (ex) {
42
- TelemetryHelper.logLoadingEvent(LogLevel.ERROR, {
43
+ TelemetryHelper.logConfigDataEvent(LogLevel.ERROR, {
43
44
  Event: TelemetryEvent.ParseAdaptiveCardFailed,
44
45
  Description: "Adaptive Card JSON Parse Failed.",
45
46
  ExceptionDetails: {
@@ -66,14 +67,29 @@ export const PreChatSurveyPaneStateful = props => {
66
67
  });
67
68
 
68
69
  try {
69
- const prechatResponseValues = extractPreChatSurveyResponseValues(state.domainStates.preChatSurveyResponse, values);
70
- const optionalParams = {
71
- initContext: {
72
- preChatResponse: prechatResponseValues
73
- }
74
- };
75
- setPreChatResponseEmail(values);
76
- await initStartChat(optionalParams);
70
+ var _DataStoreManager$cli, _persistedState$domai;
71
+
72
+ const widgetStateFromCache = (_DataStoreManager$cli = DataStoreManager.clientDataStore) === null || _DataStoreManager$cli === void 0 ? void 0 : _DataStoreManager$cli.getData(Constants.widgetStateDataKey, "localStorage");
73
+ const persistedState = widgetStateFromCache ? JSON.parse(widgetStateFromCache) : undefined;
74
+ let optionalParams = {};
75
+
76
+ if (persistedState !== null && persistedState !== void 0 && (_persistedState$domai = persistedState.domainStates) !== null && _persistedState$domai !== void 0 && _persistedState$domai.liveChatContext) {
77
+ var _persistedState$domai2;
78
+
79
+ optionalParams = {
80
+ liveChatContext: persistedState === null || persistedState === void 0 ? void 0 : (_persistedState$domai2 = persistedState.domainStates) === null || _persistedState$domai2 === void 0 ? void 0 : _persistedState$domai2.liveChatContext
81
+ };
82
+ await initStartChat(optionalParams, persistedState);
83
+ } else {
84
+ const prechatResponseValues = extractPreChatSurveyResponseValues(state.domainStates.preChatSurveyResponse, values);
85
+ optionalParams = {
86
+ initContext: {
87
+ preChatResponse: prechatResponseValues
88
+ }
89
+ };
90
+ setPreChatResponseEmail(values);
91
+ await initStartChat(optionalParams);
92
+ }
77
93
  } catch (ex) {
78
94
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
79
95
  Event: TelemetryEvent.PreChatSurveyStartChatMethodFailed,
@@ -28,7 +28,7 @@ export const ProactiveChatPaneStateful = props => {
28
28
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
29
29
  payload: ConversationState.Closed
30
30
  });
31
- TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
31
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
32
32
  Event: TelemetryEvent.ProactiveChatRejected,
33
33
  ElapsedTimeInMilliseconds: TelemetryTimers.LcwLoadToChatButtonTimer.milliSecondsElapsed,
34
34
  Description: "Proactive chat invitation timed out."
@@ -51,12 +51,12 @@ export const ProactiveChatPaneStateful = props => {
51
51
  if (state.appStates.proactiveChatStates.proactiveChatInNewWindow) {
52
52
  // TODO: BroadcastService: replace with the sdk broadcast service, when in place
53
53
  const startPopoutChatEvent = {
54
- eventName: "StartPopoutChat"
54
+ eventName: TelemetryEvent.ProactiveChatStartPopoutChat
55
55
  };
56
56
  BroadcastService.postMessage(startPopoutChatEvent);
57
57
  dispatch({
58
- type: LiveChatWidgetActionType.SET_SKIP_CHAT_BUTTON_RENDERING,
59
- payload: true
58
+ type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
59
+ payload: ConversationState.Closed
60
60
  });
61
61
  } else if (((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : (_state$domainStates$l2 = _state$domainStates$l.LiveWSAndLiveChatEngJoin) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.OutOfOperatingHours) === "True") {
62
62
  dispatch({
@@ -68,6 +68,10 @@ export const ProactiveChatPaneStateful = props => {
68
68
  payload: ConversationState.OutOfOffice
69
69
  });
70
70
  } else {
71
+ const proactiveChatStarted = {
72
+ eventName: TelemetryEvent.ProactiveChatStartChat
73
+ };
74
+ BroadcastService.postMessage(proactiveChatStarted);
71
75
  await startChat();
72
76
  }
73
77
  },
@@ -30,4 +30,6 @@ export let LiveChatWidgetActionType;
30
30
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_UNREAD_MESSAGE_COUNT"] = 26] = "SET_UNREAD_MESSAGE_COUNT";
31
31
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_FOCUS_CHAT_BUTTON"] = 27] = "SET_FOCUS_CHAT_BUTTON";
32
32
  LiveChatWidgetActionType[LiveChatWidgetActionType["SET_CONVERSATION_ENDED_BY_AGENT"] = 28] = "SET_CONVERSATION_ENDED_BY_AGENT";
33
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_WIDGET_STATE"] = 29] = "SET_WIDGET_STATE";
34
+ LiveChatWidgetActionType[LiveChatWidgetActionType["SET_LIVE_CHAT_CONTEXT"] = 30] = "SET_LIVE_CHAT_CONTEXT";
33
35
  })(LiveChatWidgetActionType || (LiveChatWidgetActionType = {}));
@@ -13,7 +13,8 @@ export const getLiveChatWidgetContextInitialState = props => {
13
13
  chatToken: undefined,
14
14
  postChatContext: undefined,
15
15
  telemetryInternalData: {},
16
- globalDir: "ltr"
16
+ globalDir: "ltr",
17
+ liveChatContext: undefined
17
18
  },
18
19
  appStates: {
19
20
  conversationState: ConversationState.Closed,
@@ -136,6 +136,7 @@ export const createReducer = () => {
136
136
  case LiveChatWidgetActionType.SET_CHAT_TOKEN:
137
137
  return { ...state,
138
138
  domainStates: { ...state.domainStates,
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
140
  chatToken: action.payload
140
141
  }
141
142
  };
@@ -208,6 +209,18 @@ export const createReducer = () => {
208
209
  }
209
210
  };
210
211
 
212
+ case LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT:
213
+ return { ...state,
214
+ domainStates: { ...state.domainStates,
215
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
216
+ liveChatContext: action.payload
217
+ }
218
+ };
219
+
220
+ case LiveChatWidgetActionType.SET_WIDGET_STATE:
221
+ return { ...action.payload
222
+ };
223
+
211
224
  case LiveChatWidgetActionType.SET_CONVERSATION_ENDED_BY_AGENT:
212
225
  return { ...state,
213
226
  appStates: { ...state.appStates,
@@ -13,6 +13,7 @@ export declare class Constants {
13
13
  static readonly true = "true";
14
14
  static readonly false = "false";
15
15
  static readonly maximumUnreadMessageCount = 99;
16
+ static readonly widgetStateDataKey = "LcwChatWidgetState";
16
17
  static readonly channelIdKey = "ChannelId-";
17
18
  static readonly ChannelId = "lcw";
18
19
  static readonly CustomerTag = "FromCustomer";
@@ -0,0 +1,4 @@
1
+ import { IContextDataStore } from "../interfaces/IContextDataStore";
2
+ export declare class DataStoreManager {
3
+ static clientDataStore?: IContextDataStore;
4
+ }