@microsoft/omnichannel-chat-widget 1.7.8-main.9e74278 → 1.7.8-main.bd4de53
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/telemetry/TelemetryConstants.js +5 -0
- package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -5
- package/lib/cjs/components/headerstateful/HeaderStateful.js +3 -5
- package/lib/cjs/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -1
- package/lib/cjs/components/livechatwidget/common/chatDisconnectHelper.js +3 -1
- package/lib/cjs/components/livechatwidget/common/endChat.js +4 -18
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -11
- package/lib/cjs/components/ooohpanestateful/OOOHPaneStateful.js +9 -3
- package/lib/cjs/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +22 -6
- package/lib/cjs/components/postchatsurveypanestateful/common/isValidSurveyUrl.js +28 -0
- package/lib/cjs/components/webchatcontainerstateful/WebChatContainerStateful.js +4 -3
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +4 -0
- package/lib/cjs/contexts/common/LiveChatWidgetContextInitialState.js +18 -6
- package/lib/cjs/firstresponselatency/Constants.js +13 -0
- package/lib/cjs/firstresponselatency/FirstResponseLatencyTracker.js +152 -0
- package/lib/cjs/firstresponselatency/util.js +85 -0
- package/lib/cjs/plugins/createChatTranscript.js +4 -4
- package/lib/cjs/plugins/newMessageEventHandler.js +102 -88
- package/lib/esm/common/telemetry/TelemetryConstants.js +5 -0
- package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -5
- package/lib/esm/components/headerstateful/HeaderStateful.js +3 -5
- package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js +4 -1
- package/lib/esm/components/livechatwidget/common/chatDisconnectHelper.js +3 -1
- package/lib/esm/components/livechatwidget/common/endChat.js +4 -18
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +17 -11
- package/lib/esm/components/ooohpanestateful/OOOHPaneStateful.js +9 -3
- package/lib/esm/components/postchatsurveypanestateful/PostChatSurveyPaneStateful.js +22 -6
- package/lib/esm/components/postchatsurveypanestateful/common/isValidSurveyUrl.js +21 -0
- package/lib/esm/components/webchatcontainerstateful/WebChatContainerStateful.js +4 -3
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/renderingmiddlewares/timestamps/DeliveredTimestamp.js +4 -0
- package/lib/esm/contexts/common/LiveChatWidgetContextInitialState.js +18 -6
- package/lib/esm/firstresponselatency/Constants.js +6 -0
- package/lib/esm/firstresponselatency/FirstResponseLatencyTracker.js +145 -0
- package/lib/esm/firstresponselatency/util.js +75 -0
- package/lib/esm/plugins/createChatTranscript.js +4 -4
- package/lib/esm/plugins/newMessageEventHandler.js +100 -86
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +5 -0
- package/lib/types/components/postchatsurveypanestateful/common/isValidSurveyUrl.d.ts +2 -0
- package/lib/types/contexts/common/ILiveChatWidgetContext.d.ts +1 -1
- package/lib/types/firstresponselatency/Constants.d.ts +30 -0
- package/lib/types/firstresponselatency/FirstResponseLatencyTracker.d.ts +17 -0
- package/lib/types/firstresponselatency/util.d.ts +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.FirstResponseLatencyTracker = void 0;
|
|
7
|
+
var _TelemetryConstants = require("../common/telemetry/TelemetryConstants");
|
|
8
|
+
var _TelemetryHelper = require("../common/telemetry/TelemetryHelper");
|
|
9
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
10
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
11
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
12
|
+
class FirstResponseLatencyTracker {
|
|
13
|
+
constructor() {
|
|
14
|
+
_defineProperty(this, "isABotConversation", false);
|
|
15
|
+
_defineProperty(this, "isStarted", false);
|
|
16
|
+
_defineProperty(this, "isEnded", false);
|
|
17
|
+
_defineProperty(this, "startTrackingMessage", void 0);
|
|
18
|
+
_defineProperty(this, "stopTrackingMessage", void 0);
|
|
19
|
+
// this is a workaround to ensure in reload we track effectively the messages
|
|
20
|
+
// we do have a mechanism in place to prevent log agent messages.
|
|
21
|
+
this.isABotConversation = true;
|
|
22
|
+
}
|
|
23
|
+
createTrackingMessage(payload, type) {
|
|
24
|
+
return {
|
|
25
|
+
Id: payload.Id,
|
|
26
|
+
role: payload.role,
|
|
27
|
+
timestamp: payload === null || payload === void 0 ? void 0 : payload.timestamp,
|
|
28
|
+
tags: payload.tags,
|
|
29
|
+
messageType: payload.messageType,
|
|
30
|
+
text: payload.text,
|
|
31
|
+
type: type,
|
|
32
|
+
checkTime: new Date().getTime()
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Tracking Functions
|
|
37
|
+
startTracking(payload) {
|
|
38
|
+
// this prevents to initiate tracking for multiple incoming messages
|
|
39
|
+
if (this.isStarted) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// this is to ensure we track only messages where bot is engaged
|
|
43
|
+
if (!this.isABotConversation) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// control of states to prevent clashing of messages
|
|
48
|
+
this.isStarted = true;
|
|
49
|
+
this.isEnded = false;
|
|
50
|
+
|
|
51
|
+
// The idea of using types is to enrich telemetry data
|
|
52
|
+
this.startTrackingMessage = this.createTrackingMessage(payload, "userMessage");
|
|
53
|
+
}
|
|
54
|
+
handleAgentMessage(payload) {
|
|
55
|
+
var _payload$tags;
|
|
56
|
+
// this tag so far is only present in agent messages
|
|
57
|
+
if (payload !== null && payload !== void 0 && (_payload$tags = payload.tags) !== null && _payload$tags !== void 0 && _payload$tags.includes("public")) {
|
|
58
|
+
this.deregister();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
stopTracking(payload) {
|
|
62
|
+
var _this$stopTrackingMes, _this$startTrackingMe;
|
|
63
|
+
// this prevents execution for multiple incoming messages from the bot.
|
|
64
|
+
if (this.isEnded && !this.isStarted) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// control of states to prevent clashing of messages
|
|
69
|
+
this.isEnded = true;
|
|
70
|
+
this.isStarted = false;
|
|
71
|
+
|
|
72
|
+
// The idea of using types is to enrich telemetry data
|
|
73
|
+
this.stopTrackingMessage = this.createTrackingMessage(payload, "botMessage");
|
|
74
|
+
// calculating elapsed time
|
|
75
|
+
const elapsedTime = (((_this$stopTrackingMes = this.stopTrackingMessage) === null || _this$stopTrackingMes === void 0 ? void 0 : _this$stopTrackingMes.checkTime) ?? 0) - (((_this$startTrackingMe = this.startTrackingMessage) === null || _this$startTrackingMe === void 0 ? void 0 : _this$startTrackingMe.checkTime) ?? 0);
|
|
76
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
77
|
+
Event: _TelemetryConstants.TelemetryEvent.MessageLapTrack,
|
|
78
|
+
Description: "First response latency tracking",
|
|
79
|
+
CustomProperties: {
|
|
80
|
+
elapsedTime,
|
|
81
|
+
userMessage: this.startTrackingMessage,
|
|
82
|
+
botMessage: this.stopTrackingMessage
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// mechanism to ensure we track only allowed conversations
|
|
88
|
+
isMessageFromValidSender(payload) {
|
|
89
|
+
var _payload$tags2;
|
|
90
|
+
// agent scenario
|
|
91
|
+
if (payload !== null && payload !== void 0 && (_payload$tags2 = payload.tags) !== null && _payload$tags2 !== void 0 && _payload$tags2.includes("public")) {
|
|
92
|
+
this.handleAgentMessage(payload);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
startClock(payload) {
|
|
98
|
+
try {
|
|
99
|
+
if (!payload || !payload.Id) {
|
|
100
|
+
throw new Error("Invalid payload");
|
|
101
|
+
}
|
|
102
|
+
// in the case of a reload, tracker will be paused, until last history message is received
|
|
103
|
+
// this is because we dont have a way to identidy send messages as part of the history
|
|
104
|
+
//if (this.inPause) return;
|
|
105
|
+
this.startTracking(payload);
|
|
106
|
+
} catch (e) {
|
|
107
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
108
|
+
Event: _TelemetryConstants.TelemetryEvent.MessageStartLapTrackError,
|
|
109
|
+
Description: "Error while starting the clock",
|
|
110
|
+
ExceptionDetails: e,
|
|
111
|
+
CustomProperties: {
|
|
112
|
+
payload: payload
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
stopClock(payload) {
|
|
118
|
+
try {
|
|
119
|
+
if (!payload || !payload.Id) {
|
|
120
|
+
throw new Error("Invalid payload");
|
|
121
|
+
}
|
|
122
|
+
if (!this.isMessageFromValidSender(payload)) return;
|
|
123
|
+
if (this.isABotConversation && this.isStarted) {
|
|
124
|
+
this.stopTracking(payload);
|
|
125
|
+
}
|
|
126
|
+
} catch (e) {
|
|
127
|
+
console.error("FRL : error while trying to stop the tracker", e);
|
|
128
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.ERROR, {
|
|
129
|
+
Event: _TelemetryConstants.TelemetryEvent.MessageStopLapTrackError,
|
|
130
|
+
Description: "Error while stopping the clock",
|
|
131
|
+
ExceptionDetails: e,
|
|
132
|
+
CustomProperties: {
|
|
133
|
+
payload: payload
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
//reset state
|
|
137
|
+
this.startTrackingMessage = undefined;
|
|
138
|
+
this.stopTrackingMessage = undefined;
|
|
139
|
+
this.isStarted = false;
|
|
140
|
+
this.isEnded = false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
deregister() {
|
|
144
|
+
// Reset State
|
|
145
|
+
this.isABotConversation = false;
|
|
146
|
+
this.isStarted = false;
|
|
147
|
+
this.isEnded = false;
|
|
148
|
+
this.startTrackingMessage = undefined;
|
|
149
|
+
this.stopTrackingMessage = undefined;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.FirstResponseLatencyTracker = FirstResponseLatencyTracker;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.polyfillMessagePayloadForEvent = exports.isHistoryMessage = exports.getScenarioType = exports.buildMessagePayload = void 0;
|
|
7
|
+
var _Constants = require("./Constants");
|
|
8
|
+
var _Constants2 = require("../common/Constants");
|
|
9
|
+
const isHistoryMessage = (activity, startTime) => {
|
|
10
|
+
try {
|
|
11
|
+
if ((activity === null || activity === void 0 ? void 0 : activity.type) === _Constants2.Constants.message) {
|
|
12
|
+
var _activity$channelData, _activity$channelData2;
|
|
13
|
+
// this is an old piece of code, probably no longer relevant
|
|
14
|
+
if (activity !== null && activity !== void 0 && (_activity$channelData = activity.channelData) !== null && _activity$channelData !== void 0 && (_activity$channelData2 = _activity$channelData.tags) !== null && _activity$channelData2 !== void 0 && _activity$channelData2.includes(_Constants2.Constants.historyMessageTag)) return true;
|
|
15
|
+
|
|
16
|
+
// Id is an epoch time in milliseconds , in utc format, for some reason is in a string format
|
|
17
|
+
if (activity !== null && activity !== void 0 && activity.id) {
|
|
18
|
+
/// activity.id is an string that contains epoch time in milliseconds
|
|
19
|
+
const activityId = parseInt(activity === null || activity === void 0 ? void 0 : activity.id);
|
|
20
|
+
|
|
21
|
+
// if the activity id is not a number, we default to new message
|
|
22
|
+
if (isNaN(activityId)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// if the activity id is less than the start time, it means that the message is a history message
|
|
27
|
+
if (activityId < startTime) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// anything else will be considered a new message
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
// if there is an error in parsing the activity id, we will consider it a new message
|
|
36
|
+
console.error("Error in parsing activity id: ", e);
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
40
|
+
exports.isHistoryMessage = isHistoryMessage;
|
|
41
|
+
const buildMessagePayload = (activity, userId) => {
|
|
42
|
+
var _text, _text2, _activity$channelData3, _activity$from;
|
|
43
|
+
return {
|
|
44
|
+
// To identify hidden contents vs empty content
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
text: (activity === null || activity === void 0 ? void 0 : (_text = activity.text) === null || _text === void 0 ? void 0 : _text.length) >= 1 ? `*contents hidden (${activity === null || activity === void 0 ? void 0 : (_text2 = activity.text) === null || _text2 === void 0 ? void 0 : _text2.length} chars)*` : "",
|
|
47
|
+
type: activity === null || activity === void 0 ? void 0 : activity.type,
|
|
48
|
+
timestamp: activity === null || activity === void 0 ? void 0 : activity.timestamp,
|
|
49
|
+
userId: userId,
|
|
50
|
+
tags: activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : _activity$channelData3.tags,
|
|
51
|
+
messageType: "",
|
|
52
|
+
Id: activity === null || activity === void 0 ? void 0 : activity.id,
|
|
53
|
+
role: activity === null || activity === void 0 ? void 0 : (_activity$from = activity.from) === null || _activity$from === void 0 ? void 0 : _activity$from.role,
|
|
54
|
+
isChatComplete: false
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
exports.buildMessagePayload = buildMessagePayload;
|
|
58
|
+
const polyfillMessagePayloadForEvent = (activity, payload, conversationId) => {
|
|
59
|
+
var _activity$conversatio, _attachments, _activity$from2;
|
|
60
|
+
return {
|
|
61
|
+
...payload,
|
|
62
|
+
channelData: activity === null || activity === void 0 ? void 0 : activity.channelData,
|
|
63
|
+
chatId: activity === null || activity === void 0 ? void 0 : (_activity$conversatio = activity.conversation) === null || _activity$conversatio === void 0 ? void 0 : _activity$conversatio.id,
|
|
64
|
+
conversationId: conversationId,
|
|
65
|
+
Id: activity === null || activity === void 0 ? void 0 : activity.id,
|
|
66
|
+
isChatComplete: false,
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
text: activity === null || activity === void 0 ? void 0 : activity.text,
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
70
|
+
attachment: (activity === null || activity === void 0 ? void 0 : (_attachments = activity.attachments) === null || _attachments === void 0 ? void 0 : _attachments.length) >= 1 ? activity === null || activity === void 0 ? void 0 : activity.attachments : [],
|
|
71
|
+
role: activity === null || activity === void 0 ? void 0 : (_activity$from2 = activity.from) === null || _activity$from2 === void 0 ? void 0 : _activity$from2.role
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
exports.polyfillMessagePayloadForEvent = polyfillMessagePayloadForEvent;
|
|
75
|
+
const getScenarioType = activity => {
|
|
76
|
+
var _activity$from3, _activity$channelData4, _activity$channelData5;
|
|
77
|
+
if ((activity === null || activity === void 0 ? void 0 : (_activity$from3 = activity.from) === null || _activity$from3 === void 0 ? void 0 : _activity$from3.role) === _Constants2.Constants.userMessageTag) {
|
|
78
|
+
return _Constants.ScenarioType.UserSendMessageStrategy;
|
|
79
|
+
}
|
|
80
|
+
if (activity !== null && activity !== void 0 && (_activity$channelData4 = activity.channelData) !== null && _activity$channelData4 !== void 0 && (_activity$channelData5 = _activity$channelData4.tags) !== null && _activity$channelData5 !== void 0 && _activity$channelData5.includes(_Constants2.Constants.systemMessageTag)) {
|
|
81
|
+
return _Constants.ScenarioType.SystemMessageStrategy;
|
|
82
|
+
}
|
|
83
|
+
return _Constants.ScenarioType.ReceivedMessageStrategy;
|
|
84
|
+
};
|
|
85
|
+
exports.getScenarioType = getScenarioType;
|
|
@@ -173,7 +173,7 @@ class TranscriptHTMLBuilder {
|
|
|
173
173
|
<script>
|
|
174
174
|
class Translator {
|
|
175
175
|
static convertTranscriptMessageToActivity(message) {
|
|
176
|
-
const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences} = message;
|
|
176
|
+
const {created, OriginalMessageId, id, isControlMessage, content, tags, from, attachments, amsMetadata, amsReferences, amsreferences} = message;
|
|
177
177
|
|
|
178
178
|
//it's required to convert the id to a number, otherwise the webchat will not render the messages in the correct order
|
|
179
179
|
// if the OrginalMessageId is not present, we can use the id as the sequence id, which is always present.
|
|
@@ -220,7 +220,7 @@ class TranscriptHTMLBuilder {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
// Attachments
|
|
223
|
-
if (amsReferences && amsMetadata) {
|
|
223
|
+
if ((amsReferences || amsreferences) && amsMetadata) {
|
|
224
224
|
const metadata = JSON.parse(amsMetadata);
|
|
225
225
|
const { fileName } = metadata[0];
|
|
226
226
|
const text = \`${this.attachmentMessage}\${fileName}\`;
|
|
@@ -244,7 +244,7 @@ class TranscriptHTMLBuilder {
|
|
|
244
244
|
// Message
|
|
245
245
|
if (content) {
|
|
246
246
|
// Adaptive card formatting
|
|
247
|
-
if (content.includes('"
|
|
247
|
+
if (content.includes('"attachments"') || content.includes('"suggestedActions"')) {
|
|
248
248
|
try {
|
|
249
249
|
const partialActivity = JSON.parse(content);
|
|
250
250
|
return {
|
|
@@ -683,7 +683,7 @@ const createChatTranscript = async function (transcript, facadeChatSDK) {
|
|
|
683
683
|
messages = await Promise.all(transcriptMessages.map(async message => {
|
|
684
684
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
685
685
|
const {
|
|
686
|
-
amsReferences,
|
|
686
|
+
amsReferences = message.amsreferences,
|
|
687
687
|
amsMetadata
|
|
688
688
|
} = message;
|
|
689
689
|
if (amsReferences && amsMetadata) {
|
|
@@ -5,102 +5,116 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.createOnNewAdapterActivityHandler = void 0;
|
|
7
7
|
var _TelemetryConstants = require("../common/telemetry/TelemetryConstants");
|
|
8
|
+
var _Constants = require("../firstresponselatency/Constants");
|
|
9
|
+
var _util = require("../firstresponselatency/util");
|
|
8
10
|
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
9
|
-
var
|
|
11
|
+
var _Constants2 = require("../common/Constants");
|
|
12
|
+
var _FirstResponseLatencyTracker = require("../firstresponselatency/FirstResponseLatencyTracker");
|
|
10
13
|
var _TelemetryHelper = require("../common/telemetry/TelemetryHelper");
|
|
11
14
|
var _TelemetryManager = require("../common/telemetry/TelemetryManager");
|
|
12
15
|
const createOnNewAdapterActivityHandler = (chatId, userId) => {
|
|
16
|
+
// Hooking the message tracker in the listener, a bit invasive but easier to control.
|
|
17
|
+
const firstResponseLatencyTracker = new _FirstResponseLatencyTracker.FirstResponseLatencyTracker();
|
|
18
|
+
// epoch time in utc for when start to listen.
|
|
19
|
+
// We dont longer have a mechanism to know if a message is history or new, so any message older than the time we start listening will be considered a history message.
|
|
20
|
+
// this is a workaround for the fact that we dont have a way to identify if a message is history or new, and it will provide consistency across different scenarios
|
|
21
|
+
const startTime = new Date().getTime();
|
|
22
|
+
let isHistoryMessageReceivedEventRaised = false;
|
|
13
23
|
const onNewAdapterActivityHandler = activity => {
|
|
14
|
-
|
|
15
|
-
const isActivityMessage = (activity === null || activity === void 0 ? void 0 : activity.type) === _Constants.Constants.message;
|
|
16
|
-
const isHistoryMessage = isActivityMessage && ((activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : (_activity$channelData2 = _activity$channelData.tags) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.includes(_Constants.Constants.historyMessageTag)) || (activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : _activity$channelData3.fromList));
|
|
17
|
-
raiseMessageEvent(activity, isHistoryMessage);
|
|
24
|
+
raiseMessageEvent(activity);
|
|
18
25
|
};
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
const userSendMessageStrategy = activity => {
|
|
27
|
+
var _TelemetryManager$Int;
|
|
28
|
+
const payload = (0, _util.buildMessagePayload)(activity, userId);
|
|
21
29
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
channelData: activity === null || activity === void 0 ? void 0 : activity.channelData,
|
|
27
|
-
chatId: activity === null || activity === void 0 ? void 0 : (_activity$conversatio = activity.conversation) === null || _activity$conversatio === void 0 ? void 0 : _activity$conversatio.id,
|
|
28
|
-
conversationId: (_TelemetryManager$Int = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.conversationId,
|
|
29
|
-
id: activity === null || activity === void 0 ? void 0 : activity.id,
|
|
30
|
-
isChatComplete: false,
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
32
|
-
text: activity === null || activity === void 0 ? void 0 : activity.text,
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
-
attachment: (activity === null || activity === void 0 ? void 0 : (_attachments = activity.attachments) === null || _attachments === void 0 ? void 0 : _attachments.length) >= 1 ? activity === null || activity === void 0 ? void 0 : activity.attachments : []
|
|
35
|
-
};
|
|
30
|
+
payload.messageType = _Constants2.Constants.userMessageTag;
|
|
31
|
+
const newMessageSentEvent = {
|
|
32
|
+
eventName: _TelemetryConstants.BroadcastEvent.NewMessageSent,
|
|
33
|
+
payload: (0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.conversationId)
|
|
36
34
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
35
|
+
_omnichannelChatComponents.BroadcastService.postMessage(newMessageSentEvent);
|
|
36
|
+
if (!(0, _util.isHistoryMessage)(activity, startTime)) {
|
|
37
|
+
firstResponseLatencyTracker.startClock(payload);
|
|
38
|
+
}
|
|
39
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
40
|
+
Event: _TelemetryConstants.TelemetryEvent.MessageSent,
|
|
41
|
+
Description: "New message sent"
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
const systemMessageStrategy = activity => {
|
|
45
|
+
const payload = (0, _util.buildMessagePayload)(activity, userId);
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
+
payload.messageType = _Constants2.Constants.systemMessageTag;
|
|
48
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
49
|
+
Event: _TelemetryConstants.TelemetryEvent.SystemMessageReceived,
|
|
50
|
+
Description: "System message received"
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const historyMessageStrategy = payload => {
|
|
54
|
+
const newMessageReceivedEvent = {
|
|
55
|
+
eventName: _TelemetryConstants.BroadcastEvent.HistoryMessageReceived,
|
|
56
|
+
payload: payload
|
|
57
|
+
};
|
|
58
|
+
_omnichannelChatComponents.BroadcastService.postMessage(newMessageReceivedEvent);
|
|
59
|
+
if (!isHistoryMessageReceivedEventRaised) {
|
|
60
|
+
// this is needed for reload scenarios, it helps to identify the last message received before the reload
|
|
61
|
+
isHistoryMessageReceivedEventRaised = true;
|
|
62
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
63
|
+
Event: _TelemetryConstants.TelemetryEvent.RehydrateMessageReceived,
|
|
64
|
+
Description: "History message received",
|
|
65
|
+
CustomProperties: payload
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const isValidMessage = activity => {
|
|
70
|
+
var _activity$channelData, _activity$channelData2, _activity$channelData3;
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
72
|
+
const messageHasNoText = !(activity !== null && activity !== void 0 && activity.text);
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
74
|
+
const messageHasNoTags = !(activity !== null && activity !== void 0 && activity.channelData) || !(activity !== null && activity !== void 0 && (_activity$channelData = activity.channelData) !== null && _activity$channelData !== void 0 && _activity$channelData.tags) || (activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : (_activity$channelData3 = _activity$channelData2.tags) === null || _activity$channelData3 === void 0 ? void 0 : _activity$channelData3.length) === 0;
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
+
const messageHasNoAttachments = !(activity !== null && activity !== void 0 && activity.attachments) || (activity === null || activity === void 0 ? void 0 : activity.attachments.length) === 0;
|
|
77
|
+
if (messageHasNoTags && messageHasNoText && messageHasNoAttachments) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
};
|
|
82
|
+
const receivedMessageStrategy = activity => {
|
|
83
|
+
var _TelemetryManager$Int3;
|
|
84
|
+
if (!isValidMessage(activity)) return;
|
|
85
|
+
const isHistoryMessageReceived = (0, _util.isHistoryMessage)(activity, startTime);
|
|
86
|
+
const payload = (0, _util.buildMessagePayload)(activity, userId);
|
|
87
|
+
payload.messageType = _Constants2.Constants.userMessageTag;
|
|
88
|
+
if (isHistoryMessageReceived) {
|
|
89
|
+
var _TelemetryManager$Int2;
|
|
90
|
+
historyMessageStrategy((0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int2 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int2 === void 0 ? void 0 : _TelemetryManager$Int2.conversationId));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
firstResponseLatencyTracker.stopClock(payload);
|
|
94
|
+
const newMessageReceivedEvent = {
|
|
95
|
+
eventName: _TelemetryConstants.BroadcastEvent.NewMessageReceived,
|
|
96
|
+
payload: (0, _util.polyfillMessagePayloadForEvent)(activity, payload, (_TelemetryManager$Int3 = _TelemetryManager.TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int3 === void 0 ? void 0 : _TelemetryManager$Int3.conversationId)
|
|
97
|
+
};
|
|
98
|
+
_omnichannelChatComponents.BroadcastService.postMessage(newMessageReceivedEvent);
|
|
99
|
+
_TelemetryHelper.TelemetryHelper.logActionEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
100
|
+
Event: _TelemetryConstants.TelemetryEvent.MessageReceived,
|
|
101
|
+
Description: "New message received",
|
|
102
|
+
CustomProperties: payload
|
|
103
|
+
});
|
|
104
|
+
};
|
|
105
|
+
const raiseMessageEvent = activity => {
|
|
106
|
+
if ((activity === null || activity === void 0 ? void 0 : activity.type) === _Constants2.Constants.message) {
|
|
107
|
+
const scenarioType = (0, _util.getScenarioType)(activity);
|
|
108
|
+
switch (scenarioType) {
|
|
109
|
+
case _Constants.ScenarioType.UserSendMessageStrategy:
|
|
110
|
+
userSendMessageStrategy(activity);
|
|
111
|
+
break;
|
|
112
|
+
case _Constants.ScenarioType.SystemMessageStrategy:
|
|
113
|
+
systemMessageStrategy(activity);
|
|
114
|
+
break;
|
|
115
|
+
case _Constants.ScenarioType.ReceivedMessageStrategy:
|
|
116
|
+
receivedMessageStrategy(activity);
|
|
117
|
+
break;
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
120
|
};
|
|
@@ -199,6 +199,9 @@ export let TelemetryEvent;
|
|
|
199
199
|
TelemetryEvent["ReconnectChatMinimize"] = "ReconnectChatMinimize";
|
|
200
200
|
TelemetryEvent["MessageSent"] = "MessageSent";
|
|
201
201
|
TelemetryEvent["MessageReceived"] = "MessageReceived";
|
|
202
|
+
TelemetryEvent["MessageLapTrack"] = "MessageLapTrack";
|
|
203
|
+
TelemetryEvent["MessageStartLapTrackError"] = "MessageStartLapTrackError";
|
|
204
|
+
TelemetryEvent["MessageStopLapTrackError"] = "MessageStopLapTrackError";
|
|
202
205
|
TelemetryEvent["SystemMessageReceived"] = "SystemMessageReceived";
|
|
203
206
|
TelemetryEvent["RehydrateMessageReceived"] = "RehydrateMessageReceived";
|
|
204
207
|
TelemetryEvent["CustomContextReceived"] = "CustomContextReceived";
|
|
@@ -213,6 +216,8 @@ export let TelemetryEvent;
|
|
|
213
216
|
TelemetryEvent["PostChatContextCallFailed"] = "PostChatContextCallFailed";
|
|
214
217
|
TelemetryEvent["PostChatSurveyLoadingPaneLoaded"] = "PostChatSurveyLoadingPaneLoaded";
|
|
215
218
|
TelemetryEvent["PostChatSurveyLoaded"] = "PostChatSurveyLoaded";
|
|
219
|
+
TelemetryEvent["PostChatSurveyUrlValidationCompleted"] = "PostChatSurveyUrlValidationCompleted";
|
|
220
|
+
TelemetryEvent["PostChatSurveyUrlValidationFailed"] = "PostChatSurveyUrlValidationFailed";
|
|
216
221
|
TelemetryEvent["ChatDisconnectThreadEventReceived"] = "ChatDisconnectThreadEventReceived";
|
|
217
222
|
TelemetryEvent["HiddenAdaptiveCardMessageReceived"] = "HiddenAdaptiveCardMessageReceived";
|
|
218
223
|
TelemetryEvent["EndingAdapterAfterDisconnectionError"] = "EndingAdapterAfterDisconnectionError";
|
|
@@ -11,7 +11,7 @@ import { defaultOutOfOfficeChatButtonStyleProps } from "./common/styleProps/defa
|
|
|
11
11
|
import useChatContextStore from "../../hooks/useChatContextStore";
|
|
12
12
|
let uiTimer;
|
|
13
13
|
export const ChatButtonStateful = props => {
|
|
14
|
-
var
|
|
14
|
+
var _buttonProps$controlP, _props$buttonProps, _props$buttonProps$co, _props$buttonProps2, _props$buttonProps2$c, _props$buttonProps3, _props$buttonProps3$c;
|
|
15
15
|
// this is to ensure the telemetry is set only once and start the load timer
|
|
16
16
|
useEffect(() => {
|
|
17
17
|
uiTimer = createTimer();
|
|
@@ -28,7 +28,8 @@ export const ChatButtonStateful = props => {
|
|
|
28
28
|
startChat
|
|
29
29
|
} = props;
|
|
30
30
|
//Setting OutOfOperatingHours Flag
|
|
31
|
-
|
|
31
|
+
//Setting OutOfOperatingHours Flag - to string conversion to normalize the value (could be boolean from other states or string directly from config)
|
|
32
|
+
const [outOfOperatingHours, setOutOfOperatingHours] = useState(state.appStates.outsideOperatingHours);
|
|
32
33
|
const ref = useRef(() => {
|
|
33
34
|
return;
|
|
34
35
|
});
|
|
@@ -87,9 +88,7 @@ export const ChatButtonStateful = props => {
|
|
|
87
88
|
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
|
|
88
89
|
};
|
|
89
90
|
useEffect(() => {
|
|
90
|
-
|
|
91
|
-
setOutOfOperatingHours(true);
|
|
92
|
-
}
|
|
91
|
+
setOutOfOperatingHours(state.appStates.outsideOperatingHours);
|
|
93
92
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
94
93
|
Event: TelemetryEvent.LCWChatButtonShow,
|
|
95
94
|
ElapsedTimeInMilliseconds: TelemetryTimers.LcwLoadToChatButtonTimer.milliSecondsElapsed
|
|
@@ -12,7 +12,7 @@ import useChatAdapterStore from "../../hooks/useChatAdapterStore";
|
|
|
12
12
|
import useChatContextStore from "../../hooks/useChatContextStore";
|
|
13
13
|
let uiTimer;
|
|
14
14
|
export const HeaderStateful = props => {
|
|
15
|
-
var _state$domainStates
|
|
15
|
+
var _state$domainStates, _headerProps$controlP, _headerProps$controlP2, _headerProps$controlP3, _outOfOfficeHeaderPro, _state$domainStates3;
|
|
16
16
|
useEffect(() => {
|
|
17
17
|
uiTimer = createTimer();
|
|
18
18
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
@@ -28,7 +28,7 @@ export const HeaderStateful = props => {
|
|
|
28
28
|
endChat
|
|
29
29
|
} = props;
|
|
30
30
|
//Setting OutOfOperatingHours Flag
|
|
31
|
-
const [outOfOperatingHours, setOutOfOperatingHours] = useState(
|
|
31
|
+
const [outOfOperatingHours, setOutOfOperatingHours] = useState(state.appStates.outsideOperatingHours);
|
|
32
32
|
const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeHeaderStyleProps, outOfOfficeHeaderProps === null || outOfOfficeHeaderProps === void 0 ? void 0 : outOfOfficeHeaderProps.styleProps);
|
|
33
33
|
|
|
34
34
|
// For some reason state object is not getting updated values in this component
|
|
@@ -100,9 +100,7 @@ export const HeaderStateful = props => {
|
|
|
100
100
|
hideCloseButton: state.appStates.conversationState === ConversationState.OutOfOffice || (outOfOfficeHeaderProps === null || outOfOfficeHeaderProps === void 0 ? void 0 : (_outOfOfficeHeaderPro = outOfOfficeHeaderProps.controlProps) === null || _outOfOfficeHeaderPro === void 0 ? void 0 : _outOfOfficeHeaderPro.hideCloseButton)
|
|
101
101
|
};
|
|
102
102
|
useEffect(() => {
|
|
103
|
-
|
|
104
|
-
setOutOfOperatingHours(true);
|
|
105
|
-
}
|
|
103
|
+
setOutOfOperatingHours(state.appStates.outsideOperatingHours);
|
|
106
104
|
}, []);
|
|
107
105
|
useEffect(() => {
|
|
108
106
|
var _state$domainStates2;
|
package/lib/esm/components/livechatwidget/common/ActivitySubscriber/BotAuthActivitySubscriber.js
CHANGED
|
@@ -6,6 +6,7 @@ function _toPrimitive(input, hint) { if (typeof input !== "object" || input ===
|
|
|
6
6
|
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
7
7
|
import { BroadcastEvent, LogLevel, TelemetryEvent } from "../../../../common/telemetry/TelemetryConstants";
|
|
8
8
|
import { TelemetryHelper } from "../../../../common/telemetry/TelemetryHelper";
|
|
9
|
+
import { TelemetryManager } from "../../../../common/telemetry/TelemetryManager";
|
|
9
10
|
const supportedSignInCardContentTypes = ["application/vnd.microsoft.card.signin", "application/vnd.microsoft.card.oauth"];
|
|
10
11
|
const botOauthUrlRegex = /[\S]+.botframework.com\/api\/oauth\/signin\?signin=([\S]+)/;
|
|
11
12
|
const delay = t => new Promise(resolve => setTimeout(resolve, t));
|
|
@@ -83,6 +84,7 @@ export class BotAuthActivitySubscriber {
|
|
|
83
84
|
return (activity === null || activity === void 0 ? void 0 : (_activity$attachments = activity.attachments) === null || _activity$attachments === void 0 ? void 0 : _activity$attachments.length) > 0 && activity.attachments[0] && supportedSignInCardContentTypes.indexOf(activity.attachments[0].contentType) >= 0;
|
|
84
85
|
}
|
|
85
86
|
async apply(activity) {
|
|
87
|
+
var _TelemetryManager$Int;
|
|
86
88
|
this.observer.next(false); // Hides card
|
|
87
89
|
const attachment = activity.attachments[0];
|
|
88
90
|
const signInUrl = attachment.content.buttons[0].value;
|
|
@@ -102,7 +104,8 @@ export class BotAuthActivitySubscriber {
|
|
|
102
104
|
const event = {
|
|
103
105
|
eventName: BroadcastEvent.SigninCardReceived,
|
|
104
106
|
payload: {
|
|
105
|
-
sasUrl
|
|
107
|
+
sasUrl,
|
|
108
|
+
conversationId: (_TelemetryManager$Int = TelemetryManager.InternalTelemetryData) === null || _TelemetryManager$Int === void 0 ? void 0 : _TelemetryManager$Int.conversationId
|
|
106
109
|
}
|
|
107
110
|
};
|
|
108
111
|
if (!sasUrl) {
|
|
@@ -6,7 +6,7 @@ import { defaultMiddlewareLocalizedTexts } from "../../webchatcontainerstateful/
|
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
8
|
const handleChatDisconnect = (props, state, setWebChatStyles) => {
|
|
9
|
-
var _state$appStates, _state$domainStates, _state$domainStates$m, _props$webChatContain, _props$webChatContain2;
|
|
9
|
+
var _state$appStates, _state$domainStates, _state$domainStates$m, _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4;
|
|
10
10
|
const chatDisconnectState = state === null || state === void 0 ? void 0 : (_state$appStates = state.appStates) === null || _state$appStates === void 0 ? void 0 : _state$appStates.chatDisconnectEventReceived;
|
|
11
11
|
const chatDisconnectMessage = (state === null || state === void 0 ? void 0 : (_state$domainStates = state.domainStates) === null || _state$domainStates === void 0 ? void 0 : (_state$domainStates$m = _state$domainStates.middlewareLocalizedTexts) === null || _state$domainStates$m === void 0 ? void 0 : _state$domainStates$m.MIDDLEWARE_BANNER_CHAT_DISCONNECT) ?? defaultMiddlewareLocalizedTexts.MIDDLEWARE_BANNER_CHAT_DISCONNECT;
|
|
12
12
|
const hideSendBoxOnConversationEnd = props === null || props === void 0 ? void 0 : (_props$webChatContain = props.webChatContainerProps) === null || _props$webChatContain === void 0 ? void 0 : (_props$webChatContain2 = _props$webChatContain.renderingMiddlewareProps) === null || _props$webChatContain2 === void 0 ? void 0 : _props$webChatContain2.hideSendboxOnConversationEnd;
|
|
@@ -27,6 +27,8 @@ const handleChatDisconnect = (props, state, setWebChatStyles) => {
|
|
|
27
27
|
});
|
|
28
28
|
break;
|
|
29
29
|
case false:
|
|
30
|
+
// this means customer on purpose wants to hide the send box, we should not override it
|
|
31
|
+
if ((props === null || props === void 0 ? void 0 : (_props$webChatContain3 = props.webChatContainerProps) === null || _props$webChatContain3 === void 0 ? void 0 : (_props$webChatContain4 = _props$webChatContain3.webChatStyles) === null || _props$webChatContain4 === void 0 ? void 0 : _props$webChatContain4.hideSendBox) === true) return;
|
|
30
32
|
if (hideSendBoxOnConversationEnd !== false) {
|
|
31
33
|
setWebChatStyles(styles => {
|
|
32
34
|
return {
|