@microsoft/omnichannel-chat-widget 1.7.8-main.d38af40 → 1.7.8-main.d71f599

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 (36) hide show
  1. package/lib/cjs/common/facades/FacadeChatSDK.js +15 -4
  2. package/lib/cjs/common/telemetry/TelemetryConstants.js +4 -0
  3. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -5
  4. package/lib/cjs/components/headerstateful/HeaderStateful.js +3 -5
  5. package/lib/cjs/components/livechatwidget/common/chatDisconnectHelper.js +3 -1
  6. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +0 -5
  7. package/lib/cjs/components/livechatwidget/common/startChat.js +2 -23
  8. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +3 -3
  9. package/lib/cjs/components/ooohpanestateful/OOOHPaneStateful.js +6 -4
  10. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +4 -3
  11. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +4 -0
  12. package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +14 -2
  13. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +118 -0
  14. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +32 -5
  15. package/lib/cjs/firstresponselatency/util.js +15 -2
  16. package/lib/esm/common/facades/FacadeChatSDK.js +15 -4
  17. package/lib/esm/common/telemetry/TelemetryConstants.js +4 -0
  18. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -5
  19. package/lib/esm/components/headerstateful/HeaderStateful.js +3 -5
  20. package/lib/esm/components/livechatwidget/common/chatDisconnectHelper.js +3 -1
  21. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +1 -6
  22. package/lib/esm/components/livechatwidget/common/startChat.js +3 -24
  23. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +3 -3
  24. package/lib/esm/components/ooohpanestateful/OOOHPaneStateful.js +6 -4
  25. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +4 -3
  26. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +4 -0
  27. package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +14 -2
  28. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +112 -0
  29. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +33 -6
  30. package/lib/esm/firstresponselatency/util.js +12 -0
  31. package/lib/types/common/facades/FacadeChatSDK.d.ts +1 -0
  32. package/lib/types/common/telemetry/TelemetryConstants.d.ts +5 -1
  33. package/lib/types/firstresponselatency/FirstMessageTrackerFromBot.d.ts +1 -0
  34. package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +5 -0
  35. package/lib/types/firstresponselatency/util.d.ts +2 -1
  36. package/package.json +13 -3
@@ -142,9 +142,20 @@ export class FacadeChatSDK {
142
142
  }
143
143
  }
144
144
  }
145
+ async corroborateTokenIsSet(chatSDK) {
146
+ var _chatSDK$chatSDKConfi;
147
+ // if getAuthToken is not set, it's because handleAuthentication hasnt being called
148
+ // so we need to call it
149
+ if (this.isAuthenticated && (chatSDK === null || chatSDK === void 0 ? void 0 : (_chatSDK$chatSDKConfi = chatSDK.chatSDKConfig) === null || _chatSDK$chatSDKConfi === void 0 ? void 0 : _chatSDK$chatSDKConfi.getAuthToken) === undefined) {
150
+ handleAuthentication(this.chatSDK, this.chatConfig, this.getAuthToken);
151
+ }
152
+ }
145
153
  async tokenRing() {
146
154
  var _this$chatSDK$chatSDK;
147
155
  if (this.disableReauthentication === true) {
156
+ // Since we are not validating the token anymore, we at least need to check if the token is set
157
+ // no need to validate anything other that the token is set
158
+ await this.corroborateTokenIsSet(this.chatSDK);
148
159
  // facade feature is disabled, so we are bypassing the re authentication and let it fail.
149
160
  return {
150
161
  result: true,
@@ -188,7 +199,7 @@ export class FacadeChatSDK {
188
199
  this.expiration = 0;
189
200
  try {
190
201
  const ring = await handleAuthentication(this.chatSDK, this.chatConfig, this.getAuthToken);
191
- if (ring.result === true && ring.token) {
202
+ if ((ring === null || ring === void 0 ? void 0 : ring.result) === true && ring !== null && ring !== void 0 && ring.token) {
192
203
  await this.setToken(ring.token);
193
204
  TelemetryHelper.logFacadeChatSDKEvent(LogLevel.INFO, {
194
205
  Event: TelemetryEvent.NewTokenSuccess,
@@ -205,12 +216,12 @@ export class FacadeChatSDK {
205
216
  var _ring$error, _ring$error2;
206
217
  TelemetryHelper.logFacadeChatSDKEvent(LogLevel.ERROR, {
207
218
  Event: TelemetryEvent.NewTokenFailed,
208
- Description: (_ring$error = ring.error) === null || _ring$error === void 0 ? void 0 : _ring$error.message,
209
- ExceptionDetails: ring.error
219
+ Description: ring === null || ring === void 0 ? void 0 : (_ring$error = ring.error) === null || _ring$error === void 0 ? void 0 : _ring$error.message,
220
+ ExceptionDetails: ring === null || ring === void 0 ? void 0 : ring.error
210
221
  });
211
222
  return {
212
223
  result: false,
213
- message: ((_ring$error2 = ring.error) === null || _ring$error2 === void 0 ? void 0 : _ring$error2.message) || "Failed to get token"
224
+ message: (ring === null || ring === void 0 ? void 0 : (_ring$error2 = ring.error) === null || _ring$error2 === void 0 ? void 0 : _ring$error2.message) || "Failed to get token"
214
225
  };
215
226
  }
216
227
  } catch (e) {
@@ -61,6 +61,8 @@ export let BroadcastEvent;
61
61
  BroadcastEvent["ContactIdNotFound"] = "ContactIdNotFound";
62
62
  BroadcastEvent["SyncMinimize"] = "SyncMinimize";
63
63
  BroadcastEvent["OnWidgetError"] = "OnWidgetError";
64
+ BroadcastEvent["FMLTrackingCompletedAck"] = "FMLTrackingCompletedAck";
65
+ BroadcastEvent["FMLTrackingCompleted"] = "FMLTrackingCompleted";
64
66
  })(BroadcastEvent || (BroadcastEvent = {}));
65
67
  export let TelemetryEvent;
66
68
  (function (TelemetryEvent) {
@@ -200,6 +202,8 @@ export let TelemetryEvent;
200
202
  TelemetryEvent["MessageSent"] = "MessageSent";
201
203
  TelemetryEvent["MessageReceived"] = "MessageReceived";
202
204
  TelemetryEvent["MessageLapTrack"] = "MessageLapTrack";
205
+ TelemetryEvent["BotFirstMessageLapTrack"] = "BotFirstMessageLapTrack";
206
+ TelemetryEvent["BotFirstMessageLapTrackError"] = "BotFirstMessageLapTrackError";
203
207
  TelemetryEvent["MessageStartLapTrackError"] = "MessageStartLapTrackError";
204
208
  TelemetryEvent["MessageStopLapTrackError"] = "MessageStopLapTrackError";
205
209
  TelemetryEvent["SystemMessageReceived"] = "SystemMessageReceived";
@@ -11,7 +11,7 @@ import { defaultOutOfOfficeChatButtonStyleProps } from "./common/styleProps/defa
11
11
  import useChatContextStore from "../../hooks/useChatContextStore";
12
12
  let uiTimer;
13
13
  export const ChatButtonStateful = props => {
14
- var _state$domainStates$l, _state$domainStates$l2, _buttonProps$controlP, _props$buttonProps, _props$buttonProps$co, _props$buttonProps2, _props$buttonProps2$c, _props$buttonProps3, _props$buttonProps3$c;
14
+ var _buttonProps$controlP, _props$buttonProps, _props$buttonProps$co, _props$buttonProps2, _props$buttonProps2$c, _props$buttonProps3, _props$buttonProps3$c;
15
15
  // this is to ensure the telemetry is set only once and start the load timer
16
16
  useEffect(() => {
17
17
  uiTimer = createTimer();
@@ -28,7 +28,8 @@ export const ChatButtonStateful = props => {
28
28
  startChat
29
29
  } = props;
30
30
  //Setting OutOfOperatingHours Flag
31
- const [outOfOperatingHours, setOutOfOperatingHours] = useState(((_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");
31
+ //Setting OutOfOperatingHours Flag - to string conversion to normalize the value (could be boolean from other states or string directly from config)
32
+ const [outOfOperatingHours, setOutOfOperatingHours] = useState(state.appStates.outsideOperatingHours);
32
33
  const ref = useRef(() => {
33
34
  return;
34
35
  });
@@ -87,9 +88,7 @@ export const ChatButtonStateful = props => {
87
88
  ...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
88
89
  };
89
90
  useEffect(() => {
90
- if (state.appStates.outsideOperatingHours) {
91
- setOutOfOperatingHours(true);
92
- }
91
+ setOutOfOperatingHours(state.appStates.outsideOperatingHours);
93
92
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
94
93
  Event: TelemetryEvent.LCWChatButtonShow,
95
94
  ElapsedTimeInMilliseconds: TelemetryTimers.LcwLoadToChatButtonTimer.milliSecondsElapsed
@@ -12,7 +12,7 @@ import useChatAdapterStore from "../../hooks/useChatAdapterStore";
12
12
  import useChatContextStore from "../../hooks/useChatContextStore";
13
13
  let uiTimer;
14
14
  export const HeaderStateful = props => {
15
- var _state$domainStates$l, _state$domainStates$l2, _state$domainStates, _headerProps$controlP, _headerProps$controlP2, _headerProps$controlP3, _outOfOfficeHeaderPro, _state$domainStates3;
15
+ var _state$domainStates, _headerProps$controlP, _headerProps$controlP2, _headerProps$controlP3, _outOfOfficeHeaderPro, _state$domainStates3;
16
16
  useEffect(() => {
17
17
  uiTimer = createTimer();
18
18
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -28,7 +28,7 @@ export const HeaderStateful = props => {
28
28
  endChat
29
29
  } = props;
30
30
  //Setting OutOfOperatingHours Flag
31
- const [outOfOperatingHours, setOutOfOperatingHours] = useState(((_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");
31
+ const [outOfOperatingHours, setOutOfOperatingHours] = useState(state.appStates.outsideOperatingHours);
32
32
  const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeHeaderStyleProps, outOfOfficeHeaderProps === null || outOfOfficeHeaderProps === void 0 ? void 0 : outOfOfficeHeaderProps.styleProps);
33
33
 
34
34
  // For some reason state object is not getting updated values in this component
@@ -100,9 +100,7 @@ export const HeaderStateful = props => {
100
100
  hideCloseButton: state.appStates.conversationState === ConversationState.OutOfOffice || (outOfOfficeHeaderProps === null || outOfOfficeHeaderProps === void 0 ? void 0 : (_outOfOfficeHeaderPro = outOfOfficeHeaderProps.controlProps) === null || _outOfOfficeHeaderPro === void 0 ? void 0 : _outOfOfficeHeaderPro.hideCloseButton)
101
101
  };
102
102
  useEffect(() => {
103
- if (state.appStates.outsideOperatingHours) {
104
- setOutOfOperatingHours(true);
105
- }
103
+ setOutOfOperatingHours(state.appStates.outsideOperatingHours);
106
104
  }, []);
107
105
  useEffect(() => {
108
106
  var _state$domainStates2;
@@ -6,7 +6,7 @@ import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/
6
6
 
7
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
8
  const handleChatDisconnect = (props, state, setWebChatStyles) => {
9
- var _state$appStates, _state$domainStates, _state$domainStates$m, _props$webChatContain, _props$webChatContain2;
9
+ var _state$appStates, _state$domainStates, _state$domainStates$m, _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4;
10
10
  const chatDisconnectState = state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.chatDisconnectEventReceived;
11
11
  const chatDisconnectMessage = (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$m = _state$domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_BANNER_CHAT_DISCONNECT) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_CHAT_DISCONNECT;
12
12
  const hideSendBoxOnConversationEnd = props === null || props === void 0 ? void 0 : (_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : (_props$webChatContain2 = _props$webChatContain.renderingMiddlewareProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hideSendboxOnConversationEnd;
@@ -27,6 +27,8 @@ const handleChatDisconnect = (props, state, setWebChatStyles) => {
27
27
  });
28
28
  break;
29
29
  case false:
30
+ // this means customer on purpose wants to hide the send box, we should not override it
31
+ if ((props === null || props === void 0 ? void 0 : (_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : (_props$webChatContain4 = _props$webChatContain3.webChatStyles) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.hideSendBox) === true) return;
30
32
  if (hideSendBoxOnConversationEnd !== false) {
31
33
  setWebChatStyles(styles => {
32
34
  return {
@@ -2,7 +2,7 @@ import "regenerator-runtime/runtime";
2
2
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
3
3
  import { ConversationMode, WidgetLoadCustomErrorString } from "../../../common/Constants";
4
4
  import { checkContactIdError, isNullOrEmptyString, isNullOrUndefined } from "../../../common/utils";
5
- import { handleAuthentication, removeAuthTokenProvider } from "./authHelper";
5
+ import { removeAuthTokenProvider } from "./authHelper";
6
6
  import { BroadcastService } from "@microsoft/omnichannel-chat-components";
7
7
  import { ConversationState } from "../../../contexts/common/ConversationState";
8
8
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
@@ -61,11 +61,6 @@ const getChatReconnectContext = async (facadeChatSDK, chatConfig, props, isAuthe
61
61
  const chatReconnectOptionalParams = {
62
62
  reconnectId: (_props$reconnectChatP4 = props.reconnectChatPaneProps) === null || _props$reconnectChatP4 === void 0 ? void 0 : _props$reconnectChatP4.reconnectId
63
63
  };
64
- // Get auth token for getting chat reconnect context
65
- if (isAuthenticatedChat) {
66
- // handle authentication will throw error if auth token is not available, so no need to check for response
67
- await handleAuthentication(facadeChatSDK.getChatSDK(), chatConfig, props.getAuthToken);
68
- }
69
64
  const reconnectChatContext = await (facadeChatSDK === null || facadeChatSDK === void 0 ? void 0 : facadeChatSDK.getChatReconnectContext(chatReconnectOptionalParams));
70
65
  if (isAuthenticatedChat) {
71
66
  // remove auth token after reconnectId is fetched
@@ -1,7 +1,6 @@
1
1
  import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
2
- import { Constants, LiveWorkItemState, WidgetLoadCustomErrorString, WidgetLoadTelemetryMessage } from "../../../common/Constants";
2
+ import { Constants, LiveWorkItemState, WidgetLoadTelemetryMessage } from "../../../common/Constants";
3
3
  import { checkContactIdError, createTimer, getConversationDetailsCall, getStateFromCache, getWidgetCacheIdfromProps, isNullOrEmptyString, isNullOrUndefined, isUndefinedOrEmpty } from "../../../common/utils";
4
- import { getAuthClientFunction, handleAuthentication } from "./authHelper";
5
4
  import { handleChatReconnect, isPersistentEnabled, isReconnectEnabled } from "./reconnectChatHelper";
6
5
  import { handleStartChatError, logWidgetLoadComplete } from "./startChatErrorHandler";
7
6
  import { ActivityStreamHandler } from "./ActivityStreamHandler";
@@ -13,6 +12,7 @@ import { TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
13
12
  import { chatSDKStateCleanUp } from "./endChat";
14
13
  import { createAdapter } from "./createAdapter";
15
14
  import { createOnNewAdapterActivityHandler } from "../../../plugins/newMessageEventHandler";
15
+ import { createTrackingForFirstMessage } from "../../../firstresponselatency/FirstMessageTrackerFromBot";
16
16
  import { isPersistentChatEnabled } from "./liveChatConfigUtils";
17
17
  import { setPostChatContextAndLoadSurvey } from "./setPostChatContextAndLoadSurvey";
18
18
  import { shouldSetPreChatIfPersistentChat } from "./persistentChatHelper";
@@ -25,20 +25,6 @@ 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, facadeChatSDK) => {
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(facadeChatSDK.getChatSDK(), chatConfig, getAuthToken);
36
- if (!authSuccess.result) {
37
- throw new Error(WidgetLoadCustomErrorString.AuthenticationFailedErrorString);
38
- }
39
- }
40
- };
41
-
42
28
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
29
  const prepareStartChat = async (props, facadeChatSDK, state, dispatch, setAdapter) => {
44
30
  optionalParams = {}; //Resetting to ensure no stale values
@@ -66,11 +52,6 @@ const prepareStartChat = async (props, facadeChatSDK, state, dispatch, setAdapte
66
52
  const isProactiveChat = state.appStates.conversationState === ConversationState.ProactiveChat;
67
53
  const isPreChatEnabledInProactiveChat = state.appStates.proactiveChatStates.proactiveChatEnablePrechat;
68
54
 
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, facadeChatSDK);
72
- }
73
-
74
55
  //Setting PreChat and intiate chat
75
56
  await setPreChatAndInitiateChat(facadeChatSDK, dispatch, setAdapter, isProactiveChat, isPreChatEnabledInProactiveChat, state, props);
76
57
  };
@@ -145,6 +126,7 @@ const setPreChatAndInitiateChat = async (facadeChatSDK, dispatch, setAdapter, is
145
126
  const optionalParams = {
146
127
  isProactiveChat
147
128
  };
129
+ createTrackingForFirstMessage();
148
130
  await initStartChat(facadeChatSDK, dispatch, setAdapter, state, props, optionalParams);
149
131
  };
150
132
 
@@ -172,9 +154,6 @@ const initStartChat = async (facadeChatSDK, dispatch, setAdapter, state, props,
172
154
  Description: "Widget loading started"
173
155
  });
174
156
 
175
- // Auth token retrieval needs to happen during start chat to support pop-out chat
176
- await setAuthenticationIfApplicable(props, facadeChatSDK);
177
-
178
157
  //Check if chat retrieved from cache
179
158
  if (persistedState || params !== null && params !== void 0 && params.liveChatContext) {
180
159
  var _persistedState$domai, _persistedState$domai2, _persistedState$domai3, _persistedState$domai4, _persistedState$domai5;
@@ -56,7 +56,7 @@ import useChatContextStore from "../../../hooks/useChatContextStore";
56
56
  import useFacadeSDKStore from "../../../hooks/useFacadeChatSDKStore";
57
57
  let uiTimer;
58
58
  export const LiveChatWidgetStateful = props => {
59
- var _props$webChatContain, _props$styleProps, _props$webChatContain2, _props$webChatContain3, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain7, _state$appStates14, _props$webChatContain9, _props$webChatContain10, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _props$webChatContain11, _props$webChatContain12, _props$webChatContain13, _props$webChatContain14, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
59
+ var _props$webChatContain, _props$styleProps, _props$webChatContain2, _props$webChatContain3, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain7, _state$appStates14, _props$webChatContain9, _props$webChatContain10, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _props$webChatContain11, _props$webChatContain12, _props$webChatContain13, _props$webChatContain14, _props$webChatContain15, _props$webChatContain16, _props$webChatContain17, _props$webChatContain18, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
60
60
  useEffect(() => {
61
61
  uiTimer = createTimer();
62
62
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -874,8 +874,8 @@ export const LiveChatWidgetStateful = props => {
874
874
  userID: userID,
875
875
  styleOptions: {
876
876
  ...webChatStyles,
877
- bubbleBackground: ((_props$webChatContain11 = props.webChatContainerProps) === null || _props$webChatContain11 === void 0 ? void 0 : (_props$webChatContain12 = _props$webChatContain11.adaptiveCardStyles) === null || _props$webChatContain12 === void 0 ? void 0 : _props$webChatContain12.background) ?? defaultAdaptiveCardStyles.background,
878
- bubbleTextColor: ((_props$webChatContain13 = props.webChatContainerProps) === null || _props$webChatContain13 === void 0 ? void 0 : (_props$webChatContain14 = _props$webChatContain13.adaptiveCardStyles) === null || _props$webChatContain14 === void 0 ? void 0 : _props$webChatContain14.color) ?? defaultAdaptiveCardStyles.color
877
+ bubbleBackground: ((_props$webChatContain11 = props.webChatContainerProps) === null || _props$webChatContain11 === void 0 ? void 0 : (_props$webChatContain12 = _props$webChatContain11.webChatStyles) === null || _props$webChatContain12 === void 0 ? void 0 : _props$webChatContain12.bubbleBackground) ?? ((_props$webChatContain13 = props.webChatContainerProps) === null || _props$webChatContain13 === void 0 ? void 0 : (_props$webChatContain14 = _props$webChatContain13.adaptiveCardStyles) === null || _props$webChatContain14 === void 0 ? void 0 : _props$webChatContain14.background) ?? defaultAdaptiveCardStyles.background,
878
+ bubbleTextColor: ((_props$webChatContain15 = props.webChatContainerProps) === null || _props$webChatContain15 === void 0 ? void 0 : (_props$webChatContain16 = _props$webChatContain15.webChatStyles) === null || _props$webChatContain16 === void 0 ? void 0 : _props$webChatContain16.bubbleTextColor) ?? ((_props$webChatContain17 = props.webChatContainerProps) === null || _props$webChatContain17 === void 0 ? void 0 : (_props$webChatContain18 = _props$webChatContain17.adaptiveCardStyles) === null || _props$webChatContain18 === void 0 ? void 0 : _props$webChatContain18.color) ?? defaultAdaptiveCardStyles.color
879
879
  },
880
880
  directLine: directLine
881
881
  }), /*#__PURE__*/React.createElement(Stack, {
@@ -1,11 +1,11 @@
1
1
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
2
2
  import React, { useEffect } from "react";
3
3
  import { createTimer, findAllFocusableElement } from "../../common/utils";
4
+ import DOMPurify from "dompurify";
4
5
  import { OutOfOfficeHoursPane } from "@microsoft/omnichannel-chat-components";
5
6
  import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper";
6
7
  import { defaultGeneralStyleProps } from "./common/defaultStyleProps/defaultgeneralOOOHPaneStyleProps";
7
8
  import useChatContextStore from "../../hooks/useChatContextStore";
8
- import DOMPurify from "dompurify";
9
9
  let uiTimer;
10
10
  export const OutOfOfficeHoursPaneStateful = props => {
11
11
  var _props$styleProps;
@@ -29,9 +29,11 @@ export const OutOfOfficeHoursPaneStateful = props => {
29
29
 
30
30
  // Move focus to the first button
31
31
  useEffect(() => {
32
- const firstElement = findAllFocusableElement(`#${state.domainStates.widgetElementId}`);
33
- if (firstElement && firstElement[0]) {
34
- firstElement[0].focus();
32
+ if (state.domainStates.widgetElementId !== null && state.domainStates.widgetElementId !== undefined && state.domainStates.widgetElementId.trim() !== "") {
33
+ const firstElement = findAllFocusableElement(`#${state.domainStates.widgetElementId}`);
34
+ if (firstElement && firstElement[0]) {
35
+ firstElement[0].focus();
36
+ }
35
37
  }
36
38
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
37
39
  Event: TelemetryEvent.OutOfOfficePaneLoaded
@@ -1,12 +1,12 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
 
3
+ import { Constants, HtmlAttributeNames, HtmlClassNames } from "../../common/Constants";
3
4
  import { Stack } from "@fluentui/react";
4
5
  import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants";
5
6
  import React, { useEffect } from "react";
6
7
  import { createTimer, getDeviceType, setFocusOnSendBox } from "../../common/utils";
7
8
  import { BotMagicCodeStore } from "./webchatcontroller/BotMagicCodeStore";
8
9
  import { Components } from "botframework-webchat";
9
- import { Constants, HtmlAttributeNames, HtmlClassNames } from "../../common/Constants";
10
10
  import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType";
11
11
  import { NotificationHandler } from "./webchatcontroller/notification/NotificationHandler";
12
12
  import { NotificationScenarios } from "./webchatcontroller/enums/NotificationScenarios";
@@ -48,7 +48,7 @@ const createMagicCodeSuccessResponse = signin => {
48
48
  };
49
49
  };
50
50
  export const WebChatContainerStateful = props => {
51
- var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _props$webChatContain9, _props$webChatContain10;
51
+ var _webChatContainerProp, _webChatContainerProp2, _webChatContainerProp3, _webChatContainerProp4, _webChatContainerProp5, _webChatContainerProp6, _webChatContainerProp7, _props$webChatContain5, _props$webChatContain6, _defaultWebChatContai, _props$webChatContain7, _props$webChatContain8, _defaultWebChatContai2, _webChatContainerProp8, _webChatContainerProp9, _webChatContainerProp10, _webChatContainerProp11, _webChatContainerProp12, _webChatContainerProp13, _webChatContainerProp14, _webChatContainerProp15, _webChatContainerProp16, _props$webChatContain9, _props$webChatContain10;
52
52
  useEffect(() => {
53
53
  uiTimer = createTimer();
54
54
  TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
@@ -233,8 +233,9 @@ export const WebChatContainerStateful = props => {
233
233
  color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp14 = webChatContainerProps.renderingMiddlewareProps) === null || _webChatContainerProp14 === void 0 ? void 0 : (_webChatContainerProp15 = _webChatContainerProp14.sentMessageAnchorStyles) === null || _webChatContainerProp15 === void 0 ? void 0 : _webChatContainerProp15.color) ?? (defaultSentMessageAnchorStyles === null || defaultSentMessageAnchorStyles === void 0 ? void 0 : defaultSentMessageAnchorStyles.color)};
234
234
  }
235
235
 
236
+ // we had a nasty bug long time ago with crashing borders messing with the sendbox, so if customer adds this value, they need to deal with that
236
237
  .webchat__bubble:not(.webchat__bubble--from-user) .webchat__bubble__content {
237
- border-radius: 0 !important; /* Override border-radius */
238
+ border-radius: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp16 = webChatContainerProps.webChatStyles) === null || _webChatContainerProp16 === void 0 ? void 0 : _webChatContainerProp16.bubbleBorderRadius) ?? 0} !important; /* Override border-radius */
238
239
  }
239
240
 
240
241
  .webchat__stacked-layout_container>div {
@@ -35,6 +35,10 @@ export const DeliveredTimestamp = _ref => {
35
35
  return /*#__PURE__*/React.createElement("span", {
36
36
  dir: "ltr"
37
37
  }, getTimestampHourMinute(timestamp));
38
+ } else {
39
+ return /*#__PURE__*/React.createElement("span", {
40
+ dir: dir
41
+ }, getTimestampHourMinute(timestamp));
38
42
  }
39
43
  return timeString;
40
44
  };
@@ -6,6 +6,10 @@ import { defaultClientDataStoreProvider } from "../../common/storage/default/def
6
6
  import { defaultMiddlewareLocalizedTexts } from "../../components/webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
7
7
  export const getLiveChatWidgetContextInitialState = props => {
8
8
  var _props$controlProps, _props$webChatContain;
9
+ const isOutsideOperatingHours = () => {
10
+ var _props$chatConfig, _props$chatConfig$Liv, _props$chatConfig$Liv2;
11
+ return ((_props$chatConfig = props.chatConfig) === null || _props$chatConfig === void 0 ? void 0 : (_props$chatConfig$Liv = _props$chatConfig.LiveWSAndLiveChatEngJoin) === null || _props$chatConfig$Liv === void 0 ? void 0 : (_props$chatConfig$Liv2 = _props$chatConfig$Liv.OutOfOperatingHours) === null || _props$chatConfig$Liv2 === void 0 ? void 0 : _props$chatConfig$Liv2.toString().toLowerCase()) === "true";
12
+ };
9
13
  const widgetCacheId = getWidgetCacheIdfromProps(props);
10
14
  const cacheTtlInMins = (props === null || props === void 0 ? void 0 : (_props$controlProps = props.controlProps) === null || _props$controlProps === void 0 ? void 0 : _props$controlProps.cacheTtlInMins) ?? Constants.CacheTtlInMinutes;
11
15
  const storageType = (props === null || props === void 0 ? void 0 : props.useSessionStorage) === true ? StorageType.sessionStorage : StorageType.localStorage;
@@ -22,6 +26,14 @@ export const getLiveChatWidgetContextInitialState = props => {
22
26
  if (initialStateFromCache.appStates.conversationState === ConversationState.Prechat) {
23
27
  initialStateFromCache.appStates.conversationState = ConversationState.Closed;
24
28
  }
29
+
30
+ // we are always setting the chatConfig from the props to avoid any issues with the cache
31
+ initialStateFromCache.domainStates.liveChatConfig = props.chatConfig;
32
+
33
+ // Cache the result of isOutsideOperatingHours() to ensure consistency
34
+ const outsideOperatingHours = isOutsideOperatingHours();
35
+ initialStateFromCache.appStates.outsideOperatingHours = outsideOperatingHours;
36
+ initialStateFromCache.appStates.conversationState = outsideOperatingHours ? ConversationState.OutOfOffice : initialStateFromCache.appStates.conversationState;
25
37
  return initialStateFromCache;
26
38
  }
27
39
  const LiveChatWidgetContextInitialState = {
@@ -46,11 +58,11 @@ export const getLiveChatWidgetContextInitialState = props => {
46
58
  startChatFailureType: StartChatFailureType.Generic
47
59
  },
48
60
  appStates: {
49
- conversationState: ConversationState.Closed,
61
+ conversationState: isOutsideOperatingHours() ? ConversationState.OutOfOffice : ConversationState.Closed,
50
62
  isMinimized: undefined,
51
63
  previousElementIdOnFocusBeforeModalOpen: null,
52
64
  startChatFailed: false,
53
- outsideOperatingHours: false,
65
+ outsideOperatingHours: isOutsideOperatingHours(),
54
66
  preChatResponseEmail: "",
55
67
  isAudioMuted: null,
56
68
  newMessage: false,
@@ -0,0 +1,112 @@
1
+ import { BroadcastEvent, LogLevel, TelemetryEvent } from "../common/telemetry/TelemetryConstants";
2
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
3
+ import { TelemetryHelper } from "../common/telemetry/TelemetryHelper";
4
+ import { createTrackingMessage } from "./util";
5
+
6
+ // This tracker is event based, this is since we are tracking events coming from different sources
7
+ // with different timeline, therefore this is a functional approach to track the events, instead of a class based approach
8
+ export const createTrackingForFirstMessage = () => {
9
+ // Reset the tracking variables
10
+ let startTracking = false;
11
+ let stopTracking = false;
12
+ let startTime = 0;
13
+ let stopTime = 0;
14
+ let stopTrackingMessage;
15
+ let flag = false;
16
+ const isMessageFromValidSender = payload => {
17
+ var _payload$tags;
18
+ // agent scenario
19
+ if (payload !== null && payload !== void 0 && (_payload$tags = payload.tags) !== null && _payload$tags !== void 0 && _payload$tags.includes("public")) {
20
+ return false;
21
+ }
22
+ return true;
23
+ };
24
+ const widgetLoadListener = BroadcastService.getMessageByEventName(TelemetryEvent.WidgetLoadComplete).subscribe(() => {
25
+ if (startTracking) return;
26
+ startTracking = true;
27
+ startTime = new Date().getTime();
28
+ });
29
+ const newMessageListener = BroadcastService.getMessageByEventName(BroadcastEvent.NewMessageReceived).subscribe(message => {
30
+ const payload = message.payload;
31
+
32
+ // we only care for bot, so we need to check if the message is from the bot
33
+ // pending to add typing message indicator signal detection
34
+
35
+ if (isMessageFromValidSender(payload)) {
36
+ if (startTracking && !stopTracking) {
37
+ stopTime = new Date().getTime();
38
+ const elapsedTime = stopTime - startTime;
39
+ stopTracking = true;
40
+ stopTrackingMessage = createTrackingMessage(payload, "botMessage");
41
+ notifyFMLTrackingCompleted();
42
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
43
+ Event: TelemetryEvent.BotFirstMessageLapTrack,
44
+ Description: "First Message from Bot latency tracking",
45
+ CustomProperties: {
46
+ elapsedTime,
47
+ widgetLoadedAt: startTime,
48
+ botMessage: stopTrackingMessage
49
+ }
50
+ });
51
+ }
52
+ }
53
+
54
+ // this track only first message, if coming from the bot or not
55
+ // the only difference is that it logs only those from bot
56
+ disconnectListener();
57
+ });
58
+ const notifyFMLTrackingCompleted = () => {
59
+ ackListener();
60
+ // Retry sending until flag is true, but do not block the main thread
61
+ const interval = setInterval(() => {
62
+ if (flag) {
63
+ clearInterval(interval);
64
+ } else {
65
+ BroadcastService.postMessage({
66
+ eventName: BroadcastEvent.FMLTrackingCompleted,
67
+ payload: null
68
+ });
69
+ }
70
+ }, 100);
71
+ };
72
+ const ackListener = () => {
73
+ const listen = BroadcastService.getMessageByEventName(BroadcastEvent.FMLTrackingCompletedAck).subscribe(() => {
74
+ flag = true;
75
+ listen.unsubscribe();
76
+ });
77
+ };
78
+
79
+ // Rehydrate message is received when the widget is reloaded, this is to ensure that we are not tracking messages that are not part of the current conversation
80
+ // No need to keep listerning for tracking, enforcing disconnection for the listners
81
+ const rehydrateListener = BroadcastService.getMessageByEventName(TelemetryEvent.RehydrateMessageReceived).subscribe(() => {
82
+ startTracking = false;
83
+ stopTracking = false;
84
+ disconnectListener();
85
+ });
86
+
87
+ // Rehydrate message is received when the widget is reloaded, this is to ensure that we are not tracking messages that are not part of the current conversation
88
+ // No need to keep listerning for tracking, enforcing disconnection for the listners
89
+ const historyListener = BroadcastService.getMessageByEventName(BroadcastEvent.HistoryMessageReceived).subscribe(() => {
90
+ startTracking = false;
91
+ stopTracking = false;
92
+ disconnectListener();
93
+ });
94
+ const offlineNetworkListener = BroadcastService.getMessageByEventName(TelemetryEvent.NetworkDisconnected).subscribe(() => {
95
+ startTracking = false;
96
+ stopTracking = false;
97
+ disconnectListener();
98
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
99
+ Event: TelemetryEvent.BotFirstMessageLapTrackError,
100
+ Description: "Tracker Stopped due to network disconnection"
101
+ });
102
+ });
103
+
104
+ // this is to ensure that we are not tracking messages that are not part of the current conversation
105
+ const disconnectListener = () => {
106
+ historyListener.unsubscribe();
107
+ rehydrateListener.unsubscribe();
108
+ newMessageListener.unsubscribe();
109
+ widgetLoadListener.unsubscribe();
110
+ offlineNetworkListener.unsubscribe();
111
+ };
112
+ };
@@ -1,7 +1,8 @@
1
1
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
2
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
- import { LogLevel, TelemetryEvent } from "../common/telemetry/TelemetryConstants";
4
+ import { BroadcastEvent, LogLevel, TelemetryEvent } from "../common/telemetry/TelemetryConstants";
5
+ import { BroadcastService } from "@microsoft/omnichannel-chat-components";
5
6
  import { TelemetryHelper } from "../common/telemetry/TelemetryHelper";
6
7
  export class FirstResponseLatencyTracker {
7
8
  constructor() {
@@ -10,6 +11,32 @@ export class FirstResponseLatencyTracker {
10
11
  _defineProperty(this, "isEnded", false);
11
12
  _defineProperty(this, "startTrackingMessage", void 0);
12
13
  _defineProperty(this, "stopTrackingMessage", void 0);
14
+ _defineProperty(this, "isReady", false);
15
+ _defineProperty(this, "offlineNetworkListener", BroadcastService.getMessageByEventName(TelemetryEvent.NetworkDisconnected).subscribe(() => {
16
+ this.isStarted = false;
17
+ this.isEnded = false;
18
+ TelemetryHelper.logActionEvent(LogLevel.INFO, {
19
+ Event: TelemetryEvent.MessageStopLapTrackError,
20
+ Description: "Tracker Stopped due to network disconnection"
21
+ });
22
+ }));
23
+ _defineProperty(this, "fmltrackingListener", BroadcastService.getMessageByEventName(BroadcastEvent.FMLTrackingCompleted).subscribe(() => {
24
+ this.isReady = true;
25
+ BroadcastService.postMessage({
26
+ eventName: BroadcastEvent.FMLTrackingCompletedAck,
27
+ payload: null
28
+ });
29
+ }));
30
+ // Rehydrate message is received when the widget is reloaded, this is to ensure that we are not tracking messages that are not part of the current conversation
31
+ // No need to keep listerning for tracking, enforcing disconnection for the listners
32
+ _defineProperty(this, "rehydrateListener", BroadcastService.getMessageByEventName(TelemetryEvent.RehydrateMessageReceived).subscribe(() => {
33
+ this.isReady = true;
34
+ }));
35
+ // Rehydrate message is received when the widget is reloaded, this is to ensure that we are not tracking messages that are not part of the current conversation
36
+ // No need to keep listerning for tracking, enforcing disconnection for the listners
37
+ _defineProperty(this, "historyListener", BroadcastService.getMessageByEventName(BroadcastEvent.HistoryMessageReceived).subscribe(() => {
38
+ this.isReady = true;
39
+ }));
13
40
  // this is a workaround to ensure in reload we track effectively the messages
14
41
  // we do have a mechanism in place to prevent log agent messages.
15
42
  this.isABotConversation = true;
@@ -29,6 +56,7 @@ export class FirstResponseLatencyTracker {
29
56
 
30
57
  // Tracking Functions
31
58
  startTracking(payload) {
59
+ if (!this.isReady) return;
32
60
  // this prevents to initiate tracking for multiple incoming messages
33
61
  if (this.isStarted) {
34
62
  return;
@@ -37,11 +65,9 @@ export class FirstResponseLatencyTracker {
37
65
  if (!this.isABotConversation) {
38
66
  return;
39
67
  }
40
-
41
68
  // control of states to prevent clashing of messages
42
69
  this.isStarted = true;
43
70
  this.isEnded = false;
44
-
45
71
  // The idea of using types is to enrich telemetry data
46
72
  this.startTrackingMessage = this.createTrackingMessage(payload, "userMessage");
47
73
  }
@@ -93,9 +119,6 @@ export class FirstResponseLatencyTracker {
93
119
  if (!payload || !payload.Id) {
94
120
  throw new Error("Invalid payload");
95
121
  }
96
- // in the case of a reload, tracker will be paused, until last history message is received
97
- // this is because we dont have a way to identidy send messages as part of the history
98
- //if (this.inPause) return;
99
122
  this.startTracking(payload);
100
123
  } catch (e) {
101
124
  TelemetryHelper.logActionEvent(LogLevel.ERROR, {
@@ -141,5 +164,9 @@ export class FirstResponseLatencyTracker {
141
164
  this.isEnded = false;
142
165
  this.startTrackingMessage = undefined;
143
166
  this.stopTrackingMessage = undefined;
167
+ this.offlineNetworkListener.unsubscribe();
168
+ this.fmltrackingListener.unsubscribe();
169
+ this.rehydrateListener.unsubscribe();
170
+ this.historyListener.unsubscribe();
144
171
  }
145
172
  }
@@ -72,4 +72,16 @@ export const getScenarioType = activity => {
72
72
  return ScenarioType.SystemMessageStrategy;
73
73
  }
74
74
  return ScenarioType.ReceivedMessageStrategy;
75
+ };
76
+ export const createTrackingMessage = (payload, type) => {
77
+ return {
78
+ Id: payload.Id,
79
+ role: payload.role,
80
+ timestamp: payload === null || payload === void 0 ? void 0 : payload.timestamp,
81
+ tags: payload.tags,
82
+ messageType: payload.messageType,
83
+ text: payload.text,
84
+ type: type,
85
+ checkTime: new Date().getTime()
86
+ };
75
87
  };
@@ -43,6 +43,7 @@ export declare class FacadeChatSDK {
43
43
  private enforceBase64Encoding;
44
44
  private extractExpFromToken;
45
45
  private setToken;
46
+ private corroborateTokenIsSet;
46
47
  private tokenRing;
47
48
  private validateAndExecuteCall;
48
49
  initialize(optionalParams?: InitializeOptionalParams): Promise<ChatConfig>;
@@ -54,7 +54,9 @@ export declare enum BroadcastEvent {
54
54
  UpdateConversationDataForTelemetry = "UpdateConversationDataForTelemetry",
55
55
  ContactIdNotFound = "ContactIdNotFound",
56
56
  SyncMinimize = "SyncMinimize",
57
- OnWidgetError = "OnWidgetError"
57
+ OnWidgetError = "OnWidgetError",
58
+ FMLTrackingCompletedAck = "FMLTrackingCompletedAck",
59
+ FMLTrackingCompleted = "FMLTrackingCompleted"
58
60
  }
59
61
  export declare enum TelemetryEvent {
60
62
  CallAdded = "CallAdded",
@@ -193,6 +195,8 @@ export declare enum TelemetryEvent {
193
195
  MessageSent = "MessageSent",
194
196
  MessageReceived = "MessageReceived",
195
197
  MessageLapTrack = "MessageLapTrack",
198
+ BotFirstMessageLapTrack = "BotFirstMessageLapTrack",
199
+ BotFirstMessageLapTrackError = "BotFirstMessageLapTrackError",
196
200
  MessageStartLapTrackError = "MessageStartLapTrackError",
197
201
  MessageStopLapTrackError = "MessageStopLapTrackError",
198
202
  SystemMessageReceived = "SystemMessageReceived",
@@ -0,0 +1 @@
1
+ export declare const createTrackingForFirstMessage: () => void;