@tiledesk/tiledesk-server 2.1.41 → 2.2.4
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/.circleci/config.yml +54 -0
- package/.env.sample +1 -1
- package/.github/workflows/docker-community-push-latest.yml +22 -0
- package/.github/workflows/{docker-image-push.yml → docker-image-en-tag-push.yml} +1 -1
- package/.github/workflows/docker-image-tag-community-tag-push.yml +21 -0
- package/.github/workflows/{docker-push-latest.yml → docker-push-en-push-latest.yml} +1 -1
- package/CHANGELOG.md +198 -1
- package/Dockerfile +1 -1
- package/Dockerfile-en +1 -1
- package/README.md +5 -7
- package/app.js +12 -1
- package/channels/chat21/chat21Contact.js +34 -8
- package/channels/chat21/chat21Handler.js +48 -5
- package/channels/chat21/chat21WebHook.js +34 -5
- package/channels/chat21/nativeauth.js +2 -2
- package/config/email.js +2 -1
- package/config/global.js +3 -0
- package/config/labels/widget.json +170 -16
- package/event/messageEvent.js +18 -1
- package/middleware/passport.js +10 -4
- package/models/actionsConstants.js +7 -0
- package/models/department.js +3 -0
- package/models/faq.js +8 -2
- package/models/faq_kb.js +6 -0
- package/models/message.js +10 -4
- package/models/messageConstants.js +3 -3
- package/models/request.js +33 -3
- package/package.json +31 -28
- package/pubmodules/emailNotification/requestNotification.js +380 -62
- package/pubmodules/messageActions/messageActionsInterceptor.js +20 -7
- package/pubmodules/messageTransformer/index.js +1 -1
- package/pubmodules/messageTransformer/microLanguageAttributesTransformerInterceptor.js +67 -0
- package/pubmodules/pubModulesManager.js +66 -14
- package/pubmodules/rules/conciergeBot.js +81 -49
- package/routes/auth.js +34 -10
- package/routes/campaigns.js +117 -25
- package/routes/faq.js +19 -0
- package/routes/faq_kb.js +13 -4
- package/routes/faqpub.js +1 -1
- package/routes/images.js +1 -1
- package/routes/jwt.js +0 -1
- package/routes/logs.js +26 -0
- package/routes/message.js +7 -2
- package/routes/messagesRoot.js +73 -16
- package/routes/project_user.js +36 -1
- package/routes/request.js +88 -12
- package/routes/requestUtilRoot.js +30 -0
- package/routes/urls.js +12 -0
- package/routes/users.js +5 -1
- package/services/BotSubscriptionNotifier.js +1 -0
- package/services/departmentService.js +29 -5
- package/services/emailService.js +1103 -298
- package/services/faqBotHandler.js +176 -61
- package/services/faqBotSupport.js +181 -117
- package/services/faqService.js +17 -14
- package/services/messageService.js +57 -9
- package/services/modulesManager.js +86 -23
- package/services/requestService.js +58 -17
- package/template/email/assignedEmailMessage.html +205 -0
- package/template/email/assignedRequest.html +44 -14
- package/template/email/beenInvitedExistingUser.html +2 -2
- package/template/email/beenInvitedNewUser.html +1 -1
- package/template/email/newMessage.html +31 -12
- package/template/email/passwordChanged.html +2 -3
- package/template/email/pooledEmailMessage.html +208 -0
- package/template/email/pooledRequest.html +41 -14
- package/template/email/resetPassword.html +2 -3
- package/template/email/sendTranscript.html +1 -1
- package/template/email/test.html +1 -1
- package/template/email/ticket.html +78 -52
- package/template/email/ticket.txt +5 -1
- package/template/email/verify.html +1 -1
- package/test/authentication.js +76 -4
- package/test/authenticationJwt.js +76 -2
- package/test/campaignsRoute.js +226 -0
- package/test/faqService.js +3 -3
- package/test/faqkbRoute.js +3 -2
- package/test/messageRootRoute.js +193 -0
- package/test/messageRoute.js +75 -0
- package/test/messageService.js +5 -5
- package/test/requestRoute.js +27 -9
- package/test/requestService.js +472 -11
- package/test-int/bot.js +673 -8
- package/websocket/webSocketServer.js +7 -4
- package/template/email/ticket-taking.txt +0 -7
@@ -10,9 +10,60 @@ var BotFromParticipant = require("../utils/botFromParticipant");
|
|
10
10
|
var cacheUtil = require('../utils/cacheUtil');
|
11
11
|
var eventService = require('../pubmodules/events/eventService');
|
12
12
|
var mongoose = require('mongoose');
|
13
|
+
const { TiledeskChatbotUtil } = require('@tiledesk/tiledesk-chatbot-util');
|
14
|
+
const ActionsConstants = require('../models/actionsConstants');
|
13
15
|
|
14
16
|
class FaqBotHandler {
|
15
17
|
|
18
|
+
static is_command(text) {
|
19
|
+
// console.log("msg:", msg);
|
20
|
+
if (!text) {
|
21
|
+
return {
|
22
|
+
'command': null,
|
23
|
+
'text': null
|
24
|
+
}
|
25
|
+
}
|
26
|
+
// const text = msg.text;
|
27
|
+
// console.log("msg.text:", msg.text);
|
28
|
+
// console.log("TiledeskChatbotUtil.AGENT_COMMAND:", TiledeskChatbotUtil.AGENT_COMMAND.replace(/\\\\/g, '\\'));
|
29
|
+
//const agent_pattern = new RegExp('^(' + TiledeskChatbotUtil.AGENT_COMMAND.replace(/\\/g, '\\\\') + ')$', 'm');
|
30
|
+
// console.log("agent_pattern:", agent_pattern);
|
31
|
+
//const match_agent = text.match(agent_pattern);
|
32
|
+
//console.log("match_agent: ", match_agent);
|
33
|
+
const match_agent = text.indexOf(ActionsConstants.CHAT_ACTION_MESSAGE.AGENT);
|
34
|
+
const match_close = text.indexOf(ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE);
|
35
|
+
//console.log("match_agent: ", match_agent);
|
36
|
+
// const agent_handoff = null;
|
37
|
+
//if (match_agent && match_agent.length >=2) {
|
38
|
+
if (match_close >-1) {
|
39
|
+
// console.log("match!");
|
40
|
+
// let parts = text.split('\\agent');
|
41
|
+
// console.log(parts)
|
42
|
+
const new_msg_text = text.replace(ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE,"");
|
43
|
+
// const new_msg_text = parts[0].trim()
|
44
|
+
// console.log(new_msg_text)
|
45
|
+
return {
|
46
|
+
'command': ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE,
|
47
|
+
'text': new_msg_text
|
48
|
+
}
|
49
|
+
}
|
50
|
+
if (match_agent >-1) {
|
51
|
+
// console.log("match!");
|
52
|
+
// let parts = text.split('\\agent');
|
53
|
+
// console.log(parts)
|
54
|
+
const new_msg_text = text.replace(ActionsConstants.CHAT_ACTION_MESSAGE.AGENT,"");
|
55
|
+
// const new_msg_text = parts[0].trim()
|
56
|
+
// console.log(new_msg_text)
|
57
|
+
return {
|
58
|
+
'command': ActionsConstants.CHAT_ACTION_MESSAGE.AGENT,
|
59
|
+
'text': new_msg_text
|
60
|
+
}
|
61
|
+
}
|
62
|
+
return {
|
63
|
+
'command': null,
|
64
|
+
'text': text
|
65
|
+
}
|
66
|
+
}
|
16
67
|
|
17
68
|
|
18
69
|
listen() {
|
@@ -51,8 +102,14 @@ class FaqBotHandler {
|
|
51
102
|
var query = { "id_project": message.id_project, "id_faq_kb": faq_kb._id, "question": message.text};
|
52
103
|
|
53
104
|
if (message.attributes && message.attributes.action) {
|
105
|
+
|
54
106
|
var action = message.attributes.action;
|
55
|
-
|
107
|
+
var action_parameters_index = action.indexOf("?");
|
108
|
+
if (action_parameters_index > -1) {
|
109
|
+
action = action.substring(0,action_parameters_index);
|
110
|
+
}
|
111
|
+
winston.debug("action: " + action);
|
112
|
+
|
56
113
|
var isObjectId = mongoose.Types.ObjectId.isValid(action);
|
57
114
|
winston.debug("isObjectId:"+ isObjectId);
|
58
115
|
|
@@ -66,7 +123,18 @@ class FaqBotHandler {
|
|
66
123
|
winston.debug("query message.attributes.action ", query);
|
67
124
|
}
|
68
125
|
|
69
|
-
|
126
|
+
|
127
|
+
if (message.request && message.request.attributes && message.request.attributes.blocked_intent) {
|
128
|
+
query = { "id_project": message.id_project, "id_faq_kb": faq_kb._id, $or:[{"intent_id": message.request.attributes.blocked_intent}, {"intent_display_name": message.request.attributes.blocked_intent}]};
|
129
|
+
// TODO skip if type reset (better create a resetIntent action /reset reset the attributes) -> TODO DELETE message.request.attributes.blocked_intent for next call
|
130
|
+
winston.debug("query message.attributes.blocked_intent ", query);
|
131
|
+
// res.send({text:"ripeti la mail", action: id_intent}); fai un test che forse già funziona
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
|
70
138
|
Faq.find(query)
|
71
139
|
.lean().
|
72
140
|
exec(function (err, faqs) {
|
@@ -91,31 +159,6 @@ class FaqBotHandler {
|
|
91
159
|
answerObj.score = 100; //exact search not set score
|
92
160
|
winston.debug("answerObj.score", answerObj.score);
|
93
161
|
|
94
|
-
|
95
|
-
|
96
|
-
// === TEMPORARY: search for handoff to agent command (\agent)
|
97
|
-
/*
|
98
|
-
const handoff_parsed = TiledeskChatbotUtil.is_agent_handoff_command(message);
|
99
|
-
winston.debug('handoff_parsed?', handoff_parsed);
|
100
|
-
|
101
|
-
if (handoff_parsed.agent_handoff) {
|
102
|
-
console.log("agent_handoff command found");
|
103
|
-
|
104
|
-
messageService.send(sender, botName, message.recipient, handoff_parsed.agent_handoff,
|
105
|
-
message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
|
106
|
-
winston.info("faqbot agent sent ", savedMessage.toObject());
|
107
|
-
});
|
108
|
-
|
109
|
-
// PATCH: Chat clients (i.e. web widget) remove messages with text = null
|
110
|
-
// handoff_parsed.text contains the eventual text before the \agent command
|
111
|
-
// or 'all the message text' if \agent was not found
|
112
|
-
message.text = handoff_parsed.text? handoff_parsed.text : '';
|
113
|
-
}
|
114
|
-
*/
|
115
|
-
// === TEMPORARY: search for handoff to agent command (\agent)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
162
|
// qui
|
120
163
|
faqBotSupport.getParsedMessage(answerObj.answer, message, faq_kb, answerObj).then(function(bot_answer) {
|
121
164
|
// send(sender, senderFullname, recipient, text, id_project, createdBy, attributes, type) {
|
@@ -128,66 +171,90 @@ class FaqBotHandler {
|
|
128
171
|
// attr._answer = that.getCircularReplacer(answerObj);
|
129
172
|
if (answerObj && answerObj._id) {
|
130
173
|
attr._answerid = answerObj._id.toString();
|
131
|
-
}
|
132
|
-
|
174
|
+
}
|
133
175
|
|
134
176
|
let question_payload = Object.assign({}, message);
|
135
177
|
delete question_payload.request;
|
136
178
|
|
137
179
|
winston.debug("question_payload", question_payload);
|
138
180
|
|
181
|
+
let clonedfaqs = faqs.slice();
|
182
|
+
if (clonedfaqs && clonedfaqs.length>0) {
|
183
|
+
clonedfaqs = clonedfaqs.shift()
|
184
|
+
}
|
185
|
+
winston.verbose("clonedfaqs", clonedfaqs);
|
186
|
+
|
139
187
|
const intent_info = {
|
140
188
|
intent_name: answerObj.intent_display_name,
|
141
189
|
is_fallback: false,
|
142
190
|
confidence: answerObj.score,
|
143
|
-
question_payload: question_payload
|
191
|
+
question_payload: question_payload,
|
192
|
+
others: clonedfaqs
|
144
193
|
}
|
145
194
|
winston.debug("intent_info", intent_info);
|
146
195
|
attr.intent_info = intent_info;
|
147
196
|
|
148
197
|
winston.debug("answerObj", answerObj);
|
149
198
|
// winston.info("that.getCircularReplacer(answerObj)", that.getCircularReplacer(answerObj));
|
150
|
-
winston.debug("attr", attr);
|
199
|
+
winston.debug("attr", attr);
|
151
200
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
201
|
+
|
202
|
+
|
203
|
+
const command_parsed = FaqBotHandler.is_command(bot_answer.text);
|
204
|
+
winston.debug('command_parsed?', command_parsed);
|
205
|
+
|
206
|
+
if (command_parsed.command) {
|
207
|
+
winston.debug("agent_handoff faqs command found");
|
208
|
+
|
209
|
+
messageService.send(sender, botName, message.recipient, command_parsed.command,
|
210
|
+
message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
|
211
|
+
winston.debug("agent_handoff faqs agent sent ", savedMessage.toObject());
|
212
|
+
});
|
213
|
+
// PATCH: Chat clients (i.e. web widget) remove messages with text = null
|
214
|
+
// command_parsed.text contains the eventual text before the \agent command
|
215
|
+
// or 'all the message text' if \agent was not found
|
216
|
+
bot_answer.text = command_parsed.text? command_parsed.text : undefined;
|
217
|
+
winston.debug("bot_answer.text1 "+ bot_answer.text );
|
218
|
+
}
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
winston.debug("bot_answer.text2 "+ bot_answer.text );
|
223
|
+
// if (bot_answer.text) { //can be undefined id /agent only
|
224
|
+
messageService.send(sender, botName, message.recipient, bot_answer.text,
|
225
|
+
message.id_project, sender, attr, bot_answer.type, bot_answer.metadata, bot_answer.language).then(function(savedMessage){
|
226
|
+
winston.debug("faqbot message botAns ", savedMessage.toObject());
|
227
|
+
});
|
228
|
+
// }
|
229
|
+
|
230
|
+
|
231
|
+
|
161
232
|
});
|
162
233
|
|
163
234
|
|
164
235
|
}
|
165
236
|
|
166
|
-
|
167
|
-
// getBotMessageNew(botAnswer, projectid, bot, language, threshold)
|
168
|
-
// faqBotSupport.getBotMessageNew(answerObj, message.id_project, faq_kb, message, 1.2).then(function(botAns){
|
169
|
-
// // faqBotSupport.getBotMessage(answerObj, message.id_project, message.request.department._id, message.language, 1.2).then(function(botAns){
|
170
|
-
// winston.debug("faqbot message botAns ", botAns);
|
171
|
-
|
172
|
-
// if (botAns) {
|
173
|
-
// // let attributes = {bot_reponse_template: botAns.template};
|
174
|
-
// messageService.send(sender, botName, message.recipient, botAns.text,
|
175
|
-
// message.id_project, sender, botAns.attributes, botAns.type, botAns.metadata).then(function(savedMessage){
|
176
|
-
// winston.info("faqbot message bot answer " ,savedMessage.toObject());
|
177
|
-
// });
|
178
|
-
// }
|
179
|
-
// });
|
180
|
-
|
237
|
+
|
181
238
|
|
182
239
|
} else {
|
183
240
|
|
184
241
|
query = { "id_project": message.id_project, "id_faq_kb": faq_kb._id};
|
185
|
-
|
186
|
-
|
242
|
+
|
243
|
+
var search_obj = {"$search": message.text};
|
244
|
+
|
245
|
+
if (faq_kb.language) {
|
246
|
+
search_obj["$language"] = faq_kb.language;
|
247
|
+
}
|
248
|
+
query.$text = search_obj;
|
249
|
+
winston.debug("fulltext search query", query);
|
250
|
+
|
187
251
|
Faq.find(query, {score: { $meta: "textScore" } })
|
188
252
|
.sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
|
189
253
|
.lean().
|
190
254
|
exec(function (err, faqs) {
|
255
|
+
if (err) {
|
256
|
+
return winston.error('Error getting fulltext objects.', err);
|
257
|
+
}
|
191
258
|
winston.debug("faqs", faqs);
|
192
259
|
|
193
260
|
// botprefix
|
@@ -218,11 +285,18 @@ class FaqBotHandler {
|
|
218
285
|
|
219
286
|
winston.debug("question_payload", question_payload);
|
220
287
|
|
288
|
+
let clonedfaqs = faqs.slice();
|
289
|
+
if (clonedfaqs && clonedfaqs.length>0) {
|
290
|
+
clonedfaqs = clonedfaqs.shift()
|
291
|
+
}
|
292
|
+
winston.verbose("clonedfaqs", clonedfaqs);
|
293
|
+
|
221
294
|
const intent_info = {
|
222
295
|
intent_name: answerObj.intent_display_name,
|
223
296
|
is_fallback: false,
|
224
297
|
confidence: answerObj.score,
|
225
|
-
question_payload: question_payload
|
298
|
+
question_payload: question_payload,
|
299
|
+
others: clonedfaqs
|
226
300
|
}
|
227
301
|
winston.debug("intent_info", intent_info);
|
228
302
|
attr.intent_info = intent_info;
|
@@ -230,9 +304,30 @@ class FaqBotHandler {
|
|
230
304
|
|
231
305
|
|
232
306
|
winston.debug("attr", attr);
|
307
|
+
|
308
|
+
|
309
|
+
const command_parsed = FaqBotHandler.is_command(bot_answer.text);
|
310
|
+
winston.debug('command_parsed?', command_parsed);
|
311
|
+
|
312
|
+
if (command_parsed.command) {
|
313
|
+
winston.debug("agent_handoff faqs command found");
|
314
|
+
|
315
|
+
messageService.send(sender, botName, message.recipient, command_parsed.command,
|
316
|
+
message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
|
317
|
+
winston.debug("agent_handoff faqs agent sent ", savedMessage.toObject());
|
318
|
+
});
|
319
|
+
// PATCH: Chat clients (i.e. web widget) remove messages with text = null
|
320
|
+
// command_parsed.text contains the eventual text before the \agent command
|
321
|
+
// or 'all the message text' if \agent was not found
|
322
|
+
bot_answer.text = command_parsed.text? command_parsed.text : undefined;
|
323
|
+
winston.debug("bot_answer.text1 "+ bot_answer.text );
|
324
|
+
}
|
325
|
+
|
326
|
+
|
327
|
+
|
233
328
|
// send(sender, senderFullname, recipient, text, id_project, createdBy, attributes) {
|
234
329
|
messageService.send(sender, botName, message.recipient, bot_answer.text,
|
235
|
-
message.id_project, sender, attr, bot_answer.type, bot_answer.metadata).then(function(savedMessage){
|
330
|
+
message.id_project, sender, attr, bot_answer.type, bot_answer.metadata, bot_answer.language).then(function(savedMessage){
|
236
331
|
|
237
332
|
winston.debug("faqbot message sending ", savedMessage.toObject());
|
238
333
|
});
|
@@ -244,7 +339,6 @@ class FaqBotHandler {
|
|
244
339
|
var threshold = 1.2;
|
245
340
|
|
246
341
|
faqBotSupport.getBotMessage(answerObj, message.id_project, faq_kb, message, threshold).then(function(botAns){
|
247
|
-
// faqBotSupport.getBotMessage(answerObj, message.id_project, message.request.department._id, message.language, 1.2).then(function(botAns){
|
248
342
|
winston.debug("faqbot message botAns ", botAns);
|
249
343
|
|
250
344
|
if (botAns) {
|
@@ -304,9 +398,30 @@ class FaqBotHandler {
|
|
304
398
|
winston.debug("attr", attr);
|
305
399
|
|
306
400
|
|
401
|
+
|
402
|
+
const command_parsed = FaqBotHandler.is_command(botAns.text);
|
403
|
+
winston.debug('command_parsed?', command_parsed);
|
404
|
+
|
405
|
+
if (command_parsed.command) {
|
406
|
+
winston.debug("agent_handoff faqs command found");
|
407
|
+
|
408
|
+
messageService.send(sender, botName, message.recipient, command_parsed.command,
|
409
|
+
message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
|
410
|
+
winston.debug("agent_handoff faqs agent sent ", savedMessage.toObject());
|
411
|
+
});
|
412
|
+
// PATCH: Chat clients (i.e. web widget) remove messages with text = null
|
413
|
+
// command_parsed.text contains the eventual text before the \agent command
|
414
|
+
// or 'all the message text' if \agent was not found
|
415
|
+
botAns.text = command_parsed.text? command_parsed.text : undefined;
|
416
|
+
winston.debug("bot_answer.text1 "+ botAns.text );
|
417
|
+
}
|
418
|
+
|
419
|
+
|
420
|
+
|
421
|
+
|
307
422
|
// send(sender, senderFullname, recipient, text, id_project, createdBy, attributes, type, metadata)
|
308
423
|
messageService.send(sender, botName, message.recipient, botAns.text,
|
309
|
-
message.id_project, sender, attr, botAns.type, botAns.metadata).then(function(savedMessage){
|
424
|
+
message.id_project, sender, attr, botAns.type, botAns.metadata, botAns.language).then(function(savedMessage){
|
310
425
|
winston.debug("faqbot message botAns " ,savedMessage.toObject());
|
311
426
|
});
|
312
427
|
}
|