@microsoft/omnichannel-chat-widget 1.7.3-main.7a38853 → 1.7.3-main.aa696dc

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 (55) hide show
  1. package/lib/cjs/common/telemetry/TelemetryConstants.js +1 -0
  2. package/lib/cjs/components/livechatwidget/LiveChatWidget.js +6 -1
  3. package/lib/cjs/components/livechatwidget/common/endChat.js +20 -5
  4. package/lib/cjs/components/livechatwidget/common/getMockChatSDKIfApplicable.js +26 -0
  5. package/lib/cjs/components/livechatwidget/common/overridePropsOnMockIfApplicable.js +41 -0
  6. package/lib/cjs/components/livechatwidget/common/startChat.js +52 -37
  7. package/lib/cjs/components/livechatwidget/common/startChatErrorHandler.js +6 -6
  8. package/lib/cjs/components/livechatwidget/common/updateSessionDataForTelemetry.js +8 -3
  9. package/lib/cjs/components/livechatwidget/interfaces/IMockProps.js +7 -0
  10. package/lib/cjs/components/webchatcontainerstateful/common/DemoChatAdapter.js +87 -0
  11. package/lib/cjs/components/webchatcontainerstateful/common/DemoChatSDK.js +17 -0
  12. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +41 -0
  13. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatSDK.js +17 -0
  14. package/lib/cjs/components/webchatcontainerstateful/common/MockBotCardCommandType.js +14 -0
  15. package/lib/cjs/components/webchatcontainerstateful/common/MockBotCommand.js +19 -0
  16. package/lib/cjs/components/webchatcontainerstateful/common/mockchatsdk.js +3 -0
  17. package/lib/cjs/components/webchatcontainerstateful/common/utils/attachmentActivityUtils.js +71 -0
  18. package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +90 -0
  19. package/lib/cjs/plugins/newMessageEventHandler.js +4 -2
  20. package/lib/esm/common/telemetry/TelemetryConstants.js +1 -0
  21. package/lib/esm/components/livechatwidget/LiveChatWidget.js +6 -1
  22. package/lib/esm/components/livechatwidget/common/endChat.js +20 -5
  23. package/lib/esm/components/livechatwidget/common/getMockChatSDKIfApplicable.js +20 -0
  24. package/lib/esm/components/livechatwidget/common/overridePropsOnMockIfApplicable.js +34 -0
  25. package/lib/esm/components/livechatwidget/common/startChat.js +52 -37
  26. package/lib/esm/components/livechatwidget/common/startChatErrorHandler.js +7 -7
  27. package/lib/esm/components/livechatwidget/common/updateSessionDataForTelemetry.js +7 -2
  28. package/lib/esm/components/livechatwidget/interfaces/IMockProps.js +6 -0
  29. package/lib/esm/components/webchatcontainerstateful/common/DemoChatAdapter.js +79 -0
  30. package/lib/esm/components/webchatcontainerstateful/common/DemoChatSDK.js +10 -0
  31. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +33 -0
  32. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatSDK.js +10 -0
  33. package/lib/esm/components/webchatcontainerstateful/common/MockBotCardCommandType.js +7 -0
  34. package/lib/esm/components/webchatcontainerstateful/common/MockBotCommand.js +12 -0
  35. package/lib/esm/components/webchatcontainerstateful/common/mockchatsdk.js +3 -0
  36. package/lib/esm/components/webchatcontainerstateful/common/utils/attachmentActivityUtils.js +61 -0
  37. package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +77 -0
  38. package/lib/esm/plugins/newMessageEventHandler.js +4 -2
  39. package/lib/types/common/telemetry/TelemetryConstants.d.ts +1 -0
  40. package/lib/types/components/livechatwidget/common/getMockChatSDKIfApplicable.d.ts +1 -0
  41. package/lib/types/components/livechatwidget/common/overridePropsOnMockIfApplicable.d.ts +3 -0
  42. package/lib/types/components/livechatwidget/common/updateSessionDataForTelemetry.d.ts +1 -1
  43. package/lib/types/components/livechatwidget/interfaces/ILiveChatWidgetProps.d.ts +2 -0
  44. package/lib/types/components/livechatwidget/interfaces/IMockProps.d.ts +8 -0
  45. package/lib/types/components/webchatcontainerstateful/common/DemoChatAdapter.d.ts +10 -0
  46. package/lib/types/components/webchatcontainerstateful/common/DemoChatSDK.d.ts +6 -0
  47. package/lib/types/components/webchatcontainerstateful/common/DesignerChatAdapter.d.ts +8 -0
  48. package/lib/types/components/webchatcontainerstateful/common/DesignerChatSDK.d.ts +6 -0
  49. package/lib/types/components/webchatcontainerstateful/common/MockBotCardCommandType.d.ts +6 -0
  50. package/lib/types/components/webchatcontainerstateful/common/MockBotCommand.d.ts +11 -0
  51. package/lib/types/components/webchatcontainerstateful/common/mockadapter.d.ts +2 -1
  52. package/lib/types/components/webchatcontainerstateful/common/mockchatsdk.d.ts +6 -0
  53. package/lib/types/components/webchatcontainerstateful/common/utils/attachmentActivityUtils.d.ts +9 -0
  54. package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +9 -0
  55. package/package.json +3 -3
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createThumbnailCardAttachment = exports.createSigninCardAttachment = exports.createJpgFileAttachment = exports.createHeroCardAttachment = void 0;
7
+ const createJpgFileAttachment = () => {
8
+ return {
9
+ contentType: "image/jpeg",
10
+ name: "600x400.jpg",
11
+ contentUrl: "https://raw.githubusercontent.com/microsoft/omnichannel-chat-sdk/e7e75d4ede351e1cf2e52f13860d2284848c4af0/playwright/public/images/600x400.jpg"
12
+ };
13
+ };
14
+ exports.createJpgFileAttachment = createJpgFileAttachment;
15
+ const createHeroCardAttachment = () => {
16
+ return {
17
+ contentType: "application/vnd.microsoft.card.hero",
18
+ content: {
19
+ buttons: [{
20
+ title: "Bellevue",
21
+ type: "imBack",
22
+ value: "Bellevue"
23
+ }, {
24
+ title: "Redmond",
25
+ type: "imBack",
26
+ value: "Redmond"
27
+ }, {
28
+ title: "Seattle",
29
+ type: "imBack",
30
+ value: "Seattle"
31
+ }],
32
+ title: "Choose your location"
33
+ }
34
+ };
35
+ };
36
+ exports.createHeroCardAttachment = createHeroCardAttachment;
37
+ const createThumbnailCardAttachment = () => {
38
+ return {
39
+ contentType: "application/vnd.microsoft.card.thumbnail",
40
+ content: {
41
+ title: "Microsoft",
42
+ subtitle: "Our mission is to empower every person and every organization on the planet to achieve more.",
43
+ text: "Microsoft creates platforms and tools powered by AI to deliver innovative solutions that meet the evolving needs of our customers. The technology company is committed to making AI available broadly and doing so responsibly, with a mission to empower every person and every organization on the planet to achieve more.",
44
+ images: [{
45
+ alt: "Microsoft logo",
46
+ url: "https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1Mu3b?ver=5c31" // logo from https://microsoft.com
47
+ }],
48
+
49
+ buttons: [{
50
+ title: "Learn more",
51
+ type: "openUrl",
52
+ value: "https://www.microsoft.com/"
53
+ }]
54
+ }
55
+ };
56
+ };
57
+ exports.createThumbnailCardAttachment = createThumbnailCardAttachment;
58
+ const createSigninCardAttachment = () => {
59
+ return {
60
+ contentType: "application/vnd.microsoft.card.signin",
61
+ content: {
62
+ text: "Please login",
63
+ buttons: [{
64
+ type: "signin",
65
+ title: "Signin",
66
+ value: "https://login.live.com/"
67
+ }]
68
+ }
69
+ };
70
+ };
71
+ exports.createSigninCardAttachment = createSigninCardAttachment;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.postSystemMessageActivity = exports.postEchoActivity = exports.postBotTypingActivity = exports.postBotMessageActivity = exports.postBotAttachmentActivity = exports.customerUser = exports.botUser = void 0;
7
+ var _omnichannelChatSdk = require("@microsoft/omnichannel-chat-sdk");
8
+ const customerUser = {
9
+ id: "usedId",
10
+ name: "User",
11
+ role: "user"
12
+ };
13
+ exports.customerUser = customerUser;
14
+ const botUser = {
15
+ id: "botId",
16
+ name: "Bot",
17
+ role: "bot"
18
+ };
19
+
20
+ // WebChat expects an "echo" activity to confirm the message has been sent successfully
21
+ exports.botUser = botUser;
22
+ const postEchoActivity = function (activityObserver, activity, user) {
23
+ let delay = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
24
+ const echoActivity = {
25
+ ...activity,
26
+ id: (0, _omnichannelChatSdk.uuidv4)(),
27
+ from: {
28
+ ...activity.from,
29
+ ...user
30
+ },
31
+ timestamp: new Date().toISOString()
32
+ };
33
+ setTimeout(() => {
34
+ activityObserver === null || activityObserver === void 0 ? void 0 : activityObserver.next(echoActivity); // mock message sent activity
35
+ }, delay);
36
+ };
37
+ exports.postEchoActivity = postEchoActivity;
38
+ const postBotMessageActivity = function (activityObserver, text) {
39
+ let tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
40
+ let delay = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
41
+ setTimeout(() => {
42
+ activityObserver === null || activityObserver === void 0 ? void 0 : activityObserver.next({
43
+ id: (0, _omnichannelChatSdk.uuidv4)(),
44
+ from: {
45
+ ...botUser
46
+ },
47
+ text,
48
+ type: "message",
49
+ channelData: {
50
+ tags
51
+ },
52
+ timestamp: new Date().toISOString()
53
+ });
54
+ }, delay);
55
+ };
56
+ exports.postBotMessageActivity = postBotMessageActivity;
57
+ const postSystemMessageActivity = function (activityObserver, text) {
58
+ let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
59
+ postBotMessageActivity(activityObserver, text, "system", delay);
60
+ };
61
+ exports.postSystemMessageActivity = postSystemMessageActivity;
62
+ const postBotTypingActivity = function (activityObserver) {
63
+ let delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
64
+ setTimeout(() => {
65
+ activityObserver === null || activityObserver === void 0 ? void 0 : activityObserver.next({
66
+ id: (0, _omnichannelChatSdk.uuidv4)(),
67
+ from: {
68
+ ...botUser
69
+ },
70
+ type: "typing"
71
+ });
72
+ }, delay);
73
+ };
74
+ exports.postBotTypingActivity = postBotTypingActivity;
75
+ const postBotAttachmentActivity = function (activityObserver) {
76
+ let attachments = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
77
+ let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
78
+ setTimeout(() => {
79
+ activityObserver === null || activityObserver === void 0 ? void 0 : activityObserver.next({
80
+ id: (0, _omnichannelChatSdk.uuidv4)(),
81
+ from: {
82
+ ...botUser
83
+ },
84
+ attachments,
85
+ type: "message",
86
+ timestamp: new Date().toISOString()
87
+ });
88
+ }, delay);
89
+ };
90
+ exports.postBotAttachmentActivity = postBotAttachmentActivity;
@@ -20,7 +20,7 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
20
20
  const raiseMessageEvent = (activity, isHistoryMessage) => {
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
22
  const polyfillMessagePayloadForEvent = payload => {
23
- var _activity$conversatio, _TelemetryManager$Int;
23
+ var _activity$conversatio, _TelemetryManager$Int, _attachments;
24
24
  return {
25
25
  ...payload,
26
26
  channelData: activity === null || activity === void 0 ? void 0 : activity.channelData,
@@ -29,7 +29,9 @@ const createOnNewAdapterActivityHandler = (chatId, userId) => {
29
29
  id: activity === null || activity === void 0 ? void 0 : activity.id,
30
30
  isChatComplete: false,
31
31
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
- text: activity === null || activity === void 0 ? void 0 : activity.text
32
+ text: activity === null || activity === void 0 ? void 0 : activity.text,
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ attachment: (activity === null || activity === void 0 ? void 0 : (_attachments = activity.attachments) === null || _attachments === void 0 ? void 0 : _attachments.length) >= 1 ? activity === null || activity === void 0 ? void 0 : activity.attachments : []
33
35
  };
34
36
  };
35
37
  if ((activity === null || activity === void 0 ? void 0 : activity.type) === _Constants.Constants.message) {
@@ -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";
@@ -5,13 +5,18 @@ import { ChatSDKStore } from "../../contexts/ChatSDKStore";
5
5
  import LiveChatWidgetStateful from "./livechatwidgetstateful/LiveChatWidgetStateful";
6
6
  import { createReducer } from "../../contexts/createReducer";
7
7
  import { getLiveChatWidgetContextInitialState } from "../../contexts/common/LiveChatWidgetContextInitialState";
8
+ import { getMockChatSDKIfApplicable } from "./common/getMockChatSDKIfApplicable";
9
+ import overridePropsOnMockIfApplicable from "./common/overridePropsOnMockIfApplicable";
8
10
  export const LiveChatWidget = props => {
11
+ var _props$mock;
9
12
  const reducer = createReducer();
10
13
  const [state, dispatch] = useReducer(reducer, getLiveChatWidgetContextInitialState(props));
11
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
15
  const [adapter, setAdapter] = useState(undefined);
16
+ const chatSDK = getMockChatSDKIfApplicable(props.chatSDK, props === null || props === void 0 ? void 0 : (_props$mock = props.mock) === null || _props$mock === void 0 ? void 0 : _props$mock.type);
17
+ overridePropsOnMockIfApplicable(props);
13
18
  return /*#__PURE__*/React.createElement(ChatSDKStore.Provider, {
14
- value: props.chatSDK
19
+ value: chatSDK
15
20
  }, /*#__PURE__*/React.createElement(ChatAdapterStore.Provider, {
16
21
  value: [adapter, setAdapter]
17
22
  }, /*#__PURE__*/React.createElement(ChatContextStore.Provider, {
@@ -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);
@@ -0,0 +1,20 @@
1
+ import { DemoChatSDK } from "../../webchatcontainerstateful/common/DemoChatSDK";
2
+ import { DesignerChatSDK } from "../../webchatcontainerstateful/common/DesignerChatSDK";
3
+ import { MockChatSDK } from "../../webchatcontainerstateful/common/mockchatsdk";
4
+
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ export const getMockChatSDKIfApplicable = (chatSDK, type) => {
7
+ if (type) {
8
+ switch (type.toLowerCase()) {
9
+ case "demo":
10
+ chatSDK = new DemoChatSDK();
11
+ break;
12
+ case "designer":
13
+ chatSDK = new DesignerChatSDK();
14
+ break;
15
+ default:
16
+ chatSDK = new MockChatSDK();
17
+ }
18
+ }
19
+ return chatSDK;
20
+ };
@@ -0,0 +1,34 @@
1
+ const overridePropsOnMockIfApplicable = props => {
2
+ var _props$mock, _props$mock2;
3
+ if (props !== null && props !== void 0 && (_props$mock = props.mock) !== null && _props$mock !== void 0 && _props$mock.type && (props === null || props === void 0 ? void 0 : (_props$mock2 = props.mock) === null || _props$mock2 === void 0 ? void 0 : _props$mock2.type.toLowerCase()) === "designer") {
4
+ if (!props.webChatContainerProps) {
5
+ props.webChatContainerProps = {};
6
+ }
7
+ if (!props.webChatContainerProps.webChatProps) {
8
+ props.webChatContainerProps.webChatProps = {};
9
+ }
10
+ if (!props.webChatContainerProps.webChatStyles) {
11
+ props.webChatContainerProps.webChatStyles = {};
12
+ }
13
+ if (!props.webChatContainerProps.webChatProps.overrideLocalizedStrings) {
14
+ props.webChatContainerProps.webChatProps.overrideLocalizedStrings = {};
15
+ }
16
+ props.webChatContainerProps = {
17
+ ...props.webChatContainerProps,
18
+ webChatProps: {
19
+ disabled: true,
20
+ ...props.webChatContainerProps.webChatProps,
21
+ overrideLocalizedStrings: {
22
+ TEXT_INPUT_PLACEHOLDER: "Send a message . . .",
23
+ ...props.webChatContainerProps.webChatProps.overrideLocalizedStrings
24
+ }
25
+ },
26
+ webChatStyles: {
27
+ hideUploadButton: false,
28
+ sendBoxBackground: "rgb(243, 242, 241)",
29
+ ...props.webChatContainerProps.webChatStyles
30
+ }
31
+ };
32
+ }
33
+ };
34
+ export default overridePropsOnMockIfApplicable;
@@ -2,21 +2,21 @@ import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/teleme
2
2
  import { Constants, LiveWorkItemState, WidgetLoadCustomErrorString, WidgetLoadTelemetryMessage } from "../../../common/Constants";
3
3
  import { checkContactIdError, createTimer, getConversationDetailsCall, getStateFromCache, getWidgetCacheIdfromProps, isNullOrEmptyString, isUndefinedOrEmpty } from "../../../common/utils";
4
4
  import { getAuthClientFunction, handleAuthentication } from "./authHelper";
5
+ import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "./reconnectChatHelper";
6
+ import { handleStartChatError, logWidgetLoadComplete } from "./startChatErrorHandler";
5
7
  import { ActivityStreamHandler } from "./ActivityStreamHandler";
6
8
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
7
9
  import { ConversationState } from "../../../contexts/common/ConversationState";
8
10
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
9
11
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
10
12
  import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
13
+ import { chatSDKStateCleanUp } from "./endChat";
11
14
  import { createAdapter } from "./createAdapter";
12
15
  import { createOnNewAdapterActivityHandler } from "../../../plugins/newMessageEventHandler";
13
- import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "./reconnectChatHelper";
14
- import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey";
15
- import { updateSessionDataForTelemetry } from "./updateSessionDataForTelemetry";
16
- import { logWidgetLoadComplete, handleStartChatError } from "./startChatErrorHandler";
17
- import { chatSDKStateCleanUp } from "./endChat";
18
16
  import { isPersistentChatEnabled } from "./liveChatConfigUtils";
17
+ import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey";
19
18
  import { shouldSetPreChatIfPersistentChat } from "./persistentChatHelper";
19
+ import { updateTelemetryData } from "./updateSessionDataForTelemetry";
20
20
 
21
21
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
22
  let optionalParams = {};
@@ -25,10 +25,25 @@ let widgetInstanceId;
25
25
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
26
  let popoutWidgetInstanceId;
27
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
+
28
42
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
43
  const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) => {
30
44
  optionalParams = {}; //Resetting to ensure no stale values
31
45
  widgetInstanceId = getWidgetCacheIdfromProps(props);
46
+
32
47
  // reconnect > chat from cache
33
48
  if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
34
49
  const shouldStartChatNormally = await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
@@ -51,6 +66,11 @@ const prepareStartChat = async (props, chatSDK, state, dispatch, setAdapter) =>
51
66
  const isProactiveChat = state.appStates.conversationState === ConversationState.ProactiveChat;
52
67
  const isPreChatEnabledInProactiveChat = state.appStates.proactiveChatStates.proactiveChatEnablePrechat;
53
68
 
69
+ // Setting auth settings to OC API to retrieve existing persistent chat session before start chat if any
70
+ if (isPersistentEnabled(props.chatConfig)) {
71
+ await setAuthenticationIfApplicable(props, chatSDK);
72
+ }
73
+
54
74
  //Setting PreChat and intiate chat
55
75
  await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat, state, props);
56
76
  };
@@ -125,15 +145,13 @@ const setPreChatAndInitiateChat = async (chatSDK, dispatch, setAdapter, isProact
125
145
  const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params, persistedState) => {
126
146
  var _state$domainStates5, _state$domainStates5$, _state$domainStates5$2;
127
147
  let isStartChatSuccessful = false;
128
- const chatConfig = props === null || props === void 0 ? void 0 : props.chatConfig;
129
- const getAuthToken = props === null || props === void 0 ? void 0 : props.getAuthToken;
130
148
  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);
131
149
  if ((state === null || state === void 0 ? void 0 : state.appStates.conversationState) === ConversationState.Closed) {
132
150
  // Preventive reset to avoid starting chat with previous requestId which could potentially cause problems
133
151
  chatSDKStateCleanUp(chatSDK);
134
152
  }
135
153
  try {
136
- var _state$appStates2, _newAdapter$activity$;
154
+ var _state$appStates2;
137
155
  // Clear disconnect state on start chat
138
156
  (state === null || state === void 0 ? void 0 : (_state$appStates2 = state.appStates) === null || _state$appStates2 === void 0 ? void 0 : _state$appStates2.chatDisconnectEventReceived) && dispatch({
139
157
  type: LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
@@ -146,14 +164,9 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
146
164
  Event: TelemetryEvent.WidgetLoadStarted,
147
165
  Description: "Widget loading started"
148
166
  });
149
- const authClientFunction = getAuthClientFunction(chatConfig);
150
- if (getAuthToken && authClientFunction) {
151
- // set auth token to chat sdk before start chat
152
- const authSuccess = await handleAuthentication(chatSDK, chatConfig, getAuthToken);
153
- if (!authSuccess) {
154
- throw new Error(WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
155
- }
156
- }
167
+
168
+ // Auth token retrieval needs to happen during start chat to support pop-out chat
169
+ await setAuthenticationIfApplicable(props, chatSDK);
157
170
 
158
171
  //Check if chat retrieved from cache
159
172
  if (persistedState || params !== null && params !== void 0 && params.liveChatContext) {
@@ -190,16 +203,6 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
190
203
  throw error;
191
204
  }
192
205
 
193
- // New adapter creation
194
- const newAdapter = await createAdapter(chatSDK);
195
- setAdapter(newAdapter);
196
- const chatToken = await chatSDK.getChatToken();
197
- dispatch({
198
- type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
199
- payload: chatToken
200
- });
201
- newAdapter === null || newAdapter === void 0 ? void 0 : (_newAdapter$activity$ = newAdapter.activity$) === null || _newAdapter$activity$ === void 0 ? void 0 : _newAdapter$activity$.subscribe(createOnNewAdapterActivityHandler(chatToken === null || chatToken === void 0 ? void 0 : chatToken.chatId, chatToken === null || chatToken === void 0 ? void 0 : chatToken.visitorId));
202
-
203
206
  // Set app state to Active
204
207
  if (isStartChatSuccessful) {
205
208
  ActivityStreamHandler.uncork();
@@ -219,27 +222,26 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
219
222
  payload: persistedState
220
223
  });
221
224
  logWidgetLoadComplete(WidgetLoadTelemetryMessage.PersistedStateRetrievedMessage);
222
- await setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
225
+ // Set post chat context in state, load in background to do not block the load
226
+ setPostChatContextAndLoadSurvey(chatSDK, dispatch, true);
223
227
  return;
224
228
  }
225
-
226
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
227
- const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
229
+ await createAdapterAndSubscribe(chatSDK, dispatch, setAdapter);
228
230
 
229
231
  // Persistent Chat relies on the `reconnectId` retrieved from reconnectablechats API to reconnect upon start chat and not `liveChatContext`
230
232
  if (!persistentChatEnabled) {
233
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
234
+ const liveChatContext = await (chatSDK === null || chatSDK === void 0 ? void 0 : chatSDK.getCurrentLiveChatContext());
231
235
  dispatch({
232
236
  type: LiveChatWidgetActionType.SET_LIVE_CHAT_CONTEXT,
233
237
  payload: liveChatContext
234
238
  });
235
239
  }
236
240
  logWidgetLoadComplete();
237
- // Set post chat context in state
238
- // Commenting this for now as post chat context is fetched during end chat
239
- await setPostChatContextAndLoadSurvey(chatSDK, dispatch);
240
-
241
+ // Set post chat context in state, load in background to do not block the load
242
+ setPostChatContextAndLoadSurvey(chatSDK, dispatch);
241
243
  // Updating chat session detail for telemetry
242
- await updateSessionDataForTelemetry(chatSDK, dispatch);
244
+ await updateTelemetryData(chatSDK, dispatch);
243
245
  } catch (ex) {
244
246
  handleStartChatError(dispatch, chatSDK, props, ex, isStartChatSuccessful);
245
247
  } finally {
@@ -248,6 +250,21 @@ const initStartChat = async (chatSDK, dispatch, setAdapter, state, props, params
248
250
  }
249
251
  };
250
252
 
253
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
254
+ const createAdapterAndSubscribe = async (chatSDK, dispatch, setAdapter) => {
255
+ var _newAdapter$activity$;
256
+ // New adapter creation
257
+ const newAdapter = await createAdapter(chatSDK);
258
+ setAdapter(newAdapter);
259
+
260
+ //start chat is already seeding the chat token, so no need to get it again
261
+ const chatToken = await chatSDK.getChatToken(true);
262
+ dispatch({
263
+ type: LiveChatWidgetActionType.SET_CHAT_TOKEN,
264
+ payload: chatToken
265
+ });
266
+ newAdapter === null || newAdapter === void 0 ? void 0 : (_newAdapter$activity$ = newAdapter.activity$) === null || _newAdapter$activity$ === void 0 ? void 0 : _newAdapter$activity$.subscribe(createOnNewAdapterActivityHandler(chatToken === null || chatToken === void 0 ? void 0 : chatToken.chatId, chatToken === null || chatToken === void 0 ? void 0 : chatToken.visitorId));
267
+ };
251
268
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
252
269
  const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdapter) => {
253
270
  var _state$appStates3, _persistedState$domai6, _persistedState$appSt;
@@ -336,10 +353,8 @@ const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
336
353
  var _state$domainStates8, _state$domainStates8$, _state$domainStates9;
337
354
  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;
338
355
  const liveChatContext = state === null || state === void 0 ? void 0 : (_state$domainStates9 = state.domainStates) === null || _state$domainStates9 === void 0 ? void 0 : _state$domainStates9.liveChatContext;
339
-
340
356
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
341
357
  let conversationDetails = undefined;
342
-
343
358
  // Preserve current requestId
344
359
  const currentRequestId = chatSDK.requestId ?? "";
345
360
  dispatch({
@@ -1,14 +1,14 @@
1
- import { ChatSDKErrorName, ChatSDKError } from "@microsoft/omnichannel-chat-sdk";
1
+ import { ChatSDKError, ChatSDKErrorName } from "@microsoft/omnichannel-chat-sdk";
2
2
  import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
3
- import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
4
- import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
3
+ import { PrepareEndChatDescriptionConstants, WidgetLoadCustomErrorString, WidgetLoadTelemetryMessage } from "../../../common/Constants";
4
+ import { callingStateCleanUp, chatSDKStateCleanUp, closeChatStateCleanUp, endChatStateCleanUp } from "./endChat";
5
5
  import { ConversationState } from "../../../contexts/common/ConversationState";
6
- import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
7
- import { callingStateCleanUp, endChatStateCleanUp, closeChatStateCleanUp, chatSDKStateCleanUp } from "./endChat";
8
6
  import { DataStoreManager } from "../../../common/contextDataStore/DataStoreManager";
9
- import { getWidgetCacheIdfromProps } from "../../../common/utils";
10
- import { PrepareEndChatDescriptionConstants, WidgetLoadCustomErrorString, WidgetLoadTelemetryMessage } from "../../../common/Constants";
7
+ import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
11
8
  import { StartChatFailureType } from "../../../contexts/common/StartChatFailureType";
9
+ import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
10
+ import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
11
+ import { getWidgetCacheIdfromProps } from "../../../common/utils";
12
12
 
13
13
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
14
  export const handleStartChatError = (dispatch, chatSDK, props, ex, isStartChatSuccessful) => {
@@ -6,7 +6,13 @@ import { TelemetryManager } from "../../../common/telemetry/TelemetryManager";
6
6
  import { getConversationDetailsCall } from "../../../common/utils";
7
7
 
8
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- export const updateSessionDataForTelemetry = async (chatSDK, dispatch) => {
9
+ export const updateTelemetryData = async (chatSDK, dispatch) => {
10
+ // load it concurrently, this will reduce the load time
11
+ await Promise.all([updateSessionDataForTelemetry(chatSDK, dispatch), updateConversationDataForTelemetry(chatSDK, dispatch)]);
12
+ };
13
+
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ const updateSessionDataForTelemetry = async (chatSDK, dispatch) => {
10
16
  if (chatSDK) {
11
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
18
  const chatSession = await chatSDK.getCurrentLiveChatContext();
@@ -21,7 +27,6 @@ export const updateSessionDataForTelemetry = async (chatSDK, dispatch) => {
21
27
  chatSession
22
28
  }
23
29
  });
24
- await updateConversationDataForTelemetry(chatSDK, dispatch);
25
30
  }
26
31
  };
27
32
 
@@ -0,0 +1,6 @@
1
+ var LiveChatWidgetMockType;
2
+ (function (LiveChatWidgetMockType) {
3
+ LiveChatWidgetMockType["Test"] = "Test";
4
+ LiveChatWidgetMockType["Demo"] = "Demo";
5
+ })(LiveChatWidgetMockType || (LiveChatWidgetMockType = {}));
6
+ export {};
@@ -0,0 +1,79 @@
1
+ import "rxjs/add/operator/share";
2
+ import "rxjs/add/observable/of";
3
+ import { Observable } from "rxjs/Observable";
4
+ import MockAdapter from "./mockadapter";
5
+ import { customerUser, postBotMessageActivity, postBotAttachmentActivity, postBotTypingActivity, postEchoActivity, postSystemMessageActivity } from "./utils/chatAdapterUtils";
6
+ import { createHeroCardAttachment, createJpgFileAttachment, createSigninCardAttachment, createThumbnailCardAttachment } from "./utils/attachmentActivityUtils";
7
+ import MockBotCommand from "./MockBotCommand";
8
+ import MockBotCardCommandType from "./MockBotCardCommandType";
9
+ export class DemoChatAdapter extends MockAdapter {
10
+ constructor() {
11
+ super();
12
+ setTimeout(() => {
13
+ postSystemMessageActivity(this.activityObserver, "You're currently using a demo.", 0);
14
+ postBotMessageActivity(this.activityObserver, "Type `/help` to learn more", undefined, 0); // send init message from bot
15
+ }, 1000);
16
+ }
17
+ postBotCommandsActivity() {
18
+ let delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1000;
19
+ postBotAttachmentActivity(this.activityObserver, [{
20
+ contentType: "application/vnd.microsoft.card.thumbnail",
21
+ content: {
22
+ buttons: [{
23
+ title: "Send system message",
24
+ type: "imBack",
25
+ value: "send system message"
26
+ }, {
27
+ title: "Send typing",
28
+ type: "imBack",
29
+ value: "send typing"
30
+ }, {
31
+ title: "Send bot message",
32
+ type: "imBack",
33
+ value: "send bot message"
34
+ }],
35
+ title: "Commands"
36
+ }
37
+ }], delay);
38
+ }
39
+ postActivity(activity) {
40
+ if (activity) {
41
+ postEchoActivity(this.activityObserver, activity, customerUser);
42
+ if (activity.text) {
43
+ switch (true) {
44
+ case activity.text === MockBotCommand.Help:
45
+ this.postBotCommandsActivity();
46
+ break;
47
+ case activity.text === MockBotCommand.SendSystemMessage:
48
+ postSystemMessageActivity(this.activityObserver, "Contoso has joined the chat.");
49
+ break;
50
+ case activity.text === MockBotCommand.SendTyping:
51
+ postBotTypingActivity(this.activityObserver);
52
+ break;
53
+ case activity.text === MockBotCommand.SendAttachment:
54
+ postBotAttachmentActivity(this.activityObserver, [createJpgFileAttachment()]);
55
+ break;
56
+ case activity.text === MockBotCommand.SendBotMessage:
57
+ postBotMessageActivity(this.activityObserver, "Hi, how can I help you?");
58
+ break;
59
+ case activity.text === `${MockBotCommand.Card} ${MockBotCardCommandType.Signin}`:
60
+ postBotAttachmentActivity(this.activityObserver, [createSigninCardAttachment()]);
61
+ break;
62
+ case activity.text === `${MockBotCommand.Card} ${MockBotCardCommandType.Hero}`:
63
+ postBotAttachmentActivity(this.activityObserver, [createHeroCardAttachment()]);
64
+ break;
65
+ case activity.text === `${MockBotCommand.Card} ${MockBotCardCommandType.Thumbnail}`:
66
+ postBotAttachmentActivity(this.activityObserver, [createThumbnailCardAttachment()]);
67
+ break;
68
+ case activity.text.startsWith(`${MockBotCommand.Bot} `):
69
+ postBotMessageActivity(this.activityObserver, activity.text.substring(5));
70
+ break;
71
+ case activity.text.startsWith(`${MockBotCommand.System} `):
72
+ postSystemMessageActivity(this.activityObserver, activity.text.substring(8));
73
+ break;
74
+ }
75
+ }
76
+ }
77
+ return Observable.of(activity.id || "");
78
+ }
79
+ }
@@ -0,0 +1,10 @@
1
+ import { DemoChatAdapter } from "./DemoChatAdapter";
2
+ import { MockChatSDK } from "./mockchatsdk";
3
+ export class DemoChatSDK extends MockChatSDK {
4
+ constructor() {
5
+ super();
6
+ }
7
+ createChatAdapter() {
8
+ return new DemoChatAdapter();
9
+ }
10
+ }