@tiledesk/tiledesk-server 2.9.26 → 2.9.28
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 +9 -0
- package/package.json +2 -2
- package/pubmodules/pubModulesManager.js +41 -41
- package/pubmodules/routing-queue/listenerQueued.js +72 -27
- package/routes/faq_kb.js +1 -1
- package/routes/kb.js +2 -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/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 +1 -1
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,15 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.9.28
|
9
|
+
- Updated number_assigned_request count logic (removed incr/decr)
|
10
|
+
|
11
|
+
# 2.9.27
|
12
|
+
- Updated tybot-connector to 0.2.107
|
13
|
+
- Improved quotas slots
|
14
|
+
- Improved requests quota count (temporary conversation will no longer counted)
|
15
|
+
- Fixed bug: savedFaq is not defined in /importjson
|
16
|
+
|
8
17
|
# 2.9.26
|
9
18
|
- Updated tybot-connector to 0.2.105
|
10
19
|
- Added route for faqs csv file uploading on /kb
|
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.28",
|
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');
|
@@ -2,6 +2,7 @@ const authEvent = require('../../event/authEvent');
|
|
2
2
|
const requestEvent = require('../../event/requestEvent');
|
3
3
|
var Project = require('../../models/project');
|
4
4
|
var Project_user = require('../../models/project_user');
|
5
|
+
var Request = require('../../models/request')
|
5
6
|
var winston = require('../../config/winston');
|
6
7
|
|
7
8
|
var ProjectUserUtil = require("../../utils/project_userUtil");
|
@@ -34,44 +35,88 @@ class Listener {
|
|
34
35
|
this.enabled = false;
|
35
36
|
}
|
36
37
|
winston.debug("Listener this.enabled: "+ this.enabled);
|
37
|
-
}
|
38
|
+
}
|
38
39
|
|
39
40
|
|
40
|
-
|
41
|
+
// db.getCollection('project_users').find({"number_assigned_requests" : {"$lt":0}}).count()
|
42
|
+
|
43
|
+
// New version of updateProjectUser() method.
|
44
|
+
// This will not increment or decrement the number_assigned_requests field but search the exact number of assigned conversation to the project user
|
45
|
+
updateProjectUser(id_user, id_project, operation) {
|
46
|
+
winston.debug("Route queue updateProjectUser start operation: " + operation + "id_user " + id_user + " id_project " + id_project);
|
47
|
+
|
48
|
+
return Request.countDocuments({ id_project: id_project, participantsAgents: id_user, status: { $lt: 1000 } }, (err, requestsCount) => {
|
49
|
+
console.log("requestsCount for id_user: ", id_user, "and project: ", id_project, "-->", requestsCount);
|
50
|
+
if (err) {
|
51
|
+
return winston.error(err);
|
52
|
+
}
|
53
|
+
|
54
|
+
return Project_user
|
55
|
+
.findOneAndUpdate({ id_user: id_user, id_project: id_project }, { number_assigned_requests: requestsCount }, { new: true, upsert: false }, function (err, updatedPU) {
|
56
|
+
if (err) {
|
57
|
+
return winston.error(err);
|
58
|
+
}
|
59
|
+
// winston.debug("Route queue number_assigned_requests +1 :" + updatedPU.id);
|
60
|
+
// winston.debug("Route queue number_assigned_requests +1 :" + updatedPU.id);
|
61
|
+
winston.debug("Route queue number_assigned_requests updated to " + requestsCount + "for project user " + updatedPU.id);
|
62
|
+
|
63
|
+
updatedPU.populate({ path: 'id_user', select: { 'firstname': 1, 'lastname': 1 } }, function (err, updatedProject_userPopulated) {
|
64
|
+
|
65
|
+
var pu = updatedProject_userPopulated.toJSON();
|
66
|
+
|
67
|
+
return Project.findById(id_project).exec(function (err, project) {
|
68
|
+
pu.isBusy = ProjectUserUtil.isBusy(updatedProject_userPopulated, project.settings && project.settings.max_agent_assigned_chat);
|
69
|
+
winston.debug("Route queue pu.isBusy: " + pu.isBusy);
|
70
|
+
|
71
|
+
authEvent.emit('project_user.update', { updatedProject_userPopulated: pu, req: undefined, skipArchive: true }); //if queued with jobs -> websocket notification on project_user.update doesn't work??? forse si in quanto viene convertito in .pub.queue e poi rifunziiona
|
72
|
+
|
73
|
+
|
74
|
+
// project_user.update triggers activityArchiver(tested), cache invalidation(tested), subscriptionNotifierQueued and websocket(tested works from queue i trigger ws)
|
75
|
+
if (requestEvent.queueEnabled) { //force to .queue to be catched into the queue (activity archiver, subscriptionNotifierQueued )
|
76
|
+
authEvent.emit('project_user.update.queue', { updatedProject_userPopulated: pu, req: undefined, skipArchive: true });
|
77
|
+
}
|
78
|
+
|
79
|
+
})
|
80
|
+
|
81
|
+
});
|
82
|
+
|
83
|
+
});
|
84
|
+
})
|
41
85
|
|
86
|
+
}
|
42
87
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
88
|
+
_updateProjectUser(id_user, id_project, operation) {
|
89
|
+
winston.debug("Route queue updateProjectUser start operation: " + operation + "id_user " + id_user + " id_project " + id_project);
|
90
|
+
return Project_user
|
91
|
+
.findOneAndUpdate({ id_user: id_user, id_project: id_project }, { $inc: { 'number_assigned_requests': operation } }, { new: true, upsert: false }, function (err, updatedPU) {
|
92
|
+
if (err) {
|
93
|
+
return winston.error(err);
|
94
|
+
}
|
95
|
+
winston.debug("Route queue number_assigned_requests +1 :" + updatedPU.id);
|
96
|
+
winston.debug("Route queue number_assigned_requests +1 :" + updatedPU.id);
|
52
97
|
|
53
|
-
|
98
|
+
updatedPU.populate({ path: 'id_user', select: { 'firstname': 1, 'lastname': 1 } }, function (err, updatedProject_userPopulated) {
|
54
99
|
|
55
|
-
|
100
|
+
var pu = updatedProject_userPopulated.toJSON();
|
56
101
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
authEvent.emit('project_user.update', {updatedProject_userPopulated:pu, req: undefined, skipArchive: true}); //if queued with jobs -> websocket notification on project_user.update doesn't work??? forse si in quanto viene convertito in .pub.queue e poi rifunziiona
|
102
|
+
return Project.findById(id_project).exec(function (err, project) {
|
103
|
+
pu.isBusy = ProjectUserUtil.isBusy(updatedProject_userPopulated, project.settings && project.settings.max_agent_assigned_chat);
|
104
|
+
winston.debug("Route queue pu.isBusy: " + pu.isBusy);
|
62
105
|
|
106
|
+
authEvent.emit('project_user.update', { updatedProject_userPopulated: pu, req: undefined, skipArchive: true }); //if queued with jobs -> websocket notification on project_user.update doesn't work??? forse si in quanto viene convertito in .pub.queue e poi rifunziiona
|
63
107
|
|
64
|
-
// project_user.update triggers activityArchiver(tested), cache invalidation(tested), subscriptionNotifierQueued and websocket(tested works from queue i trigger ws)
|
65
|
-
if (requestEvent.queueEnabled) { //force to .queue to be catched into the queue (activity archiver, subscriptionNotifierQueued )
|
66
|
-
authEvent.emit('project_user.update.queue', {updatedProject_userPopulated:pu, req: undefined, skipArchive: true});
|
67
|
-
}
|
68
108
|
|
69
|
-
|
70
|
-
|
71
|
-
|
109
|
+
// project_user.update triggers activityArchiver(tested), cache invalidation(tested), subscriptionNotifierQueued and websocket(tested works from queue i trigger ws)
|
110
|
+
if (requestEvent.queueEnabled) { //force to .queue to be catched into the queue (activity archiver, subscriptionNotifierQueued )
|
111
|
+
authEvent.emit('project_user.update.queue', { updatedProject_userPopulated: pu, req: undefined, skipArchive: true });
|
112
|
+
}
|
72
113
|
|
73
|
-
|
74
|
-
|
114
|
+
})
|
115
|
+
|
116
|
+
});
|
117
|
+
|
118
|
+
});
|
119
|
+
}
|
75
120
|
|
76
121
|
updateParticipatingProjectUsers(request, operation) {
|
77
122
|
winston.debug("Route queue request.participatingAgents", request.participatingAgents);
|
package/routes/faq_kb.js
CHANGED
package/routes/kb.js
CHANGED
@@ -466,7 +466,7 @@ router.get('/namespace/:id/chatbots', async (req, res) => {
|
|
466
466
|
|
467
467
|
let project_id = req.projectid;
|
468
468
|
let namespace_id = req.params.id;
|
469
|
-
|
469
|
+
|
470
470
|
let chatbotsArray = [];
|
471
471
|
|
472
472
|
let namespaces = await Namespace.find({ id_project: project_id }).catch((err) => {
|
@@ -492,6 +492,7 @@ router.get('/namespace/:id/chatbots', async (req, res) => {
|
|
492
492
|
let chatbots = intents.map(i => i.id_faq_kb);
|
493
493
|
let uniqueChatbots = [...new Set(chatbots)];
|
494
494
|
|
495
|
+
|
495
496
|
let chatbotPromises = uniqueChatbots.map(async (c_id) => {
|
496
497
|
try {
|
497
498
|
let chatbot = await faq_kb.findOne({ _id: c_id, trashed: false });
|
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
|
|