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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +46 -1
  2. package/lib/cjs/common/Constants.js +8 -2
  3. package/lib/cjs/common/telemetry/TelemetryConstants.js +3 -0
  4. package/lib/cjs/common/telemetry/TelemetryHelper.js +7 -5
  5. package/lib/cjs/common/utils.js +27 -2
  6. package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  7. package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  8. package/lib/cjs/components/livechatwidget/common/createMarkdown.js +54 -1
  9. package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
  10. package/lib/cjs/components/livechatwidget/common/endChat.js +13 -2
  11. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +8 -3
  12. package/lib/cjs/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
  13. package/lib/cjs/components/livechatwidget/common/startChat.js +5 -4
  14. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -6
  15. package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +1 -2
  16. package/lib/cjs/components/webchatcontainerstateful/common/DesignerChatAdapter.js +3 -1
  17. package/lib/cjs/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +27 -2
  18. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +42 -0
  19. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +72 -0
  20. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
  21. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +45 -0
  22. package/lib/cjs/contexts/common/CustomEventType.js +1 -0
  23. package/lib/cjs/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  24. package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  25. package/lib/cjs/firstresponselatency/util.js +24 -10
  26. package/lib/cjs/plugins/createChatTranscript.js +13 -0
  27. package/lib/cjs/plugins/newMessageEventHandler.js +2 -2
  28. package/lib/esm/common/Constants.js +8 -2
  29. package/lib/esm/common/telemetry/TelemetryConstants.js +3 -0
  30. package/lib/esm/common/telemetry/TelemetryHelper.js +7 -5
  31. package/lib/esm/common/utils.js +21 -0
  32. package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
  33. package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +22 -9
  34. package/lib/esm/components/livechatwidget/common/createMarkdown.js +54 -1
  35. package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
  36. package/lib/esm/components/livechatwidget/common/endChat.js +13 -2
  37. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +9 -4
  38. package/lib/esm/components/livechatwidget/common/renderSurveyHelpers.js +23 -0
  39. package/lib/esm/components/livechatwidget/common/startChat.js +5 -4
  40. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -6
  41. package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +1 -2
  42. package/lib/esm/components/webchatcontainerstateful/common/DesignerChatAdapter.js +4 -2
  43. package/lib/esm/components/webchatcontainerstateful/common/utils/chatAdapterUtils.js +23 -0
  44. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.js +36 -0
  45. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.js +65 -0
  46. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
  47. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.js +38 -0
  48. package/lib/esm/contexts/common/CustomEventType.js +1 -0
  49. package/lib/esm/firstresponselatency/FirstMessageTrackerFromBot.js +101 -36
  50. package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +39 -21
  51. package/lib/esm/firstresponselatency/util.js +21 -8
  52. package/lib/esm/plugins/createChatTranscript.js +13 -0
  53. package/lib/esm/plugins/newMessageEventHandler.js +3 -3
  54. package/lib/types/common/Constants.d.ts +8 -2
  55. package/lib/types/common/telemetry/TelemetryConstants.d.ts +3 -0
  56. package/lib/types/common/utils.d.ts +8 -0
  57. package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
  58. package/lib/types/components/webchatcontainerstateful/common/utils/chatAdapterUtils.d.ts +2 -0
  59. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/callActionMiddleware.d.ts +8 -0
  60. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/citationsMiddleware.d.ts +5 -0
  61. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
  62. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware.d.ts +5 -0
  63. package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
  64. package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +2 -2
  65. package/lib/types/firstresponselatency/util.d.ts +1 -0
  66. package/package.json +5 -4
@@ -14,6 +14,7 @@ var _TelemetryManager = require("../../../common/telemetry/TelemetryManager");
14
14
  var _endChat = require("../common/endChat");
15
15
  var _startChat = require("../common/startChat");
16
16
  var _utils = require("../../../common/utils");
17
+ var _customEventHandler = require("../common/customEventHandler");
17
18
  var _defaultClientDataStoreProvider = require("../../../common/storage/default/defaultClientDataStoreProvider");
18
19
  var _reconnectChatHelper = require("../common/reconnectChatHelper");
19
20
  var _componentController = require("../../../controller/componentController");
@@ -421,7 +422,7 @@ const LiveChatWidgetStateful = props => {
421
422
  _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.StartChat).subscribe(msg => {
422
423
  var _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3, _inMemoryState$appSta4;
423
424
  // If chat is out of operating hours chat widget sets the conversation state to OutOfOffice.
424
- if (state.appStates.outsideOperatingHours === true) {
425
+ if (state.appStates.outsideOperatingHours && state.appStates.conversationState !== _ConversationState.ConversationState.Active) {
425
426
  dispatch({
426
427
  type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
427
428
  payload: false
@@ -588,6 +589,9 @@ const LiveChatWidgetStateful = props => {
588
589
  }
589
590
  });
590
591
 
592
+ // subscribe custom event
593
+ (0, _customEventHandler.subscribeToSendCustomEvent)(_omnichannelChatComponents.BroadcastService, facadeChatSDK, _customEventHandler.customEventCallback);
594
+
591
595
  // Check for TPC and log in telemetry if blocked
592
596
  (0, _defaultClientDataStoreProvider.isCookieAllowed)();
593
597
  return () => {
@@ -723,11 +727,7 @@ const LiveChatWidgetStateful = props => {
723
727
  (0, _endChat.endChat)(props, facadeChatSDK, state, dispatch, setAdapter, setWebChatStyles, adapter, false, false, true);
724
728
  return;
725
729
  }
726
- const inMemoryState = (0, _createReducer.executeReducer)(state, {
727
- type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
728
- payload: null
729
- });
730
- let isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
730
+ const isConversationalSurveyEnabled = state.appStates.isConversationalSurveyEnabled;
731
731
 
732
732
  // In conversational survey, we need to check post chat survey logics before we set ConversationState to InActive
733
733
  // Hence setting ConversationState to InActive will be done later in the post chat flows
@@ -900,11 +900,21 @@ const LiveChatWidgetStateful = props => {
900
900
  .webchat__basic-transcript__activity-markdown-body > :first-child {
901
901
  margin-top: 0px;
902
902
  }
903
+
903
904
  .webchat__basic-transcript__activity-markdown-body img.webchat__render-markdown__external-link-icon {
904
905
  background-image : url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIzIDMgMTggMTgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTcuMjUwMSA0LjUwMDE3SDEwLjc0OTVDMTEuMTYzNyA0LjUwMDE3IDExLjQ5OTUgNC44MzU5NiAxMS40OTk1IDUuMjUwMTdDMTEuNDk5NSA1LjYyOTg2IDExLjIxNzMgNS45NDM2NiAxMC44NTEzIDUuOTkzMzJMMTAuNzQ5NSA2LjAwMDE3SDcuMjQ5NzRDNi4wNzA3OSA1Ljk5OTYxIDUuMTAzNDkgNi45MDY1NiA1LjAwNzg2IDguMDYxMTJMNS4wMDAyOCA4LjIyMDAzTDUuMDAzMTIgMTYuNzUwN0M1LjAwMzQzIDE3Ljk0MTUgNS45Mjg4NSAxOC45MTYxIDcuMDk5NjYgMTguOTk0OUw3LjI1MzcxIDE5LjAwMDFMMTUuNzUxOCAxOC45ODg0QzE2Ljk0MTUgMTguOTg2OCAxNy45MTQ1IDE4LjA2MiAxNy45OTM1IDE2Ljg5MjNMMTcuOTk4NyAxNi43Mzg0VjEzLjIzMjFDMTcuOTk4NyAxMi44MTc5IDE4LjMzNDUgMTIuNDgyMSAxOC43NDg3IDEyLjQ4MjFDMTkuMTI4NCAxMi40ODIxIDE5LjQ0MjIgMTIuNzY0MyAxOS40OTE4IDEzLjEzMDNMMTkuNDk4NyAxMy4yMzIxVjE2LjczODRDMTkuNDk4NyAxOC43NDA3IDE3LjkyOTMgMjAuMzc2OSAxNS45NTI4IDIwLjQ4MjlMMTUuNzUzOCAyMC40ODg0TDcuMjU4MjcgMjAuNTAwMUw3LjA1NDk1IDIwLjQ5NDlDNS4xNDIzOSAyMC4zOTU0IDMuNjA4OTUgMTguODYyNyAzLjUwODM3IDE2Ljk1MDJMMy41MDMxMiAxNi43NTExTDMuNTAwODkgOC4yNTI3TDMuNTA1MjkgOC4wNTAyQzMuNjA1MzkgNi4xMzc0OSA1LjEzODY3IDQuNjA0NDkgNy4wNTA5NiA0LjUwNTI3TDcuMjUwMSA0LjUwMDE3SDEwLjc0OTVINy4yNTAxWk0xMy43NDgxIDMuMDAxNDZMMjAuMzAxOCAzLjAwMTk3TDIwLjQwMTQgMy4wMTU3NUwyMC41MDIyIDMuMDQzOTNMMjAuNTU5IDMuMDY4MDNDMjAuNjEyMiAzLjA5MTIyIDIwLjY2MzQgMy4xMjE2MyAyMC43MTExIDMuMTU4ODVMMjAuNzgwNCAzLjIyMTU2TDIwLjg2NDEgMy4zMjAxNEwyMC45MTgzIDMuNDEwMjVMMjAuOTU3IDMuNTAwNTdMMjAuOTc2MiAzLjU2NDc2TDIwLjk4OTggMy42Mjg2MkwyMC45OTkyIDMuNzIyODJMMjAuOTk5NyAxMC4yNTU0QzIwLjk5OTcgMTAuNjY5NiAyMC42NjM5IDExLjAwNTQgMjAuMjQ5NyAxMS4wMDU0QzE5Ljg3IDExLjAwNTQgMTkuNTU2MiAxMC43MjMyIDE5LjUwNjUgMTAuMzU3MUwxOS40OTk3IDEwLjI1NTRMMTkuNDk4OSA1LjU2MTQ3TDEyLjI3OTcgMTIuNzg0N0MxMi4wMTM0IDEzLjA1MSAxMS41OTY4IDEzLjA3NTMgMTEuMzAzMSAxMi44NTc1TDExLjIxOSAxMi43ODQ5QzEwLjk1MjcgMTIuNTE4NyAxMC45Mjg0IDEyLjEwMjEgMTEuMTQ2MiAxMS44MDg0TDExLjIxODggMTEuNzI0M0wxOC40MzY5IDQuNTAxNDZIMTMuNzQ4MUMxMy4zNjg0IDQuNTAxNDYgMTMuMDU0NiA0LjIxOTMxIDEzLjAwNSAzLjg1MzI0TDEyLjk5ODEgMy43NTE0NkMxMi45OTgxIDMuMzcxNzcgMTMuMjgwMyAzLjA1Nzk3IDEzLjY0NjQgMy4wMDgzMUwxMy43NDgxIDMuMDAxNDZaIiBmaWxsPSIjMjEyMTIxIiAvPjwvc3ZnPg==) !important;
905
906
  height: .75em;
906
907
  margin-left: .25em;
907
908
  }
909
+
910
+ .webchat__link-definitions__header-text {
911
+ color: ${bubbleBackground}
912
+ }
913
+
914
+ .webchat__link-definitions__header-chevron {
915
+ color: ${bubbleBackground}
916
+ }
917
+
908
918
  ${(sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight) && `
909
919
  .webchat__auto-resize-textarea.webchat__send-box-text-box__text-area {
910
920
  min-height: ${sendBoxTextArea === null || sendBoxTextArea === void 0 ? void 0 : sendBoxTextArea.minHeight} !important;
@@ -186,7 +186,7 @@ const WebChatContainerStateful = props => {
186
186
  }
187
187
 
188
188
  .webchat__bubble__content>div#ms_lcw_webchat_adaptive_card .ac-textBlock {
189
- color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp2 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp2 === void 0 ? void 0 : _webChatContainerProp2.color) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.color} !important;
189
+ color: ${(webChatContainerProps === null || webChatContainerProps === void 0 ? void 0 : (_webChatContainerProp2 = webChatContainerProps.adaptiveCardStyles) === null || _webChatContainerProp2 === void 0 ? void 0 : _webChatContainerProp2.color) ?? _defaultAdaptiveCardStyles.defaultAdaptiveCardStyles.color};
190
190
  }
191
191
 
192
192
  .webchat__stacked-layout__content div.webchat__stacked-layout__message-row div.webchat__bubble--from-user {
@@ -295,7 +295,6 @@ const WebChatContainerStateful = props => {
295
295
  overflow-y: unset;
296
296
  }
297
297
 
298
-
299
298
  `), /*#__PURE__*/_react2.default.createElement(_react.Stack, {
300
299
  styles: containerStyles,
301
300
  className: "webchat__stacked-layout_container"
@@ -29,10 +29,12 @@ let DesignerChatAdapter = /*#__PURE__*/function (_MockAdapter) {
29
29
  _this = _super.call(this);
30
30
  setTimeout(() => {
31
31
  (0, _chatAdapterUtils.postBotMessageActivity)(_this.activityObserver, "Thank you for contacting us! How can I help you today?", undefined, 0);
32
+ (0, _chatAdapterUtils.postBotMessageActivity)(_this.activityObserver, "Please accept terms and conditions to proceed. Visit the link for terms and conditions <a href=\"\">here</a>.", undefined, 0);
32
33
  _this.postUserActivity("I need to change my address.", 0);
33
34
  (0, _chatAdapterUtils.postBotMessageActivity)(_this.activityObserver, "Okay, let me connect you with a live agent.", undefined, 100);
34
35
  (0, _chatAdapterUtils.postSystemMessageActivity)(_this.activityObserver, "John has joined the chat", 100);
35
- (0, _chatAdapterUtils.postBotMessageActivity)(_this.activityObserver, "I'd be happy to help you update your account.", undefined, 100);
36
+ (0, _chatAdapterUtils.postAgentMessageActivity)(_this.activityObserver, "I'd be happy to help you update your account.", undefined, 100);
37
+ _this.postUserActivity("I have trouble visiting the signin page <a href=\"\">signin</a>.", 0);
36
38
  }, 1000);
37
39
  return _this;
38
40
  }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.postSystemMessageActivity = exports.postEchoActivity = exports.postBotTypingActivity = exports.postBotMessageActivity = exports.postBotAttachmentActivity = exports.customerUser = exports.botUser = void 0;
6
+ exports.postSystemMessageActivity = exports.postEchoActivity = exports.postBotTypingActivity = exports.postBotMessageActivity = exports.postBotAttachmentActivity = exports.postAgentMessageActivity = exports.customerUser = exports.botUser = exports.agentUser = void 0;
7
7
  var _omnichannelChatSdk = require("@microsoft/omnichannel-chat-sdk");
8
8
  const customerUser = {
9
9
  id: "usedId",
@@ -16,9 +16,15 @@ const botUser = {
16
16
  name: "Bot",
17
17
  role: "bot"
18
18
  };
19
+ exports.botUser = botUser;
20
+ const agentUser = {
21
+ id: "AgentId",
22
+ name: "John",
23
+ role: "bot"
24
+ };
19
25
 
20
26
  // WebChat expects an "echo" activity to confirm the message has been sent successfully
21
- exports.botUser = botUser;
27
+ exports.agentUser = agentUser;
22
28
  const postEchoActivity = function (activityObserver, activity, user) {
23
29
  let delay = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
24
30
  const echoActivity = {
@@ -54,6 +60,25 @@ const postBotMessageActivity = function (activityObserver, text) {
54
60
  }, delay);
55
61
  };
56
62
  exports.postBotMessageActivity = postBotMessageActivity;
63
+ const postAgentMessageActivity = function (activityObserver, text) {
64
+ let tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
65
+ let delay = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1000;
66
+ setTimeout(() => {
67
+ activityObserver === null || activityObserver === void 0 ? void 0 : activityObserver.next({
68
+ id: (0, _omnichannelChatSdk.uuidv4)(),
69
+ from: {
70
+ ...agentUser
71
+ },
72
+ text,
73
+ type: "message",
74
+ channelData: {
75
+ tags
76
+ },
77
+ timestamp: new Date().toISOString()
78
+ });
79
+ }, delay);
80
+ };
81
+ exports.postAgentMessageActivity = postAgentMessageActivity;
57
82
  const postSystemMessageActivity = function (activityObserver, text) {
58
83
  let delay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
59
84
  postBotMessageActivity(activityObserver, text, "system", delay);
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _WebChatActionType = require("../../enums/WebChatActionType");
8
+ /******
9
+ * CallActionMiddleware
10
+ *
11
+ * Intercepts custom call actions and handles tel: URL navigation
12
+ ******/
13
+
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
15
+ const createCallActionMiddleware = () => () => next => action => {
16
+ // Intercept incoming activities to modify suggested actions with call type
17
+ if (action.type === _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY) {
18
+ var _action$payload, _activity$suggestedAc;
19
+ const activity = (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : _action$payload.activity;
20
+
21
+ // Check if activity has suggested actions with call type
22
+ if (activity !== null && activity !== void 0 && (_activity$suggestedAc = activity.suggestedActions) !== null && _activity$suggestedAc !== void 0 && _activity$suggestedAc.actions) {
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ activity.suggestedActions.actions = activity.suggestedActions.actions.map(suggestedAction => {
25
+ if (suggestedAction.type === "call") {
26
+ // Convert call action to openUrl with encoded tel URL scheme
27
+ const telUrl = suggestedAction.value;
28
+ const convertedAction = {
29
+ ...suggestedAction,
30
+ type: "openUrl",
31
+ value: `tel:${telUrl}`
32
+ };
33
+ return convertedAction;
34
+ }
35
+ return suggestedAction;
36
+ });
37
+ }
38
+ }
39
+ return next(action);
40
+ };
41
+ var _default = createCallActionMiddleware;
42
+ exports.default = _default;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createCitationsMiddleware = void 0;
7
+ var _TelemetryConstants = require("../../../../../common/telemetry/TelemetryConstants");
8
+ var _TelemetryHelper = require("../../../../../common/telemetry/TelemetryHelper");
9
+ const createCitationsMiddleware = _ref => {
10
+ let {
11
+ dispatch
12
+ } = _ref;
13
+ return next => action => {
14
+ var _action$payload;
15
+ if ((_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
16
+ if (isApplicable(action)) {
17
+ try {
18
+ const gptFeedback = JSON.parse(action.payload.activity.channelData.metadata["pva:gpt-feedback"]);
19
+ // Replace citations in the text
20
+ const updatedText = replaceCitations(action.payload.activity.text, gptFeedback.summarizationOpenAIResponse.result.textCitations);
21
+ action.payload.activity.text = updatedText;
22
+ } catch (error) {
23
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
24
+ Event: _TelemetryConstants.TelemetryEvent.CitationMiddlewareFailed,
25
+ ExceptionDetails: {
26
+ ErrorData: "Error while converting citation labels",
27
+ Exception: error
28
+ }
29
+ });
30
+ }
31
+ }
32
+ }
33
+ return next(action);
34
+ };
35
+ };
36
+ exports.createCitationsMiddleware = createCitationsMiddleware;
37
+ const isApplicable = action => {
38
+ var _action$payload2, _action$payload2$acti, _action$payload3, _action$payload3$acti;
39
+ if ((action === null || action === void 0 ? void 0 : (_action$payload2 = action.payload) === null || _action$payload2 === void 0 ? void 0 : (_action$payload2$acti = _action$payload2.activity) === null || _action$payload2$acti === void 0 ? void 0 : _action$payload2$acti.actionType) === "DIRECT_LINE/INCOMING_ACTIVITY" && (action === null || action === void 0 ? void 0 : (_action$payload3 = action.payload) === null || _action$payload3 === void 0 ? void 0 : (_action$payload3$acti = _action$payload3.activity) === null || _action$payload3$acti === void 0 ? void 0 : _action$payload3$acti.channelId) === "ACS_CHANNEL") {
40
+ var _action$payload4, _action$payload4$acti, _action$payload4$acti2, _action$payload4$acti3;
41
+ // Validate if pva:gpt-feedback exists and is not null
42
+ if (action !== null && action !== void 0 && (_action$payload4 = action.payload) !== null && _action$payload4 !== void 0 && (_action$payload4$acti = _action$payload4.activity) !== null && _action$payload4$acti !== void 0 && (_action$payload4$acti2 = _action$payload4$acti.channelData) !== null && _action$payload4$acti2 !== void 0 && (_action$payload4$acti3 = _action$payload4$acti2.metadata) !== null && _action$payload4$acti3 !== void 0 && _action$payload4$acti3["pva:gpt-feedback"]) {
43
+ return true;
44
+ }
45
+ }
46
+ return false;
47
+ };
48
+ const replaceCitations = (text, citations) => {
49
+ if (!citations || !Array.isArray(citations)) {
50
+ return text;
51
+ }
52
+ try {
53
+ return text.replace(/\[(\d+)\]:\s(cite:\d+)\s"([^"]+)"/g, (match, number, citeId) => {
54
+ const citation = citations.find(c => c.id === citeId);
55
+ if (citation) {
56
+ // Replace only the citation label while preserving the original format
57
+ return `[${number}]: ${citeId} "${citation.title}"`;
58
+ }
59
+ return match; // Keep the original match if no replacement is found
60
+ });
61
+ } catch (error) {
62
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
63
+ Event: _TelemetryConstants.TelemetryEvent.CitationMiddlewareFailed,
64
+ ExceptionDetails: {
65
+ ErrorData: "Error while finding citations references",
66
+ Exception: error
67
+ }
68
+ });
69
+ // Return the original text in case of issues
70
+ return text;
71
+ }
72
+ };
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isValidCustomEvent = exports.default = void 0;
7
+ var _Constants = require("../../../../../common/Constants");
8
+ var _WebChatActionType = require("../../enums/WebChatActionType");
9
+ /******
10
+ * CustomEventMiddleware
11
+ *
12
+ * This middleware is invoked when a custom event is received.
13
+ * The callback is then invoked to handle the custom event.
14
+ ******/
15
+
16
+ const isValidCustomEvent = activity => {
17
+ var _activity$channelData, _activity$channelData2, _activity$channelData3, _activity$channelData4, _activity$channelData5, _activity$channelData6, _activity$channelData7, _activity$from, _activity$channelData8, _activity$channelData9, _activity$channelData10, _activity$channelData11;
18
+ return !!(activity !== null && activity !== void 0 && (_activity$channelData = activity.channelData) !== null && _activity$channelData !== void 0 && (_activity$channelData2 = _activity$channelData.metadata) !== null && _activity$channelData2 !== void 0 && _activity$channelData2.customEvent && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : (_activity$channelData4 = _activity$channelData3.metadata) === null || _activity$channelData4 === void 0 ? void 0 : _activity$channelData4.customEvent) === _Constants.Constants.String && (activity === null || activity === void 0 ? void 0 : (_activity$channelData5 = activity.channelData) === null || _activity$channelData5 === void 0 ? void 0 : (_activity$channelData6 = _activity$channelData5.metadata) === null || _activity$channelData6 === void 0 ? void 0 : (_activity$channelData7 = _activity$channelData6.customEvent) === null || _activity$channelData7 === void 0 ? void 0 : _activity$channelData7.toLowerCase()) === _Constants.Constants.true && (activity === null || activity === void 0 ? void 0 : (_activity$from = activity.from) === null || _activity$from === void 0 ? void 0 : _activity$from.role) !== _Constants.Constants.userMessageTag && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData8 = activity.channelData) === null || _activity$channelData8 === void 0 ? void 0 : (_activity$channelData9 = _activity$channelData8.metadata) === null || _activity$channelData9 === void 0 ? void 0 : _activity$channelData9.customEventName) === _Constants.Constants.String && activity !== null && activity !== void 0 && (_activity$channelData10 = activity.channelData) !== null && _activity$channelData10 !== void 0 && (_activity$channelData11 = _activity$channelData10.metadata) !== null && _activity$channelData11 !== void 0 && _activity$channelData11.customEventValue);
19
+ };
20
+ exports.isValidCustomEvent = isValidCustomEvent;
21
+ const createCustomEventMiddleware = broadcastservice => () => next => action => {
22
+ var _action$payload;
23
+ if ((action === null || action === void 0 ? void 0 : action.type) == _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && (_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
24
+ const activity = action.payload.activity;
25
+ if (isValidCustomEvent(activity)) {
26
+ const customEvent = {
27
+ eventName: _Constants.Constants.onCustomEvent,
28
+ payload: {
29
+ messageId: activity.messageid ?? activity.id,
30
+ customEventName: activity.channelData.metadata.customEventName,
31
+ customEventValue: activity.channelData.metadata.customEventValue
32
+ }
33
+ };
34
+ broadcastservice.postMessage(customEvent);
35
+ return;
36
+ }
37
+ }
38
+ return next(action);
39
+ };
40
+ var _default = createCustomEventMiddleware;
41
+ exports.default = _default;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createQueueOverflowMiddleware = void 0;
7
+ var _WebChatActionType = require("../../enums/WebChatActionType");
8
+ var _TelemetryConstants = require("../../../../../common/telemetry/TelemetryConstants");
9
+ var _TelemetryHelper = require("../../../../../common/telemetry/TelemetryHelper");
10
+ var _LiveChatWidgetActionType = require("../../../../../contexts/common/LiveChatWidgetActionType");
11
+ var _createReducer = require("../../../../../contexts/createReducer");
12
+ var _utils = require("../../../../../common/utils");
13
+ const queueOverflowHandlingHelper = async (state, dispatch) => {
14
+ const {
15
+ appStates
16
+ } = (0, _createReducer.executeReducer)(state, {
17
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
18
+ payload: undefined
19
+ });
20
+ if (!appStates.chatDisconnectEventReceived) {
21
+ dispatch({
22
+ type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
23
+ payload: true
24
+ });
25
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
26
+ Event: _TelemetryConstants.TelemetryEvent.QueueOverflowEvent,
27
+ Description: "Set chat disconnect event received."
28
+ });
29
+ }
30
+ };
31
+ const createQueueOverflowMiddleware = (state, dispatch) => () => next => action => {
32
+ var _action$payload;
33
+ if ((action === null || action === void 0 ? void 0 : action.type) == _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && (_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
34
+ const activity = action.payload.activity;
35
+ if ((0, _utils.isEndConversationDueToOverflowActivity)(activity)) {
36
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
37
+ Event: _TelemetryConstants.TelemetryEvent.QueueOverflowEvent,
38
+ Description: "Queue overflow event received."
39
+ });
40
+ queueOverflowHandlingHelper(state, dispatch);
41
+ }
42
+ }
43
+ return next(action);
44
+ };
45
+ exports.createQueueOverflowMiddleware = createQueueOverflowMiddleware;
@@ -0,0 +1 @@
1
+ "use strict";
@@ -12,54 +12,96 @@ var _util = require("./util");
12
12
  // with different timeline, therefore this is a functional approach to track the events, instead of a class based approach
13
13
  const createTrackingForFirstMessage = () => {
14
14
  // Reset the tracking variables
15
- let startTracking = false;
16
- let stopTracking = false;
15
+ let isTracking = false;
17
16
  let startTime = 0;
18
17
  let stopTime = 0;
19
- let stopTrackingMessage;
18
+ let stopTrackingMessage = null;
20
19
  let flag = false;
20
+ let trackingTimeoutId;
21
+
22
+ /**
23
+ * Checks if the message payload is from a valid sender (not an agent).
24
+ * Returns false if the message is from an agent (tag 'public'), true otherwise.
25
+ */
21
26
  const isMessageFromValidSender = payload => {
22
27
  var _payload$tags;
23
- // agent scenario
24
28
  if (payload !== null && payload !== void 0 && (_payload$tags = payload.tags) !== null && _payload$tags !== void 0 && _payload$tags.includes("public")) {
25
29
  return false;
26
30
  }
27
31
  return true;
28
32
  };
33
+
34
+ /**
35
+ * Listener for widget load completion event.
36
+ * Starts tracking the time for the first bot message after widget loads.
37
+ * Sets a 5-second timeout to auto-reset if no bot message is received.
38
+ */
29
39
  const widgetLoadListener = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.TelemetryEvent.WidgetLoadComplete).subscribe(() => {
30
- if (startTracking) return;
31
- startTracking = true;
40
+ if (isTracking) return;
41
+ isTracking = true;
32
42
  startTime = new Date().getTime();
43
+ // Start a 5-second timeout to auto-stop tracking if not stopped
44
+ if (trackingTimeoutId) {
45
+ clearTimeout(trackingTimeoutId);
46
+ }
47
+ trackingTimeoutId = setTimeout(() => {
48
+ if (isTracking) {
49
+ // Reset state and disengage, no telemetry or FMLTrackingCompleted
50
+ isTracking = false;
51
+ startTime = 0;
52
+ stopTime = 0;
53
+ stopTrackingMessage = null;
54
+ trackingTimeoutId = undefined;
55
+ disconnectListener();
56
+ }
57
+ }, 10000); //adding more time since it meassures from widget load complete till message received
33
58
  });
59
+
60
+ /**
61
+ * Listener for new bot message event.
62
+ * If a valid bot message is received, stops tracking and logs telemetry.
63
+ * If the message is invalid, resets and disengages listeners.
64
+ */
34
65
  const newMessageListener = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.NewMessageReceived).subscribe(message => {
35
66
  const payload = message.payload;
36
-
37
- // we only care for bot, so we need to check if the message is from the bot
38
- // pending to add typing message indicator signal detection
39
-
40
- if (isMessageFromValidSender(payload)) {
41
- if (startTracking && !stopTracking) {
42
- stopTime = new Date().getTime();
43
- const elapsedTime = stopTime - startTime;
44
- stopTracking = true;
45
- stopTrackingMessage = (0, _util.createTrackingMessage)(payload, "botMessage");
46
- notifyFMLTrackingCompleted();
47
- _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
48
- Event: _TelemetryConstants.TelemetryEvent.BotFirstMessageLapTrack,
49
- Description: "First Message from Bot latency tracking",
50
- CustomProperties: {
51
- elapsedTime,
52
- widgetLoadedAt: startTime,
53
- botMessage: stopTrackingMessage
54
- }
55
- });
67
+ if (!isMessageFromValidSender(payload)) {
68
+ // If not valid, stop everything and clean up
69
+ isTracking = false;
70
+ if (trackingTimeoutId) {
71
+ clearTimeout(trackingTimeoutId);
72
+ trackingTimeoutId = undefined;
56
73
  }
74
+ disconnectListener();
75
+ return;
76
+ }
77
+ if (isTracking) {
78
+ isTracking = false;
79
+ // Clear the timeout if it exists
80
+ if (trackingTimeoutId) {
81
+ clearTimeout(trackingTimeoutId);
82
+ trackingTimeoutId = undefined;
83
+ }
84
+ stopTime = new Date().getTime();
85
+ const elapsedTime = stopTime - startTime;
86
+ stopTrackingMessage = (0, _util.createTrackingMessage)(payload, "botMessage");
87
+ notifyFMLTrackingCompleted();
88
+ _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
89
+ Event: _TelemetryConstants.TelemetryEvent.BotFirstMessageLapTrack,
90
+ Description: "First Message from Bot latency tracking",
91
+ CustomProperties: {
92
+ elapsedTime,
93
+ widgetLoadedAt: startTime,
94
+ botMessage: stopTrackingMessage
95
+ }
96
+ });
97
+ disconnectListener();
57
98
  }
58
-
59
- // this track only first message, if coming from the bot or not
60
- // the only difference is that it logs only those from bot
61
- disconnectListener();
62
99
  });
100
+
101
+ /**
102
+ * Notifies that FML (First Message Latency) tracking is completed.
103
+ * Retries sending the completion event until acknowledged.
104
+ */
63
105
  const notifyFMLTrackingCompleted = () => {
64
106
  ackListener();
65
107
  // Retry sending until flag is true, but do not block the main thread
@@ -74,6 +116,11 @@ const createTrackingForFirstMessage = () => {
74
116
  }
75
117
  }, 100);
76
118
  };
119
+
120
+ /**
121
+ * Listener for FMLTrackingCompletedAck event.
122
+ * Sets the flag to true when acknowledgment is received.
123
+ */
77
124
  const ackListener = () => {
78
125
  const listen = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.FMLTrackingCompletedAck).subscribe(() => {
79
126
  flag = true;
@@ -83,22 +130,32 @@ const createTrackingForFirstMessage = () => {
83
130
 
84
131
  // 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
85
132
  // No need to keep listerning for tracking, enforcing disconnection for the listners
133
+ /**
134
+ * Listener for widget rehydration event.
135
+ * Resets tracking and disconnects listeners when widget is reloaded.
136
+ */
86
137
  const rehydrateListener = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.TelemetryEvent.RehydrateMessageReceived).subscribe(() => {
87
- startTracking = false;
88
- stopTracking = false;
138
+ isTracking = false;
89
139
  disconnectListener();
90
140
  });
91
141
 
92
142
  // 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
93
143
  // No need to keep listerning for tracking, enforcing disconnection for the listners
144
+ /**
145
+ * Listener for history message event.
146
+ * Resets tracking and disconnects listeners when history is loaded.
147
+ */
94
148
  const historyListener = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.HistoryMessageReceived).subscribe(() => {
95
- startTracking = false;
96
- stopTracking = false;
149
+ isTracking = false;
97
150
  disconnectListener();
98
151
  });
152
+
153
+ /**
154
+ * Listener for network disconnection event.
155
+ * Resets tracking, disconnects listeners, and logs a telemetry error.
156
+ */
99
157
  const offlineNetworkListener = _omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.TelemetryEvent.NetworkDisconnected).subscribe(() => {
100
- startTracking = false;
101
- stopTracking = false;
158
+ isTracking = false;
102
159
  disconnectListener();
103
160
  _TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
104
161
  Event: _TelemetryConstants.TelemetryEvent.BotFirstMessageLapTrackError,
@@ -107,7 +164,15 @@ const createTrackingForFirstMessage = () => {
107
164
  });
108
165
 
109
166
  // this is to ensure that we are not tracking messages that are not part of the current conversation
167
+ /**
168
+ * Disconnects all listeners and clears the tracking timeout.
169
+ * Used for cleanup when tracking is stopped or reset.
170
+ */
110
171
  const disconnectListener = () => {
172
+ if (trackingTimeoutId) {
173
+ clearTimeout(trackingTimeoutId);
174
+ trackingTimeoutId = undefined;
175
+ }
111
176
  historyListener.unsubscribe();
112
177
  rehydrateListener.unsubscribe();
113
178
  newMessageListener.unsubscribe();