@botfabrik/engine-webclient 4.96.6 → 4.96.10
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 +5 -0
- package/dist/auth/auth-pages.d.ts +6 -0
- package/dist/auth/auth-pages.js +102 -0
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.js +145 -0
- package/dist/auth/relay-state.d.ts +2 -0
- package/dist/auth/relay-state.js +39 -0
- package/dist/auth/ttl-cache.d.ts +14 -0
- package/dist/auth/ttl-cache.js +52 -0
- package/dist/client/assets/index-BKoo63hO.js +124 -0
- package/dist/client/assets/{index-DyL1BpAK.js.map → index-BKoo63hO.js.map} +1 -1
- package/dist/client/assets/{index-CEalwQZJ.css → index-BdXpbt-o.css} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +4 -0
- package/dist/createSessionInfo.d.ts +3 -3
- package/dist/createSessionInfo.js +35 -9
- package/dist/createSessionInfo.test.js +27 -3
- package/dist/index.d.ts +3 -140
- package/dist/index.js +90 -79
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +2 -2
- package/dist/requestSessionData.d.ts +1 -2
- package/dist/requestSessionData.js +2 -2
- package/dist/speechToText.d.ts +1 -5
- package/dist/types.d.ts +170 -0
- package/dist/types.js +8 -0
- package/package.json +9 -5
- package/dist/client/assets/index-DyL1BpAK.js +0 -124
package/dist/index.js
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
18
|
};
|
|
5
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.CLIENT_TYPE = exports.Devices = void 0;
|
|
7
20
|
const engine_domain_1 = require("@botfabrik/engine-domain");
|
|
8
21
|
const engine_transcript_export_1 = require("@botfabrik/engine-transcript-export");
|
|
9
22
|
const express_1 = require("express");
|
|
10
|
-
const node_crypto_1 = require("node:crypto");
|
|
11
23
|
const package_json_1 = require("../package.json");
|
|
24
|
+
const auth_1 = require("./auth");
|
|
25
|
+
const constants_1 = require("./constants");
|
|
12
26
|
const createSessionInfo_1 = __importDefault(require("./createSessionInfo"));
|
|
13
27
|
const extractLocale_1 = __importDefault(require("./extractLocale"));
|
|
14
28
|
const getSupportedClientLocale_1 = __importDefault(require("./getSupportedClientLocale"));
|
|
@@ -17,18 +31,11 @@ const middleware_1 = __importDefault(require("./middleware"));
|
|
|
17
31
|
const requestSessionData_1 = __importDefault(require("./requestSessionData"));
|
|
18
32
|
const setTranslations_1 = __importDefault(require("./setTranslations"));
|
|
19
33
|
const speechToText_1 = __importDefault(require("./speechToText"));
|
|
34
|
+
const types_1 = require("./types");
|
|
20
35
|
const views_1 = __importDefault(require("./views"));
|
|
21
|
-
|
|
22
|
-
const USER_ID_COOKIE_NAME = 'user-id';
|
|
23
|
-
var Devices;
|
|
24
|
-
(function (Devices) {
|
|
25
|
-
Devices["All"] = "all";
|
|
26
|
-
Devices["Mobile"] = "mobile";
|
|
27
|
-
Devices["Desktop"] = "desktop";
|
|
28
|
-
Devices["None"] = "none";
|
|
29
|
-
})(Devices || (exports.Devices = Devices = {}));
|
|
36
|
+
__exportStar(require("./types"), exports);
|
|
30
37
|
exports.default = (clientName, environment, props) => async (bot) => {
|
|
31
|
-
const logger = bot.logger.child({ clientType:
|
|
38
|
+
const logger = bot.logger.child({ clientType: constants_1.CLIENT_TYPE, clientName });
|
|
32
39
|
// serve transcript pdf
|
|
33
40
|
bot.webserver.express.use('/transcript-pdf/:sessionId', async (req, res) => {
|
|
34
41
|
const sessionId = req.params['sessionId'];
|
|
@@ -64,21 +71,6 @@ exports.default = (clientName, environment, props) => async (bot) => {
|
|
|
64
71
|
});
|
|
65
72
|
}
|
|
66
73
|
bot.webserver.express.use(`/${clientName}/embed`, (0, express_1.static)(__dirname + '/embed', serveStaticOptions));
|
|
67
|
-
// TODO: remove in future versions
|
|
68
|
-
bot.webserver.express.get(`/${clientName}/me/session`, (req, res) => {
|
|
69
|
-
logger.info(`Old client access get token from ip: ${req.ip}`);
|
|
70
|
-
const cookies = req.cookies || {};
|
|
71
|
-
const sessionId = cookies[SESSION_ID_COOKIE_NAME] || (0, node_crypto_1.randomUUID)();
|
|
72
|
-
const userId = cookies[USER_ID_COOKIE_NAME] ||
|
|
73
|
-
cookies['bubble-chat-user-id'] || // TODO: remove in future versions
|
|
74
|
-
(0, node_crypto_1.randomUUID)();
|
|
75
|
-
res.status(201).json({ sessionIdToken: sessionId, userIdToken: userId });
|
|
76
|
-
});
|
|
77
|
-
// TODO: remove in future versions
|
|
78
|
-
bot.webserver.express.delete(`/${clientName}/me/session`, (req, res) => {
|
|
79
|
-
logger.info(`Old client access delete token from ip: ${req.ip}`);
|
|
80
|
-
res.sendStatus(204);
|
|
81
|
-
});
|
|
82
74
|
bot.webserver.express.get(`/${clientName}/logo.svg`, (_req, res) => {
|
|
83
75
|
res.redirect(`/cms/chatbot/design/logo.svg?client=${clientName}`);
|
|
84
76
|
});
|
|
@@ -97,6 +89,11 @@ exports.default = (clientName, environment, props) => async (bot) => {
|
|
|
97
89
|
sendConfigurationToClient(socket, props, bot, clientName);
|
|
98
90
|
socket.on('start-chat', onStartChat(socket, props, bot, clientName, environment, logger));
|
|
99
91
|
socket.on('terminate-session', onTerminateSession(socket, bot));
|
|
92
|
+
if (props.auth) {
|
|
93
|
+
socket.on('login-requested', (data) => {
|
|
94
|
+
(0, auth_1.storeLoginRequestToken)(data.loginRequestToken, socket.id);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
100
97
|
}
|
|
101
98
|
catch (error) {
|
|
102
99
|
logger.error('Error while connecting webclient with backend.');
|
|
@@ -105,6 +102,9 @@ exports.default = (clientName, environment, props) => async (bot) => {
|
|
|
105
102
|
socket.emit('action', engine_domain_1.Actions.sendMessageToGuest(errorMessage));
|
|
106
103
|
}
|
|
107
104
|
});
|
|
105
|
+
if (props.auth) {
|
|
106
|
+
(0, auth_1.setUpSamlAuth)(bot, props.auth, clientName, nsp);
|
|
107
|
+
}
|
|
108
108
|
const client = {
|
|
109
109
|
name: `${clientName}Webclient`,
|
|
110
110
|
middleware: (0, middleware_1.default)(clientName, nsp),
|
|
@@ -134,59 +134,70 @@ const onTerminateSession = (socket, bot) => async ({ sessionId, // passed if the
|
|
|
134
134
|
socket.leave(sessionId);
|
|
135
135
|
await session.dispatch(engine_domain_1.Actions.guestDisconnected(sessionId));
|
|
136
136
|
};
|
|
137
|
-
const onStartChat = (socket, props, bot, clientName, environment, logger) => async ({ sessionId: sessionIdFromClient, userId: defaultUserId, querystrings,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
socket.emit('enable-conversation-rating', {
|
|
155
|
-
rating: sessionInfo.client.payload.conversationRating,
|
|
137
|
+
const onStartChat = (socket, props, bot, clientName, environment, logger) => async ({ sessionId: sessionIdFromClient, userId: defaultUserId, querystrings, loginToken, }) => {
|
|
138
|
+
try {
|
|
139
|
+
const authenticatedUser = (0, auth_1.verifyLoginToken)(loginToken, props.auth, logger);
|
|
140
|
+
console.log('Authenticated user:', authenticatedUser);
|
|
141
|
+
const locale = (0, extractLocale_1.default)(querystrings, socket.request.headers['accept-language']);
|
|
142
|
+
const sessionsCollection = bot.store.db.collection('sessions');
|
|
143
|
+
const { sessionId, sessionInfo: defaultSessionInfo, isNew, } = await (0, requestSessionData_1.default)(sessionIdFromClient, querystrings, sessionsCollection, clientName, props);
|
|
144
|
+
// create a channel for each session
|
|
145
|
+
socket.join(sessionId);
|
|
146
|
+
const sessionInfo = await (0, createSessionInfo_1.default)(socket, clientName, environment, defaultSessionInfo, defaultUserId, locale, querystrings, authenticatedUser, props)();
|
|
147
|
+
const session = await bot.createSession(sessionId, sessionInfo);
|
|
148
|
+
sendConfigurationToClient(socket, props, bot, clientName);
|
|
149
|
+
// sending persisted state to client
|
|
150
|
+
const previousConversations = await (0, loadPreviousConversation_1.default)(bot.store, sessionId);
|
|
151
|
+
socket.emit('restore-client-state', {
|
|
152
|
+
sessionId,
|
|
153
|
+
messages: previousConversations,
|
|
156
154
|
});
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
await session.dispatch(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
sessionsCollection.updateOne({ _id: sessionId }, { $set: { 'sessionInfo.client.payload.conversationRating': rating } });
|
|
171
|
-
session.dispatch({
|
|
172
|
-
type: engine_domain_1.ActionTypes.CONVERSATION_RATING_FROM_GUEST,
|
|
173
|
-
payload: { rating },
|
|
155
|
+
// enable conversation rating
|
|
156
|
+
if (props.enableConversationRating) {
|
|
157
|
+
socket.emit('enable-conversation-rating', {
|
|
158
|
+
rating: sessionInfo.client.payload.conversationRating,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Notify middlewares about a connected or reconnected guest
|
|
162
|
+
await session.dispatch(engine_domain_1.Actions.guestConnected(sessionId));
|
|
163
|
+
if (isNew && props.getStartedAction) {
|
|
164
|
+
await session.dispatch(props.getStartedAction);
|
|
165
|
+
}
|
|
166
|
+
registerListener(socket, 'action', async (action) => {
|
|
167
|
+
await session.dispatch(JSON.parse(action));
|
|
174
168
|
});
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
169
|
+
registerListener(socket, 'disconnect', async () => {
|
|
170
|
+
await session.dispatch(engine_domain_1.Actions.guestDisconnected(sessionId));
|
|
171
|
+
});
|
|
172
|
+
registerListener(socket, 'conversation-rating', async (rating) => {
|
|
173
|
+
sessionsCollection.updateOne({ _id: sessionId }, {
|
|
174
|
+
$set: { 'sessionInfo.client.payload.conversationRating': rating },
|
|
175
|
+
});
|
|
176
|
+
session.dispatch({
|
|
177
|
+
type: engine_domain_1.ActionTypes.CONVERSATION_RATING_FROM_GUEST,
|
|
178
|
+
payload: { rating },
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
registerListener(socket, 'audio-message', async (buffer) => {
|
|
182
|
+
if (props.speech) {
|
|
183
|
+
try {
|
|
184
|
+
const text = await (0, speechToText_1.default)(props.speech, session.translator.locale, buffer);
|
|
185
|
+
if (text && text.length) {
|
|
186
|
+
socket.emit('speech-transcription', text);
|
|
187
|
+
session.dispatch(engine_domain_1.Actions.receiveTextMessageFromGuest(text));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
logger.error(error);
|
|
183
192
|
}
|
|
184
193
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
logger.error('Error while starting chat session:', error);
|
|
198
|
+
socket.disconnect(true);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
190
201
|
};
|
|
191
202
|
const registerListener = (socket, event, listener) => {
|
|
192
203
|
// remove all listeners for the event to avoid multiple listeners
|
|
@@ -201,7 +212,8 @@ const sendConfigurationToClient = (socket, props, bot, clientName) => {
|
|
|
201
212
|
(0, setTranslations_1.default)(socket, bot, clientLocale, clientName);
|
|
202
213
|
const settings = {
|
|
203
214
|
version: package_json_1.version,
|
|
204
|
-
|
|
215
|
+
requiresUserAuthentication: !!props.auth,
|
|
216
|
+
enableStartScreen: !!props.enableStartScreen || !!props.auth,
|
|
205
217
|
enableStandaloneView: !!props.enableStandaloneView,
|
|
206
218
|
enableTranscriptExportPdf: !!props.enableTranscriptExportPdf,
|
|
207
219
|
enableTranscriptExportEmail: !!props.enableTranscriptExportEmail,
|
|
@@ -212,11 +224,10 @@ const sendConfigurationToClient = (socket, props, bot, clientName) => {
|
|
|
212
224
|
};
|
|
213
225
|
socket.emit('set-settings', settings);
|
|
214
226
|
if (props.expandChatWindowAtStart &&
|
|
215
|
-
props.expandChatWindowAtStart !== Devices.None) {
|
|
227
|
+
props.expandChatWindowAtStart !== types_1.Devices.None) {
|
|
216
228
|
socket.emit('expand-window', {
|
|
217
229
|
devices: props.expandChatWindowAtStart,
|
|
218
230
|
initial: true,
|
|
219
231
|
});
|
|
220
232
|
}
|
|
221
233
|
};
|
|
222
|
-
exports.CLIENT_TYPE = 'webclient';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Middleware } from '@botfabrik/engine-domain';
|
|
2
2
|
import type { Namespace } from 'socket.io';
|
|
3
|
-
import type
|
|
3
|
+
import { type WebclientMiddlewareState } from '../types';
|
|
4
4
|
declare const _default: (clientName: string, nsp: Namespace) => Middleware<WebclientMiddlewareState>;
|
|
5
5
|
export default _default;
|
package/dist/middleware/index.js
CHANGED
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const engine_domain_1 = require("@botfabrik/engine-domain");
|
|
7
7
|
const engine_utils_1 = require("@botfabrik/engine-utils");
|
|
8
|
-
const __1 = require("..");
|
|
9
8
|
const setTranslations_1 = __importDefault(require("../setTranslations"));
|
|
9
|
+
const types_1 = require("../types");
|
|
10
10
|
exports.default = (clientName, nsp) => async (bot) => {
|
|
11
11
|
return async (next, _state, action, session) => {
|
|
12
12
|
const sessionInfo = session.getSessionInfo();
|
|
@@ -57,7 +57,7 @@ const sendToChatClient = async (nsp, session, action) => {
|
|
|
57
57
|
};
|
|
58
58
|
const expandChatWindow = (nsp, session, action) => {
|
|
59
59
|
const devices = action.payload?.devices;
|
|
60
|
-
if (!!devices && devices !==
|
|
60
|
+
if (!!devices && devices !== types_1.Devices.None) {
|
|
61
61
|
nsp
|
|
62
62
|
.to(session.id)
|
|
63
63
|
.emit('expand-window', { devices: action.payload.devices });
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { SessionInfo } from '@botfabrik/engine-domain';
|
|
2
|
-
import {
|
|
3
|
-
import type { SessionInfoClientPayload, SessionInfoUserPayload } from './types';
|
|
2
|
+
import type { SessionInfoClientPayload, SessionInfoUserPayload, WebClientProps } from './types';
|
|
4
3
|
interface SessionData {
|
|
5
4
|
sessionId: string;
|
|
6
5
|
sessionInfo: SessionInfo<SessionInfoClientPayload, SessionInfoUserPayload>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const crypto_1 = require("crypto");
|
|
4
|
-
const
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
5
|
const requestSessionData = async (sessionId, querystrings, sessionsCollection, clientName, props) => {
|
|
6
6
|
const baseQuery = {
|
|
7
|
-
'sessionInfo.client.type':
|
|
7
|
+
'sessionInfo.client.type': constants_1.CLIENT_TYPE,
|
|
8
8
|
'sessionInfo.client.name': clientName,
|
|
9
9
|
};
|
|
10
10
|
let findSessionRecordQuery;
|
package/dist/speechToText.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
clientEmail: string;
|
|
3
|
-
privateKey: string;
|
|
4
|
-
contextPhrases?: any;
|
|
5
|
-
}
|
|
1
|
+
import type { SpeechToTextProps } from './types';
|
|
6
2
|
declare const speechToText: (speechProps: SpeechToTextProps, locale: string, speechBytes: any) => Promise<string>;
|
|
7
3
|
export default speechToText;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Action, SessionInfoUser } from '@botfabrik/engine-domain';
|
|
1
2
|
export type SessionInfoClientPayload = {
|
|
2
3
|
querystrings: any;
|
|
3
4
|
referrer: string;
|
|
@@ -9,3 +10,172 @@ export type ConversationRating = {
|
|
|
9
10
|
};
|
|
10
11
|
export type SessionInfoUserPayload = {};
|
|
11
12
|
export type WebclientMiddlewareState = {};
|
|
13
|
+
export type RequestUserInfos = (querystrings: any) => Promise<Partial<SessionInfoUser<SessionInfoUserPayload>>>;
|
|
14
|
+
export type RequestSessionRecordQuery = (params: {
|
|
15
|
+
querystrings: any;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
}) => Promise<Record<string, unknown>>;
|
|
18
|
+
export type MenuItemType = 'link' | 'action';
|
|
19
|
+
export type MenuItemIcon = 'mail' | 'phone' | 'scroll' | 'link';
|
|
20
|
+
export type MenuItemVisibility = 'always' | 'chat-only' | 'start-screen-only';
|
|
21
|
+
type BaseMenuItem = {
|
|
22
|
+
/**
|
|
23
|
+
* Unique key for this menu item.
|
|
24
|
+
* Used for translation as `header.menu.<id>`.
|
|
25
|
+
*/
|
|
26
|
+
id: string;
|
|
27
|
+
/**
|
|
28
|
+
* Icon displayed for this menu item.
|
|
29
|
+
*/
|
|
30
|
+
icon: MenuItemIcon;
|
|
31
|
+
/**
|
|
32
|
+
* If true, a divider (line) will be displayed after this item in the menu.
|
|
33
|
+
*/
|
|
34
|
+
withDivider?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Visibility of the menu item.
|
|
37
|
+
* - `always`: visible in all contexts (start screen, chat)
|
|
38
|
+
* - `chat-only`: visible only in the chat context
|
|
39
|
+
* - `start-screen-only`: visible only in the start screen context
|
|
40
|
+
*/
|
|
41
|
+
visibility: MenuItemVisibility;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Represents a menu item that points to a web link.
|
|
45
|
+
*/
|
|
46
|
+
type LinkMenuItem = BaseMenuItem & {
|
|
47
|
+
type: 'link';
|
|
48
|
+
/**
|
|
49
|
+
* The URL that the menu item points to.
|
|
50
|
+
*/
|
|
51
|
+
url: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Represents a menu item that triggers an action.
|
|
55
|
+
*/
|
|
56
|
+
type ActionMenuItem = BaseMenuItem & {
|
|
57
|
+
type: 'action';
|
|
58
|
+
/**
|
|
59
|
+
* The action to be executed when the menu item is clicked.
|
|
60
|
+
*/
|
|
61
|
+
action: Action;
|
|
62
|
+
};
|
|
63
|
+
export type MenuItem = LinkMenuItem | ActionMenuItem;
|
|
64
|
+
export interface SpeechToTextProps {
|
|
65
|
+
clientEmail: string;
|
|
66
|
+
privateKey: string;
|
|
67
|
+
contextPhrases?: any;
|
|
68
|
+
}
|
|
69
|
+
export type SamlAuthConfig = {
|
|
70
|
+
entryPoint: string;
|
|
71
|
+
issuer: string;
|
|
72
|
+
idpCert: string | string[];
|
|
73
|
+
/**
|
|
74
|
+
* Options are passed to the passport-saml strategy.
|
|
75
|
+
*/
|
|
76
|
+
options?: Record<string, unknown>;
|
|
77
|
+
};
|
|
78
|
+
export type Auth = {
|
|
79
|
+
/**
|
|
80
|
+
* JWT secret used to sign the login token.
|
|
81
|
+
*/
|
|
82
|
+
jwtSecret: string;
|
|
83
|
+
/**
|
|
84
|
+
* SAML authentication configuration.
|
|
85
|
+
*/
|
|
86
|
+
saml: SamlAuthConfig;
|
|
87
|
+
};
|
|
88
|
+
export interface WebClientProps {
|
|
89
|
+
getStartedAction?: Action;
|
|
90
|
+
requestUserInfos?: RequestUserInfos;
|
|
91
|
+
requestSessionRecordQuery?: RequestSessionRecordQuery;
|
|
92
|
+
speech?: SpeechToTextProps | undefined;
|
|
93
|
+
expandChatWindowAtStart?: Devices;
|
|
94
|
+
fabVisible?: boolean;
|
|
95
|
+
/**
|
|
96
|
+
* SAML authentication configuration for the web client.
|
|
97
|
+
* If set, users must authenticate via SAML before accessing the chat.
|
|
98
|
+
* If omitted, the chat is accessible without authentication.
|
|
99
|
+
*
|
|
100
|
+
* @default undefined
|
|
101
|
+
*/
|
|
102
|
+
auth?: Auth;
|
|
103
|
+
/**
|
|
104
|
+
* Displays a start screen before a new chat begins, useful for user opt-in (e.g., terms acceptance).
|
|
105
|
+
* Contains a text (`start-screen.intro` in Markdown), form fields, and a start button (`start-screen.start-chat`).
|
|
106
|
+
* No user data is collected until the user clicks the start button.
|
|
107
|
+
*
|
|
108
|
+
* @default false (unless `auth` is set)
|
|
109
|
+
*/
|
|
110
|
+
enableStartScreen?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Enables the conversation rating feature.
|
|
113
|
+
* When set to true, users will be prompted to rate the conversation
|
|
114
|
+
* on a scale from 1 to 5 stars and optionally provide written feedback.
|
|
115
|
+
*
|
|
116
|
+
* Useful for collecting quality insights, improving support, or tracking user satisfaction.
|
|
117
|
+
*
|
|
118
|
+
* @default false
|
|
119
|
+
*/
|
|
120
|
+
enableConversationRating?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Enables the option to export the chat transcript as a PDF file.
|
|
123
|
+
*
|
|
124
|
+
* When set to `true`, users can download the current chat conversation
|
|
125
|
+
* as a PDF document.
|
|
126
|
+
*
|
|
127
|
+
* @default false
|
|
128
|
+
*/
|
|
129
|
+
enableTranscriptExportPdf?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Enables the option to send the chat transcript to the user via email.
|
|
132
|
+
*
|
|
133
|
+
* When set to `true`, users can request the current chat conversation
|
|
134
|
+
* to be sent to their email address.
|
|
135
|
+
*
|
|
136
|
+
* @default false
|
|
137
|
+
*/
|
|
138
|
+
enableTranscriptExportEmail?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Enables the option to open the chat client in a standalone tab or window.
|
|
141
|
+
* When set to true, a button will be shown that allows users to open the chat
|
|
142
|
+
* outside of an embedded iframe, in a new browser tab.
|
|
143
|
+
*
|
|
144
|
+
* @default false
|
|
145
|
+
*/
|
|
146
|
+
enableStandaloneView?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Enables the display of general terms and conditions above the chat window.
|
|
149
|
+
* When set to true, a section containing general conditions (e.g. legal notice,
|
|
150
|
+
* consent information, disclaimers) will be shown above the chat interface.
|
|
151
|
+
*
|
|
152
|
+
* Useful for compliance, legal requirements, or informing users before starting a conversation.
|
|
153
|
+
*
|
|
154
|
+
* @default false
|
|
155
|
+
* */
|
|
156
|
+
enableGeneralConditions?: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* List of available chat commands that can be used in the input field.
|
|
159
|
+
*
|
|
160
|
+
* Each command may trigger a predefined action, insert a message template,
|
|
161
|
+
* or activate a special feature.
|
|
162
|
+
*
|
|
163
|
+
* Useful for advanced chat interactions, power-user features, or slash commands (e.g. /help, /end).
|
|
164
|
+
*
|
|
165
|
+
* @default []
|
|
166
|
+
* */
|
|
167
|
+
commands?: string[];
|
|
168
|
+
/**
|
|
169
|
+
* List of custom menu items displayed in the chat header.
|
|
170
|
+
*
|
|
171
|
+
* @default []
|
|
172
|
+
*/
|
|
173
|
+
menuItems?: MenuItem[];
|
|
174
|
+
}
|
|
175
|
+
export declare enum Devices {
|
|
176
|
+
All = "all",
|
|
177
|
+
Mobile = "mobile",
|
|
178
|
+
Desktop = "desktop",
|
|
179
|
+
None = "none"
|
|
180
|
+
}
|
|
181
|
+
export {};
|
package/dist/types.js
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Devices = void 0;
|
|
4
|
+
var Devices;
|
|
5
|
+
(function (Devices) {
|
|
6
|
+
Devices["All"] = "all";
|
|
7
|
+
Devices["Mobile"] = "mobile";
|
|
8
|
+
Devices["Desktop"] = "desktop";
|
|
9
|
+
Devices["None"] = "none";
|
|
10
|
+
})(Devices || (exports.Devices = Devices = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botfabrik/engine-webclient",
|
|
3
|
-
"version": "4.96.
|
|
3
|
+
"version": "4.96.10",
|
|
4
4
|
"description": "Webclient for Botfabriks Bot Engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,23 +21,27 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@botfabrik/engine-domain": "^4.96.6",
|
|
24
|
-
"@botfabrik/engine-transcript-export": "^4.96.
|
|
25
|
-
"@botfabrik/engine-utils": "^4.96.
|
|
24
|
+
"@botfabrik/engine-transcript-export": "^4.96.10",
|
|
25
|
+
"@botfabrik/engine-utils": "^4.96.10",
|
|
26
26
|
"@google-cloud/speech": "^7.2.0",
|
|
27
|
+
"@node-saml/passport-saml": "^5.1.0",
|
|
27
28
|
"accept-language-parser": "^1.5.0",
|
|
28
29
|
"express": "^5.1.0",
|
|
30
|
+
"jsonwebtoken": "^9.0.2",
|
|
31
|
+
"passport": "^0.7.0",
|
|
29
32
|
"uuid": "^11.1.0"
|
|
30
33
|
},
|
|
31
34
|
"devDependencies": {
|
|
32
35
|
"@types/accept-language-parser": "^1.5.8",
|
|
33
36
|
"@types/express": "^5.0.3",
|
|
37
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
34
38
|
"@types/serve-static": "^1.15.8",
|
|
35
39
|
"@types/ua-parser-js": "^0.7.39",
|
|
36
40
|
"copyfiles": "^2.4.1",
|
|
37
41
|
"rimraf": "^6.0.1",
|
|
38
42
|
"socket.io": "^4.8.1",
|
|
39
43
|
"tsx": "^4.20.3",
|
|
40
|
-
"typescript": "5.
|
|
44
|
+
"typescript": "5.9.2"
|
|
41
45
|
},
|
|
42
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "5437e6c08dbc77d813fa8bc979ab6e311cbb33d6"
|
|
43
47
|
}
|