@tiledesk/tiledesk-server 2.2.37 → 2.3.1

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/LICENSE +14 -657
  3. package/README.md +21 -18
  4. package/app.js +27 -3
  5. package/config/labels/widget.json +320 -0
  6. package/event/subscriptionEvent.js +11 -0
  7. package/models/subscriptionEvent.js +11 -0
  8. package/models/subscriptionLog.js +34 -0
  9. package/models/tagLibrary.js +42 -0
  10. package/package.json +5 -11
  11. package/pubmodules/activities/activityArchiver.js +295 -0
  12. package/pubmodules/activities/index.js +3 -0
  13. package/pubmodules/activities/models/activity.js +88 -0
  14. package/pubmodules/activities/routes/activity.js +710 -0
  15. package/pubmodules/activities/test/activityRoute.js +85 -0
  16. package/pubmodules/analytics/analytics.js +1719 -0
  17. package/pubmodules/analytics/index.js +3 -0
  18. package/pubmodules/canned/cannedResponse.js +51 -0
  19. package/pubmodules/canned/cannedResponseRoute.js +157 -0
  20. package/pubmodules/canned/index.js +3 -0
  21. package/pubmodules/pubModulesManager.js +115 -7
  22. package/pubmodules/rasa/index.js +8 -1
  23. package/pubmodules/rasa/listener.js +28 -7
  24. package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +2 -2
  25. package/pubmodules/trigger/default.js +271 -0
  26. package/pubmodules/trigger/event/actionEventEmitter.js +10 -0
  27. package/pubmodules/trigger/event/flowEventEmitter.js +10 -0
  28. package/pubmodules/trigger/event/triggerEventEmitter.js +10 -0
  29. package/pubmodules/trigger/index.js +3 -0
  30. package/pubmodules/trigger/models/trigger.js +149 -0
  31. package/pubmodules/trigger/rulesTrigger.js +1180 -0
  32. package/pubmodules/trigger/start.js +114 -0
  33. package/pubmodules/trigger/triggerRoute.js +150 -0
  34. package/routes/department.js +51 -0
  35. package/routes/group.js +140 -0
  36. package/routes/project.js +52 -0
  37. package/routes/request.js +3 -2
  38. package/routes/subscription.js +140 -0
  39. package/routes/tag.js +138 -0
  40. package/services/faqBotHandler.js +2 -2
  41. package/services/faqBotSupport.js +0 -1
  42. package/services/faqService.js +1 -1
  43. package/services/modulesManager.js +16 -182
  44. package/services/subscriptionNotifier.js +485 -0
  45. package/template/email/assignedEmailMessage.html +1 -1
  46. package/template/email/assignedRequest.html +1 -1
  47. package/template/email/newMessage.html +1 -1
  48. package/template/email/passwordChanged.html +1 -1
  49. package/template/email/pooledEmailMessage.html +1 -1
  50. package/template/email/pooledRequest.html +1 -1
  51. package/template/email/resetPassword.html +2 -2
  52. package/template/email/ticket.html +1 -1
  53. package/views/messages.jade +1 -1
@@ -0,0 +1,3 @@
1
+ const analyticsRoute = require("./analytics");
2
+
3
+ module.exports = {analyticsRoute:analyticsRoute};
@@ -0,0 +1,51 @@
1
+ var mongoose = require('mongoose');
2
+ var Schema = mongoose.Schema;
3
+ var winston = require('../../config/winston');
4
+
5
+
6
+ var CannedResponseSchema = new Schema({
7
+
8
+ title: {
9
+ type: String,
10
+ required: false,
11
+ index: true
12
+ },
13
+ text: {
14
+ type: String,
15
+ required: true,
16
+ },
17
+ attributes: {
18
+ type: Object,
19
+ },
20
+ id_project: {
21
+ type: String,
22
+ required: true,
23
+ index: true
24
+ },
25
+ createdBy: {
26
+ type: String,
27
+ required: true
28
+ },
29
+ status: {
30
+ type: Number,
31
+ required: false,
32
+ default: 100,
33
+ index: true
34
+ },
35
+ },{
36
+ timestamps: true
37
+ }
38
+ );
39
+
40
+
41
+ // CannedResponseSchema.index({text: 'text'},
42
+ // {"name":"cannedresponse_fulltext","default_language": "italian","language_override": "dummy"}); // schema level
43
+
44
+ var CannedResponse = mongoose.model('cannedResponse', CannedResponseSchema);
45
+
46
+ if (process.env.MONGOOSE_SYNCINDEX) {
47
+ CannedResponse.syncIndexes();
48
+ winston.info("CannedResponse syncIndexes")
49
+ }
50
+
51
+ module.exports = CannedResponse;
@@ -0,0 +1,157 @@
1
+ var express = require('express');
2
+ var router = express.Router();
3
+ var CannedResponse = require("./cannedResponse");
4
+ var winston = require('../../config/winston');
5
+ // const CannedResponseEvent = require('../event/CannedResponseEvent');
6
+
7
+
8
+ router.post('/', function (req, res) {
9
+
10
+ winston.debug(req.body);
11
+ winston.debug("req.user", req.user);
12
+
13
+ var newCannedResponse = new CannedResponse({
14
+ title: req.body.title,
15
+ text: req.body.text,
16
+ id_project: req.projectid,
17
+ createdBy: req.user.id,
18
+ updatedBy: req.user.id
19
+ });
20
+
21
+ newCannedResponse.save(function (err, savedCannedResponse) {
22
+ if (err) {
23
+ winston.error('--- > ERROR ', err)
24
+
25
+ return res.status(500).send({ success: false, msg: 'Error saving object.' });
26
+ }
27
+
28
+ res.json(savedCannedResponse);
29
+ });
30
+ });
31
+
32
+ router.put('/:cannedResponseid', function (req, res) {
33
+ winston.debug(req.body);
34
+ var update = {};
35
+
36
+ if (req.body.title!=undefined) {
37
+ update.title = req.body.title;
38
+ }
39
+ if (req.body.text!=undefined) {
40
+ update.text = req.body.text;
41
+ }
42
+ if (req.body.attributes!=undefined) {
43
+ update.attributes = req.body.attributes;
44
+ }
45
+
46
+
47
+ CannedResponse.findByIdAndUpdate(req.params.cannedResponseid, update, { new: true, upsert: true }, function (err, updatedCannedResponse) {
48
+ if (err) {
49
+ winston.error('--- > ERROR ', err);
50
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
51
+ }
52
+
53
+
54
+
55
+ // CannedResponseEvent.emit('CannedResponse.update', updatedCannedResponse);
56
+ res.json(updatedCannedResponse);
57
+ });
58
+ });
59
+
60
+ router.delete('/:cannedResponseid', function (req, res) {
61
+ winston.debug(req.body);
62
+
63
+ CannedResponse.findByIdAndUpdate(req.params.cannedResponseid, {status: 1000}, { new: true, upsert: true }, function (err, updatedCannedResponse) {
64
+ if (err) {
65
+ winston.error('--- > ERROR ', err);
66
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
67
+ }
68
+
69
+
70
+
71
+ // CannedResponseEvent.emit('CannedResponse.delete', updatedCannedResponse);
72
+ res.json(updatedCannedResponse);
73
+ });
74
+ });
75
+
76
+ router.delete('/:cannedResponseid/physical', function (req, res) {
77
+ winston.debug(req.body);
78
+
79
+ CannedResponse.remove({ _id: req.params.cannedResponseid }, function (err, cannedResponse) {
80
+ if (err) {
81
+ winston.error('--- > ERROR ', err);
82
+ return res.status(500).send({ success: false, msg: 'Error deleting object.' });
83
+ }
84
+
85
+
86
+ // CannedResponseEvent.emit('CannedResponse.delete', CannedResponse);
87
+
88
+ res.json(cannedResponse);
89
+ });
90
+ });
91
+
92
+ router.get('/:cannedResponseid', function (req, res) {
93
+ winston.debug(req.body);
94
+
95
+ CannedResponse.findById(req.params.cannedResponseid, function (err, cannedResponse) {
96
+ if (err) {
97
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
98
+ }
99
+ if (!cannedResponse) {
100
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
101
+ }
102
+ res.json(cannedResponse);
103
+ });
104
+ });
105
+
106
+ router.get('/', function (req, res) {
107
+ var limit = 40; // Number of CannedResponses per page
108
+ var page = 0;
109
+
110
+ if (req.query.page) {
111
+ page = req.query.page;
112
+ }
113
+
114
+ var skip = page * limit;
115
+ winston.debug('CannedResponse ROUTE - SKIP PAGE ', skip);
116
+
117
+
118
+ var query = { "id_project": req.projectid, "status": {$lt:1000}};
119
+
120
+ if (req.query.full_text) {
121
+ winston.debug('CannedResponse ROUTE req.query.fulltext', req.query.full_text);
122
+ query.$text = { "$search": req.query.full_text };
123
+ }
124
+
125
+
126
+ var direction = -1; //-1 descending , 1 ascending
127
+ if (req.query.direction) {
128
+ direction = req.query.direction;
129
+ }
130
+
131
+ var sortField = "createdAt";
132
+ if (req.query.sort) {
133
+ sortField = req.query.sort;
134
+ }
135
+
136
+ var sortQuery = {};
137
+ sortQuery[sortField] = direction;
138
+
139
+ winston.debug("sort query", sortQuery);
140
+
141
+ return CannedResponse.find(query).
142
+ skip(skip).limit(limit).
143
+ sort(sortQuery).
144
+ exec(function (err, cannedResponses) {
145
+ if (err) {
146
+ winston.error('CannedResponse ROUTE - REQUEST FIND ERR ', err)
147
+ return (err);
148
+ }
149
+
150
+ return res.json(cannedResponses);
151
+ });
152
+ });
153
+
154
+
155
+
156
+
157
+ module.exports = router;
@@ -0,0 +1,3 @@
1
+ const cannedResponseRoute = require("./cannedResponseRoute");
2
+
3
+ module.exports = {cannedResponseRoute: cannedResponseRoute};
@@ -1,10 +1,9 @@
1
1
 
2
2
  var winston = require('../config/winston');
3
- // var validtoken = require('../middleware/valid-token');
4
- // var roleChecker = require('../middleware/has-role');
5
- // var passport = require('passport');
6
- // require('../middleware/passport')(passport);
7
-
3
+ var validtoken = require('../middleware/valid-token');
4
+ var roleChecker = require('../middleware/has-role');
5
+ var passport = require('passport');
6
+ require('../middleware/passport')(passport);
8
7
 
9
8
  class PubModulesManager {
10
9
 
@@ -20,12 +19,29 @@ class PubModulesManager {
20
19
  this.scheduler = undefined;
21
20
 
22
21
  this.rasa = undefined;
22
+ this.rasaRoute = undefined;
23
+
24
+ this.activityArchiver = undefined;
25
+ this.activityRoute = undefined;
26
+
27
+ this.analyticsRoute = undefined;
28
+
29
+ this.cannedResponseRoute = undefined;
30
+
31
+ this.trigger = undefined;
32
+ this.triggerRoute = undefined;
33
+
23
34
  }
24
35
 
25
36
 
26
37
 
27
38
  use(app) {
28
39
 
40
+ if (this.rasaRoute) {
41
+ app.use('/modules/rasa', this.rasaRoute);
42
+ winston.info("ModulesManager rasaRoute controller loaded");
43
+ }
44
+
29
45
  }
30
46
  useUnderProjects(app) {
31
47
  var that = this;
@@ -39,10 +55,31 @@ class PubModulesManager {
39
55
  winston.info("ModulesManager eventsRoute controller loaded");
40
56
  }
41
57
 
58
+
59
+ if (this.activityRoute) {
60
+ app.use('/:projectid/activities', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], this.activityRoute);
61
+ winston.info("ModulesManager activities controller loaded");
62
+ }
63
+
64
+ if (this.analyticsRoute) {
65
+ app.use('/:projectid/analytics', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], this.analyticsRoute);
66
+ winston.info("ModulesManager analytics controller loaded");
67
+ }
68
+
69
+ if (this.cannedResponseRoute) {
70
+ app.use('/:projectid/canned', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], this.cannedResponseRoute);
71
+ winston.info("ModulesManager canned controller loaded");
72
+ }
73
+
74
+ if (this.triggerRoute) {
75
+ app.use('/:projectid/modules/triggers', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], this.triggerRoute);
76
+ winston.info("ModulesManager trigger controller loaded");
77
+ }
78
+
42
79
  }
43
80
 
44
81
 
45
- init() {
82
+ init(config) {
46
83
  winston.debug("PubModulesManager init");
47
84
 
48
85
  try {
@@ -145,7 +182,10 @@ class PubModulesManager {
145
182
  try {
146
183
  this.rasa = require('./rasa');
147
184
  winston.debug("this.rasa:"+ this.rasa);
148
- this.rasa.listener.listen();
185
+ this.rasa.listener.listen(config);
186
+
187
+ this.rasaRoute = this.rasa.rasaRoute;
188
+
149
189
  winston.info("PubModulesManager initialized rasa.");
150
190
  } catch(err) {
151
191
  if (err.code == 'MODULE_NOT_FOUND') {
@@ -157,7 +197,65 @@ class PubModulesManager {
157
197
 
158
198
 
159
199
 
200
+
201
+ try {
202
+ this.activityArchiver = require('./activities').activityArchiver;
203
+ // this.activityArchiver.listen();
204
+ winston.debug("this.activityArchiver:"+ this.activityArchiver);
205
+
206
+ this.activityRoute = require('./activities').activityRoute;
207
+ winston.debug("this.activityRoute:"+ this.activityRoute);
208
+
209
+ winston.info("ModulesManager activities initialized");
210
+ } catch(err) {
211
+ if (err.code == 'MODULE_NOT_FOUND') {
212
+ winston.info("ModulesManager init activities module not found");
213
+ }else {
214
+ winston.error("ModulesManager error initializing init activities module", err);
215
+ }
216
+ }
217
+
218
+
219
+ try {
220
+ this.analyticsRoute = require('./analytics').analyticsRoute;
221
+ winston.debug("this.analyticsRoute:"+ this.analyticsRoute);
222
+ winston.info("ModulesManager analyticsRoute initialized");
223
+ } catch(err) {
224
+ if (err.code == 'MODULE_NOT_FOUND') {
225
+ winston.info("ModulesManager init analytics module not found");
226
+ }else {
227
+ winston.error("ModulesManager error initializing init analytics module", err);
228
+ }
229
+ }
230
+
231
+
232
+
233
+ try {
234
+ this.cannedResponseRoute = require('./canned').cannedResponseRoute;
235
+ winston.debug("this.cannedResponseRoute:"+ this.cannedResponseRoute);
236
+ winston.info("ModulesManager cannedResponseRoute initialized");
237
+ } catch(err) {
238
+ if (err.code == 'MODULE_NOT_FOUND') {
239
+ winston.info("ModulesManager init canned module not found");
240
+ }else {
241
+ winston.error("ModulesManager error initializing init canned module", err);
242
+ }
243
+ }
244
+
160
245
 
246
+ try {
247
+ this.trigger = require('./trigger').start;
248
+ winston.debug("this.trigger:"+ this.trigger);
249
+ this.triggerRoute = require('./trigger').triggerRoute;
250
+ winston.debug("this.triggerRoute:"+ this.triggerRoute);
251
+ winston.info("ModulesManager trigger initialized");
252
+ } catch(err) {
253
+ if (err.code == 'MODULE_NOT_FOUND') {
254
+ winston.info("ModulesManager init trigger module not found");
255
+ }else {
256
+ winston.error("ModulesManager error initializing init trigger module", err);
257
+ }
258
+ }
161
259
 
162
260
  }
163
261
 
@@ -212,6 +310,16 @@ class PubModulesManager {
212
310
  }
213
311
 
214
312
 
313
+ if (this.activityArchiver) {
314
+ try {
315
+ this.activityArchiver.listen();
316
+ winston.info("ModulesManager activityArchiver started");
317
+ } catch(err) {
318
+ winston.info("ModulesManager error starting activityArchiver module", err);
319
+ }
320
+ }
321
+
322
+
215
323
  }
216
324
 
217
325
 
@@ -1,3 +1,10 @@
1
1
  const listener = require("./listener");
2
2
 
3
- module.exports = {listener:listener };
3
+ const rasa = require("@tiledesk/tiledesk-rasa-connector");
4
+ const rasaRoute = rasa.router;
5
+
6
+
7
+
8
+
9
+
10
+ module.exports = { listener: listener, rasaRoute: rasaRoute };
@@ -1,25 +1,46 @@
1
1
  const botEvent = require('../../event/botEvent');
2
2
  var Faq_kb = require("../../models/faq_kb");
3
3
  var winston = require('../../config/winston');
4
+ const rasa = require("@tiledesk/tiledesk-rasa-connector");
5
+ var configGlobal = require('../../config/global');
4
6
 
5
- const BOT_RASA_ENDPOINT = process.env.BOT_RASA_ENDPOINT;
7
+ var port = process.env.PORT || '3000';
8
+
9
+ const BOT_RASA_ENDPOINT = "http://localhost:" + port+ "/modules/rasa/rasabot" || process.env.BOT_RASA_ENDPOINT;
6
10
  winston.debug("BOT_RASA_ENDPOINT: " + BOT_RASA_ENDPOINT);
7
11
 
8
- if (BOT_RASA_ENDPOINT) {
12
+ // if (BOT_RASA_ENDPOINT) {
9
13
  winston.info("Rasa endpoint: " + BOT_RASA_ENDPOINT);
10
- } else {
11
- winston.info("Rasa endpoint not configured");
12
- }
14
+ // } else {
15
+ // winston.info("Rasa endpoint not configured");
16
+ // }
13
17
 
18
+ const apiUrl = process.env.API_URL || configGlobal.apiUrl;
19
+ winston.info('Rasa apiUrl: '+ apiUrl);
14
20
 
15
21
  class Listener {
16
22
 
17
- listen() {
23
+ listen(config) {
18
24
 
19
- winston.debug('rasa Listener listen');
25
+ winston.info('Rasa Listener listen');
26
+ winston.debug("config databaseUri: " + config.databaseUri);
27
+
20
28
 
21
29
  var that = this;
22
30
 
31
+
32
+ rasa.startRasa(
33
+ {
34
+ KVBASE_COLLECTION : process.env.KVBASE_COLLECTION,
35
+ MONGODB_URI: config.databaseUri,
36
+ API_ENDPOINT: apiUrl,
37
+ log: true
38
+ }, () => {
39
+ winston.info("RASA proxy server successfully started.");
40
+ });
41
+
42
+
43
+
23
44
  botEvent.on('faqbot.create', function(bot) {
24
45
  if (BOT_RASA_ENDPOINT) {
25
46
 
@@ -50,8 +50,8 @@ scheduleUnresponsiveRequests() {
50
50
  //https://crontab.guru/examples.html
51
51
  var s= schedule.scheduleJob(this.cronExp, function(fireDate){ //TODO aggiungi un bias random
52
52
 
53
- let timeInMs = Math.random() * (1000); // avoid cluster concurrent jobs in multiple nodes between 0 and 1sec
54
- winston.info('timeInMs => '+ timeInMs);
53
+ let timeInMs = Math.random() * (1000); // avoid cluster concurrent jobs in multiple nodes delay between 0 and 1sec
54
+ winston.debug('timeInMs => '+ timeInMs);
55
55
 
56
56
  setTimeout(function () {
57
57
  winston.debug('CloseBotUnresponsiveRequestTask scheduleUnresponsiveRequests job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date());