@microsoft/omnichannel-chat-widget 1.8.2-main.d82a79b → 1.8.2-main.f638bed
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/README.md +46 -1
- package/lib/cjs/common/Constants.js +5 -0
- package/lib/cjs/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/cjs/common/utils.js +21 -2
- package/lib/cjs/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/cjs/components/livechatwidget/common/customEventHandler.js +53 -0
- package/lib/cjs/components/livechatwidget/common/initWebChatComposer.js +3 -1
- package/lib/cjs/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +5 -1
- package/lib/cjs/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +41 -0
- package/lib/cjs/contexts/common/CustomEventType.js +1 -0
- package/lib/esm/common/Constants.js +5 -0
- package/lib/esm/common/telemetry/TelemetryConstants.js +1 -0
- package/lib/esm/common/utils.js +17 -0
- package/lib/esm/components/chatbuttonstateful/ChatButtonStateful.js +4 -4
- package/lib/esm/components/livechatwidget/common/customEventHandler.js +45 -0
- package/lib/esm/components/livechatwidget/common/initWebChatComposer.js +3 -1
- package/lib/esm/components/livechatwidget/livechatwidgetstateful/LiveChatWidgetStateful.js +5 -1
- package/lib/esm/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.js +33 -0
- package/lib/esm/contexts/common/CustomEventType.js +1 -0
- package/lib/types/common/Constants.d.ts +5 -0
- package/lib/types/common/telemetry/TelemetryConstants.d.ts +1 -0
- package/lib/types/common/utils.d.ts +3 -0
- package/lib/types/components/livechatwidget/common/customEventHandler.d.ts +4 -0
- package/lib/types/components/webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware.d.ts +22 -0
- package/lib/types/contexts/common/CustomEventType.d.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -223,6 +223,51 @@ const customizedFooterProp: IFooterProps = {
|
|
|
223
223
|
|
|
224
224
|
> :pushpin: Note that [WebChat hooks](https://github.com/microsoft/BotFramework-WebChat/blob/main/docs/HOOKS.md) can also be used in any custom components.
|
|
225
225
|
|
|
226
|
+
#### Bidirectional Custom Events
|
|
227
|
+
- Sending events from a hosting web page to bots/agents
|
|
228
|
+
- Register a function to post event
|
|
229
|
+
```js
|
|
230
|
+
//define sendCustomEvent function
|
|
231
|
+
const sendCustomEvent = (payload) => {
|
|
232
|
+
const customEvent = {
|
|
233
|
+
eventName: "sendCustomEvent",
|
|
234
|
+
payload
|
|
235
|
+
};
|
|
236
|
+
BroadcastService.postMessage(customEvent);
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
//attach the sendCustomEvent function to window object
|
|
240
|
+
window["sendCustomEvent"] = sendCustomEvent;
|
|
241
|
+
|
|
242
|
+
//invoke the sendCustomEvent function with some customized payload
|
|
243
|
+
window.sendCustomEvent({
|
|
244
|
+
customEventName: "TestEvent",
|
|
245
|
+
customEventValue: {
|
|
246
|
+
boolVar: true,
|
|
247
|
+
displayableVar: {
|
|
248
|
+
isDisplayable: true,
|
|
249
|
+
value: "From C2: "+ new Date().toISOString()
|
|
250
|
+
},
|
|
251
|
+
numberVar: -10.5,
|
|
252
|
+
stringVar: "Hello from C2 str: " + new Date().toISOString()
|
|
253
|
+
}
|
|
254
|
+
})
|
|
255
|
+
```
|
|
256
|
+
- Receiving events from bots/agents
|
|
257
|
+
```js
|
|
258
|
+
//define setOnCustomEvent function
|
|
259
|
+
const setOnCustomEvent = (callback) => {
|
|
260
|
+
BroadcastService.getMessageByEventName("onCustomEvent").subscribe((event) => {
|
|
261
|
+
if (event && typeof callback === "function") {
|
|
262
|
+
callback(event);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
//set callback function
|
|
268
|
+
setOnCustomEvent((event) => console.log(event));
|
|
269
|
+
```
|
|
270
|
+
|
|
226
271
|
## See Also
|
|
227
272
|
|
|
228
273
|
[Customizations Dev Guide](https://github.com/microsoft/omnichannel-chat-widget/blob/main/docs/customizations/getstarted.md)\
|
|
@@ -232,4 +277,4 @@ const customizedFooterProp: IFooterProps = {
|
|
|
232
277
|
[How to Add Visual Regression Tests](https://github.com/microsoft/omnichannel-chat-widget/blob/main/docs/VisualRegressionTestingGuide.md)\
|
|
233
278
|
[Security](https://github.com/microsoft/omnichannel-chat-widget/blob/main/SECURITY.md)\
|
|
234
279
|
[Third Party Cookie Support](https://github.com/microsoft/omnichannel-chat-widget/blob/main/docs/Tpc.md)\
|
|
235
|
-
[Storybook](https://microsoft.github.io/omnichannel-chat-widget/docs/storybook/)
|
|
280
|
+
[Storybook](https://microsoft.github.io/omnichannel-chat-widget/docs/storybook/)
|
|
@@ -131,6 +131,11 @@ _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsRespon
|
|
|
131
131
|
_defineProperty(Constants, "OCOriginalMessageId", "OriginalMessageId");
|
|
132
132
|
_defineProperty(Constants, "WebchatSequenceIdAttribute", "webchat:sequence-id");
|
|
133
133
|
_defineProperty(Constants, "MessageSequenceIdOverride", "MessageSequenceIdOverride");
|
|
134
|
+
_defineProperty(Constants, "sendCustomEvent", "sendCustomEvent");
|
|
135
|
+
_defineProperty(Constants, "onCustomEvent", "onCustomEvent");
|
|
136
|
+
_defineProperty(Constants, "customEventName", "customEventName");
|
|
137
|
+
_defineProperty(Constants, "customEventValue", "customEventValue");
|
|
138
|
+
_defineProperty(Constants, "Hidden", "Hidden");
|
|
134
139
|
_defineProperty(Constants, "EndConversationDueToOverflow", "endconversationduetooverflow");
|
|
135
140
|
const Regex = (_class = /*#__PURE__*/_createClass(function Regex() {
|
|
136
141
|
_classCallCheck(this, Regex);
|
|
@@ -229,6 +229,7 @@ exports.TelemetryEvent = TelemetryEvent;
|
|
|
229
229
|
TelemetryEvent["SystemMessageReceived"] = "SystemMessageReceived";
|
|
230
230
|
TelemetryEvent["RehydrateMessageReceived"] = "RehydrateMessageReceived";
|
|
231
231
|
TelemetryEvent["CustomContextReceived"] = "CustomContextReceived";
|
|
232
|
+
TelemetryEvent["CustomEventAction"] = "CustomEventAction";
|
|
232
233
|
TelemetryEvent["NetworkDisconnected"] = "NetworkDisconnected";
|
|
233
234
|
TelemetryEvent["NetworkReconnected"] = "NetworkReconnected";
|
|
234
235
|
TelemetryEvent["LinkModePostChatWorkflowStarted"] = "LinkModePostChatWorkflowStarted";
|
package/lib/cjs/common/utils.js
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.formatTemplateString = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
|
|
6
|
+
exports.getCustomEventValue = exports.getConversationDetailsCall = exports.getBroadcastChannelName = exports.formatTemplateString = exports.findParentFocusableElementsWithoutChildContainer = exports.findAllFocusableElement = exports.extractPreChatSurveyResponseValues = exports.escapeHtml = exports.debounceLeading = exports.createTimer = exports.createFileAndDownload = exports.checkContactIdError = exports.changeLanguageCodeFormatForWebChat = exports.addDelayInMs = void 0;
|
|
7
7
|
exports.getDeviceType = getDeviceType;
|
|
8
8
|
exports.getWidgetEndChatEventName = exports.getWidgetCacheIdfromProps = exports.getWidgetCacheId = exports.getTimestampHourMinute = exports.getStateFromCache = exports.getLocaleDirection = exports.getIconText = exports.getDomain = void 0;
|
|
9
9
|
exports.isEndConversationDueToOverflowActivity = isEndConversationDueToOverflowActivity;
|
|
10
|
-
exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = void 0;
|
|
10
|
+
exports.setTabIndices = exports.setOcUserAgent = exports.setFocusOnSendBox = exports.setFocusOnElement = exports.preventFocusToMoveOutOfElement = exports.parseLowerCaseString = exports.parseAdaptiveCardPayload = exports.newGuid = exports.isValidCustomEvent = exports.isUndefinedOrEmpty = exports.isThisSessionPopout = exports.isNullOrUndefined = exports.isNullOrEmptyString = void 0;
|
|
11
11
|
var _Constants = require("./Constants");
|
|
12
12
|
var _TelemetryConstants = require("./telemetry/TelemetryConstants");
|
|
13
13
|
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
@@ -497,6 +497,25 @@ function getDeviceType() {
|
|
|
497
497
|
return "standard";
|
|
498
498
|
}
|
|
499
499
|
}
|
|
500
|
+
|
|
501
|
+
//Bots expect a payload containing:
|
|
502
|
+
//1. customEventName: this should be string describe the event name
|
|
503
|
+
//2. customEventValue: given the value is from customer with unknown type, it is required to stringify the payload later
|
|
504
|
+
const isValidCustomEvent = payload => {
|
|
505
|
+
if (_Constants.Constants.customEventName in payload && payload.customEventName && typeof payload.customEventName === _Constants.Constants.String && _Constants.Constants.customEventValue in payload && payload.customEventValue) return true;
|
|
506
|
+
return false;
|
|
507
|
+
};
|
|
508
|
+
exports.isValidCustomEvent = isValidCustomEvent;
|
|
509
|
+
const getCustomEventValue = customEventPayload => {
|
|
510
|
+
let returnVal = "";
|
|
511
|
+
try {
|
|
512
|
+
returnVal = typeof customEventPayload.customEventValue === _Constants.Constants.String ? customEventPayload.customEventValue : JSON.stringify(customEventPayload.customEventValue);
|
|
513
|
+
} catch (error) {
|
|
514
|
+
console.error(error);
|
|
515
|
+
}
|
|
516
|
+
return returnVal;
|
|
517
|
+
};
|
|
518
|
+
exports.getCustomEventValue = getCustomEventValue;
|
|
500
519
|
function isEndConversationDueToOverflowActivity(activity) {
|
|
501
520
|
var _activity$channelData, _activity$channelData2;
|
|
502
521
|
return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(_Constants.Constants.EndConversationDueToOverflow);
|
|
@@ -74,7 +74,6 @@ const ChatButtonStateful = props => {
|
|
|
74
74
|
};
|
|
75
75
|
const outOfOfficeStyleProps = Object.assign({}, _defaultOutOfOfficeChatButtonStyleProps.defaultOutOfOfficeChatButtonStyleProps, outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.styleProps);
|
|
76
76
|
const controlProps = {
|
|
77
|
-
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps),
|
|
78
77
|
id: "oc-lcw-chat-button",
|
|
79
78
|
dir: state.domainStates.globalDir,
|
|
80
79
|
titleText: "Let's Chat!",
|
|
@@ -83,7 +82,8 @@ const ChatButtonStateful = props => {
|
|
|
83
82
|
unreadMessageCount: state.appStates.unreadMessageCount ? state.appStates.unreadMessageCount > _Constants.Constants.maximumUnreadMessageCount ? (_props$buttonProps = props.buttonProps) === null || _props$buttonProps === void 0 ? void 0 : (_props$buttonProps$co = _props$buttonProps.controlProps) === null || _props$buttonProps$co === void 0 ? void 0 : _props$buttonProps$co.largeUnreadMessageString : state.appStates.unreadMessageCount.toString() : "0",
|
|
84
83
|
unreadMessageString: (_props$buttonProps2 = props.buttonProps) === null || _props$buttonProps2 === void 0 ? void 0 : (_props$buttonProps2$c = _props$buttonProps2.controlProps) === null || _props$buttonProps2$c === void 0 ? void 0 : _props$buttonProps2$c.unreadMessageString,
|
|
85
84
|
// Regular chat button onClick - this will always take precedence
|
|
86
|
-
onClick: () => ref.current()
|
|
85
|
+
onClick: () => ref.current(),
|
|
86
|
+
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps)
|
|
87
87
|
};
|
|
88
88
|
const outOfOfficeControlProps = {
|
|
89
89
|
// Only take specific properties from outOfOfficeButtonProps, never onClick
|
|
@@ -92,7 +92,6 @@ const ChatButtonStateful = props => {
|
|
|
92
92
|
titleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro === void 0 ? void 0 : _outOfOfficeButtonPro.titleText) || "We're Offline",
|
|
93
93
|
subtitleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro2 = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro2 === void 0 ? void 0 : _outOfOfficeButtonPro2.subtitleText) || "No agents available",
|
|
94
94
|
unreadMessageString: (_props$buttonProps3 = props.buttonProps) === null || _props$buttonProps3 === void 0 ? void 0 : (_props$buttonProps3$c = _props$buttonProps3.controlProps) === null || _props$buttonProps3$c === void 0 ? void 0 : _props$buttonProps3$c.unreadMessageString,
|
|
95
|
-
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps),
|
|
96
95
|
// Out-of-office specific onClick - this will ALWAYS take precedence
|
|
97
96
|
onClick: () => {
|
|
98
97
|
if (state.appStates.isMinimized) {
|
|
@@ -105,7 +104,8 @@ const ChatButtonStateful = props => {
|
|
|
105
104
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
106
105
|
payload: _ConversationState.ConversationState.OutOfOffice
|
|
107
106
|
});
|
|
108
|
-
}
|
|
107
|
+
},
|
|
108
|
+
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
|
|
109
109
|
};
|
|
110
110
|
(0, _react.useEffect)(() => {
|
|
111
111
|
_TelemetryHelper.TelemetryHelper.logLoadingEvent(_TelemetryConstants.LogLevel.INFO, {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.subscribeToSendCustomEvent = exports.customEventCallback = void 0;
|
|
7
|
+
var _Constants = require("../../../common/Constants");
|
|
8
|
+
var _TelemetryHelper = require("../../../common/telemetry/TelemetryHelper");
|
|
9
|
+
var _TelemetryConstants = require("../../../common/telemetry/TelemetryConstants");
|
|
10
|
+
var _utils = require("../../../common/utils");
|
|
11
|
+
const customEventCallback = facadeChatSDK => event => {
|
|
12
|
+
if (!(_Constants.Constants.payload in event)) return;
|
|
13
|
+
if ((0, _utils.isValidCustomEvent)(event.payload)) {
|
|
14
|
+
const customEventPayload = event.payload;
|
|
15
|
+
try {
|
|
16
|
+
const customEventValueStr = (0, _utils.getCustomEventValue)(customEventPayload);
|
|
17
|
+
const customEventName = customEventPayload.customEventName;
|
|
18
|
+
const messageMeta = {
|
|
19
|
+
customEvent: _Constants.Constants.true,
|
|
20
|
+
customEventName: customEventName,
|
|
21
|
+
customEventValue: customEventValueStr
|
|
22
|
+
};
|
|
23
|
+
const messagePayload = {
|
|
24
|
+
content: "",
|
|
25
|
+
tags: [_Constants.Constants.Hidden],
|
|
26
|
+
metadata: messageMeta,
|
|
27
|
+
timestamp: new Date()
|
|
28
|
+
};
|
|
29
|
+
facadeChatSDK.sendMessage(messagePayload);
|
|
30
|
+
_TelemetryHelper.TelemetryHelper.logActionEventToAllTelemetry(_TelemetryConstants.LogLevel.DEBUG, {
|
|
31
|
+
Event: _TelemetryConstants.TelemetryEvent.CustomEventAction,
|
|
32
|
+
Description: "Sent customEvent.",
|
|
33
|
+
CustomProperties: {
|
|
34
|
+
customEventName,
|
|
35
|
+
lengthCustomEventValue: customEventValueStr.length
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
} catch (error) {
|
|
39
|
+
_TelemetryHelper.TelemetryHelper.logActionEventToAllTelemetry(_TelemetryConstants.LogLevel.ERROR, {
|
|
40
|
+
Event: _TelemetryConstants.TelemetryEvent.CustomEventAction,
|
|
41
|
+
Description: "Failed to process CustomEvent.",
|
|
42
|
+
ExceptionDetails: {
|
|
43
|
+
error
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.customEventCallback = customEventCallback;
|
|
50
|
+
const subscribeToSendCustomEvent = (broadcastService, facadeChatSDK, customEventCallback) => {
|
|
51
|
+
broadcastService.getMessageByEventName(_Constants.Constants.sendCustomEvent).subscribe(customEventCallback(facadeChatSDK));
|
|
52
|
+
};
|
|
53
|
+
exports.subscribeToSendCustomEvent = subscribeToSendCustomEvent;
|
|
@@ -37,9 +37,11 @@ var _htmlPlayerMiddleware = _interopRequireDefault(require("../../webchatcontain
|
|
|
37
37
|
var _htmlTextMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/htmlTextMiddleware"));
|
|
38
38
|
var _preProcessingMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware"));
|
|
39
39
|
var _sanitizationMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware"));
|
|
40
|
+
var _customEventMiddleware = _interopRequireDefault(require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware"));
|
|
40
41
|
var _ConversationState = require("../../../contexts/common/ConversationState");
|
|
41
42
|
var _createReducer = require("../../../contexts/createReducer");
|
|
42
43
|
var _queueOverflowHandlerMiddleware = require("../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware");
|
|
44
|
+
var _omnichannelChatComponents = require("@microsoft/omnichannel-chat-components");
|
|
43
45
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
44
46
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
47
|
const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
@@ -118,7 +120,7 @@ const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) =>
|
|
|
118
120
|
};
|
|
119
121
|
webChatStore = (0, _botframeworkWebchat.createStore)({},
|
|
120
122
|
//initial state
|
|
121
|
-
_preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_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), (0, _queueOverflowHandlerMiddleware.createQueueOverflowMiddleware)(state, dispatch), (0, _channelDataMiddleware.default)(addConversationalSurveyTagsCallback), (0, _conversationEndMiddleware.default)(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.createMessageTimeStampMiddleware, _messageSequenceIdOverrideMiddleware.createMessageSequenceIdOverrideMiddleware, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, (0, _htmlTextMiddleware.default)(honorsTargetInHTMLLinks), (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
|
|
123
|
+
_preProcessingMiddleware.default, _attachmentProcessingMiddleware.default, (0, _attachmentUploadValidatorMiddleware.default)((_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), (0, _customEventMiddleware.default)(_omnichannelChatComponents.BroadcastService), (0, _queueOverflowHandlerMiddleware.createQueueOverflowMiddleware)(state, dispatch), (0, _channelDataMiddleware.default)(addConversationalSurveyTagsCallback), (0, _conversationEndMiddleware.default)(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), (0, _dataMaskingMiddleware.default)((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), _messageTimestampMiddleware.createMessageTimeStampMiddleware, _messageSequenceIdOverrideMiddleware.createMessageSequenceIdOverrideMiddleware, _gifUploadMiddleware.default, _htmlPlayerMiddleware.default, (0, _htmlTextMiddleware.default)(honorsTargetInHTMLLinks), (0, _maxMessageSizeValidator.default)(localizedTexts), _sanitizationMiddleware.default,
|
|
122
124
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
123
125
|
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
124
126
|
_WebChatStoreLoader.WebChatStoreLoader.store = webChatStore;
|
|
@@ -57,6 +57,7 @@ var _startProactiveChat = require("../common/startProactiveChat");
|
|
|
57
57
|
var _useChatAdapterStore = _interopRequireDefault(require("../../../hooks/useChatAdapterStore"));
|
|
58
58
|
var _useChatContextStore = _interopRequireDefault(require("../../../hooks/useChatContextStore"));
|
|
59
59
|
var _useFacadeChatSDKStore = _interopRequireDefault(require("../../../hooks/useFacadeChatSDKStore"));
|
|
60
|
+
var _customEventHandler = require("../common/customEventHandler");
|
|
60
61
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
61
62
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
62
63
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
@@ -421,7 +422,7 @@ const LiveChatWidgetStateful = props => {
|
|
|
421
422
|
_omnichannelChatComponents.BroadcastService.getMessageByEventName(_TelemetryConstants.BroadcastEvent.StartChat).subscribe(msg => {
|
|
422
423
|
var _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3, _inMemoryState$appSta4;
|
|
423
424
|
// If chat is out of operating hours chat widget sets the conversation state to OutOfOffice.
|
|
424
|
-
if (state.appStates.outsideOperatingHours
|
|
425
|
+
if (state.appStates.outsideOperatingHours && state.appStates.conversationState !== _ConversationState.ConversationState.Active) {
|
|
425
426
|
dispatch({
|
|
426
427
|
type: _LiveChatWidgetActionType.LiveChatWidgetActionType.SET_MINIMIZED,
|
|
427
428
|
payload: false
|
|
@@ -588,6 +589,9 @@ const LiveChatWidgetStateful = props => {
|
|
|
588
589
|
}
|
|
589
590
|
});
|
|
590
591
|
|
|
592
|
+
// subscribe custom event
|
|
593
|
+
(0, _customEventHandler.subscribeToSendCustomEvent)(_omnichannelChatComponents.BroadcastService, facadeChatSDK, _customEventHandler.customEventCallback);
|
|
594
|
+
|
|
591
595
|
// Check for TPC and log in telemetry if blocked
|
|
592
596
|
(0, _defaultClientDataStoreProvider.isCookieAllowed)();
|
|
593
597
|
return () => {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isValidCustomEvent = exports.default = void 0;
|
|
7
|
+
var _Constants = require("../../../../../common/Constants");
|
|
8
|
+
var _WebChatActionType = require("../../enums/WebChatActionType");
|
|
9
|
+
/******
|
|
10
|
+
* CustomEventMiddleware
|
|
11
|
+
*
|
|
12
|
+
* This middleware is invoked when a custom event is received.
|
|
13
|
+
* The callback is then invoked to handle the custom event.
|
|
14
|
+
******/
|
|
15
|
+
|
|
16
|
+
const isValidCustomEvent = activity => {
|
|
17
|
+
var _activity$channelData, _activity$channelData2, _activity$channelData3, _activity$channelData4, _activity$channelData5, _activity$channelData6, _activity$channelData7, _activity$from, _activity$channelData8, _activity$channelData9, _activity$channelData10, _activity$channelData11;
|
|
18
|
+
return !!(activity !== null && activity !== void 0 && (_activity$channelData = activity.channelData) !== null && _activity$channelData !== void 0 && (_activity$channelData2 = _activity$channelData.metadata) !== null && _activity$channelData2 !== void 0 && _activity$channelData2.customEvent && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : (_activity$channelData4 = _activity$channelData3.metadata) === null || _activity$channelData4 === void 0 ? void 0 : _activity$channelData4.customEvent) === _Constants.Constants.String && (activity === null || activity === void 0 ? void 0 : (_activity$channelData5 = activity.channelData) === null || _activity$channelData5 === void 0 ? void 0 : (_activity$channelData6 = _activity$channelData5.metadata) === null || _activity$channelData6 === void 0 ? void 0 : (_activity$channelData7 = _activity$channelData6.customEvent) === null || _activity$channelData7 === void 0 ? void 0 : _activity$channelData7.toLowerCase()) === _Constants.Constants.true && (activity === null || activity === void 0 ? void 0 : (_activity$from = activity.from) === null || _activity$from === void 0 ? void 0 : _activity$from.role) !== _Constants.Constants.userMessageTag && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData8 = activity.channelData) === null || _activity$channelData8 === void 0 ? void 0 : (_activity$channelData9 = _activity$channelData8.metadata) === null || _activity$channelData9 === void 0 ? void 0 : _activity$channelData9.customEventName) === _Constants.Constants.String && activity !== null && activity !== void 0 && (_activity$channelData10 = activity.channelData) !== null && _activity$channelData10 !== void 0 && (_activity$channelData11 = _activity$channelData10.metadata) !== null && _activity$channelData11 !== void 0 && _activity$channelData11.customEventValue);
|
|
19
|
+
};
|
|
20
|
+
exports.isValidCustomEvent = isValidCustomEvent;
|
|
21
|
+
const createCustomEventMiddleware = broadcastservice => () => next => action => {
|
|
22
|
+
var _action$payload;
|
|
23
|
+
if ((action === null || action === void 0 ? void 0 : action.type) == _WebChatActionType.WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && (_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
|
|
24
|
+
const activity = action.payload.activity;
|
|
25
|
+
if (isValidCustomEvent(activity)) {
|
|
26
|
+
const customEvent = {
|
|
27
|
+
eventName: _Constants.Constants.onCustomEvent,
|
|
28
|
+
payload: {
|
|
29
|
+
messageId: activity.messageid ?? activity.id,
|
|
30
|
+
customEventName: activity.channelData.metadata.customEventName,
|
|
31
|
+
customEventValue: activity.channelData.metadata.customEventValue
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
broadcastservice.postMessage(customEvent);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return next(action);
|
|
39
|
+
};
|
|
40
|
+
var _default = createCustomEventMiddleware;
|
|
41
|
+
exports.default = _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -124,6 +124,11 @@ _defineProperty(Constants, "InitContextParamsResponse", "initContextParamsRespon
|
|
|
124
124
|
_defineProperty(Constants, "OCOriginalMessageId", "OriginalMessageId");
|
|
125
125
|
_defineProperty(Constants, "WebchatSequenceIdAttribute", "webchat:sequence-id");
|
|
126
126
|
_defineProperty(Constants, "MessageSequenceIdOverride", "MessageSequenceIdOverride");
|
|
127
|
+
_defineProperty(Constants, "sendCustomEvent", "sendCustomEvent");
|
|
128
|
+
_defineProperty(Constants, "onCustomEvent", "onCustomEvent");
|
|
129
|
+
_defineProperty(Constants, "customEventName", "customEventName");
|
|
130
|
+
_defineProperty(Constants, "customEventValue", "customEventValue");
|
|
131
|
+
_defineProperty(Constants, "Hidden", "Hidden");
|
|
127
132
|
_defineProperty(Constants, "EndConversationDueToOverflow", "endconversationduetooverflow");
|
|
128
133
|
export const Regex = (_class = /*#__PURE__*/_createClass(function Regex() {
|
|
129
134
|
_classCallCheck(this, Regex);
|
|
@@ -223,6 +223,7 @@ export let TelemetryEvent;
|
|
|
223
223
|
TelemetryEvent["SystemMessageReceived"] = "SystemMessageReceived";
|
|
224
224
|
TelemetryEvent["RehydrateMessageReceived"] = "RehydrateMessageReceived";
|
|
225
225
|
TelemetryEvent["CustomContextReceived"] = "CustomContextReceived";
|
|
226
|
+
TelemetryEvent["CustomEventAction"] = "CustomEventAction";
|
|
226
227
|
TelemetryEvent["NetworkDisconnected"] = "NetworkDisconnected";
|
|
227
228
|
TelemetryEvent["NetworkReconnected"] = "NetworkReconnected";
|
|
228
229
|
TelemetryEvent["LinkModePostChatWorkflowStarted"] = "LinkModePostChatWorkflowStarted";
|
package/lib/esm/common/utils.js
CHANGED
|
@@ -454,6 +454,23 @@ export function getDeviceType() {
|
|
|
454
454
|
return "standard";
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
|
+
|
|
458
|
+
//Bots expect a payload containing:
|
|
459
|
+
//1. customEventName: this should be string describe the event name
|
|
460
|
+
//2. customEventValue: given the value is from customer with unknown type, it is required to stringify the payload later
|
|
461
|
+
export const isValidCustomEvent = payload => {
|
|
462
|
+
if (Constants.customEventName in payload && payload.customEventName && typeof payload.customEventName === Constants.String && Constants.customEventValue in payload && payload.customEventValue) return true;
|
|
463
|
+
return false;
|
|
464
|
+
};
|
|
465
|
+
export const getCustomEventValue = customEventPayload => {
|
|
466
|
+
let returnVal = "";
|
|
467
|
+
try {
|
|
468
|
+
returnVal = typeof customEventPayload.customEventValue === Constants.String ? customEventPayload.customEventValue : JSON.stringify(customEventPayload.customEventValue);
|
|
469
|
+
} catch (error) {
|
|
470
|
+
console.error(error);
|
|
471
|
+
}
|
|
472
|
+
return returnVal;
|
|
473
|
+
};
|
|
457
474
|
export function isEndConversationDueToOverflowActivity(activity) {
|
|
458
475
|
var _activity$channelData, _activity$channelData2;
|
|
459
476
|
return (activity === null || activity === void 0 ? void 0 : (_activity$channelData = activity.channelData) === null || _activity$channelData === void 0 ? void 0 : _activity$channelData.tags) && Array.isArray(activity === null || activity === void 0 ? void 0 : (_activity$channelData2 = activity.channelData) === null || _activity$channelData2 === void 0 ? void 0 : _activity$channelData2.tags) && activity.channelData.tags.includes(Constants.EndConversationDueToOverflow);
|
|
@@ -65,7 +65,6 @@ export const ChatButtonStateful = props => {
|
|
|
65
65
|
};
|
|
66
66
|
const outOfOfficeStyleProps = Object.assign({}, defaultOutOfOfficeChatButtonStyleProps, outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.styleProps);
|
|
67
67
|
const controlProps = {
|
|
68
|
-
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps),
|
|
69
68
|
id: "oc-lcw-chat-button",
|
|
70
69
|
dir: state.domainStates.globalDir,
|
|
71
70
|
titleText: "Let's Chat!",
|
|
@@ -74,7 +73,8 @@ export const ChatButtonStateful = props => {
|
|
|
74
73
|
unreadMessageCount: state.appStates.unreadMessageCount ? state.appStates.unreadMessageCount > Constants.maximumUnreadMessageCount ? (_props$buttonProps = props.buttonProps) === null || _props$buttonProps === void 0 ? void 0 : (_props$buttonProps$co = _props$buttonProps.controlProps) === null || _props$buttonProps$co === void 0 ? void 0 : _props$buttonProps$co.largeUnreadMessageString : state.appStates.unreadMessageCount.toString() : "0",
|
|
75
74
|
unreadMessageString: (_props$buttonProps2 = props.buttonProps) === null || _props$buttonProps2 === void 0 ? void 0 : (_props$buttonProps2$c = _props$buttonProps2.controlProps) === null || _props$buttonProps2$c === void 0 ? void 0 : _props$buttonProps2$c.unreadMessageString,
|
|
76
75
|
// Regular chat button onClick - this will always take precedence
|
|
77
|
-
onClick: () => ref.current()
|
|
76
|
+
onClick: () => ref.current(),
|
|
77
|
+
...(buttonProps === null || buttonProps === void 0 ? void 0 : buttonProps.controlProps)
|
|
78
78
|
};
|
|
79
79
|
const outOfOfficeControlProps = {
|
|
80
80
|
// Only take specific properties from outOfOfficeButtonProps, never onClick
|
|
@@ -83,7 +83,6 @@ export const ChatButtonStateful = props => {
|
|
|
83
83
|
titleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro === void 0 ? void 0 : _outOfOfficeButtonPro.titleText) || "We're Offline",
|
|
84
84
|
subtitleText: (outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : (_outOfOfficeButtonPro2 = outOfOfficeButtonProps.controlProps) === null || _outOfOfficeButtonPro2 === void 0 ? void 0 : _outOfOfficeButtonPro2.subtitleText) || "No agents available",
|
|
85
85
|
unreadMessageString: (_props$buttonProps3 = props.buttonProps) === null || _props$buttonProps3 === void 0 ? void 0 : (_props$buttonProps3$c = _props$buttonProps3.controlProps) === null || _props$buttonProps3$c === void 0 ? void 0 : _props$buttonProps3$c.unreadMessageString,
|
|
86
|
-
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps),
|
|
87
86
|
// Out-of-office specific onClick - this will ALWAYS take precedence
|
|
88
87
|
onClick: () => {
|
|
89
88
|
if (state.appStates.isMinimized) {
|
|
@@ -96,7 +95,8 @@ export const ChatButtonStateful = props => {
|
|
|
96
95
|
type: LiveChatWidgetActionType.SET_CONVERSATION_STATE,
|
|
97
96
|
payload: ConversationState.OutOfOffice
|
|
98
97
|
});
|
|
99
|
-
}
|
|
98
|
+
},
|
|
99
|
+
...(outOfOfficeButtonProps === null || outOfOfficeButtonProps === void 0 ? void 0 : outOfOfficeButtonProps.controlProps)
|
|
100
100
|
};
|
|
101
101
|
useEffect(() => {
|
|
102
102
|
TelemetryHelper.logLoadingEvent(LogLevel.INFO, {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Constants } from "../../../common/Constants";
|
|
2
|
+
import { TelemetryHelper } from "../../../common/telemetry/TelemetryHelper";
|
|
3
|
+
import { LogLevel, TelemetryEvent } from "../../../common/telemetry/TelemetryConstants";
|
|
4
|
+
import { getCustomEventValue, isValidCustomEvent } from "../../../common/utils";
|
|
5
|
+
export const customEventCallback = facadeChatSDK => event => {
|
|
6
|
+
if (!(Constants.payload in event)) return;
|
|
7
|
+
if (isValidCustomEvent(event.payload)) {
|
|
8
|
+
const customEventPayload = event.payload;
|
|
9
|
+
try {
|
|
10
|
+
const customEventValueStr = getCustomEventValue(customEventPayload);
|
|
11
|
+
const customEventName = customEventPayload.customEventName;
|
|
12
|
+
const messageMeta = {
|
|
13
|
+
customEvent: Constants.true,
|
|
14
|
+
customEventName: customEventName,
|
|
15
|
+
customEventValue: customEventValueStr
|
|
16
|
+
};
|
|
17
|
+
const messagePayload = {
|
|
18
|
+
content: "",
|
|
19
|
+
tags: [Constants.Hidden],
|
|
20
|
+
metadata: messageMeta,
|
|
21
|
+
timestamp: new Date()
|
|
22
|
+
};
|
|
23
|
+
facadeChatSDK.sendMessage(messagePayload);
|
|
24
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.DEBUG, {
|
|
25
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
26
|
+
Description: "Sent customEvent.",
|
|
27
|
+
CustomProperties: {
|
|
28
|
+
customEventName,
|
|
29
|
+
lengthCustomEventValue: customEventValueStr.length
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
TelemetryHelper.logActionEventToAllTelemetry(LogLevel.ERROR, {
|
|
34
|
+
Event: TelemetryEvent.CustomEventAction,
|
|
35
|
+
Description: "Failed to process CustomEvent.",
|
|
36
|
+
ExceptionDetails: {
|
|
37
|
+
error
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const subscribeToSendCustomEvent = (broadcastService, facadeChatSDK, customEventCallback) => {
|
|
44
|
+
broadcastService.getMessageByEventName(Constants.sendCustomEvent).subscribe(customEventCallback(facadeChatSDK));
|
|
45
|
+
};
|
|
@@ -32,9 +32,11 @@ import htmlTextMiddleware from "../../webchatcontainerstateful/webchatcontroller
|
|
|
32
32
|
import preProcessingMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/preProcessingMiddleware";
|
|
33
33
|
import sanitizationMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/sanitizationMiddleware";
|
|
34
34
|
import { Constants } from "../../../common/Constants";
|
|
35
|
+
import createCustomEventMiddleware from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/customEventMiddleware";
|
|
35
36
|
import { ConversationState } from "../../../contexts/common/ConversationState";
|
|
36
37
|
import { executeReducer } from "../../../contexts/createReducer";
|
|
37
38
|
import { createQueueOverflowMiddleware } from "../../webchatcontainerstateful/webchatcontroller/middlewares/storemiddlewares/queueOverflowHandlerMiddleware";
|
|
39
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
38
40
|
|
|
39
41
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
40
42
|
export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endChat) => {
|
|
@@ -113,7 +115,7 @@ export const initWebChatComposer = (props, state, dispatch, facadeChatSDK, endCh
|
|
|
113
115
|
};
|
|
114
116
|
webChatStore = createStore({},
|
|
115
117
|
//initial state
|
|
116
|
-
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), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
118
|
+
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), createCustomEventMiddleware(BroadcastService), createQueueOverflowMiddleware(state, dispatch), channelDataMiddleware(addConversationalSurveyTagsCallback), createConversationEndMiddleware(conversationEndCallback, startConversationalSurveyCallback, endConversationalSurveyCallback), createDataMaskingMiddleware((_state$domainStates$l3 = state.domainStates.liveChatConfig) === null || _state$domainStates$l3 === void 0 ? void 0 : _state$domainStates$l3.DataMaskingInfo), createMessageTimeStampMiddleware, createMessageSequenceIdOverrideMiddleware, gifUploadMiddleware, htmlPlayerMiddleware, htmlTextMiddleware(honorsTargetInHTMLLinks), createMaxMessageSizeValidator(localizedTexts), sanitizationMiddleware,
|
|
117
119
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
120
|
...(((_props$webChatContain7 = props.webChatContainerProps) === null || _props$webChatContain7 === void 0 ? void 0 : _props$webChatContain7.storeMiddlewares) ?? []));
|
|
119
121
|
WebChatStoreLoader.store = webChatStore;
|
|
@@ -53,6 +53,7 @@ import { startProactiveChat } from "../common/startProactiveChat";
|
|
|
53
53
|
import useChatAdapterStore from "../../../hooks/useChatAdapterStore";
|
|
54
54
|
import useChatContextStore from "../../../hooks/useChatContextStore";
|
|
55
55
|
import useFacadeSDKStore from "../../../hooks/useFacadeChatSDKStore";
|
|
56
|
+
import { customEventCallback, subscribeToSendCustomEvent } from "../common/customEventHandler";
|
|
56
57
|
let uiTimer;
|
|
57
58
|
export const LiveChatWidgetStateful = props => {
|
|
58
59
|
var _props$webChatContain, _props$webChatContain2, _props$webChatContain3, _props$webChatContain4, _props$webChatContain5, _props$webChatContain6, _props$webChatContain7, _props$webChatContain8, _props$webChatContain9, _props$styleProps, _props$webChatContain10, _props$webChatContain11, _props$controlProps, _props$controlProps3, _state$appStates7, _props$webChatContain15, _state$appStates14, _props$webChatContain17, _props$webChatContain18, _props$controlProps12, _props$draggableChatW, _props$draggableChatW2, _props$draggableChatW3, _props$draggableChatW4, _props$draggableChatW5, _livechatProps$webCha, _livechatProps$styleP, _livechatProps$contro, _livechatProps$contro2, _livechatProps$compon, _livechatProps$contro3, _livechatProps$compon2, _livechatProps$contro4, _livechatProps$compon3, _livechatProps$contro5, _livechatProps$compon4, _livechatProps$contro6, _livechatProps$compon5, _livechatProps$contro7, _livechatProps$compon6, _livechatProps$contro8, _livechatProps$compon7, _livechatProps$contro9, _livechatProps$compon8, _livechatProps$contro10, _livechatProps$contro11, _livechatProps$compon9, _livechatProps$contro12, _livechatProps$compon10, _livechatProps$contro13, _livechatProps$compon11, _livechatProps$compon12, _livechatProps$compon13;
|
|
@@ -413,7 +414,7 @@ export const LiveChatWidgetStateful = props => {
|
|
|
413
414
|
BroadcastService.getMessageByEventName(BroadcastEvent.StartChat).subscribe(msg => {
|
|
414
415
|
var _msg$payload5, _msg$payload6, _msg$payload7, _msg$payload9, _inMemoryState$appSta2, _inMemoryState$appSta3, _inMemoryState$appSta4;
|
|
415
416
|
// If chat is out of operating hours chat widget sets the conversation state to OutOfOffice.
|
|
416
|
-
if (state.appStates.outsideOperatingHours
|
|
417
|
+
if (state.appStates.outsideOperatingHours && state.appStates.conversationState !== ConversationState.Active) {
|
|
417
418
|
dispatch({
|
|
418
419
|
type: LiveChatWidgetActionType.SET_MINIMIZED,
|
|
419
420
|
payload: false
|
|
@@ -580,6 +581,9 @@ export const LiveChatWidgetStateful = props => {
|
|
|
580
581
|
}
|
|
581
582
|
});
|
|
582
583
|
|
|
584
|
+
// subscribe custom event
|
|
585
|
+
subscribeToSendCustomEvent(BroadcastService, facadeChatSDK, customEventCallback);
|
|
586
|
+
|
|
583
587
|
// Check for TPC and log in telemetry if blocked
|
|
584
588
|
isCookieAllowed();
|
|
585
589
|
return () => {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/******
|
|
2
|
+
* CustomEventMiddleware
|
|
3
|
+
*
|
|
4
|
+
* This middleware is invoked when a custom event is received.
|
|
5
|
+
* The callback is then invoked to handle the custom event.
|
|
6
|
+
******/
|
|
7
|
+
|
|
8
|
+
import { Constants } from "../../../../../common/Constants";
|
|
9
|
+
import { WebChatActionType } from "../../enums/WebChatActionType";
|
|
10
|
+
export const isValidCustomEvent = activity => {
|
|
11
|
+
var _activity$channelData, _activity$channelData2, _activity$channelData3, _activity$channelData4, _activity$channelData5, _activity$channelData6, _activity$channelData7, _activity$from, _activity$channelData8, _activity$channelData9, _activity$channelData10, _activity$channelData11;
|
|
12
|
+
return !!(activity !== null && activity !== void 0 && (_activity$channelData = activity.channelData) !== null && _activity$channelData !== void 0 && (_activity$channelData2 = _activity$channelData.metadata) !== null && _activity$channelData2 !== void 0 && _activity$channelData2.customEvent && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData3 = activity.channelData) === null || _activity$channelData3 === void 0 ? void 0 : (_activity$channelData4 = _activity$channelData3.metadata) === null || _activity$channelData4 === void 0 ? void 0 : _activity$channelData4.customEvent) === Constants.String && (activity === null || activity === void 0 ? void 0 : (_activity$channelData5 = activity.channelData) === null || _activity$channelData5 === void 0 ? void 0 : (_activity$channelData6 = _activity$channelData5.metadata) === null || _activity$channelData6 === void 0 ? void 0 : (_activity$channelData7 = _activity$channelData6.customEvent) === null || _activity$channelData7 === void 0 ? void 0 : _activity$channelData7.toLowerCase()) === Constants.true && (activity === null || activity === void 0 ? void 0 : (_activity$from = activity.from) === null || _activity$from === void 0 ? void 0 : _activity$from.role) !== Constants.userMessageTag && typeof (activity === null || activity === void 0 ? void 0 : (_activity$channelData8 = activity.channelData) === null || _activity$channelData8 === void 0 ? void 0 : (_activity$channelData9 = _activity$channelData8.metadata) === null || _activity$channelData9 === void 0 ? void 0 : _activity$channelData9.customEventName) === Constants.String && activity !== null && activity !== void 0 && (_activity$channelData10 = activity.channelData) !== null && _activity$channelData10 !== void 0 && (_activity$channelData11 = _activity$channelData10.metadata) !== null && _activity$channelData11 !== void 0 && _activity$channelData11.customEventValue);
|
|
13
|
+
};
|
|
14
|
+
const createCustomEventMiddleware = broadcastservice => () => next => action => {
|
|
15
|
+
var _action$payload;
|
|
16
|
+
if ((action === null || action === void 0 ? void 0 : action.type) == WebChatActionType.DIRECT_LINE_INCOMING_ACTIVITY && (_action$payload = action.payload) !== null && _action$payload !== void 0 && _action$payload.activity) {
|
|
17
|
+
const activity = action.payload.activity;
|
|
18
|
+
if (isValidCustomEvent(activity)) {
|
|
19
|
+
const customEvent = {
|
|
20
|
+
eventName: Constants.onCustomEvent,
|
|
21
|
+
payload: {
|
|
22
|
+
messageId: activity.messageid ?? activity.id,
|
|
23
|
+
customEventName: activity.channelData.metadata.customEventName,
|
|
24
|
+
customEventValue: activity.channelData.metadata.customEventValue
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
broadcastservice.postMessage(customEvent);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return next(action);
|
|
32
|
+
};
|
|
33
|
+
export default createCustomEventMiddleware;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -96,6 +96,11 @@ export declare class Constants {
|
|
|
96
96
|
static readonly OCOriginalMessageId = "OriginalMessageId";
|
|
97
97
|
static readonly WebchatSequenceIdAttribute = "webchat:sequence-id";
|
|
98
98
|
static readonly MessageSequenceIdOverride = "MessageSequenceIdOverride";
|
|
99
|
+
static readonly sendCustomEvent = "sendCustomEvent";
|
|
100
|
+
static readonly onCustomEvent = "onCustomEvent";
|
|
101
|
+
static readonly customEventName = "customEventName";
|
|
102
|
+
static readonly customEventValue = "customEventValue";
|
|
103
|
+
static readonly Hidden = "Hidden";
|
|
99
104
|
static readonly EndConversationDueToOverflow = "endconversationduetooverflow";
|
|
100
105
|
}
|
|
101
106
|
export declare const Regex: {
|
|
@@ -211,6 +211,7 @@ export declare enum TelemetryEvent {
|
|
|
211
211
|
SystemMessageReceived = "SystemMessageReceived",
|
|
212
212
|
RehydrateMessageReceived = "RehydrateMessageReceived",
|
|
213
213
|
CustomContextReceived = "CustomContextReceived",
|
|
214
|
+
CustomEventAction = "CustomEventAction",
|
|
214
215
|
NetworkDisconnected = "NetworkDisconnected",
|
|
215
216
|
NetworkReconnected = "NetworkReconnected",
|
|
216
217
|
LinkModePostChatWorkflowStarted = "LinkModePostChatWorkflowStarted",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FacadeChatSDK } from "./facades/FacadeChatSDK";
|
|
2
2
|
import { ITimer } from "./interfaces/ITimer";
|
|
3
|
+
import * as CustomEventType from "../contexts/common/CustomEventType";
|
|
3
4
|
export declare const setTabIndices: (elements: HTMLElement[] | null, tabIndexMap: Map<string, number>, shouldBeFocusable: boolean) => void;
|
|
4
5
|
export declare const findParentFocusableElementsWithoutChildContainer: (elementId: string) => HTMLElement[] | null;
|
|
5
6
|
export declare const findAllFocusableElement: (parent: string | HTMLElement) => any[] | null;
|
|
@@ -47,6 +48,8 @@ export declare const formatTemplateString: (templateMessage: string, values: any
|
|
|
47
48
|
export declare const parseLowerCaseString: (property: string | boolean | undefined) => string;
|
|
48
49
|
export declare const setOcUserAgent: (chatSDK: any) => void;
|
|
49
50
|
export declare function getDeviceType(): string;
|
|
51
|
+
export declare const isValidCustomEvent: (payload: object) => boolean;
|
|
52
|
+
export declare const getCustomEventValue: (customEventPayload: CustomEventType.ICustomEvent) => string;
|
|
50
53
|
export declare function isEndConversationDueToOverflowActivity(activity: {
|
|
51
54
|
channelData?: {
|
|
52
55
|
tags?: string[];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { FacadeChatSDK } from "../../../common/facades/FacadeChatSDK";
|
|
2
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
3
|
+
export declare const customEventCallback: (facadeChatSDK: FacadeChatSDK) => (event: object) => void;
|
|
4
|
+
export declare const subscribeToSendCustomEvent: (broadcastService: typeof BroadcastService, facadeChatSDK: FacadeChatSDK, customEventCallback: (fackageSdK: FacadeChatSDK) => (event: object) => void) => void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/******
|
|
2
|
+
* CustomEventMiddleware
|
|
3
|
+
*
|
|
4
|
+
* This middleware is invoked when a custom event is received.
|
|
5
|
+
* The callback is then invoked to handle the custom event.
|
|
6
|
+
******/
|
|
7
|
+
import { IWebChatAction } from "../../../interfaces/IWebChatAction";
|
|
8
|
+
import { BroadcastService } from "@microsoft/omnichannel-chat-components";
|
|
9
|
+
export declare const isValidCustomEvent: (activity: {
|
|
10
|
+
channelData?: {
|
|
11
|
+
metadata?: {
|
|
12
|
+
customEvent?: string;
|
|
13
|
+
customEventName?: string;
|
|
14
|
+
customEventValue?: unknown;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
from?: {
|
|
18
|
+
role: string;
|
|
19
|
+
};
|
|
20
|
+
}) => boolean;
|
|
21
|
+
declare const createCustomEventMiddleware: (broadcastservice: typeof BroadcastService) => () => (next: (action: IWebChatAction) => void) => (action: IWebChatAction) => void;
|
|
22
|
+
export default createCustomEventMiddleware;
|