@microsoft/omnichannel-chat-widget 1.2.2 → 1.2.3-main.2ce131d

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 (23) hide show
  1. package/lib/cjs/common/Constants.js +5 -1
  2. package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +2 -1
  3. package/lib/cjs/components/livechatwidget/common/reconnectChatHelper.js +12 -7
  4. package/lib/cjs/components/livechatwidget/common/startChat.js +6 -5
  5. package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -15
  6. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +5 -0
  7. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.js +65 -0
  8. package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.spec.js +342 -0
  9. package/lib/cjs/plugins/createChatTranscript.js +28 -4
  10. package/lib/esm/common/Constants.js +5 -1
  11. package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +2 -1
  12. package/lib/esm/components/livechatwidget/common/reconnectChatHelper.js +12 -7
  13. package/lib/esm/components/livechatwidget/common/startChat.js +6 -5
  14. package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +16 -15
  15. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/attachmentMiddleware.js +5 -0
  16. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.js +58 -0
  17. package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.spec.js +338 -0
  18. package/lib/esm/plugins/createChatTranscript.js +28 -4
  19. package/lib/types/common/Constants.d.ts +4 -0
  20. package/lib/types/components/livechatwidget/common/reconnectChatHelper.d.ts +1 -1
  21. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.d.ts +5 -0
  22. package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware.spec.d.ts +1 -0
  23. package/package.json +2 -2
@@ -124,7 +124,13 @@ class TranscriptHTMLBuilder {
124
124
  <script>
125
125
  class Translator {
126
126
  static convertTranscriptMessageToActivity(message) {
127
- const {created, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences} = message;
127
+ const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences} = message;
128
+
129
+ //it's required to convert the id to a number, otherwise the webchat will not render the messages in the correct order
130
+ // if the OrginalMessageId is not present, we can use the id as the sequence id, which is always present.
131
+
132
+ const webchatSequenceId = Translator.convertStringValueToInt(OriginalMessageId) || Translator.convertStringValueToInt(id);
133
+
128
134
  const activity = {
129
135
  from: {
130
136
  role: 'bot'
@@ -179,7 +185,10 @@ class TranscriptHTMLBuilder {
179
185
  return {
180
186
  ...activity,
181
187
  text,
182
- timestamp: created
188
+ timestamp: created,
189
+ channelData: {
190
+ "webchat:sequence-id": webchatSequenceId
191
+ }
183
192
  }
184
193
  }
185
194
 
@@ -192,7 +201,10 @@ class TranscriptHTMLBuilder {
192
201
  return {
193
202
  ...activity,
194
203
  ...partialActivity,
195
- timestamp: created
204
+ timestamp: created,
205
+ channelData: {
206
+ "webchat:sequence-id": webchatSequenceId
207
+ }
196
208
  };
197
209
  } catch {
198
210
 
@@ -203,9 +215,21 @@ class TranscriptHTMLBuilder {
203
215
  return {
204
216
  ...activity,
205
217
  text: content,
206
- timestamp: created
218
+ timestamp: created,
219
+ channelData: {
220
+ "webchat:sequence-id": webchatSequenceId
221
+ }
207
222
  };
208
223
  }
224
+
225
+ static convertStringValueToInt(value) {
226
+ if (typeof value !== "string" || value === "") {
227
+ return undefined;
228
+ }
229
+
230
+ const result = parseInt(value);
231
+ return isNaN(result) ? undefined : result;
232
+ }
209
233
  }
210
234
  <\/script>
211
235
  <script>
@@ -51,7 +51,8 @@ _defineProperty(Constants, "prefixTimestampTag", "ServerMessageTimestamp_");
51
51
  _defineProperty(Constants, "acsChannel", "ACS_CHANNEL");
52
52
  _defineProperty(Constants, "publicMessageTag", "public");
53
53
  //attachmentMiddleware
54
- _defineProperty(Constants, "supportedAdaptiveCardContentTypes", ["application/vnd.microsoft.card.adaptive", "application/vnd.microsoft.card.audio", "application/vnd.microsoft.card.hero", "application/vnd.microsoft.card.receipt", "application/vnd.microsoft.card.thumbnail", "application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth"]);
54
+ _defineProperty(Constants, "supportedAdaptiveCardContentTypes", ["application/vnd.microsoft.card.adaptive", "application/vnd.microsoft.card.audio", "application/vnd.microsoft.card.hero", "application/vnd.microsoft.card.receipt", "application/vnd.microsoft.card.thumbnail", "application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth", "application/vnd.microsoft.card.video"]);
55
+ _defineProperty(Constants, "adaptiveCardContentTypePrefix", "application/vnd.microsoft.card");
55
56
  _defineProperty(Constants, "maxUploadFileSize", "500000");
56
57
  _defineProperty(Constants, "imageRegex", /(\.)(jpeg|jpg|jiff|png|gif|bmp|webp)$/i);
57
58
  _defineProperty(Constants, "audioMediaRegex", /(\.)(aac|aiff|alac|amr|flac|mp2|mp3|pcm|wav|wma)$/i);
@@ -109,6 +110,9 @@ _defineProperty(Constants, "LWICheckOnVisibilityTimeout", 3 * 60 * 1000);
109
110
  // Popup mode custom context response event message name
110
111
  _defineProperty(Constants, "InitContextParamsRequest", "initContextParamsRequest");
111
112
  _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsResponse");
113
+ _defineProperty(Constants, "OCOriginalMessageId", "OriginalMessageId");
114
+ _defineProperty(Constants, "WebchatSequenceIdAttribute", "webchat:sequence-id");
115
+ _defineProperty(Constants, "MessageSequenceIdOverride", "MessageSequenceIdOverride");
112
116
  export const Regex = (_class = class Regex {}, _defineProperty(_class, "EmailRegex", "(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])"), _class);
113
117
  export class HtmlIdNames {}
114
118
  _defineProperty(HtmlIdNames, "MSLiveChatWidget", "MSLiveChatWidget");
@@ -29,6 +29,7 @@ import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller
29
29
  import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
30
30
  import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
31
31
  import DOMPurify from "dompurify";
32
+ import createMessageSequenceIdOverrideMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/messageSequenceIdOverrideMiddleware";
32
33
 
33
34
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
35
  export const initWebChatComposer = (props, state, dispatch, chatSDK) => {
@@ -68,7 +69,7 @@ export const initWebChatComposer = (props, state, dispatch, chatSDK) => {
68
69
  };
69
70
  webChatStore = createStore({},
70
71
  //initial state
71
- preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
72
+ preProcessingMiddleware, attachmentProcessingMiddleware, createAttachmentUploadValidatorMiddleware((_state$domainStates$l = state.domainStates.liveChatConfig) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.allowedFileExtensions, (_state$domainStates$l2 = state.domainStates.liveChatConfig) === null || _state$domainStates$l2 === void 0 ? void 0 : _state$domainStates$l2.maxUploadFileSize, localizedTexts), channelDataMiddleware, createConversationEndMiddleware(conversationEndCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware, createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
72
73
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
74
  ...(((_props$webChatContain5 = props.webChatContainerProps) === null || _props$webChatContain5 === void 0 ? void 0 : _props$webChatContain5.storeMiddlewares) ?? []));
74
75
  WebChatStoreLoader.store = webChatStore;
@@ -8,10 +8,11 @@ import { ConversationState } from "../../../contexts/common/ConversationState";
8
8
  import { LiveChatWidgetActionType } from "../../../contexts/common/LiveChatWidgetActionType";
9
9
  import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
10
10
 
11
+ // Return value: should start normal chat flow when reconnect is enabled
11
12
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
13
  const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initStartChat, state) => {
13
14
  var _props$chatConfig, _props$chatConfig$Liv;
14
- if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return;
15
+ if (!isReconnectEnabled(props.chatConfig) || isPersistentEnabled(props.chatConfig)) return false;
15
16
 
16
17
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
18
  const isAuthenticatedChat = (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
@@ -23,14 +24,14 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
23
24
  if (reconnectChatContext !== null && reconnectChatContext !== void 0 && reconnectChatContext.redirectURL) {
24
25
  var _props$reconnectChatP;
25
26
  redirectPage(reconnectChatContext.redirectURL, (_props$reconnectChatP = props.reconnectChatPaneProps) === null || _props$reconnectChatP === void 0 ? void 0 : _props$reconnectChatP.redirectInSameWindow);
26
- return;
27
+ return false;
27
28
  }
28
29
  if (hasReconnectId(reconnectChatContext)) {
29
30
  var _props$reconnectChatP2, _props$reconnectChatP3;
30
31
  //if reconnect id is provided in props, don't show reconnect pane
31
32
  if ((_props$reconnectChatP2 = props.reconnectChatPaneProps) !== null && _props$reconnectChatP2 !== void 0 && _props$reconnectChatP2.reconnectId && !isNullOrEmptyString((_props$reconnectChatP3 = props.reconnectChatPaneProps) === null || _props$reconnectChatP3 === void 0 ? void 0 : _props$reconnectChatP3.reconnectId)) {
32
- await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
33
- return;
33
+ await setReconnectIdAndStartChat(isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectChatContext.reconnectId ?? "", initStartChat);
34
+ return false;
34
35
  }
35
36
 
36
37
  //show reconnect pane
@@ -43,8 +44,12 @@ const handleChatReconnect = async (chatSDK, props, dispatch, setAdapter, initSta
43
44
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
44
45
  payload: ConversationState.ReconnectChat
45
46
  });
46
- return;
47
+ return false;
47
48
  }
49
+
50
+ // If we have reached this point, it means there is no valid reconnect id or redirectUrl
51
+ // This is a unauth reconnect refresh scenario - returns true so that we can start normal hydration process
52
+ return true;
48
53
  };
49
54
 
50
55
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -81,7 +86,7 @@ const getChatReconnectContext = async (chatSDK, chatConfig, props, isAuthenticat
81
86
  };
82
87
 
83
88
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, dispatch, setAdapter, reconnectId, initStartChat) => {
89
+ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, state, props, dispatch, setAdapter, reconnectId, initStartChat) => {
85
90
  if (!isAuthenticatedChat) {
86
91
  const startUnauthenticatedReconnectChat = {
87
92
  eventName: BroadcastEvent.StartUnauthenticatedReconnectChat
@@ -99,7 +104,7 @@ const setReconnectIdAndStartChat = async (isAuthenticatedChat, chatSDK, props, d
99
104
  type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
100
105
  payload: ConversationState.Loading
101
106
  });
102
- await initStartChat(chatSDK, dispatch, setAdapter, props, optionalParams);
107
+ await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
103
108
  };
104
109
  const redirectPage = (redirectURL, redirectInSameWindow) => {
105
110
  const redirectPageRequest = {
@@ -295,16 +295,17 @@ const canConnectToExistingChat = async (props, chatSDK, state, dispatch, setAdap
295
295
 
296
296
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
297
297
  const setCustomContextParams = async (state, props) => {
298
- var _props$chatConfig, _props$chatConfig$Liv, _persistedState$domai8;
298
+ var _props$chatConfig, _props$chatConfig$Liv, _state$domainStates, _persistedState$domai8;
299
299
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
300
300
  const isAuthenticatedChat = props !== null && props !== void 0 && (_props$chatConfig = props.chatConfig) !== null && _props$chatConfig !== void 0 && (_props$chatConfig$Liv = _props$chatConfig.LiveChatConfigAuthSettings) !== null && _props$chatConfig$Liv !== void 0 && _props$chatConfig$Liv.msdyn_javascriptclientfunction ? true : false;
301
301
  //Should not set custom context for auth chat
302
302
  if (isAuthenticatedChat) {
303
303
  return;
304
304
  }
305
- if (state !== null && state !== void 0 && state.domainStates.customContext) {
305
+ if (state !== null && state !== void 0 && (_state$domainStates = state.domainStates) !== null && _state$domainStates !== void 0 && _state$domainStates.customContext) {
306
+ var _state$domainStates2;
306
307
  optionalParams = Object.assign({}, optionalParams, {
307
- customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : state.domainStates.customContext))
308
+ customContext: JSON.parse(JSON.stringify(state === null || state === void 0 ? void 0 : (_state$domainStates2 = state.domainStates) === null || _state$domainStates2 === void 0 ? void 0 : _state$domainStates2.customContext))
308
309
  });
309
310
  return;
310
311
  }
@@ -352,8 +353,8 @@ const canStartPopoutChat = async props => {
352
353
 
353
354
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
354
355
  const checkIfConversationStillValid = async (chatSDK, dispatch, state) => {
355
- var _state$domainStates, _state$domainStates$l;
356
- const requestIdFromCache = (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$l = _state$domainStates.liveChatContext) === null || _state$domainStates$l === void 0 ? void 0 : _state$domainStates$l.requestId;
356
+ var _state$domainStates3, _state$domainStates3$;
357
+ const requestIdFromCache = (_state$domainStates3 = state.domainStates) === null || _state$domainStates3 === void 0 ? void 0 : (_state$domainStates3$ = _state$domainStates3.liveChatContext) === null || _state$domainStates3$ === void 0 ? void 0 : _state$domainStates3$.requestId;
357
358
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
358
359
  let conversationDetails = undefined;
359
360
 
@@ -108,6 +108,16 @@ export const LiveChatWidgetStateful = props => {
108
108
 
109
109
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
110
  const startChat = async (props, localState) => {
111
+ const isReconnectTriggered = async () => {
112
+ if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
113
+ const noValidReconnectId = await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
114
+ // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
115
+ if (!noValidReconnectId && (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat)) {
116
+ return true;
117
+ }
118
+ }
119
+ return false;
120
+ };
111
121
  let isChatValid = false;
112
122
  //Start a chat from cache/reconnectid
113
123
  if (activeCachedChatExist === true) {
@@ -122,29 +132,20 @@ export const LiveChatWidgetStateful = props => {
122
132
  //Check if conversation state is not in wrapup or closed state
123
133
  isChatValid = await checkIfConversationStillValid(chatSDK, dispatch, state);
124
134
  if (isChatValid === true) {
125
- //Check if reconnect enabled
126
- if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
127
- await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
128
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
129
- if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
130
- return;
131
- }
135
+ const reconnectTriggered = await isReconnectTriggered();
136
+ if (!reconnectTriggered) {
137
+ await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
132
138
  }
133
- await initStartChat(chatSDK, dispatch, setAdapter, state, props, optionalParams);
134
139
  return;
135
140
  }
136
141
  }
137
142
  if (isChatValid === false) {
138
143
  if (localState) {
139
144
  // adding the reconnect logic for the case when customer tries to reconnect from a new browser or InPrivate browser
140
- if (isReconnectEnabled(props.chatConfig) === true && !isPersistentEnabled(props.chatConfig)) {
141
- await handleChatReconnect(chatSDK, props, dispatch, setAdapter, initStartChat, state);
142
- // If chat reconnect has kicked in chat state will become Active or Reconnect. So just exit, else go next
143
- if (state.appStates.conversationState === ConversationState.Active || state.appStates.conversationState === ConversationState.ReconnectChat) {
144
- return;
145
- }
145
+ const reconnectTriggered = await isReconnectTriggered();
146
+ if (!reconnectTriggered) {
147
+ await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
146
148
  }
147
- await setPreChatAndInitiateChat(chatSDK, dispatch, setAdapter, undefined, undefined, localState, props);
148
149
  return;
149
150
  } else {
150
151
  var _state$appStates4;
@@ -202,12 +202,17 @@ const createAttachmentMiddleware = enableInlinePlaying => {
202
202
  id: attachmentId,
203
203
  style: atttachmentAdaptiveCardStyles
204
204
  }, next(...args));
205
+ } else if (contentType.startsWith(Constants.adaptiveCardContentTypePrefix)) {
206
+ console.warn(`${contentType} adaptive card type is currently not supported.`);
205
207
  }
206
208
  if ((_card$activity$channe = card.activity.channelData) !== null && _card$activity$channe !== void 0 && _card$activity$channe.middlewareData) {
207
209
  attachment.contentUrl = card.activity.channelData.middlewareData[attachment.name];
208
210
  } else if (attachment !== null && attachment !== void 0 && attachment.tempContentUrl) {
209
211
  attachment.contentUrl = attachment.tempContentUrl;
210
212
  }
213
+ if (!attachment.name) {
214
+ return next(...args);
215
+ }
211
216
  const fileExtension = attachment.name.substring(attachment.name.lastIndexOf(".") + 1, attachment.name.length) || attachment.name;
212
217
  const imageExtension = Constants.imageRegex.test(attachment.name);
213
218
  const audioExtension = Constants.audioMediaRegex.test(attachment.name);
@@ -0,0 +1,58 @@
1
+ import { WebChatActionType } from "../../enums/WebChatActionType";
2
+ import { Constants } from "../../../../../common/Constants";
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
4
+ const createMessageSequenceIdOverrideMiddleware = _ref => {
5
+ let {
6
+ dispatch
7
+ } = _ref;
8
+ return next => action => {
9
+ if (isApplicable(action)) {
10
+ return next(overrideSequenceIdWithOriginalMessageId(action));
11
+ }
12
+ return next(action);
13
+ };
14
+ };
15
+ const isApplicable = action => {
16
+ return action.type === WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && isValidChannel(action) && isWebSequenceIdPresent(action) && lookupOriginalMessageId(action) !== undefined;
17
+ };
18
+ const isValidChannel = action => {
19
+ var _action$payload, _action$payload$activ;
20
+ return (action === null || action === void 0 ? void 0 : (_action$payload = action.payload) === null || _action$payload === void 0 ? void 0 : (_action$payload$activ = _action$payload.activity) === null || _action$payload$activ === void 0 ? void 0 : _action$payload$activ.channelId) === Constants.acsChannel;
21
+ };
22
+ const isChannelDataPresent = action => {
23
+ var _action$payload2, _action$payload2$acti, _action$payload3, _action$payload3$acti;
24
+ return (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.channelData) !== undefined && (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.channelData) !== null;
25
+ };
26
+ const isWebSequenceIdPresent = action => {
27
+ if (!isChannelDataPresent(action)) return false;
28
+ const channelData = action.payload.activity.channelData;
29
+ return Object.keys(channelData).some(key => {
30
+ return key === Constants.WebchatSequenceIdAttribute;
31
+ });
32
+ };
33
+ const overrideSequenceIdWithOriginalMessageId = action => {
34
+ const originalMessageId = extractOriginalMessageId(action);
35
+ const channelData = action.payload.activity.channelData;
36
+ if (originalMessageId === undefined) return action;
37
+ Object.keys(channelData).forEach(function (key) {
38
+ if (key === Constants.WebchatSequenceIdAttribute && action.payload.activity.channelData[key] !== originalMessageId) {
39
+ action.payload.activity.channelData[key] = originalMessageId;
40
+ }
41
+ });
42
+ return action;
43
+ };
44
+
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
46
+ const extractOriginalMessageId = action => {
47
+ const originalMessageId = lookupOriginalMessageId(action);
48
+ if (typeof originalMessageId !== "string" || originalMessageId === "") {
49
+ return undefined;
50
+ }
51
+ const originalMessageIdResult = parseInt(originalMessageId);
52
+ return isNaN(originalMessageIdResult) ? undefined : originalMessageIdResult;
53
+ };
54
+ const lookupOriginalMessageId = action => {
55
+ var _action$payload4, _action$payload4$acti, _action$payload4$acti2, _action$payload4$acti3;
56
+ return action === null || action === void 0 ? void 0 : (_action$payload4 = action.payload) === null || _action$payload4 === void 0 ? void 0 : (_action$payload4$acti = _action$payload4.activity) === null || _action$payload4$acti === void 0 ? void 0 : (_action$payload4$acti2 = _action$payload4$acti.channelData) === null || _action$payload4$acti2 === void 0 ? void 0 : (_action$payload4$acti3 = _action$payload4$acti2.metadata) === null || _action$payload4$acti3 === void 0 ? void 0 : _action$payload4$acti3.OriginalMessageId;
57
+ };
58
+ export default createMessageSequenceIdOverrideMiddleware;