@tiledesk/tiledesk-server 2.9.25 → 2.9.27
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/CHANGELOG.md +10 -0
- package/package.json +2 -2
- package/pubmodules/pubModulesManager.js +41 -41
- package/routes/faq_kb.js +1 -1
- package/routes/kb.js +114 -1
- package/routes/message.js +55 -50
- package/routes/request.js +581 -47
- package/routes/users.js +4 -7
- package/services/QuoteManager.js +104 -16
- package/services/emailService.js +11 -2
- package/services/operatingHoursService.js +1 -0
- package/services/projectService.js +21 -0
- package/services/requestService.js +344 -9
- package/template/email/redirectToDesktopEmail.html +2 -2
- package/test/example-kb-faqs.csv +2 -0
- package/test/kbRoute.js +45 -0
- package/test/mock/projectMock.js +29 -1
- package/test/projectRoute.js +86 -3
- package/test/quoteManager.js +77 -5
- package/test/requestRoute.js +42 -0
- package/websocket/webSocketServer.js +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@
|
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
|
7
7
|
|
|
8
|
+
# 2.9.27
|
|
9
|
+
- Updated tybot-connector to 0.2.107
|
|
10
|
+
- Improved quotas slots
|
|
11
|
+
- Improved requests quota count (temporary conversation will no longer counted)
|
|
12
|
+
- Fixed bug: savedFaq is not defined in /importjson
|
|
13
|
+
|
|
14
|
+
# 2.9.26
|
|
15
|
+
- Updated tybot-connector to 0.2.105
|
|
16
|
+
- Added route for faqs csv file uploading on /kb
|
|
17
|
+
|
|
8
18
|
# 2.9.25
|
|
9
19
|
- Updated vxml-connector to 0.1.44
|
|
10
20
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiledesk/tiledesk-server",
|
|
3
3
|
"description": "The Tiledesk server module",
|
|
4
|
-
"version": "2.9.
|
|
4
|
+
"version": "2.9.27",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "node ./bin/www",
|
|
7
7
|
"pretest": "mongodb-runner start",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
|
49
49
|
"@tiledesk/tiledesk-telegram-connector": "^0.1.14",
|
|
50
50
|
"@tiledesk/tiledesk-train-jobworker": "^0.0.11",
|
|
51
|
-
"@tiledesk/tiledesk-tybot-connector": "^0.2.
|
|
51
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.2.107",
|
|
52
52
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.73",
|
|
53
53
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.8",
|
|
54
54
|
"@tiledesk/tiledesk-sms-connector": "^0.1.10",
|
|
@@ -33,11 +33,11 @@ class PubModulesManager {
|
|
|
33
33
|
this.telegram = undefined;
|
|
34
34
|
this.telegramRoute = undefined;
|
|
35
35
|
|
|
36
|
-
this.sms = undefined;
|
|
37
|
-
this.smsRoute = undefined;
|
|
36
|
+
// this.sms = undefined;
|
|
37
|
+
// this.smsRoute = undefined;
|
|
38
38
|
|
|
39
|
-
this.voice = undefined;
|
|
40
|
-
this.voiceRoute = undefined;
|
|
39
|
+
// this.voice = undefined;
|
|
40
|
+
// this.voiceRoute = undefined;
|
|
41
41
|
|
|
42
42
|
this.mqttTest = undefined;
|
|
43
43
|
this.mqttTestRoute = undefined;
|
|
@@ -97,14 +97,14 @@ class PubModulesManager {
|
|
|
97
97
|
app.use('/modules/telegram', this.telegramRoute);
|
|
98
98
|
winston.info("PubModulesManager telegramRoute controller loaded");
|
|
99
99
|
}
|
|
100
|
-
if (this.smsRoute) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
if (this.voiceRoute) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
100
|
+
// if (this.smsRoute) {
|
|
101
|
+
// app.use('/modules/sms', this.smsRoute);
|
|
102
|
+
// winston.info("PubModulesManager smsRoute controller loaded");
|
|
103
|
+
// }
|
|
104
|
+
// if (this.voiceRoute) {
|
|
105
|
+
// app.use('/modules/voice', this.voiceRoute);
|
|
106
|
+
// winston.info("PubModulesManager voiceRoute controller loaded");
|
|
107
|
+
// }
|
|
108
108
|
if (this.mqttTestRoute) {
|
|
109
109
|
app.use('/modules/mqttTest', this.mqttTestRoute);
|
|
110
110
|
winston.info("PubModulesManager mqttTestRoute controller loaded");
|
|
@@ -345,40 +345,40 @@ class PubModulesManager {
|
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
if (process.env.VOICE_TOKEN === process.env.VOICE_SECRET) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
348
|
+
// if (process.env.VOICE_TOKEN === process.env.VOICE_SECRET) {
|
|
349
|
+
// try {
|
|
350
|
+
// this.voice = require('./voice');
|
|
351
|
+
// winston.info("this.voice: " + this.voice);
|
|
352
|
+
// this.voice.listener.listen(config);
|
|
353
353
|
|
|
354
|
-
|
|
354
|
+
// this.voiceRoute = this.voice.voiceRoute;
|
|
355
355
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
356
|
+
// winston.info("PubModulesManager initialized apps (voice).")
|
|
357
|
+
// } catch(err) {
|
|
358
|
+
// console.log("\n Unable to start voice connector: ", err);
|
|
359
|
+
// if (err.code == 'MODULE_NOT_FOUND') {
|
|
360
|
+
// winston.info("PubModulesManager init apps module not found ");
|
|
361
|
+
// } else {
|
|
362
|
+
// winston.info("PubModulesManager error initializing init apps module", err);
|
|
363
|
+
// }
|
|
364
|
+
// }
|
|
365
|
+
// }
|
|
366
366
|
|
|
367
|
-
try {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
367
|
+
// try {
|
|
368
|
+
// this.sms = require('./sms');
|
|
369
|
+
// winston.info("this.sms: " + this.sms);
|
|
370
|
+
// this.sms.listener.listen(config);
|
|
371
371
|
|
|
372
|
-
|
|
372
|
+
// this.smsRoute = this.sms.smsRoute;
|
|
373
373
|
|
|
374
|
-
|
|
375
|
-
} catch(err) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
374
|
+
// winston.info("PubModulesManager initialized apps (sms).")
|
|
375
|
+
// } catch(err) {
|
|
376
|
+
// if (err.code == 'MODULE_NOT_FOUND') {
|
|
377
|
+
// winston.info("PubModulesManager init apps module not found ");
|
|
378
|
+
// } else {
|
|
379
|
+
// winston.info("PubModulesManager error initializing init apps module", err);
|
|
380
|
+
// }
|
|
381
|
+
// }
|
|
382
382
|
|
|
383
383
|
try {
|
|
384
384
|
this.mqttTest = require('./mqttTest');
|
package/routes/faq_kb.js
CHANGED
package/routes/kb.js
CHANGED
|
@@ -14,6 +14,7 @@ var mongoose = require('mongoose');
|
|
|
14
14
|
const faq = require('../models/faq');
|
|
15
15
|
const faq_kb = require('../models/faq_kb');
|
|
16
16
|
let Integration = require('../models/integrations');
|
|
17
|
+
var parsecsv = require("fast-csv");
|
|
17
18
|
|
|
18
19
|
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
|
|
19
20
|
|
|
@@ -465,7 +466,7 @@ router.get('/namespace/:id/chatbots', async (req, res) => {
|
|
|
465
466
|
|
|
466
467
|
let project_id = req.projectid;
|
|
467
468
|
let namespace_id = req.params.id;
|
|
468
|
-
|
|
469
|
+
|
|
469
470
|
let chatbotsArray = [];
|
|
470
471
|
|
|
471
472
|
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
|
@@ -491,6 +492,7 @@ router.get('/namespace/:id/chatbots', async (req, res) => {
|
|
|
491
492
|
let chatbots = intents.map(i => i.id_faq_kb);
|
|
492
493
|
let uniqueChatbots = [...new Set(chatbots)];
|
|
493
494
|
|
|
495
|
+
|
|
494
496
|
let chatbotPromises = uniqueChatbots.map(async (c_id) => {
|
|
495
497
|
try {
|
|
496
498
|
let chatbot = await faq_kb.findOne({ _id: c_id, trashed: false });
|
|
@@ -994,6 +996,117 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
|
994
996
|
|
|
995
997
|
})
|
|
996
998
|
|
|
999
|
+
router.post('/csv', upload.single('uploadFile'), async (req, res) => {
|
|
1000
|
+
|
|
1001
|
+
let project_id = req.projectid;
|
|
1002
|
+
|
|
1003
|
+
let csv = req.file.buffer.toString('utf8');
|
|
1004
|
+
winston.debug("csv: ", csv);
|
|
1005
|
+
|
|
1006
|
+
let delimiter = req.body.delimiter || ";";
|
|
1007
|
+
winston.debug("delimiter: ", delimiter);
|
|
1008
|
+
|
|
1009
|
+
let namespace_id = req.query.namespace;
|
|
1010
|
+
if (!namespace_id) {
|
|
1011
|
+
return res.status(400).send({ success: false, error: "queryParam 'namespace' is not defined" })
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
|
1015
|
+
winston.error("find namespaces error: ", err)
|
|
1016
|
+
res.status(500).send({ success: false, error: err })
|
|
1017
|
+
})
|
|
1018
|
+
|
|
1019
|
+
if (!namespaces || namespaces.length == 0) {
|
|
1020
|
+
let alert = "No namespace found for the selected project " + project_id + ". Cannot add content to a non-existent namespace."
|
|
1021
|
+
winston.warn(alert);
|
|
1022
|
+
res.status(403).send({ success: false, error: alert });
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
let namespaceIds = namespaces.map(namespace => namespace.id);
|
|
1026
|
+
|
|
1027
|
+
if (!namespaceIds.includes(namespace_id)) {
|
|
1028
|
+
return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project." })
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
let quoteManager = req.app.get('quote_manager');
|
|
1032
|
+
let limits = await quoteManager.getPlanLimits(req.project);
|
|
1033
|
+
let kbs_limit = limits.kbs;
|
|
1034
|
+
winston.verbose("Limit of kbs for current plan: " + kbs_limit);
|
|
1035
|
+
|
|
1036
|
+
let kbs_count = await KB.countDocuments({ id_project: project_id }).exec();
|
|
1037
|
+
winston.verbose("Kbs count: " + kbs_count);
|
|
1038
|
+
|
|
1039
|
+
if (kbs_count >= kbs_limit) {
|
|
1040
|
+
return res.status(403).send({ success: false, error: "Maximum number of resources reached for the current plan", plan_limit: kbs_limit })
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
|
|
1044
|
+
|
|
1045
|
+
let kbs = [];
|
|
1046
|
+
|
|
1047
|
+
parsecsv.parseString(csv, { headers: false, delimiter: delimiter })
|
|
1048
|
+
.on("data", (data) => {
|
|
1049
|
+
|
|
1050
|
+
let question = data[0];
|
|
1051
|
+
let answer = data[1];
|
|
1052
|
+
|
|
1053
|
+
console.log("data. ", data)
|
|
1054
|
+
kbs.push({
|
|
1055
|
+
id_project: project_id,
|
|
1056
|
+
name: question,
|
|
1057
|
+
source: question,
|
|
1058
|
+
type: 'faq',
|
|
1059
|
+
content: question + "\n" + answer,
|
|
1060
|
+
namespace: namespace_id,
|
|
1061
|
+
status: -1
|
|
1062
|
+
})
|
|
1063
|
+
})
|
|
1064
|
+
.on("end", () => {
|
|
1065
|
+
winston.debug("kbs after CSV parsing: ", kbs);
|
|
1066
|
+
|
|
1067
|
+
let total_count = kbs_count + kbs.length;
|
|
1068
|
+
if (total_count >= kbs_limit) {
|
|
1069
|
+
return res.status(403).send({ success: false, error: "Cannot exceed the number of resources in the current plan", plan_limit: kbs_limit })
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if (kbs.length > 300) {
|
|
1073
|
+
return res.status(403).send({ success: false, error: "Too many faqs. Can't index more than 300 urls at a time." })
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
let operations = kbs.map(doc => {
|
|
1077
|
+
return {
|
|
1078
|
+
updateOne: {
|
|
1079
|
+
filter: { id_project: doc.id_project, type: 'faq', source: doc.source },
|
|
1080
|
+
update: doc,
|
|
1081
|
+
upsert: true,
|
|
1082
|
+
returnOriginal: false
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
})
|
|
1086
|
+
|
|
1087
|
+
saveBulk(operations, kbs, project_id).then((result) => {
|
|
1088
|
+
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
|
1089
|
+
resources = resources.map(({ _id, ...rest}) => {
|
|
1090
|
+
return { id: _id, webhooh: webhook, ...rest };
|
|
1091
|
+
})
|
|
1092
|
+
winston.verbose("resources to be sent to worker: ", resources);
|
|
1093
|
+
if (!process.env.NODE_ENV) {
|
|
1094
|
+
scheduleScrape(resources);
|
|
1095
|
+
}
|
|
1096
|
+
res.status(200).send(result);
|
|
1097
|
+
}).catch((err) => {
|
|
1098
|
+
winston.error("Unabled to saved kbs in bulk " + err);
|
|
1099
|
+
res.status(500).send(err);
|
|
1100
|
+
})
|
|
1101
|
+
|
|
1102
|
+
})
|
|
1103
|
+
.on("error", (err) => {
|
|
1104
|
+
winston.error("CSV parsing error: ", err);
|
|
1105
|
+
res.status(400).send({ success: false, error: err });
|
|
1106
|
+
})
|
|
1107
|
+
|
|
1108
|
+
})
|
|
1109
|
+
|
|
997
1110
|
router.post('/sitemap', async (req, res) => {
|
|
998
1111
|
|
|
999
1112
|
let sitemap_url = req.body.sitemap;
|
package/routes/message.js
CHANGED
|
@@ -181,77 +181,82 @@ async (req, res) => {
|
|
|
181
181
|
requester: project_user,
|
|
182
182
|
priority: req.body.priority,
|
|
183
183
|
followers: req.body.followers,
|
|
184
|
+
proactive: true
|
|
184
185
|
};
|
|
185
186
|
|
|
186
187
|
return requestService.create(new_request).then(function (savedRequest) {
|
|
187
188
|
|
|
189
|
+
|
|
190
|
+
if (!savedRequest) {
|
|
191
|
+
return res.status(403).send({ success: false, message: "Requests quota exceeded"})
|
|
192
|
+
}
|
|
188
193
|
winston.debug("returning savedRequest to", savedRequest.toJSON());
|
|
189
194
|
|
|
190
195
|
// createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status,
|
|
191
196
|
// createdBy, attributes, subject, preflight, channel, location) {
|
|
192
|
-
|
|
193
|
-
// return requestService.createWithIdAndRequester(req.params.request_id, req.projectuser._id, createdLead._id, req.projectid,
|
|
194
|
-
// req.body.text, req.body.departmentid, req.body.sourcePage,
|
|
195
|
-
// req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes, req.body.subject, undefined, req.body.channel, req.body.location ).then(function (savedRequest) {
|
|
196
197
|
|
|
198
|
+
// return requestService.createWithIdAndRequester(req.params.request_id, req.projectuser._id, createdLead._id, req.projectid,
|
|
199
|
+
// req.body.text, req.body.departmentid, req.body.sourcePage,
|
|
200
|
+
// req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes, req.body.subject, undefined, req.body.channel, req.body.location ).then(function (savedRequest) {
|
|
197
201
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// create(sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata, language, channel_type, channel) {
|
|
201
|
-
return messageService.create(sender || req.user._id, fullname, req.params.request_id, req.body.text,
|
|
202
|
-
req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata, req.body.language, undefined, req.body.channel).then(function(savedMessage){
|
|
203
|
-
|
|
204
|
-
// return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
|
205
202
|
|
|
206
|
-
let message = savedMessage.toJSON();
|
|
207
203
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
.populate({path:'requester',populate:{path:'id_user'}})
|
|
221
|
-
// .exec(function (err, savedRequestPopulated){
|
|
222
|
-
.execPopulate(function (err, savedRequestPopulated){ //bug with execPopulate request.attributes are invalid (NOT real data). but this bug is related to chat21 listener changes by reference. i think populate suffer from this problem bacause it it the same obect passed by reference
|
|
223
|
-
|
|
224
|
-
if (err) {
|
|
225
|
-
return winston.error("Error gettting savedRequestPopulated for send Message", err);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
winston.debug("returning savedRequest221 to", savedRequest.toJSON());
|
|
204
|
+
|
|
205
|
+
// create(sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata, language, channel_type, channel) {
|
|
206
|
+
return messageService.create(sender || req.user._id, fullname, req.params.request_id, req.body.text,
|
|
207
|
+
req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata, req.body.language, undefined, req.body.channel).then(function (savedMessage) {
|
|
208
|
+
|
|
209
|
+
// return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
|
210
|
+
|
|
211
|
+
let message = savedMessage.toJSON();
|
|
212
|
+
|
|
213
|
+
winston.debug("returning message to", message);
|
|
214
|
+
|
|
215
|
+
winston.debug("returning savedRequest2210 to", savedRequest.toJSON());
|
|
229
216
|
|
|
230
217
|
|
|
231
|
-
|
|
218
|
+
savedRequest //bug
|
|
219
|
+
// Request.findById(savedRequest.id)
|
|
220
|
+
.populate('lead')
|
|
221
|
+
.populate('department')
|
|
222
|
+
.populate('participatingBots')
|
|
223
|
+
.populate('participatingAgents')
|
|
224
|
+
// .populate('followers')
|
|
225
|
+
.populate({ path: 'requester', populate: { path: 'id_user' } })
|
|
226
|
+
// .exec(function (err, savedRequestPopulated){
|
|
227
|
+
.execPopulate(function (err, savedRequestPopulated) { //bug with execPopulate request.attributes are invalid (NOT real data). but this bug is related to chat21 listener changes by reference. i think populate suffer from this problem bacause it it the same obect passed by reference
|
|
232
228
|
|
|
233
|
-
|
|
229
|
+
if (err) {
|
|
230
|
+
return winston.error("Error gettting savedRequestPopulated for send Message", err);
|
|
231
|
+
}
|
|
234
232
|
|
|
233
|
+
winston.debug("returning savedRequest221 to", savedRequest.toJSON());
|
|
235
234
|
|
|
236
|
-
message.request = savedRequestPopulated;
|
|
237
|
-
winston.debug("returning2 message to", message);
|
|
238
235
|
|
|
236
|
+
winston.debug("savedRequestPopulated", savedRequestPopulated.toJSON());
|
|
239
237
|
|
|
240
|
-
|
|
241
|
-
|
|
238
|
+
winston.debug("returning savedRequest22 to", savedRequest.toJSON());
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
message.request = savedRequestPopulated;
|
|
242
|
+
winston.debug("returning2 message to", message);
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
return res.json(message);
|
|
242
246
|
});
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
// winston.error("Error creating message", err);
|
|
251
|
-
return res.status(500).send({success: false, msg: 'Error creating request', err:err });
|
|
252
|
-
});
|
|
253
|
-
|
|
247
|
+
});
|
|
248
|
+
}).catch(function (err) { //pubblica questo
|
|
249
|
+
winston.error('Error creating request: ' + JSON.stringify(err));
|
|
250
|
+
winston.log({
|
|
251
|
+
level: 'error',
|
|
252
|
+
message: 'Error creating request: ' + JSON.stringify(err) + " " + JSON.stringify(req.body),
|
|
253
|
+
label: req.projectid
|
|
254
254
|
});
|
|
255
|
+
// winston.error("Error creating message", err);
|
|
256
|
+
return res.status(500).send({ success: false, msg: 'Error creating request', err: err });
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
});
|
|
255
260
|
|
|
256
261
|
|
|
257
262
|
|