@botpress/webchat 0.4.0 → 0.5.0
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/dist/components/messages/Message.d.ts +1 -1
- package/dist/components/messages/Message.js +20 -3
- package/dist/components/messages/MessageGroup.d.ts +1 -1
- package/dist/components/messages/MessageGroup.js +5 -2
- package/dist/core/socket.d.ts +0 -1
- package/dist/core/socket.js +2 -5
- package/dist/main.d.ts +1 -1
- package/dist/main.js +23 -17
- package/dist/store/index.d.ts +4 -4
- package/dist/store/index.js +23 -24
- package/dist/store/view.js +6 -5
- package/dist/typings.d.ts +19 -15
- package/dist/utils/webchatEvents.d.ts +2 -0
- package/dist/utils/webchatEvents.js +14 -0
- package/package.json +2 -2
|
@@ -8,4 +8,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
|
|
|
8
8
|
WrappedComponent: React.ComponentType<MessageProps>;
|
|
9
9
|
} & import("mobx-react").IWrappedComponent<unknown>;
|
|
10
10
|
export default _default;
|
|
11
|
-
declare type MessageProps = Renderer.Message & WrappedComponentProps & Pick<StoreDef, 'intl'>;
|
|
11
|
+
declare type MessageProps = Renderer.Message & WrappedComponentProps & Pick<StoreDef, 'intl' | 'selectedMessageId' | 'config'>;
|
|
@@ -27,6 +27,7 @@ const classnames_1 = __importDefault(require("classnames"));
|
|
|
27
27
|
const mobx_react_1 = require("mobx-react");
|
|
28
28
|
const react_1 = __importStar(require("react"));
|
|
29
29
|
const react_intl_1 = require("react-intl");
|
|
30
|
+
const webchatEvents_1 = require("../../utils/webchatEvents");
|
|
30
31
|
class Message extends react_1.Component {
|
|
31
32
|
constructor() {
|
|
32
33
|
super(...arguments);
|
|
@@ -34,6 +35,17 @@ class Message extends react_1.Component {
|
|
|
34
35
|
hasError: false,
|
|
35
36
|
showMore: false
|
|
36
37
|
};
|
|
38
|
+
this.onMessageClick = () => {
|
|
39
|
+
var _a, _b;
|
|
40
|
+
(_a = this.props.store) === null || _a === void 0 ? void 0 : _a.setSelectedMessage(this.props.messageId);
|
|
41
|
+
(0, webchatEvents_1.postMessageToParent)('MESSAGE.SELECTED', {
|
|
42
|
+
id: this.props.messageId,
|
|
43
|
+
conversationId: (_b = this.props.store) === null || _b === void 0 ? void 0 : _b.currentConversationId,
|
|
44
|
+
sentOn: this.props.sentOn,
|
|
45
|
+
payload: this.props.payload,
|
|
46
|
+
from: this.props.isBotMessage ? 'bot' : 'user'
|
|
47
|
+
}, this.props.config.chatId);
|
|
48
|
+
};
|
|
37
49
|
}
|
|
38
50
|
static getDerivedStateFromError(_error) {
|
|
39
51
|
return { hasError: true };
|
|
@@ -70,11 +82,14 @@ class Message extends react_1.Component {
|
|
|
70
82
|
return null;
|
|
71
83
|
}
|
|
72
84
|
const additionalStyle = (this.props.payload && this.props.payload['web-style']) || {};
|
|
85
|
+
const messageSelectedClass = {
|
|
86
|
+
'bpw-message-selected': this.props.selectedMessageId === this.props.messageId
|
|
87
|
+
};
|
|
73
88
|
if (this.props.noBubble || ((_b = (_a = this.props.payload) === null || _a === void 0 ? void 0 : _a.wrapped) === null || _b === void 0 ? void 0 : _b.noBubble)) {
|
|
74
|
-
return (react_1.default.createElement("div", { className: (0, classnames_1.default)(this.props.className, wrappedClass), style: additionalStyle }, rendered));
|
|
89
|
+
return (react_1.default.createElement("div", { className: (0, classnames_1.default)(this.props.className, wrappedClass, messageSelectedClass), style: additionalStyle, onClick: this.onMessageClick }, rendered));
|
|
75
90
|
}
|
|
76
91
|
return (react_1.default.createElement("div", { className: (0, classnames_1.default)(this.props.className, wrappedClass, 'bpw-chat-bubble', `bpw-bubble-${type}`), "data-from": this.props.fromLabel, tabIndex: -1, style: additionalStyle },
|
|
77
|
-
react_1.default.createElement("div", { tabIndex: -1, className:
|
|
92
|
+
react_1.default.createElement("div", { tabIndex: -1, className: (0, classnames_1.default)('bpw-chat-bubble-content', messageSelectedClass), onClick: this.onMessageClick },
|
|
78
93
|
react_1.default.createElement("span", { className: "sr-only" }, this.props.store.intl.formatMessage({
|
|
79
94
|
id: this.props.isBotMessage ? 'message.botSaid' : 'message.iSaid',
|
|
80
95
|
defaultMessage: this.props.isBotMessage ? 'Virtual assistant said : ' : 'I said : '
|
|
@@ -85,5 +100,7 @@ class Message extends react_1.Component {
|
|
|
85
100
|
}
|
|
86
101
|
}
|
|
87
102
|
exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
88
|
-
intl: store.intl
|
|
103
|
+
intl: store.intl,
|
|
104
|
+
config: store.config,
|
|
105
|
+
selectedMessageId: store.selectedMessageId
|
|
89
106
|
}))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Message)));
|
|
@@ -43,7 +43,9 @@ class MessageGroup extends react_1.default.Component {
|
|
|
43
43
|
}) },
|
|
44
44
|
avatar,
|
|
45
45
|
react_1.default.createElement("div", { role: "region", className: 'bpw-message-container' },
|
|
46
|
-
react_1.default.createElement("div", { "aria-live": "assertive", role: "log", className: 'bpw-message-group'
|
|
46
|
+
react_1.default.createElement("div", { "aria-live": "assertive", role: "log", className: (0, classnames_1.default)('bpw-message-group', {
|
|
47
|
+
'bpw-message-group-selected': !!this.props.messages.find((m) => m.id === this.props.selectedMessageId)
|
|
48
|
+
}) },
|
|
47
49
|
react_1.default.createElement("span", { "data-from": fromLabel, className: "from hidden", "aria-hidden": "true" }, fromLabel),
|
|
48
50
|
(0, sortBy_1.default)(messages, ['sent_on', 'eventId']).map((message, i, messages) => {
|
|
49
51
|
const isLastMsg = i === messages.length - 1;
|
|
@@ -56,5 +58,6 @@ class MessageGroup extends react_1.default.Component {
|
|
|
56
58
|
exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
57
59
|
store,
|
|
58
60
|
sendFeedback: store.sendFeedback,
|
|
59
|
-
sendData: store.sendData
|
|
61
|
+
sendData: store.sendData,
|
|
62
|
+
selectedMessageId: store.selectedMessageId
|
|
60
63
|
}))(MessageGroup);
|
package/dist/core/socket.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ export default class BpSocket {
|
|
|
8
8
|
constructor(config: Config);
|
|
9
9
|
setup(): void;
|
|
10
10
|
sendPayload(payload: any): Promise<Message>;
|
|
11
|
-
postToParent: (_type: string, payload: any) => void;
|
|
12
11
|
connect(): Promise<void>;
|
|
13
12
|
reload(config: Config): Promise<void>;
|
|
14
13
|
private getCreds;
|
package/dist/core/socket.js
CHANGED
|
@@ -10,13 +10,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const messaging_socket_1 = require("@botpress/messaging-socket");
|
|
13
|
+
const webchatEvents_1 = require("../utils/webchatEvents");
|
|
13
14
|
class BpSocket {
|
|
14
15
|
constructor(config) {
|
|
15
16
|
this.config = config;
|
|
16
|
-
this.postToParent = (_type, payload) => {
|
|
17
|
-
var _a;
|
|
18
|
-
(_a = window.parent) === null || _a === void 0 ? void 0 : _a.postMessage(Object.assign(Object.assign({}, payload), { chatId: this.chatId }), '*');
|
|
19
|
-
};
|
|
20
17
|
this.chatId = config.chatId;
|
|
21
18
|
this.socket = new messaging_socket_1.MessagingSocket({ url: config.messagingUrl, clientId: config.clientId });
|
|
22
19
|
window.websocket = this.socket;
|
|
@@ -38,7 +35,7 @@ class BpSocket {
|
|
|
38
35
|
if (this.socket.userId) {
|
|
39
36
|
const userId = this.socket.userId;
|
|
40
37
|
window.BP_STORAGE.set('creds', this.socket.creds);
|
|
41
|
-
|
|
38
|
+
(0, webchatEvents_1.postMessageToParent)('USER.CONNECTED', { userId }, this.chatId);
|
|
42
39
|
}
|
|
43
40
|
});
|
|
44
41
|
}
|
package/dist/main.d.ts
CHANGED
|
@@ -10,4 +10,4 @@ declare const _default: React.ForwardRefExoticComponent<import("react-intl").Omi
|
|
|
10
10
|
export default _default;
|
|
11
11
|
declare type MainProps = {
|
|
12
12
|
store?: RootStore;
|
|
13
|
-
} & WrappedComponentProps & Pick<StoreDef, 'config' | 'initializeChat' | 'botInfo' | 'fetchBotInfo' | 'sendMessage' | 'sendData' | 'intl' | 'updateTyping' | 'updateBotUILanguage' | 'hideChat' | 'showChat' | 'toggleBotInfo' | 'widgetTransition' | 'activeView' | 'isFullscreen' | 'unreadCount' | 'hasUnreadMessages' | 'showWidgetButton' | 'addEventToConversation' | 'clearMessages' | 'updateConfig' | 'mergeConfig' | 'isWebchatReady' | 'incrementUnread' | 'displayWidgetView' | 'resetUnread' | 'setLoadingCompleted' | 'dimensions' | 'updateLastMessage' | 'fetchConversation' | 'setIntlProvider' | 'setSocket' | 'currentConversationId' | 'resetConversation'>;
|
|
13
|
+
} & WrappedComponentProps & Pick<StoreDef, 'config' | 'initializeChat' | 'botInfo' | 'fetchBotInfo' | 'sendMessage' | 'sendData' | 'intl' | 'updateTyping' | 'updateBotUILanguage' | 'hideChat' | 'showChat' | 'toggleBotInfo' | 'widgetTransition' | 'activeView' | 'isFullscreen' | 'unreadCount' | 'hasUnreadMessages' | 'showWidgetButton' | 'addEventToConversation' | 'clearMessages' | 'updateConfig' | 'mergeConfig' | 'isWebchatReady' | 'incrementUnread' | 'displayWidgetView' | 'resetUnread' | 'setLoadingCompleted' | 'dimensions' | 'updateLastMessage' | 'fetchConversation' | 'createConversation' | 'setIntlProvider' | 'setSocket' | 'currentConversationId' | 'currentConversation' | 'resetConversation'>;
|
package/dist/main.js
CHANGED
|
@@ -34,7 +34,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
34
34
|
exports.DEFAULT_TYPING_DELAY = void 0;
|
|
35
35
|
const classnames_1 = __importDefault(require("classnames"));
|
|
36
36
|
const debounce_1 = __importDefault(require("lodash/debounce"));
|
|
37
|
-
const set_1 = __importDefault(require("lodash/set"));
|
|
38
37
|
const mobx_1 = require("mobx");
|
|
39
38
|
const mobx_react_1 = require("mobx-react");
|
|
40
39
|
const query_string_1 = __importDefault(require("query-string"));
|
|
@@ -46,6 +45,7 @@ const socket_1 = __importDefault(require("./core/socket"));
|
|
|
46
45
|
const Chat_1 = __importDefault(require("./icons/Chat"));
|
|
47
46
|
const utils_1 = require("./utils");
|
|
48
47
|
const analytics_1 = require("./utils/analytics");
|
|
48
|
+
const webchatEvents_1 = require("./utils/webchatEvents");
|
|
49
49
|
exports.DEFAULT_TYPING_DELAY = 1000;
|
|
50
50
|
class Web extends react_1.default.Component {
|
|
51
51
|
constructor(props) {
|
|
@@ -93,12 +93,14 @@ class Web extends react_1.default.Component {
|
|
|
93
93
|
(0, analytics_1.trackWebchatState)('toggle');
|
|
94
94
|
}
|
|
95
95
|
else if (type === 'message') {
|
|
96
|
-
(0, analytics_1.trackMessage)('sent');
|
|
97
96
|
yield this.props.sendMessage(text);
|
|
98
97
|
}
|
|
99
98
|
else if (type === 'loadConversation') {
|
|
100
99
|
yield this.props.fetchConversation(conversationId);
|
|
101
100
|
}
|
|
101
|
+
else if (type === 'createConversation') {
|
|
102
|
+
yield this.props.createConversation();
|
|
103
|
+
}
|
|
102
104
|
else if (type === 'toggleBotInfo') {
|
|
103
105
|
this.props.toggleBotInfo();
|
|
104
106
|
}
|
|
@@ -110,7 +112,7 @@ class Web extends react_1.default.Component {
|
|
|
110
112
|
}
|
|
111
113
|
});
|
|
112
114
|
this.handleNewMessage = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
113
|
-
var _b;
|
|
115
|
+
var _b, _c, _d;
|
|
114
116
|
if (!this.isCurrentConversation(event)) {
|
|
115
117
|
// don't do anything, it's a message from another conversation
|
|
116
118
|
return;
|
|
@@ -123,7 +125,15 @@ class Web extends react_1.default.Component {
|
|
|
123
125
|
// don't do anything, it's the system message
|
|
124
126
|
return;
|
|
125
127
|
}
|
|
126
|
-
(0
|
|
128
|
+
if (((_c = this.props.currentConversation) === null || _c === void 0 ? void 0 : _c.userId) !== event.authorId) {
|
|
129
|
+
(0, analytics_1.trackMessage)('received');
|
|
130
|
+
(0, webchatEvents_1.postMessageToParent)('MESSAGE.RECEIVED', event, this.props.config.chatId);
|
|
131
|
+
// This is to handle a special case for the emulator, setting the selected css class to the last message group
|
|
132
|
+
// This needs a rethinking
|
|
133
|
+
if (event.id) {
|
|
134
|
+
(_d = this.props.store) === null || _d === void 0 ? void 0 : _d.setSelectedMessage(event.id);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
127
137
|
this.props.updateLastMessage(event.conversationId, event);
|
|
128
138
|
yield this.props.addEventToConversation(event);
|
|
129
139
|
// there's no focus on the actual conversation
|
|
@@ -137,8 +147,8 @@ class Web extends react_1.default.Component {
|
|
|
137
147
|
yield this.props.updateTyping(event);
|
|
138
148
|
});
|
|
139
149
|
this.playSound = (0, debounce_1.default)(() => __awaiter(this, void 0, void 0, function* () {
|
|
140
|
-
var
|
|
141
|
-
const disableNotificationSound = this.config.disableNotificationSound || ((
|
|
150
|
+
var _e;
|
|
151
|
+
const disableNotificationSound = this.config.disableNotificationSound || ((_e = this.props.config) === null || _e === void 0 ? void 0 : _e.disableNotificationSound);
|
|
142
152
|
if (disableNotificationSound || this.audio.readyState < 2) {
|
|
143
153
|
return;
|
|
144
154
|
}
|
|
@@ -192,12 +202,9 @@ class Web extends react_1.default.Component {
|
|
|
192
202
|
return __awaiter(this, void 0, void 0, function* () {
|
|
193
203
|
this.config = this.extractConfig();
|
|
194
204
|
this.props.updateConfig(this.config);
|
|
195
|
-
|
|
196
|
-
const storePath = this.config.chatId ? `${this.config.chatId}.webchat_store` : 'webchat_store';
|
|
197
|
-
(0, set_1.default)(window.parent, storePath, this.props.store);
|
|
198
|
-
}
|
|
205
|
+
// is this necessary ?
|
|
199
206
|
if (this.config.containerWidth) {
|
|
200
|
-
|
|
207
|
+
(0, webchatEvents_1.postMessageToParent)('UI.RESIZE', this.config.containerWidth, this.config.chatId);
|
|
201
208
|
}
|
|
202
209
|
yield this.props.fetchBotInfo();
|
|
203
210
|
if (!this.isLazySocket()) {
|
|
@@ -206,10 +213,6 @@ class Web extends react_1.default.Component {
|
|
|
206
213
|
this.setupObserver();
|
|
207
214
|
});
|
|
208
215
|
}
|
|
209
|
-
postMessageToParent(type, value) {
|
|
210
|
-
var _a;
|
|
211
|
-
(_a = window.parent) === null || _a === void 0 ? void 0 : _a.postMessage({ type, value, chatId: this.config.chatId }, '*');
|
|
212
|
-
}
|
|
213
216
|
extractConfig() {
|
|
214
217
|
let userConfig = Object.assign({}, constants_1.default.DEFAULT_CONFIG, this.props.config);
|
|
215
218
|
const { options } = query_string_1.default.parse(location.search);
|
|
@@ -239,7 +242,8 @@ class Web extends react_1.default.Component {
|
|
|
239
242
|
setupObserver() {
|
|
240
243
|
(0, mobx_1.observe)(this.props.dimensions, 'container', (data) => {
|
|
241
244
|
if (data.newValue) {
|
|
242
|
-
this
|
|
245
|
+
// is this necessary ?
|
|
246
|
+
(0, webchatEvents_1.postMessageToParent)('UI.RESIZE', data.newValue, this.config.chatId);
|
|
243
247
|
}
|
|
244
248
|
});
|
|
245
249
|
}
|
|
@@ -267,8 +271,8 @@ class Web extends react_1.default.Component {
|
|
|
267
271
|
[(_a = this.props.config) === null || _a === void 0 ? void 0 : _a.className]: !!((_b = this.props.config) === null || _b === void 0 ? void 0 : _b.className)
|
|
268
272
|
});
|
|
269
273
|
if (this.parentClass !== parentClass) {
|
|
270
|
-
this.postMessageToParent('setClass', parentClass);
|
|
271
274
|
this.parentClass = parentClass;
|
|
275
|
+
(0, webchatEvents_1.postMessageToParent)('UI.SET-CLASS', parentClass, this.config.chatId);
|
|
272
276
|
}
|
|
273
277
|
const stylesheet = this.props.config.stylesheet;
|
|
274
278
|
const extraStylesheet = (_c = this.props.botInfo) === null || _c === void 0 ? void 0 : _c.extraStylesheet;
|
|
@@ -323,8 +327,10 @@ exports.default = (0, mobx_react_1.inject)(({ store }) => ({
|
|
|
323
327
|
sendFeedback: store.sendFeedback,
|
|
324
328
|
updateLastMessage: store.updateLastMessage,
|
|
325
329
|
fetchConversation: store.fetchConversation,
|
|
330
|
+
createConversation: store.createConversation,
|
|
326
331
|
setIntlProvider: store.setIntlProvider,
|
|
327
332
|
setSocket: store.setSocket,
|
|
333
|
+
currentConversation: store.currentConversation,
|
|
328
334
|
currentConversationId: store.currentConversationId,
|
|
329
335
|
resetConversation: store.resetConversation
|
|
330
336
|
}))((0, react_intl_1.injectIntl)((0, mobx_react_1.observer)(Web)));
|
package/dist/store/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ declare class RootStore {
|
|
|
13
13
|
private api;
|
|
14
14
|
conversations: RecentConversation[];
|
|
15
15
|
currentConversation?: CurrentConversation;
|
|
16
|
+
selectedMessageId?: string;
|
|
16
17
|
botInfo: BotInfo;
|
|
17
18
|
config: Config;
|
|
18
19
|
preferredLanguage: string;
|
|
@@ -27,6 +28,7 @@ declare class RootStore {
|
|
|
27
28
|
}, config?: Config);
|
|
28
29
|
setIntlProvider(provider: IntlShape): void;
|
|
29
30
|
setSocket(socket: BpSocket): void;
|
|
31
|
+
setSelectedMessage(messageId: string): void;
|
|
30
32
|
get isConversationStarted(): boolean;
|
|
31
33
|
get botName(): string;
|
|
32
34
|
get hasBotInfoDescription(): boolean;
|
|
@@ -35,7 +37,6 @@ declare class RootStore {
|
|
|
35
37
|
get escapeHTML(): boolean;
|
|
36
38
|
get currentMessages(): Message[];
|
|
37
39
|
get currentConversationId(): uuid | undefined;
|
|
38
|
-
postMessage(name: string, payload?: any): void;
|
|
39
40
|
updateMessages(messages: Message[]): void;
|
|
40
41
|
updateLastMessage(conversationId: string, message?: Message): void;
|
|
41
42
|
clearMessages(): void;
|
|
@@ -51,7 +52,7 @@ declare class RootStore {
|
|
|
51
52
|
/** Fetch the specified conversation ID, or try to fetch a valid one from the list */
|
|
52
53
|
fetchConversation(convoId?: uuid): Promise<uuid | undefined>;
|
|
53
54
|
/** Sends the specified message, or fetch the message in the composer */
|
|
54
|
-
sendMessage(
|
|
55
|
+
sendMessage(textMessage?: string): Promise<void>;
|
|
55
56
|
/** Sends an event to start conversation & hide the bot info page */
|
|
56
57
|
startConversation(): Promise<void>;
|
|
57
58
|
/** Creates a new conversation and switches to it */
|
|
@@ -61,7 +62,7 @@ declare class RootStore {
|
|
|
61
62
|
sendFeedback(feedback: number, messageId: string): Promise<void>;
|
|
62
63
|
downloadConversation(): Promise<void>;
|
|
63
64
|
/** Sends an event or a message, depending on how the backend manages those types */
|
|
64
|
-
sendData(data: any): Promise<void>;
|
|
65
|
+
sendData(data: any): Promise<Message | void>;
|
|
65
66
|
/** Sends a message of type voice */
|
|
66
67
|
sendVoiceMessage(voice: Buffer, ext: string): Promise<void>;
|
|
67
68
|
/** Use this method to replace a value or add a new config */
|
|
@@ -69,7 +70,6 @@ declare class RootStore {
|
|
|
69
70
|
/** This replaces all the configurations by this object */
|
|
70
71
|
updateConfig(config: Config): void;
|
|
71
72
|
private _applyConfig;
|
|
72
|
-
publishConfigChanged(): void;
|
|
73
73
|
updatePreferredLanguage(lang: string): void;
|
|
74
74
|
/** Starts a timer to remove the typing animation when it's completed */
|
|
75
75
|
private _startTypingTimer;
|
package/dist/store/index.js
CHANGED
|
@@ -30,6 +30,7 @@ const main_1 = require("../main");
|
|
|
30
30
|
const translations_1 = require("../translations");
|
|
31
31
|
const utils_1 = require("../utils");
|
|
32
32
|
const analytics_1 = require("../utils/analytics");
|
|
33
|
+
const webchatEvents_1 = require("../utils/webchatEvents");
|
|
33
34
|
const composer_1 = __importDefault(require("./composer"));
|
|
34
35
|
const view_1 = __importDefault(require("./view"));
|
|
35
36
|
class RootStore {
|
|
@@ -50,6 +51,9 @@ class RootStore {
|
|
|
50
51
|
setSocket(socket) {
|
|
51
52
|
this.api = new api_1.default(socket);
|
|
52
53
|
}
|
|
54
|
+
setSelectedMessage(messageId) {
|
|
55
|
+
this.selectedMessageId = messageId;
|
|
56
|
+
}
|
|
53
57
|
get isConversationStarted() {
|
|
54
58
|
var _a;
|
|
55
59
|
return !!((_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.messages.length);
|
|
@@ -81,10 +85,6 @@ class RootStore {
|
|
|
81
85
|
var _a;
|
|
82
86
|
return (_a = this.currentConversation) === null || _a === void 0 ? void 0 : _a.id;
|
|
83
87
|
}
|
|
84
|
-
postMessage(name, payload) {
|
|
85
|
-
const chatId = this.config.chatId;
|
|
86
|
-
window.parent.postMessage({ name, chatId, payload }, '*');
|
|
87
|
-
}
|
|
88
88
|
updateMessages(messages) {
|
|
89
89
|
if (this.currentConversation) {
|
|
90
90
|
this.currentConversation.messages = messages;
|
|
@@ -160,7 +160,7 @@ class RootStore {
|
|
|
160
160
|
yield this.fetchConversation();
|
|
161
161
|
(0, mobx_1.runInAction)('-> setInitialized', () => {
|
|
162
162
|
this.isInitialized = true;
|
|
163
|
-
|
|
163
|
+
(0, webchatEvents_1.postMessageToParent)('LIFECYCLE.READY', undefined, this.config.chatId);
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
166
|
catch (err) {
|
|
@@ -229,23 +229,24 @@ class RootStore {
|
|
|
229
229
|
});
|
|
230
230
|
}
|
|
231
231
|
/** Sends the specified message, or fetch the message in the composer */
|
|
232
|
-
sendMessage(
|
|
232
|
+
sendMessage(textMessage) {
|
|
233
233
|
return __awaiter(this, void 0, void 0, function* () {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
const userMessage = this.composer.message;
|
|
238
|
-
if (!userMessage || !userMessage.length) {
|
|
234
|
+
textMessage = textMessage || this.composer.message;
|
|
235
|
+
if (!textMessage) {
|
|
239
236
|
return;
|
|
240
237
|
}
|
|
241
238
|
this.composer.updateMessage('');
|
|
242
239
|
try {
|
|
243
|
-
yield this.sendData({ type: 'text', text:
|
|
240
|
+
const message = yield this.sendData({ type: 'text', text: textMessage });
|
|
244
241
|
(0, analytics_1.trackMessage)('sent');
|
|
245
|
-
|
|
242
|
+
if (message) {
|
|
243
|
+
(0, webchatEvents_1.postMessageToParent)('MESSAGE.SENT', message, this.config.chatId);
|
|
244
|
+
}
|
|
245
|
+
this.composer.addMessageToHistory(textMessage);
|
|
246
246
|
}
|
|
247
247
|
catch (e) {
|
|
248
|
-
this.composer.updateMessage(
|
|
248
|
+
this.composer.updateMessage(textMessage);
|
|
249
|
+
console.error('Webchat cloud not send message');
|
|
249
250
|
throw e;
|
|
250
251
|
}
|
|
251
252
|
});
|
|
@@ -328,6 +329,7 @@ class RootStore {
|
|
|
328
329
|
}
|
|
329
330
|
const message = yield this.api.sendMessage(data, this.currentConversationId);
|
|
330
331
|
this.updateLastMessage(this.currentConversationId, message);
|
|
332
|
+
return message;
|
|
331
333
|
});
|
|
332
334
|
}
|
|
333
335
|
/** Sends a message of type voice */
|
|
@@ -364,10 +366,7 @@ class RootStore {
|
|
|
364
366
|
const locale = (0, translations_1.getUserLocale)(this.config.locale);
|
|
365
367
|
this.updateBotUILanguage(locale);
|
|
366
368
|
document.documentElement.setAttribute('lang', locale);
|
|
367
|
-
this.
|
|
368
|
-
}
|
|
369
|
-
publishConfigChanged() {
|
|
370
|
-
this.postMessage('configChanged', JSON.stringify(this.config, undefined, 2));
|
|
369
|
+
(0, webchatEvents_1.postMessageToParent)('CONFIG.SET', Object.assign({}, this.config), this.config.chatId);
|
|
371
370
|
}
|
|
372
371
|
updatePreferredLanguage(lang) {
|
|
373
372
|
this.preferredLanguage = lang;
|
|
@@ -439,6 +438,9 @@ __decorate([
|
|
|
439
438
|
__decorate([
|
|
440
439
|
mobx_1.observable
|
|
441
440
|
], RootStore.prototype, "currentConversation", void 0);
|
|
441
|
+
__decorate([
|
|
442
|
+
mobx_1.observable
|
|
443
|
+
], RootStore.prototype, "selectedMessageId", void 0);
|
|
442
444
|
__decorate([
|
|
443
445
|
mobx_1.observable
|
|
444
446
|
], RootStore.prototype, "botInfo", void 0);
|
|
@@ -463,6 +465,9 @@ __decorate([
|
|
|
463
465
|
__decorate([
|
|
464
466
|
mobx_1.action.bound
|
|
465
467
|
], RootStore.prototype, "setSocket", null);
|
|
468
|
+
__decorate([
|
|
469
|
+
mobx_1.action.bound
|
|
470
|
+
], RootStore.prototype, "setSelectedMessage", null);
|
|
466
471
|
__decorate([
|
|
467
472
|
mobx_1.computed
|
|
468
473
|
], RootStore.prototype, "isConversationStarted", null);
|
|
@@ -487,9 +492,6 @@ __decorate([
|
|
|
487
492
|
__decorate([
|
|
488
493
|
mobx_1.computed
|
|
489
494
|
], RootStore.prototype, "currentConversationId", null);
|
|
490
|
-
__decorate([
|
|
491
|
-
mobx_1.action.bound
|
|
492
|
-
], RootStore.prototype, "postMessage", null);
|
|
493
495
|
__decorate([
|
|
494
496
|
mobx_1.action.bound
|
|
495
497
|
], RootStore.prototype, "updateMessages", null);
|
|
@@ -556,9 +558,6 @@ __decorate([
|
|
|
556
558
|
__decorate([
|
|
557
559
|
mobx_1.action.bound
|
|
558
560
|
], RootStore.prototype, "updateConfig", null);
|
|
559
|
-
__decorate([
|
|
560
|
-
mobx_1.action.bound
|
|
561
|
-
], RootStore.prototype, "publishConfigChanged", null);
|
|
562
561
|
__decorate([
|
|
563
562
|
mobx_1.action.bound
|
|
564
563
|
], RootStore.prototype, "updatePreferredLanguage", null);
|
package/dist/store/view.js
CHANGED
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
const merge_1 = __importDefault(require("lodash/merge"));
|
|
13
13
|
const mobx_1 = require("mobx");
|
|
14
14
|
const constants_1 = __importDefault(require("../core/constants"));
|
|
15
|
+
const webchatEvents_1 = require("../utils/webchatEvents");
|
|
15
16
|
class ViewStore {
|
|
16
17
|
constructor(rootStore, fullscreen) {
|
|
17
18
|
/** If false, probably embedded on a website or on the studio */
|
|
@@ -111,7 +112,7 @@ class ViewStore {
|
|
|
111
112
|
}
|
|
112
113
|
setLoadingCompleted() {
|
|
113
114
|
this._isLoading = false;
|
|
114
|
-
this.rootStore.
|
|
115
|
+
(0, webchatEvents_1.postMessageToParent)('LIFECYCLE.LOADED', undefined, this.rootStore.config.chatId);
|
|
115
116
|
}
|
|
116
117
|
showPoweredBy() {
|
|
117
118
|
this.isPoweredByDisplayed = true;
|
|
@@ -157,7 +158,7 @@ class ViewStore {
|
|
|
157
158
|
showChat() {
|
|
158
159
|
if (this.disableAnimations) {
|
|
159
160
|
this.activeView = 'side';
|
|
160
|
-
this.rootStore.
|
|
161
|
+
(0, webchatEvents_1.postMessageToParent)('UI.OPENED', undefined, this.rootStore.config.chatId);
|
|
161
162
|
return this._updateTransitions({ widgetTransition: undefined, sideTransition: 'none' });
|
|
162
163
|
}
|
|
163
164
|
this._updateTransitions({ widgetTransition: 'fadeOut' });
|
|
@@ -165,7 +166,7 @@ class ViewStore {
|
|
|
165
166
|
this._updateTransitions({ sideTransition: 'fadeIn' });
|
|
166
167
|
}, constants_1.default.ANIMATION_DURATION + 10);
|
|
167
168
|
this._endAnimation('side');
|
|
168
|
-
this.rootStore.
|
|
169
|
+
(0, webchatEvents_1.postMessageToParent)('UI.OPENED', undefined, this.rootStore.config.chatId);
|
|
169
170
|
}
|
|
170
171
|
hideChat() {
|
|
171
172
|
if (this.isFullscreen) {
|
|
@@ -173,7 +174,7 @@ class ViewStore {
|
|
|
173
174
|
}
|
|
174
175
|
if (this.disableAnimations) {
|
|
175
176
|
this.activeView = 'widget';
|
|
176
|
-
this.rootStore.
|
|
177
|
+
(0, webchatEvents_1.postMessageToParent)('UI.CLOSED', undefined, this.rootStore.config.chatId);
|
|
177
178
|
return this._updateTransitions({ widgetTransition: undefined, sideTransition: undefined });
|
|
178
179
|
}
|
|
179
180
|
this._updateTransitions({ sideTransition: 'fadeOut' });
|
|
@@ -183,7 +184,7 @@ class ViewStore {
|
|
|
183
184
|
}, constants_1.default.ANIMATION_DURATION + 10);
|
|
184
185
|
}
|
|
185
186
|
this._endAnimation('widget');
|
|
186
|
-
this.rootStore.
|
|
187
|
+
(0, webchatEvents_1.postMessageToParent)('UI.CLOSED', undefined, this.rootStore.config.chatId);
|
|
187
188
|
}
|
|
188
189
|
_endAnimation(finalView) {
|
|
189
190
|
setTimeout(() => {
|
package/dist/typings.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { UserCredentials } from '@botpress/messaging-socket';
|
|
2
3
|
import { RootStore } from './store';
|
|
3
4
|
import { BPStorage } from './utils/storage';
|
|
4
5
|
declare global {
|
|
@@ -35,7 +36,7 @@ export declare namespace Renderer {
|
|
|
35
36
|
isLastMessage?: boolean;
|
|
36
37
|
sentOn?: Date;
|
|
37
38
|
inlineFeedback?: any;
|
|
38
|
-
onSendData?: (data: any) => Promise<void>;
|
|
39
|
+
onSendData?: (data: any) => Promise<Message | void>;
|
|
39
40
|
onFileUpload?: (label: string, payload: any, file: File) => Promise<void>;
|
|
40
41
|
/** Allows to autoplay voice messages coming from the bot */
|
|
41
42
|
onAudioEnded?: () => void;
|
|
@@ -135,11 +136,27 @@ export interface StudioConnector {
|
|
|
135
136
|
getModuleInjector: any;
|
|
136
137
|
loadModuleView: any;
|
|
137
138
|
}
|
|
139
|
+
export declare type WebchatEventType = 'LIFECYCLE.LOADED' | 'LIFECYCLE.READY' | 'UI.OPENED' | 'UI.CLOSED' | 'UI.RESIZE' | 'UI.SET-CLASS' | 'CONFIG.SET' | 'MESSAGE.SENT' | 'MESSAGE.RECEIVED' | 'MESSAGE.SELECTED' | 'USER.CONNECTED';
|
|
140
|
+
export interface WebchatEvent {
|
|
141
|
+
type: WebchatEventType;
|
|
142
|
+
value: any;
|
|
143
|
+
chatId: string;
|
|
144
|
+
}
|
|
138
145
|
export interface Config {
|
|
139
146
|
/** Url of the messaging server */
|
|
140
147
|
messagingUrl: string;
|
|
141
148
|
/** Id of your messaging client */
|
|
142
149
|
clientId: string;
|
|
150
|
+
/**
|
|
151
|
+
* Refers to a specific webchat reference in parent window. Useful when using multiple chat window
|
|
152
|
+
* @default 'bp-web-widget'
|
|
153
|
+
*/
|
|
154
|
+
chatId: string;
|
|
155
|
+
/**
|
|
156
|
+
* Url where the webchat bundle is hosted
|
|
157
|
+
* @default: '/'
|
|
158
|
+
*/
|
|
159
|
+
hostUrl?: string;
|
|
143
160
|
/**
|
|
144
161
|
* Url of the Media File Service where we fetch the bot info
|
|
145
162
|
* @default ''
|
|
@@ -250,22 +267,12 @@ export interface Config {
|
|
|
250
267
|
* Experimental: expose the store to the parent frame for more control on the webchat's behavior
|
|
251
268
|
* @default false
|
|
252
269
|
*/
|
|
253
|
-
exposeStore?: boolean;
|
|
254
|
-
/**
|
|
255
|
-
* If true, Websocket is created when the Webchat is opened. Bot cannot be proactive.
|
|
256
|
-
* @default false
|
|
257
|
-
*/
|
|
258
270
|
lazySocket?: boolean;
|
|
259
271
|
/**
|
|
260
272
|
* If true, chat will no longer play the notification sound for new messages.
|
|
261
273
|
* @default false
|
|
262
274
|
*/
|
|
263
275
|
disableNotificationSound?: boolean;
|
|
264
|
-
/**
|
|
265
|
-
* Refers to a specific webchat reference in parent window. Useful when using multiple chat window
|
|
266
|
-
* @default ''
|
|
267
|
-
*/
|
|
268
|
-
chatId?: string;
|
|
269
276
|
/**
|
|
270
277
|
* CSS class to be applied to iframe
|
|
271
278
|
* @default ''
|
|
@@ -280,10 +287,7 @@ export interface Config {
|
|
|
280
287
|
/**
|
|
281
288
|
* Allows setting a custom user id
|
|
282
289
|
*/
|
|
283
|
-
customUser?:
|
|
284
|
-
userId: string;
|
|
285
|
-
userToken: string;
|
|
286
|
-
};
|
|
290
|
+
customUser?: UserCredentials;
|
|
287
291
|
}
|
|
288
292
|
export interface BotDetails {
|
|
289
293
|
website?: string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.postMessageToParent = void 0;
|
|
7
|
+
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
8
|
+
const postMessageToParent = (type, value, chatId) => {
|
|
9
|
+
var _a;
|
|
10
|
+
//cloneDeep necessary because of potentially nested mobx proxy object isn't serializable
|
|
11
|
+
const evt = { type, value: (0, cloneDeep_1.default)(value), chatId };
|
|
12
|
+
(_a = window.parent) === null || _a === void 0 ? void 0 : _a.postMessage(evt, '*');
|
|
13
|
+
};
|
|
14
|
+
exports.postMessageToParent = postMessageToParent;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botpress/webchat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"source": "src/index.tsx",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@blueprintjs/core": "^3.23.1",
|
|
32
|
-
"@botpress/messaging-components": "0.4.
|
|
32
|
+
"@botpress/messaging-components": "0.4.2",
|
|
33
33
|
"@botpress/messaging-socket": "1.2.0",
|
|
34
34
|
"@formatjs/intl-pluralrules": "^4.1.6",
|
|
35
35
|
"@formatjs/intl-utils": "^3.8.4",
|