@microsoft/omnichannel-chat-widget 1.7.3-main.c5e352d → 1.7.3-main.e452e73
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.
- package/lib/cjs/common/Constants.js +1 -0
- package/lib/cjs/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/cjs/components/livechatwidget/common/chatDisconnectHelper.js +2 -2
- package/lib/cjs/components/livechatwidget/common/createInternetConnectionChangeHandler.js +6 -2
- package/lib/cjs/components/livechatwidget/common/createMarkdown.js +2 -2
- package/lib/cjs/components/livechatwidget/common/helpers/markdownHelper.js +23 -0
- package/lib/cjs/components/livechatwidget/common/persistentChatHelper.js +2 -1
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +30 -0
- package/lib/cjs/plugins/createChatTranscript.js +84 -0
- package/lib/esm/common/Constants.js +1 -0
- package/lib/esm/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/esm/components/livechatwidget/common/chatDisconnectHelper.js +3 -2
- package/lib/esm/components/livechatwidget/common/createInternetConnectionChangeHandler.js +6 -2
- package/lib/esm/components/livechatwidget/common/createMarkdown.js +2 -2
- package/lib/esm/components/livechatwidget/common/helpers/markdownHelper.js +15 -0
- package/lib/esm/components/livechatwidget/common/persistentChatHelper.js +2 -1
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +31 -1
- package/lib/esm/plugins/createChatTranscript.js +84 -0
- package/lib/types/common/Constants.d.ts +1 -0
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +2 -1
- package/lib/types/components/livechatwidget/common/helpers/markdownHelper.d.ts +2 -0
- package/package.json +2 -2
|
@@ -307,6 +307,7 @@ class WidgetLoadCustomErrorString {}
|
|
|
307
307
|
exports.WidgetLoadCustomErrorString = WidgetLoadCustomErrorString;
|
|
308
308
|
_defineProperty(WidgetLoadCustomErrorString, "AuthenticationFailedErrorString", "Authentication was not successful");
|
|
309
309
|
_defineProperty(WidgetLoadCustomErrorString, "NetworkErrorString", "Network Error");
|
|
310
|
+
_defineProperty(WidgetLoadCustomErrorString, "CloseAdapterAfterDisconnectionErrorString", "Error trying to end/close chat adapter after the widget is back on-line, for an already disconnected session");
|
|
310
311
|
class PrepareEndChatDescriptionConstants {}
|
|
311
312
|
exports.PrepareEndChatDescriptionConstants = PrepareEndChatDescriptionConstants;
|
|
312
313
|
_defineProperty(PrepareEndChatDescriptionConstants, "ConversationEndedByCustomerWithoutPostChat", "Conversation ended by customer. Post chat not configured or should not show.");
|
|
@@ -216,6 +216,7 @@ exports.TelemetryEvent = TelemetryEvent;
|
|
|
216
216
|
TelemetryEvent["PostChatSurveyLoaded"] = "PostChatSurveyLoaded";
|
|
217
217
|
TelemetryEvent["ChatDisconnectThreadEventReceived"] = "ChatDisconnectThreadEventReceived";
|
|
218
218
|
TelemetryEvent["HiddenAdaptiveCardMessageReceived"] = "HiddenAdaptiveCardMessageReceived";
|
|
219
|
+
TelemetryEvent["EndingAdapterAfterDisconnectionError"] = "EndingAdapterAfterDisconnectionError";
|
|
219
220
|
})(TelemetryEvent || (exports.TelemetryEvent = TelemetryEvent = {}));
|
|
220
221
|
class TelemetryConstants {
|
|
221
222
|
static map(eventTypeOrScenarioType) {
|
|
@@ -4,11 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.handleChatDisconnect = void 0;
|
|
7
|
+
var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
|
|
7
8
|
var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler");
|
|
8
9
|
var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
|
|
9
|
-
var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
|
|
10
|
-
var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
|
|
11
10
|
var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
|
|
11
|
+
var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
|
|
12
12
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
13
|
const handleChatDisconnect = (props, state, setWebChatStyles) => {
|
|
14
14
|
var _state$appStates, _state$domainStates, _state$domainStates$m, _props$webChatContain, _props$webChatContain2;
|
|
@@ -4,12 +4,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createInternetConnectionChangeHandler = void 0;
|
|
7
|
+
var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
|
|
8
|
+
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
7
9
|
var _Constants = require("../../../common/Constants");
|
|
8
10
|
var _NotificationHandler = require("../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler");
|
|
9
11
|
var _NotificationScenarios = require("../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios");
|
|
10
|
-
var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
|
|
11
12
|
var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
|
|
12
|
-
var
|
|
13
|
+
var _defaultMiddlewareLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts");
|
|
13
14
|
const isInternetConnected = async () => {
|
|
14
15
|
try {
|
|
15
16
|
const response = await fetch(_Constants.Constants.internetConnectionTestUrl);
|
|
@@ -32,6 +33,9 @@ const createInternetConnectionChangeHandler = async () => {
|
|
|
32
33
|
Event: _TelemetryConstants.TelemetryEvent.NetworkReconnected
|
|
33
34
|
});
|
|
34
35
|
_NotificationHandler.NotificationHandler.notifySuccess(_NotificationScenarios.NotificationScenarios.InternetConnection, _defaultMiddlewareLocalizedTexts.defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
36
|
+
_omnichannelChatComponents.BroadcastService.postMessage({
|
|
37
|
+
eventName: _TelemetryConstants.BroadcastEvent.NetworkReconnected
|
|
38
|
+
});
|
|
35
39
|
}
|
|
36
40
|
};
|
|
37
41
|
|
|
@@ -7,8 +7,8 @@ exports.createMarkdown = void 0;
|
|
|
7
7
|
var _Constants = require("../../../common/Constants");
|
|
8
8
|
var _markdownIt = _interopRequireDefault(require("markdown-it"));
|
|
9
9
|
var _markdownItForInline = _interopRequireDefault(require("markdown-it-for-inline"));
|
|
10
|
-
var _slackMarkdownIt = _interopRequireDefault(require("slack-markdown-it"));
|
|
11
10
|
var _defaultMarkdownLocalizedTexts = require("../../webchatcontainerstateful/common/defaultProps/defaultMarkdownLocalizedTexts");
|
|
11
|
+
var _markdownHelper = require("./helpers/markdownHelper");
|
|
12
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
13
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
14
|
const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport) => {
|
|
@@ -19,7 +19,7 @@ const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdown
|
|
|
19
19
|
linkify: true,
|
|
20
20
|
breaks: !disableNewLineMarkdownSupport
|
|
21
21
|
});
|
|
22
|
-
markdown
|
|
22
|
+
markdown = (0, _markdownHelper.addSlackMarkdownIt)(markdown);
|
|
23
23
|
} else {
|
|
24
24
|
markdown = new _markdownIt.default(_Constants.Constants.Zero, {
|
|
25
25
|
html: true,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addSlackMarkdownIt = void 0;
|
|
7
|
+
var _slackMarkdownIt = _interopRequireDefault(require("slack-markdown-it"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
const addSlackMarkdownIt = markdown => {
|
|
10
|
+
try {
|
|
11
|
+
markdown.use(_slackMarkdownIt.default);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
// this is to support the case when slack-markdown-it
|
|
14
|
+
// transpiled code doesn't export default (webpack5)
|
|
15
|
+
if (_slackMarkdownIt.default.default.apply) {
|
|
16
|
+
markdown.use(_slackMarkdownIt.default.default);
|
|
17
|
+
} else {
|
|
18
|
+
console.error("Error while adding slackMarkdown plugin", e);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return markdown;
|
|
22
|
+
};
|
|
23
|
+
exports.addSlackMarkdownIt = addSlackMarkdownIt;
|
|
@@ -11,7 +11,8 @@ const shouldSetPreChatIfPersistentChat = async (chatSDK, conversationMode, showP
|
|
|
11
11
|
let skipPreChat = false;
|
|
12
12
|
if (persistentEnabled) {
|
|
13
13
|
const reconnectableChatsParams = {
|
|
14
|
-
authenticatedUserToken: chatSDK.authenticatedUserToken
|
|
14
|
+
authenticatedUserToken: chatSDK.authenticatedUserToken,
|
|
15
|
+
requestId: chatSDK.requestId
|
|
15
16
|
};
|
|
16
17
|
try {
|
|
17
18
|
const reconnectableChatsResponse = await chatSDK.OCClient.getReconnectableChats(reconnectableChatsParams);
|
|
@@ -354,6 +354,23 @@ const LiveChatWidgetStateful = props => {
|
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
356
|
});
|
|
357
|
+
_omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.NetworkReconnected).subscribe(async () => {
|
|
358
|
+
var _window2, _window2$location;
|
|
359
|
+
if ((0, _utils.isThisSessionPopout)((_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$location = _window2.location) === null || _window2$location === void 0 ? void 0 : _window2$location.href)) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
const conversationDetails = await (0, _utils.getConversationDetailsCall)(chatSDK);
|
|
363
|
+
if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === _Constants.LiveWorkItemState.WrapUp || (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === _Constants.LiveWorkItemState.Closed) {
|
|
364
|
+
dispatch({
|
|
365
|
+
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
|
|
366
|
+
payload: true
|
|
367
|
+
});
|
|
368
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
369
|
+
Event: _TelemetryConstants.TelemetryEvent.ChatDisconnectThreadEventReceived,
|
|
370
|
+
Description: "Chat disconnected due to timeout, user went offline or blocked the device (including closing laptop)"
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
});
|
|
357
374
|
|
|
358
375
|
/**
|
|
359
376
|
* This will allow to sync multiple tabs to handle minimize and maximize state,
|
|
@@ -671,11 +688,24 @@ const LiveChatWidgetStateful = props => {
|
|
|
671
688
|
|
|
672
689
|
// Handle Chat disconnect cases
|
|
673
690
|
(0, _react2.useEffect)(() => {
|
|
691
|
+
var _inMemoryState$appSta5;
|
|
674
692
|
const inMemoryState = (0, _createReducer.executeReducer)(state, {
|
|
675
693
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
676
694
|
payload: null
|
|
677
695
|
});
|
|
678
696
|
(0, _chatDisconnectHelper.handleChatDisconnect)(props, inMemoryState, setWebChatStyles);
|
|
697
|
+
const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta5 = inMemoryState.appStates) === null || _inMemoryState$appSta5 === void 0 ? void 0 : _inMemoryState$appSta5.chatDisconnectEventReceived;
|
|
698
|
+
if (chatDisconnectState && adapter) {
|
|
699
|
+
try {
|
|
700
|
+
adapter.end();
|
|
701
|
+
adapter.close();
|
|
702
|
+
} catch (e) {
|
|
703
|
+
_TelemetryHelper.TelemetryHelper.logWebChatEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
704
|
+
Event: _TelemetryConstants.TelemetryEvent.EndingAdapterAfterDisconnectionError,
|
|
705
|
+
Description: _Constants.WidgetLoadCustomErrorString.CloseAdapterAfterDisconnectionErrorString
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
}
|
|
679
709
|
}, [state.appStates.chatDisconnectEventReceived]);
|
|
680
710
|
|
|
681
711
|
// if props state gets updates we need to update the renderingMiddlewareProps in the state
|
|
@@ -376,6 +376,90 @@ class TranscriptHTMLBuilder {
|
|
|
376
376
|
window.addEventListener("online", () => {
|
|
377
377
|
document.body.innerHTML = \`${this.networkOnlineMessage} <button onclick="window.location.reload()"> Refresh </button>\`;
|
|
378
378
|
});
|
|
379
|
+
|
|
380
|
+
document.addEventListener("copy", (event) => {
|
|
381
|
+
const clonedSelectedContent = window.getSelection().getRangeAt(0).cloneContents();
|
|
382
|
+
const copiedContent = document.createElement("div");
|
|
383
|
+
copiedContent.appendChild(clonedSelectedContent);
|
|
384
|
+
|
|
385
|
+
event.clipboardData.setData("text/plain", getAllText(copiedContent));
|
|
386
|
+
event.preventDefault();
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
getAllText = (element) => {
|
|
391
|
+
let plainText = "";
|
|
392
|
+
Array.from(element.childNodes).forEach((node) => {
|
|
393
|
+
// ignore aria-hidden elements and keyboard help text
|
|
394
|
+
const ariaHiddenAttr = node.attributes ? node.attributes.getNamedItem("aria-hidden") : null;
|
|
395
|
+
if ((ariaHiddenAttr && ariaHiddenAttr.value === "true") || node.classList && node.classList.contains("webchat__keyboard-help")) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// get all texts inside activity body, including message, translated message, attachment name, adaptive card content, status footer, etc.
|
|
400
|
+
if (node.classList && node.classList.contains("webchat__basic-transcript__activity-body")) {
|
|
401
|
+
plainText += this.processTranscriptActivityNode(node);
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
405
|
+
plainText += node.textContent + '\\n';
|
|
406
|
+
} else {
|
|
407
|
+
plainText += this.getAllText(node);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
return plainText;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
processTranscriptActivityNode = (node) => {
|
|
414
|
+
const divs = node.getElementsByTagName("div");
|
|
415
|
+
let plainText = "";
|
|
416
|
+
|
|
417
|
+
if (divs && divs.length > 1 && divs[1]) {
|
|
418
|
+
const messageRow = node.querySelector(".webchat__stacked-layout__message-row[aria-roledescription='message']");
|
|
419
|
+
const author = node.querySelector(".message-name");
|
|
420
|
+
const attachmentRow = node.querySelector(".webchat__stacked-layout__attachment-row[aria-roledescription='attachment']");
|
|
421
|
+
|
|
422
|
+
if (messageRow) {
|
|
423
|
+
let message = messageRow.getElementsByClassName("webchat__text-content__markdown");
|
|
424
|
+
|
|
425
|
+
if (message.length === 0) {
|
|
426
|
+
message = messageRow.getElementsByClassName("markdown");
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (message.length > 0) {
|
|
430
|
+
plainText += author.textContent + '\\n' + message[0].textContent + '\\n';
|
|
431
|
+
}
|
|
432
|
+
} else if (attachmentRow) {
|
|
433
|
+
const attachment = attachmentRow.getElementsByClassName("webchat__fileContent__fileName");
|
|
434
|
+
const adaptiveCard = this.getAdaptiveCardContent(attachmentRow.querySelector(".ac-container.ac-adaptiveCard"));
|
|
435
|
+
|
|
436
|
+
plainText += attachment && attachment.length > 0 ? author.textContent +'\\n' + attachment[0].textContent +'\\n': author.textContent +'\\n' + adaptiveCard +'\\n';
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const statusElements = node.getElementsByClassName("webchat__stacked-layout__status");
|
|
440
|
+
if (statusElements.length > 0) {
|
|
441
|
+
const timestampelement = statusElements[0].querySelector(".message-timestamp");
|
|
442
|
+
plainText += timestampelement ? timestampelement.textContent+'\\n\\n' : '\\n';
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return plainText;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
getAdaptiveCardContent = (node) => {
|
|
450
|
+
if (!node) {
|
|
451
|
+
return undefined;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
let plainText = "";
|
|
455
|
+
const rows = node.querySelectorAll(".ac-textBlock p");
|
|
456
|
+
rows.forEach((row) => {
|
|
457
|
+
plainText += row.textContent+ '\\n';
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
return plainText;
|
|
461
|
+
}
|
|
462
|
+
|
|
379
463
|
<\/script>
|
|
380
464
|
<div id="transcript"></div>
|
|
381
465
|
<script>
|
|
@@ -276,6 +276,7 @@ _defineProperty(WidgetLoadTelemetryMessage, "PersistedStateRetrievedMessage", "P
|
|
|
276
276
|
export class WidgetLoadCustomErrorString {}
|
|
277
277
|
_defineProperty(WidgetLoadCustomErrorString, "AuthenticationFailedErrorString", "Authentication was not successful");
|
|
278
278
|
_defineProperty(WidgetLoadCustomErrorString, "NetworkErrorString", "Network Error");
|
|
279
|
+
_defineProperty(WidgetLoadCustomErrorString, "CloseAdapterAfterDisconnectionErrorString", "Error trying to end/close chat adapter after the widget is back on-line, for an already disconnected session");
|
|
279
280
|
export class PrepareEndChatDescriptionConstants {}
|
|
280
281
|
_defineProperty(PrepareEndChatDescriptionConstants, "ConversationEndedByCustomerWithoutPostChat", "Conversation ended by customer. Post chat not configured or should not show.");
|
|
281
282
|
_defineProperty(PrepareEndChatDescriptionConstants, "ConversationEndedByCustomerWithInvalidPostChat", "Conversation ended by customer. Post chat context is invalid.");
|
|
@@ -210,6 +210,7 @@ export let TelemetryEvent;
|
|
|
210
210
|
TelemetryEvent["PostChatSurveyLoaded"] = "PostChatSurveyLoaded";
|
|
211
211
|
TelemetryEvent["ChatDisconnectThreadEventReceived"] = "ChatDisconnectThreadEventReceived";
|
|
212
212
|
TelemetryEvent["HiddenAdaptiveCardMessageReceived"] = "HiddenAdaptiveCardMessageReceived";
|
|
213
|
+
TelemetryEvent["EndingAdapterAfterDisconnectionError"] = "EndingAdapterAfterDisconnectionError";
|
|
213
214
|
})(TelemetryEvent || (TelemetryEvent = {}));
|
|
214
215
|
export class TelemetryConstants {
|
|
215
216
|
static map(eventTypeOrScenarioType) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
1
2
|
import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
|
|
2
3
|
import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
|
|
3
|
-
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
4
|
-
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
5
4
|
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
5
|
+
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
6
|
+
|
|
6
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7
8
|
const handleChatDisconnect = (props, state, setWebChatStyles) => {
|
|
8
9
|
var _state$appStates, _state$domainStates, _state$domainStates$m, _props$webChatContain, _props$webChatContain2;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
2
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
1
3
|
import { Constants } from "../../../common/Constants";
|
|
2
4
|
import { NotificationHandler } from "../../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler";
|
|
3
5
|
import { NotificationScenarios } from "../../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios";
|
|
4
|
-
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
5
6
|
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
6
|
-
import {
|
|
7
|
+
import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts";
|
|
7
8
|
const isInternetConnected = async () => {
|
|
8
9
|
try {
|
|
9
10
|
const response = await fetch(Constants.internetConnectionTestUrl);
|
|
@@ -26,6 +27,9 @@ export const createInternetConnectionChangeHandler = async () => {
|
|
|
26
27
|
Event: TelemetryEvent.NetworkReconnected
|
|
27
28
|
});
|
|
28
29
|
NotificationHandler.notifySuccess(NotificationScenarios.InternetConnection, defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_INTERNET_BACK_ONLINE);
|
|
30
|
+
BroadcastService.postMessage({
|
|
31
|
+
eventName: BroadcastEvent.NetworkReconnected
|
|
32
|
+
});
|
|
29
33
|
}
|
|
30
34
|
};
|
|
31
35
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Constants } from "../../../common/Constants";
|
|
2
2
|
import MarkdownIt from "markdown-it";
|
|
3
3
|
import MarkdownItForInline from "markdown-it-for-inline";
|
|
4
|
-
import MarkdownSlack from "slack-markdown-it";
|
|
5
4
|
import { defaultMarkdownLocalizedTexts } from "../../webchatcontainerstateful/common/defaultProps/defaultMarkdownLocalizedTexts";
|
|
5
|
+
import { addSlackMarkdownIt } from "./helpers/markdownHelper";
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
8
|
export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineMarkdownSupport) => {
|
|
@@ -13,7 +13,7 @@ export const createMarkdown = (disableMarkdownMessageFormatting, disableNewLineM
|
|
|
13
13
|
linkify: true,
|
|
14
14
|
breaks: !disableNewLineMarkdownSupport
|
|
15
15
|
});
|
|
16
|
-
markdown
|
|
16
|
+
markdown = addSlackMarkdownIt(markdown);
|
|
17
17
|
} else {
|
|
18
18
|
markdown = new MarkdownIt(Constants.Zero, {
|
|
19
19
|
html: true,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import SlackMarkdown from "slack-markdown-it";
|
|
2
|
+
export const addSlackMarkdownIt = markdown => {
|
|
3
|
+
try {
|
|
4
|
+
markdown.use(SlackMarkdown);
|
|
5
|
+
} catch (e) {
|
|
6
|
+
// this is to support the case when slack-markdown-it
|
|
7
|
+
// transpiled code doesn't export default (webpack5)
|
|
8
|
+
if (SlackMarkdown.default.apply) {
|
|
9
|
+
markdown.use(SlackMarkdown.default);
|
|
10
|
+
} else {
|
|
11
|
+
console.error("Error while adding slackMarkdown plugin", e);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return markdown;
|
|
15
|
+
};
|
|
@@ -6,7 +6,8 @@ export const shouldSetPreChatIfPersistentChat = async (chatSDK, conversationMode
|
|
|
6
6
|
let skipPreChat = false;
|
|
7
7
|
if (persistentEnabled) {
|
|
8
8
|
const reconnectableChatsParams = {
|
|
9
|
-
authenticatedUserToken: chatSDK.authenticatedUserToken
|
|
9
|
+
authenticatedUserToken: chatSDK.authenticatedUserToken,
|
|
10
|
+
requestId: chatSDK.requestId
|
|
10
11
|
};
|
|
11
12
|
try {
|
|
12
13
|
const reconnectableChatsResponse = await chatSDK.OCClient.getReconnectableChats(reconnectableChatsParams);
|
|
@@ -2,7 +2,7 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
|
|
|
2
2
|
import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
3
3
|
import { BroadcastService, BroadcastServiceInitialize, decodeComponentString } from "@microsoft/omnichannel-chat-components";
|
|
4
4
|
import { Components } from "botframework-webchat";
|
|
5
|
-
import { ConfirmationState, Constants, ConversationEndEntity, E2VVOptions, LiveWorkItemState, PrepareEndChatDescriptionConstants, StorageType } from "../../../common/Constants";
|
|
5
|
+
import { ConfirmationState, Constants, ConversationEndEntity, E2VVOptions, LiveWorkItemState, PrepareEndChatDescriptionConstants, StorageType, WidgetLoadCustomErrorString } from "../../../common/Constants";
|
|
6
6
|
import { Stack } from "@fluentui/react";
|
|
7
7
|
import React, { useEffect, useRef, useState } from "react";
|
|
8
8
|
import { TelemetryManager, TelemetryTimers } from "../../../common/telemetry/TelemetryManager";
|
|
@@ -346,6 +346,23 @@ export const LiveChatWidgetStateful = props => {
|
|
|
346
346
|
}
|
|
347
347
|
}
|
|
348
348
|
});
|
|
349
|
+
BroadcastService.getMessageByEventName(BroadcastEvent.NetworkReconnected).subscribe(async () => {
|
|
350
|
+
var _window2, _window2$location;
|
|
351
|
+
if (isThisSessionPopout((_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$location = _window2.location) === null || _window2$location === void 0 ? void 0 : _window2$location.href)) {
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const conversationDetails = await getConversationDetailsCall(chatSDK);
|
|
355
|
+
if ((conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === LiveWorkItemState.WrapUp || (conversationDetails === null || conversationDetails === void 0 ? void 0 : conversationDetails.state) === LiveWorkItemState.Closed) {
|
|
356
|
+
dispatch({
|
|
357
|
+
type: LiveChatWidgetActionType.SET_CHAT_DISCONNECT_EVENT_RECEIVED,
|
|
358
|
+
payload: true
|
|
359
|
+
});
|
|
360
|
+
TelemetryHelper.logActionEvent(LogLevel.INFO, {
|
|
361
|
+
Event: TelemetryEvent.ChatDisconnectThreadEventReceived,
|
|
362
|
+
Description: "Chat disconnected due to timeout, user went offline or blocked the device (including closing laptop)"
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
});
|
|
349
366
|
|
|
350
367
|
/**
|
|
351
368
|
* This will allow to sync multiple tabs to handle minimize and maximize state,
|
|
@@ -663,11 +680,24 @@ export const LiveChatWidgetStateful = props => {
|
|
|
663
680
|
|
|
664
681
|
// Handle Chat disconnect cases
|
|
665
682
|
useEffect(() => {
|
|
683
|
+
var _inMemoryState$appSta5;
|
|
666
684
|
const inMemoryState = executeReducer(state, {
|
|
667
685
|
type: LiveChatWidgetActionType.GET_IN_MEMORY_STATE,
|
|
668
686
|
payload: null
|
|
669
687
|
});
|
|
670
688
|
handleChatDisconnect(props, inMemoryState, setWebChatStyles);
|
|
689
|
+
const chatDisconnectState = inMemoryState === null || inMemoryState === void 0 ? void 0 : (_inMemoryState$appSta5 = inMemoryState.appStates) === null || _inMemoryState$appSta5 === void 0 ? void 0 : _inMemoryState$appSta5.chatDisconnectEventReceived;
|
|
690
|
+
if (chatDisconnectState && adapter) {
|
|
691
|
+
try {
|
|
692
|
+
adapter.end();
|
|
693
|
+
adapter.close();
|
|
694
|
+
} catch (e) {
|
|
695
|
+
TelemetryHelper.logWebChatEvent(LogLevel.ERROR, {
|
|
696
|
+
Event: TelemetryEvent.EndingAdapterAfterDisconnectionError,
|
|
697
|
+
Description: WidgetLoadCustomErrorString.CloseAdapterAfterDisconnectionErrorString
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
}
|
|
671
701
|
}, [state.appStates.chatDisconnectEventReceived]);
|
|
672
702
|
|
|
673
703
|
// if props state gets updates we need to update the renderingMiddlewareProps in the state
|
|
@@ -371,6 +371,90 @@ class TranscriptHTMLBuilder {
|
|
|
371
371
|
window.addEventListener("online", () => {
|
|
372
372
|
document.body.innerHTML = \`${this.networkOnlineMessage} <button onclick="window.location.reload()"> Refresh </button>\`;
|
|
373
373
|
});
|
|
374
|
+
|
|
375
|
+
document.addEventListener("copy", (event) => {
|
|
376
|
+
const clonedSelectedContent = window.getSelection().getRangeAt(0).cloneContents();
|
|
377
|
+
const copiedContent = document.createElement("div");
|
|
378
|
+
copiedContent.appendChild(clonedSelectedContent);
|
|
379
|
+
|
|
380
|
+
event.clipboardData.setData("text/plain", getAllText(copiedContent));
|
|
381
|
+
event.preventDefault();
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
getAllText = (element) => {
|
|
386
|
+
let plainText = "";
|
|
387
|
+
Array.from(element.childNodes).forEach((node) => {
|
|
388
|
+
// ignore aria-hidden elements and keyboard help text
|
|
389
|
+
const ariaHiddenAttr = node.attributes ? node.attributes.getNamedItem("aria-hidden") : null;
|
|
390
|
+
if ((ariaHiddenAttr && ariaHiddenAttr.value === "true") || node.classList && node.classList.contains("webchat__keyboard-help")) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// get all texts inside activity body, including message, translated message, attachment name, adaptive card content, status footer, etc.
|
|
395
|
+
if (node.classList && node.classList.contains("webchat__basic-transcript__activity-body")) {
|
|
396
|
+
plainText += this.processTranscriptActivityNode(node);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
400
|
+
plainText += node.textContent + '\\n';
|
|
401
|
+
} else {
|
|
402
|
+
plainText += this.getAllText(node);
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
return plainText;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
processTranscriptActivityNode = (node) => {
|
|
409
|
+
const divs = node.getElementsByTagName("div");
|
|
410
|
+
let plainText = "";
|
|
411
|
+
|
|
412
|
+
if (divs && divs.length > 1 && divs[1]) {
|
|
413
|
+
const messageRow = node.querySelector(".webchat__stacked-layout__message-row[aria-roledescription='message']");
|
|
414
|
+
const author = node.querySelector(".message-name");
|
|
415
|
+
const attachmentRow = node.querySelector(".webchat__stacked-layout__attachment-row[aria-roledescription='attachment']");
|
|
416
|
+
|
|
417
|
+
if (messageRow) {
|
|
418
|
+
let message = messageRow.getElementsByClassName("webchat__text-content__markdown");
|
|
419
|
+
|
|
420
|
+
if (message.length === 0) {
|
|
421
|
+
message = messageRow.getElementsByClassName("markdown");
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (message.length > 0) {
|
|
425
|
+
plainText += author.textContent + '\\n' + message[0].textContent + '\\n';
|
|
426
|
+
}
|
|
427
|
+
} else if (attachmentRow) {
|
|
428
|
+
const attachment = attachmentRow.getElementsByClassName("webchat__fileContent__fileName");
|
|
429
|
+
const adaptiveCard = this.getAdaptiveCardContent(attachmentRow.querySelector(".ac-container.ac-adaptiveCard"));
|
|
430
|
+
|
|
431
|
+
plainText += attachment && attachment.length > 0 ? author.textContent +'\\n' + attachment[0].textContent +'\\n': author.textContent +'\\n' + adaptiveCard +'\\n';
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const statusElements = node.getElementsByClassName("webchat__stacked-layout__status");
|
|
435
|
+
if (statusElements.length > 0) {
|
|
436
|
+
const timestampelement = statusElements[0].querySelector(".message-timestamp");
|
|
437
|
+
plainText += timestampelement ? timestampelement.textContent+'\\n\\n' : '\\n';
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return plainText;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
getAdaptiveCardContent = (node) => {
|
|
445
|
+
if (!node) {
|
|
446
|
+
return undefined;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
let plainText = "";
|
|
450
|
+
const rows = node.querySelectorAll(".ac-textBlock p");
|
|
451
|
+
rows.forEach((row) => {
|
|
452
|
+
plainText += row.textContent+ '\\n';
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
return plainText;
|
|
456
|
+
}
|
|
457
|
+
|
|
374
458
|
<\/script>
|
|
375
459
|
<div id="transcript"></div>
|
|
376
460
|
<script>
|
|
@@ -254,6 +254,7 @@ export declare class WidgetLoadTelemetryMessage {
|
|
|
254
254
|
export declare class WidgetLoadCustomErrorString {
|
|
255
255
|
static readonly AuthenticationFailedErrorString = "Authentication was not successful";
|
|
256
256
|
static readonly NetworkErrorString = "Network Error";
|
|
257
|
+
static readonly CloseAdapterAfterDisconnectionErrorString = "Error trying to end/close chat adapter after the widget is back on-line, for an already disconnected session";
|
|
257
258
|
}
|
|
258
259
|
export declare class PrepareEndChatDescriptionConstants {
|
|
259
260
|
static readonly ConversationEndedByCustomerWithoutPostChat = "Conversation ended by customer. Post chat not configured or should not show.";
|
|
@@ -202,7 +202,8 @@ export declare enum TelemetryEvent {
|
|
|
202
202
|
PostChatSurveyLoadingPaneLoaded = "PostChatSurveyLoadingPaneLoaded",
|
|
203
203
|
PostChatSurveyLoaded = "PostChatSurveyLoaded",
|
|
204
204
|
ChatDisconnectThreadEventReceived = "ChatDisconnectThreadEventReceived",
|
|
205
|
-
HiddenAdaptiveCardMessageReceived = "HiddenAdaptiveCardMessageReceived"
|
|
205
|
+
HiddenAdaptiveCardMessageReceived = "HiddenAdaptiveCardMessageReceived",
|
|
206
|
+
EndingAdapterAfterDisconnectionError = "EndingAdapterAfterDisconnectionError"
|
|
206
207
|
}
|
|
207
208
|
export interface TelemetryInput {
|
|
208
209
|
scenarioType: ScenarioType;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/omnichannel-chat-widget",
|
|
3
|
-
"version": "1.7.3-main.
|
|
3
|
+
"version": "1.7.3-main.e452e73",
|
|
4
4
|
"description": "Microsoft Omnichannel Chat Widget",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"types": "lib/types/index.d.ts",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@microsoft/omnichannel-chat-components": "1.1.5",
|
|
78
|
-
"@microsoft/omnichannel-chat-sdk": "^1.
|
|
78
|
+
"@microsoft/omnichannel-chat-sdk": "^1.10.1",
|
|
79
79
|
"abort-controller-es5": "^2.0.1",
|
|
80
80
|
"dompurify": "^2.5.4",
|
|
81
81
|
"markdown-it": "^12.3.2",
|