@microsoft/omnichannel-chat-widget 1.7.2 → 1.7.3-main.5f11aa4

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.
@@ -101,6 +101,7 @@ exports.TelemetryEvent = TelemetryEvent;
101
101
  TelemetryEvent["GetConversationDetailsCallStarted"] = "GetConversationDetailsCallStarted";
102
102
  TelemetryEvent["GetConversationDetailsCallFailed"] = "GetConversationDetailsCallFailed";
103
103
  TelemetryEvent["EndChatSDKCallFailed"] = "EndChatSDKCallFailed";
104
+ TelemetryEvent["DisconnectEndChatSDKCallFailed"] = "DisconnectEndChatSDKCallFailed";
104
105
  TelemetryEvent["GetChatReconnectContextSDKCallStarted"] = "GetChatReconnectContextSDKCallStarted";
105
106
  TelemetryEvent["GetChatReconnectContextSDKCallFailed"] = "GetChatReconnectContextSDKCallFailed";
106
107
  TelemetryEvent["ParseAdaptiveCardFailed"] = "ParseAdaptiveCardFailed";
@@ -141,12 +141,27 @@ const endChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatSt
141
141
  await (0, _authHelper.handleAuthentication)(chatSDK, props.chatConfig, props.getAuthToken);
142
142
  await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.endChat());
143
143
  } catch (ex) {
144
- _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.ERROR, {
145
- Event: _TelemetryConstants.TelemetryEvent.EndChatSDKCallFailed,
146
- ExceptionDetails: {
147
- exception: ex
148
- }
144
+ var _inMemoryState$appSta;
145
+ const inMemoryState = (0, _createReducer.executeReducer)(state, {
146
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
147
+ payload: null
149
148
  });
149
+ // if the chat was disconnected or ended by the agent, we don't want to log the error
150
+ if (!(inMemoryState !== null && inMemoryState !== void 0 && (_inMemoryState$appSta = inMemoryState.appStates) !== null && _inMemoryState$appSta !== void 0 && _inMemoryState$appSta.chatDisconnectEventReceived)) {
151
+ _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.ERROR, {
152
+ Event: _TelemetryConstants.TelemetryEvent.EndChatSDKCallFailed,
153
+ ExceptionDetails: {
154
+ exception: ex
155
+ }
156
+ });
157
+ } else {
158
+ _TelemetryHelper.TelemetryHelper.logSDKEvent(_TelemetryConstants.LogLevel.WARN, {
159
+ Event: _TelemetryConstants.TelemetryEvent.DisconnectEndChatSDKCallFailed,
160
+ ExceptionDetails: {
161
+ exception: ex
162
+ }
163
+ });
164
+ }
150
165
  postMessageToOtherTab = false;
151
166
  } finally {
152
167
  await endChatStateCleanUp(dispatch);
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.isPostChatSurveyEnabled = void 0;
6
+ exports.isPostChatSurveyEnabled = exports.isPersistentChatEnabled = void 0;
7
+ var _Constants = require("../../../common/Constants");
8
+ var _utils = require("../../../common/utils");
7
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
10
  const isPostChatSurveyEnabled = async chatSDK => {
9
11
  var _chatConfig$LiveWSAnd;
@@ -11,4 +13,11 @@ const isPostChatSurveyEnabled = async chatSDK => {
11
13
  const postChatEnabled = (_chatConfig$LiveWSAnd = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd === void 0 ? void 0 : _chatConfig$LiveWSAnd.msdyn_postconversationsurveyenable.toString().toLowerCase();
12
14
  return postChatEnabled === "true";
13
15
  };
14
- exports.isPostChatSurveyEnabled = isPostChatSurveyEnabled;
16
+ exports.isPostChatSurveyEnabled = isPostChatSurveyEnabled;
17
+ const isPersistentChatEnabled = async conversationMode => {
18
+ if ((0, _utils.isNullOrUndefined)(conversationMode)) {
19
+ return false;
20
+ }
21
+ return (conversationMode === null || conversationMode === void 0 ? void 0 : conversationMode.toString().toLowerCase()) === _Constants.ConversationMode.Persistent;
22
+ };
23
+ exports.isPersistentChatEnabled = isPersistentChatEnabled;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldSetPreChatIfPersistentChat = void 0;
7
+ var _liveChatConfigUtils = require("./liveChatConfigUtils");
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ const shouldSetPreChatIfPersistentChat = async (chatSDK, conversationMode, showPreChat) => {
10
+ const persistentEnabled = await (0, _liveChatConfigUtils.isPersistentChatEnabled)(conversationMode);
11
+ let skipPreChat = false;
12
+ if (persistentEnabled) {
13
+ const reconnectableChatsParams = {
14
+ authenticatedUserToken: chatSDK.authenticatedUserToken
15
+ };
16
+ try {
17
+ const reconnectableChatsResponse = await chatSDK.OCClient.getReconnectableChats(reconnectableChatsParams);
18
+ if (reconnectableChatsResponse && reconnectableChatsResponse.reconnectid) {
19
+ // Skip rendering prechat on existing persistent chat session
20
+ skipPreChat = true;
21
+ }
22
+ } catch {
23
+ // eslint-disable-line no-empty
24
+ }
25
+ }
26
+ return showPreChat && !skipPreChat;
27
+ };
28
+ exports.shouldSetPreChatIfPersistentChat = shouldSetPreChatIfPersistentChat;
@@ -21,6 +21,8 @@ var _setPostChatContextAndLoadSurvey = require("./setPostChatContextAndLoadSurve
21
21
  var _updateSessionDataForTelemetry = require("./updateSessionDataForTelemetry");
22
22
  var _startChatErrorHandler = require("./startChatErrorHandler");
23
23
  var _endChat = require("./endChat");
24
+ var _liveChatConfigUtils = require("./liveChatConfigUtils");
25
+ var _persistentChatHelper = require("./persistentChatHelper");
24
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
27
  let optionalParams = {};
26
28
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -28,6 +30,20 @@ let widgetInstanceId;
28
30
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
31
  let popoutWidgetInstanceId;
30
32
 
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ const setAuthenticationIfApplicable = async (props, chatSDK) => {
35
+ const chatConfig = props === null || props === void 0 ? void 0 : props.chatConfig;
36
+ const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
37
+ const authClientFunction = (0, _authHelper.getAuthClientFunction)(chatConfig);
38
+ if (getAuthToken && authClientFunction) {
39
+ // set auth token to chat sdk before start chat
40
+ const authSuccess = await (0, _authHelper.handleAuthentication)(chatSDK, chatConfig, getAuthToken);
41
+ if (!authSuccess) {
42
+ throw new Error(_Constants.WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
43
+ }
44
+ }
45
+ };
46
+
31
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
48
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
33
49
  optionalParams = {}; //Resetting to ensure no stale values
@@ -53,6 +69,7 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
53
69
  // Setting Proactive chat settings
54
70
  const isProactiveChat = state.appStates.conversationState === _ConversationState.ConversationState.ProactiveChat;
55
71
  const isPreChatEnabledInProactiveChat = state.appStates.proactiveChatStates.proactiveChatEnablePrechat;
72
+ await setAuthenticationIfApplicable(props, chatSDK);
56
73
 
57
74
  //Setting PreChat and intiate chat
58
75
  await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat, state, props);
@@ -61,16 +78,17 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
61
78
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
79
  exports.prepareStartChat = prepareStartChat;
63
80
  const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProactiveChat, proactiveChatEnablePrechatState, state, props) => {
64
- var _props$preChatSurveyP, _props$preChatSurveyP2, _props$controlProps;
81
+ var _props$preChatSurveyP, _props$preChatSurveyP2, _props$controlProps, _state$domainStates, _state$domainStates$l, _state$domainStates$l2;
65
82
  //Handle reconnect scenario
66
83
 
67
84
  // Getting prechat Survey Context
68
85
  const parseToJson = false;
69
86
  const preChatSurveyResponse = (props === null || props === void 0 ? void 0 : (_props$preChatSurveyP = props.preChatSurveyPaneProps) === null || _props$preChatSurveyP === void 0 ? void 0 : (_props$preChatSurveyP2 = _props$preChatSurveyP.controlProps) === null || _props$preChatSurveyP2 === void 0 ? void 0 : _props$preChatSurveyP2.payload) ?? (await chatSDK.getPreChatSurvey(parseToJson));
70
- const showPrechat = isProactiveChat ? preChatSurveyResponse && proactiveChatEnablePrechatState : preChatSurveyResponse && !(props !== null && props !== void 0 && (_props$controlProps = props.controlProps) !== null && _props$controlProps !== void 0 && _props$controlProps.hidePreChatSurveyPane);
87
+ let showPrechat = isProactiveChat ? preChatSurveyResponse && proactiveChatEnablePrechatState : preChatSurveyResponse && !(props !== null && props !== void 0 && (_props$controlProps = props.controlProps) !== null && _props$controlProps !== void 0 && _props$controlProps.hidePreChatSurveyPane);
88
+ showPrechat = await (0, _persistentChatHelper.shouldSetPreChatIfPersistentChat)(chatSDK, state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_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.msdyn_conversationmode, showPrechat);
71
89
  if (showPrechat) {
72
- var _state$domainStates, _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3;
73
- const isOutOfOperatingHours = (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_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$l3 = _state$domainStates$l2.OutOfOperatingHours) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.toLowerCase()) === "true";
90
+ var _state$domainStates2, _state$domainStates2$, _state$domainStates2$2, _state$domainStates2$3;
91
+ const isOutOfOperatingHours = (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.liveChatConfig) === null || _state$domainStates2$ === void 0 ? void 0 : (_state$domainStates2$2 = _state$domainStates2$.LiveWSAndLiveChatEngJoin) === null || _state$domainStates2$2 === void 0 ? void 0 : (_state$domainStates2$3 = _state$domainStates2$2.OutOfOperatingHours) === null || _state$domainStates2$3 === void 0 ? void 0 : _state$domainStates2$3.toLowerCase()) === "true";
74
92
  if (isOutOfOperatingHours) {
75
93
  (state === null || state === void 0 ? void 0 : state.appStates.isMinimized) && dispatch({
76
94
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
@@ -94,7 +112,7 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
94
112
 
95
113
  // If minimized, maximize the chat, if the state is missing, consider it as minimized
96
114
  if ((state === null || state === void 0 ? void 0 : state.appStates.isMinimized) == undefined || (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.isMinimized) === true) {
97
- var _state$domainStates2, _state$domainStates2$, _state$domainStates3, _state$domainStates3$;
115
+ var _state$domainStates3, _state$domainStates3$, _state$domainStates4, _state$domainStates4$;
98
116
  dispatch({
99
117
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
100
118
  payload: false
@@ -104,8 +122,8 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
104
122
  _omnichannelChatComponents.BroadcastService.postMessage({
105
123
  eventName: _TelemetryConstants.BroadcastEvent.MaximizeChat,
106
124
  payload: {
107
- height: state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.widgetSize) === null || _state$domainStates2$ === void 0 ? void 0 : _state$domainStates2$.height,
108
- width: state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.widgetSize) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.width
125
+ height: state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.widgetSize) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.height,
126
+ width: state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.widgetSize) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.width
109
127
  }
110
128
  });
111
129
  }
@@ -127,9 +145,9 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
127
145
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
146
  exports.setPreChatAndInitiateChat = setPreChatAndInitiateChat;
129
147
  const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params, persistedState) => {
148
+ var _state$domainStates5, _state$domainStates5$, _state$domainStates5$2;
130
149
  let isStartChatSuccessful = false;
131
- const chatConfig = props === null || props === void 0 ? void 0 : props.chatConfig;
132
- const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
150
+ const persistentChatEnabled = await (0, _liveChatConfigUtils.isPersistentChatEnabled)(state === null || state === void 0 ? void 0 : (_state$domainStates5 = state.domainStates) === null || _state$domainStates5 === void 0 ? void 0 : (_state$domainStates5$ = _state$domainStates5.liveChatConfig) === null || _state$domainStates5$ === void 0 ? void 0 : (_state$domainStates5$2 = _state$domainStates5$.LiveWSAndLiveChatEngJoin) === null || _state$domainStates5$2 === void 0 ? void 0 : _state$domainStates5$2.msdyn_conversationmode);
133
151
  if ((state === null || state === void 0 ? void 0 : state.appStates.conversationState) === _ConversationState.ConversationState.Closed) {
134
152
  // Preventive reset to avoid starting chat with previous requestId which could potentially cause problems
135
153
  (0, _endChat.chatSDKStateCleanUp)(chatSDK);
@@ -148,14 +166,6 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
148
166
  Event: _TelemetryConstants.TelemetryEvent.WidgetLoadStarted,
149
167
  Description: "Widget loading started"
150
168
  });
151
- const authClientFunction = (0, _authHelper.getAuthClientFunction)(chatConfig);
152
- if (getAuthToken && authClientFunction) {
153
- // set auth token to chat sdk before start chat
154
- const authSuccess = await (0, _authHelper.handleAuthentication)(chatSDK, chatConfig, getAuthToken);
155
- if (!authSuccess) {
156
- throw new Error(_Constants.WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
157
- }
158
- }
159
169
 
160
170
  //Check if chat retrieved from cache
161
171
  if (persistedState || params !== null && params !== void 0 && params.liveChatContext) {
@@ -227,10 +237,14 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
227
237
 
228
238
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
229
239
  const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
230
- dispatch({
231
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
232
- payload: liveChatContext
233
- });
240
+
241
+ // Persistent Chat relies on the `reconnectId` retrieved from reconnectablechats API to reconnect upon start chat and not `liveChatContext`
242
+ if (!persistentChatEnabled) {
243
+ dispatch({
244
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
245
+ payload: liveChatContext
246
+ });
247
+ }
234
248
  (0, _startChatErrorHandler.logWidgetLoadComplete)();
235
249
  // Set post chat context in state
236
250
  // Commenting this for now as post chat context is fetched during end chat
@@ -274,17 +288,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
274
288
 
275
289
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
276
290
  const setCustomContextParams = async (state, props) => {
277
- var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates4, _persistedState$domai8;
291
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates6, _persistedState$domai8;
278
292
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
279
293
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
280
294
  //Should not set custom context for auth chat
281
295
  if (isAuthenticatedChat) {
282
296
  return;
283
297
  }
284
- if (state !== null && state !== void 0 && (_state$domainStates4 = state.domainStates) !== null && _state$domainStates4 !== void 0 && _state$domainStates4.customContext) {
285
- var _state$domainStates5;
298
+ if (state !== null && state !== void 0 && (_state$domainStates6 = state.domainStates) !== null && _state$domainStates6 !== void 0 && _state$domainStates6.customContext) {
299
+ var _state$domainStates7;
286
300
  optionalParams = Object.assign({}, optionalParams, {
287
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates5 = state.domainStates) === null || _state$domainStates5 === void 0 ? void 0 : _state$domainStates5.customContext))
301
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates7 = state.domainStates) === null || _state$domainStates7 === void 0 ? void 0 : _state$domainStates7.customContext))
288
302
  });
289
303
  return;
290
304
  }
@@ -332,9 +346,9 @@ const canStartPopoutChat = async props => {
332
346
 
333
347
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
334
348
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
335
- var _state$domainStates6, _state$domainStates6$, _state$domainStates7;
336
- const requestIdFromCache = (_state$domainStates6 = state.domainStates) === null || _state$domainStates6 === void 0 ? void 0 : (_state$domainStates6$ = _state$domainStates6.liveChatContext) === null || _state$domainStates6$ === void 0 ? void 0 : _state$domainStates6$.requestId;
337
- const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates7 = state.domainStates) === null || _state$domainStates7 === void 0 ? void 0 : _state$domainStates7.liveChatContext;
349
+ var _state$domainStates8, _state$domainStates8$, _state$domainStates9;
350
+ const requestIdFromCache = (_state$domainStates8 = state.domainStates) === null || _state$domainStates8 === void 0 ? void 0 : (_state$domainStates8$ = _state$domainStates8.liveChatContext) === null || _state$domainStates8$ === void 0 ? void 0 : _state$domainStates8$.requestId;
351
+ const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates9 = state.domainStates) === null || _state$domainStates9 === void 0 ? void 0 : _state$domainStates9.liveChatContext;
338
352
 
339
353
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
340
354
  let conversationDetails = undefined;
@@ -66,9 +66,13 @@ class MockChatSDK {
66
66
  getLiveChatConfig() {
67
67
  return {
68
68
  LiveWSAndLiveChatEngJoin: {
69
- msdyn_postconversationsurveyenable: "true"
69
+ msdyn_postconversationsurveyenable: "true",
70
+ msdyn_conversationmode: "192350000"
70
71
  }
71
72
  };
72
73
  }
74
+ sendTypingEvent() {
75
+ return null;
76
+ }
73
77
  }
74
78
  exports.MockChatSDK = MockChatSDK;
@@ -95,6 +95,7 @@ export let TelemetryEvent;
95
95
  TelemetryEvent["GetConversationDetailsCallStarted"] = "GetConversationDetailsCallStarted";
96
96
  TelemetryEvent["GetConversationDetailsCallFailed"] = "GetConversationDetailsCallFailed";
97
97
  TelemetryEvent["EndChatSDKCallFailed"] = "EndChatSDKCallFailed";
98
+ TelemetryEvent["DisconnectEndChatSDKCallFailed"] = "DisconnectEndChatSDKCallFailed";
98
99
  TelemetryEvent["GetChatReconnectContextSDKCallStarted"] = "GetChatReconnectContextSDKCallStarted";
99
100
  TelemetryEvent["GetChatReconnectContextSDKCallFailed"] = "GetChatReconnectContextSDKCallFailed";
100
101
  TelemetryEvent["ParseAdaptiveCardFailed"] = "ParseAdaptiveCardFailed";
@@ -135,12 +135,27 @@ const endChat = async (props, chatSDK, state, dispatch, setAdapter, setWebChatSt
135
135
  await handleAuthentication(chatSDK, props.chatConfig, props.getAuthToken);
136
136
  await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.endChat());
137
137
  } catch (ex) {
138
- TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
139
- Event: TelemetryEvent.EndChatSDKCallFailed,
140
- ExceptionDetails: {
141
- exception: ex
142
- }
138
+ var _inMemoryState$appSta;
139
+ const inMemoryState = executeReducer(state, {
140
+ type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
141
+ payload: null
143
142
  });
143
+ // if the chat was disconnected or ended by the agent, we don't want to log the error
144
+ if (!(inMemoryState !== null && inMemoryState !== void 0 && (_inMemoryState$appSta = inMemoryState.appStates) !== null && _inMemoryState$appSta !== void 0 && _inMemoryState$appSta.chatDisconnectEventReceived)) {
145
+ TelemetryHelper.logSDKEvent(LogLevel.ERROR, {
146
+ Event: TelemetryEvent.EndChatSDKCallFailed,
147
+ ExceptionDetails: {
148
+ exception: ex
149
+ }
150
+ });
151
+ } else {
152
+ TelemetryHelper.logSDKEvent(LogLevel.WARN, {
153
+ Event: TelemetryEvent.DisconnectEndChatSDKCallFailed,
154
+ ExceptionDetails: {
155
+ exception: ex
156
+ }
157
+ });
158
+ }
144
159
  postMessageToOtherTab = false;
145
160
  } finally {
146
161
  await endChatStateCleanUp(dispatch);
@@ -1,7 +1,16 @@
1
+ import { ConversationMode } from "../../../common/Constants";
2
+ import { isNullOrUndefined } from "../../../common/utils";
3
+
1
4
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2
5
  export const isPostChatSurveyEnabled = async chatSDK => {
3
6
  var _chatConfig$LiveWSAnd;
4
7
  const chatConfig = await chatSDK.getLiveChatConfig();
5
8
  const postChatEnabled = (_chatConfig$LiveWSAnd = chatConfig.LiveWSAndLiveChatEngJoin) === null || _chatConfig$LiveWSAnd === void 0 ? void 0 : _chatConfig$LiveWSAnd.msdyn_postconversationsurveyenable.toString().toLowerCase();
6
9
  return postChatEnabled === "true";
10
+ };
11
+ export const isPersistentChatEnabled = async conversationMode => {
12
+ if (isNullOrUndefined(conversationMode)) {
13
+ return false;
14
+ }
15
+ return (conversationMode === null || conversationMode === void 0 ? void 0 : conversationMode.toString().toLowerCase()) === ConversationMode.Persistent;
7
16
  };
@@ -0,0 +1,22 @@
1
+ import { isPersistentChatEnabled } from "./liveChatConfigUtils";
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ export const shouldSetPreChatIfPersistentChat = async (chatSDK, conversationMode, showPreChat) => {
5
+ const persistentEnabled = await isPersistentChatEnabled(conversationMode);
6
+ let skipPreChat = false;
7
+ if (persistentEnabled) {
8
+ const reconnectableChatsParams = {
9
+ authenticatedUserToken: chatSDK.authenticatedUserToken
10
+ };
11
+ try {
12
+ const reconnectableChatsResponse = await chatSDK.OCClient.getReconnectableChats(reconnectableChatsParams);
13
+ if (reconnectableChatsResponse && reconnectableChatsResponse.reconnectid) {
14
+ // Skip rendering prechat on existing persistent chat session
15
+ skipPreChat = true;
16
+ }
17
+ } catch {
18
+ // eslint-disable-line no-empty
19
+ }
20
+ }
21
+ return showPreChat && !skipPreChat;
22
+ };
@@ -15,6 +15,8 @@ import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurv
15
15
  import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry";
16
16
  import { logWidgetLoadComplete, handleStartChatError } from "./startChatErrorHandler";
17
17
  import { chatSDKStateCleanUp } from "./endChat";
18
+ import { isPersistentChatEnabled } from "./liveChatConfigUtils";
19
+ import { shouldSetPreChatIfPersistentChat } from "./persistentChatHelper";
18
20
 
19
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
22
  let optionalParams = {};
@@ -23,6 +25,20 @@ let widgetInstanceId;
23
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
26
  let popoutWidgetInstanceId;
25
27
 
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const setAuthenticationIfApplicable = async (props, chatSDK) => {
30
+ const chatConfig = props === null || props === void 0 ? void 0 : props.chatConfig;
31
+ const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
32
+ const authClientFunction = getAuthClientFunction(chatConfig);
33
+ if (getAuthToken && authClientFunction) {
34
+ // set auth token to chat sdk before start chat
35
+ const authSuccess = await handleAuthentication(chatSDK, chatConfig, getAuthToken);
36
+ if (!authSuccess) {
37
+ throw new Error(WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
38
+ }
39
+ }
40
+ };
41
+
26
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
43
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
28
44
  optionalParams = {}; //Resetting to ensure no stale values
@@ -48,6 +64,7 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
48
64
  // Setting Proactive chat settings
49
65
  const isProactiveChat = state.appStates.conversationState === ConversationState.ProactiveChat;
50
66
  const isPreChatEnabledInProactiveChat = state.appStates.proactiveChatStates.proactiveChatEnablePrechat;
67
+ await setAuthenticationIfApplicable(props, chatSDK);
51
68
 
52
69
  //Setting PreChat and intiate chat
53
70
  await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat, state, props);
@@ -55,16 +72,17 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
55
72
 
56
73
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
74
  const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProactiveChat, proactiveChatEnablePrechatState, state, props) => {
58
- var _props$preChatSurveyP, _props$preChatSurveyP2, _props$controlProps;
75
+ var _props$preChatSurveyP, _props$preChatSurveyP2, _props$controlProps, _state$domainStates, _state$domainStates$l, _state$domainStates$l2;
59
76
  //Handle reconnect scenario
60
77
 
61
78
  // Getting prechat Survey Context
62
79
  const parseToJson = false;
63
80
  const preChatSurveyResponse = (props === null || props === void 0 ? void 0 : (_props$preChatSurveyP = props.preChatSurveyPaneProps) === null || _props$preChatSurveyP === void 0 ? void 0 : (_props$preChatSurveyP2 = _props$preChatSurveyP.controlProps) === null || _props$preChatSurveyP2 === void 0 ? void 0 : _props$preChatSurveyP2.payload) ?? (await chatSDK.getPreChatSurvey(parseToJson));
64
- const showPrechat = isProactiveChat ? preChatSurveyResponse && proactiveChatEnablePrechatState : preChatSurveyResponse && !(props !== null && props !== void 0 && (_props$controlProps = props.controlProps) !== null && _props$controlProps !== void 0 && _props$controlProps.hidePreChatSurveyPane);
81
+ let showPrechat = isProactiveChat ? preChatSurveyResponse && proactiveChatEnablePrechatState : preChatSurveyResponse && !(props !== null && props !== void 0 && (_props$controlProps = props.controlProps) !== null && _props$controlProps !== void 0 && _props$controlProps.hidePreChatSurveyPane);
82
+ showPrechat = await shouldSetPreChatIfPersistentChat(chatSDK, state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_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.msdyn_conversationmode, showPrechat);
65
83
  if (showPrechat) {
66
- var _state$domainStates, _state$domainStates$l, _state$domainStates$l2, _state$domainStates$l3;
67
- const isOutOfOperatingHours = (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_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$l3 = _state$domainStates$l2.OutOfOperatingHours) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.toLowerCase()) === "true";
84
+ var _state$domainStates2, _state$domainStates2$, _state$domainStates2$2, _state$domainStates2$3;
85
+ const isOutOfOperatingHours = (state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.liveChatConfig) === null || _state$domainStates2$ === void 0 ? void 0 : (_state$domainStates2$2 = _state$domainStates2$.LiveWSAndLiveChatEngJoin) === null || _state$domainStates2$2 === void 0 ? void 0 : (_state$domainStates2$3 = _state$domainStates2$2.OutOfOperatingHours) === null || _state$domainStates2$3 === void 0 ? void 0 : _state$domainStates2$3.toLowerCase()) === "true";
68
86
  if (isOutOfOperatingHours) {
69
87
  (state === null || state === void 0 ? void 0 : state.appStates.isMinimized) && dispatch({
70
88
  type: LiveChatWidgetActionType.SET_MINIMIZED,
@@ -88,7 +106,7 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
88
106
 
89
107
  // If minimized, maximize the chat, if the state is missing, consider it as minimized
90
108
  if ((state === null || state === void 0 ? void 0 : state.appStates.isMinimized) == undefined || (state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.isMinimized) === true) {
91
- var _state$domainStates2, _state$domainStates2$, _state$domainStates3, _state$domainStates3$;
109
+ var _state$domainStates3, _state$domainStates3$, _state$domainStates4, _state$domainStates4$;
92
110
  dispatch({
93
111
  type: LiveChatWidgetActionType.SET_MINIMIZED,
94
112
  payload: false
@@ -98,8 +116,8 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
98
116
  BroadcastService.postMessage({
99
117
  eventName: BroadcastEvent.MaximizeChat,
100
118
  payload: {
101
- height: state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : (_state$domainStates2$ = _state$domainStates2.widgetSize) === null || _state$domainStates2$ === void 0 ? void 0 : _state$domainStates2$.height,
102
- width: state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.widgetSize) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.width
119
+ height: state === null || state === void 0 ? void 0 : (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.widgetSize) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.height,
120
+ width: state === null || state === void 0 ? void 0 : (_state$domainStates4 = state.domainStates) === null || _state$domainStates4 === void 0 ? void 0 : (_state$domainStates4$ = _state$domainStates4.widgetSize) === null || _state$domainStates4$ === void 0 ? void 0 : _state$domainStates4$.width
103
121
  }
104
122
  });
105
123
  }
@@ -120,9 +138,9 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
120
138
 
121
139
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
140
  const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params, persistedState) => {
141
+ var _state$domainStates5, _state$domainStates5$, _state$domainStates5$2;
123
142
  let isStartChatSuccessful = false;
124
- const chatConfig = props === null || props === void 0 ? void 0 : props.chatConfig;
125
- const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
143
+ const persistentChatEnabled = await isPersistentChatEnabled(state === null || state === void 0 ? void 0 : (_state$domainStates5 = state.domainStates) === null || _state$domainStates5 === void 0 ? void 0 : (_state$domainStates5$ = _state$domainStates5.liveChatConfig) === null || _state$domainStates5$ === void 0 ? void 0 : (_state$domainStates5$2 = _state$domainStates5$.LiveWSAndLiveChatEngJoin) === null || _state$domainStates5$2 === void 0 ? void 0 : _state$domainStates5$2.msdyn_conversationmode);
126
144
  if ((state === null || state === void 0 ? void 0 : state.appStates.conversationState) === ConversationState.Closed) {
127
145
  // Preventive reset to avoid starting chat with previous requestId which could potentially cause problems
128
146
  chatSDKStateCleanUp(chatSDK);
@@ -141,14 +159,6 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
141
159
  Event: TelemetryEvent.WidgetLoadStarted,
142
160
  Description: "Widget loading started"
143
161
  });
144
- const authClientFunction = getAuthClientFunction(chatConfig);
145
- if (getAuthToken && authClientFunction) {
146
- // set auth token to chat sdk before start chat
147
- const authSuccess = await handleAuthentication(chatSDK, chatConfig, getAuthToken);
148
- if (!authSuccess) {
149
- throw new Error(WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
150
- }
151
- }
152
162
 
153
163
  //Check if chat retrieved from cache
154
164
  if (persistedState || params !== null && params !== void 0 && params.liveChatContext) {
@@ -220,10 +230,14 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
220
230
 
221
231
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
222
232
  const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
223
- dispatch({
224
- type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
225
- payload: liveChatContext
226
- });
233
+
234
+ // Persistent Chat relies on the `reconnectId` retrieved from reconnectablechats API to reconnect upon start chat and not `liveChatContext`
235
+ if (!persistentChatEnabled) {
236
+ dispatch({
237
+ type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
238
+ payload: liveChatContext
239
+ });
240
+ }
227
241
  logWidgetLoadComplete();
228
242
  // Set post chat context in state
229
243
  // Commenting this for now as post chat context is fetched during end chat
@@ -266,17 +280,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
266
280
 
267
281
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
268
282
  const setCustomContextParams = async (state, props) => {
269
- var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates4, _persistedState$domai8;
283
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates6, _persistedState$domai8;
270
284
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
271
285
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
272
286
  //Should not set custom context for auth chat
273
287
  if (isAuthenticatedChat) {
274
288
  return;
275
289
  }
276
- if (state !== null && state !== void 0 && (_state$domainStates4 = state.domainStates) !== null && _state$domainStates4 !== void 0 && _state$domainStates4.customContext) {
277
- var _state$domainStates5;
290
+ if (state !== null && state !== void 0 && (_state$domainStates6 = state.domainStates) !== null && _state$domainStates6 !== void 0 && _state$domainStates6.customContext) {
291
+ var _state$domainStates7;
278
292
  optionalParams = Object.assign({}, optionalParams, {
279
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates5 = state.domainStates) === null || _state$domainStates5 === void 0 ? void 0 : _state$domainStates5.customContext))
293
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates7 = state.domainStates) === null || _state$domainStates7 === void 0 ? void 0 : _state$domainStates7.customContext))
280
294
  });
281
295
  return;
282
296
  }
@@ -324,9 +338,9 @@ const canStartPopoutChat = async props => {
324
338
 
325
339
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
326
340
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
327
- var _state$domainStates6, _state$domainStates6$, _state$domainStates7;
328
- const requestIdFromCache = (_state$domainStates6 = state.domainStates) === null || _state$domainStates6 === void 0 ? void 0 : (_state$domainStates6$ = _state$domainStates6.liveChatContext) === null || _state$domainStates6$ === void 0 ? void 0 : _state$domainStates6$.requestId;
329
- const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates7 = state.domainStates) === null || _state$domainStates7 === void 0 ? void 0 : _state$domainStates7.liveChatContext;
341
+ var _state$domainStates8, _state$domainStates8$, _state$domainStates9;
342
+ const requestIdFromCache = (_state$domainStates8 = state.domainStates) === null || _state$domainStates8 === void 0 ? void 0 : (_state$domainStates8$ = _state$domainStates8.liveChatContext) === null || _state$domainStates8$ === void 0 ? void 0 : _state$domainStates8$.requestId;
343
+ const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates9 = state.domainStates) === null || _state$domainStates9 === void 0 ? void 0 : _state$domainStates9.liveChatContext;
330
344
 
331
345
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
332
346
  let conversationDetails = undefined;
@@ -59,8 +59,12 @@ export class MockChatSDK {
59
59
  getLiveChatConfig() {
60
60
  return {
61
61
  LiveWSAndLiveChatEngJoin: {
62
- msdyn_postconversationsurveyenable: "true"
62
+ msdyn_postconversationsurveyenable: "true",
63
+ msdyn_conversationmode: "192350000"
63
64
  }
64
65
  };
65
66
  }
67
+ sendTypingEvent() {
68
+ return null;
69
+ }
66
70
  }
@@ -88,6 +88,7 @@ export declare enum TelemetryEvent {
88
88
  GetConversationDetailsCallStarted = "GetConversationDetailsCallStarted",
89
89
  GetConversationDetailsCallFailed = "GetConversationDetailsCallFailed",
90
90
  EndChatSDKCallFailed = "EndChatSDKCallFailed",
91
+ DisconnectEndChatSDKCallFailed = "DisconnectEndChatSDKCallFailed",
91
92
  GetChatReconnectContextSDKCallStarted = "GetChatReconnectContextSDKCallStarted",
92
93
  GetChatReconnectContextSDKCallFailed = "GetChatReconnectContextSDKCallFailed",
93
94
  ParseAdaptiveCardFailed = "ParseAdaptiveCardFailed",
@@ -1 +1,2 @@
1
1
  export declare const isPostChatSurveyEnabled: (chatSDK: any) => Promise<boolean>;
2
+ export declare const isPersistentChatEnabled: (conversationMode: string | undefined) => Promise<boolean>;
@@ -0,0 +1 @@
1
+ export declare const shouldSetPreChatIfPersistentChat: (chatSDK: any, conversationMode: string, showPreChat: boolean) => Promise<boolean>;
@@ -31,6 +31,8 @@ export declare class MockChatSDK {
31
31
  getLiveChatConfig(): {
32
32
  LiveWSAndLiveChatEngJoin: {
33
33
  msdyn_postconversationsurveyenable: string;
34
+ msdyn_conversationmode: string;
34
35
  };
35
36
  };
37
+ sendTypingEvent(): null;
36
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/omnichannel-chat-widget",
3
- "version": "1.7.2",
3
+ "version": "1.7.3-main.5f11aa4",
4
4
  "description": "Microsoft Omnichannel Chat Widget",
5
5
  "main": "lib/cjs/index.js",
6
6
  "types": "lib/types/index.d.ts",