@tiledesk/tiledesk-server 2.2.37 → 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +8 -1
- package/LICENSE +14 -657
- package/README.md +21 -18
- package/app.js +27 -3
- package/config/labels/widget.json +320 -0
- package/event/subscriptionEvent.js +11 -0
- package/models/subscriptionEvent.js +11 -0
- package/models/subscriptionLog.js +34 -0
- package/models/tagLibrary.js +42 -0
- package/package.json +5 -11
- package/pubmodules/activities/activityArchiver.js +295 -0
- package/pubmodules/activities/index.js +3 -0
- package/pubmodules/activities/models/activity.js +88 -0
- package/pubmodules/activities/routes/activity.js +710 -0
- package/pubmodules/activities/test/activityRoute.js +85 -0
- package/pubmodules/analytics/analytics.js +1719 -0
- package/pubmodules/analytics/index.js +3 -0
- package/pubmodules/canned/cannedResponse.js +51 -0
- package/pubmodules/canned/cannedResponseRoute.js +157 -0
- package/pubmodules/canned/index.js +3 -0
- package/pubmodules/pubModulesManager.js +115 -7
- package/pubmodules/rasa/index.js +8 -1
- package/pubmodules/rasa/listener.js +28 -7
- package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +2 -2
- package/pubmodules/trigger/default.js +271 -0
- package/pubmodules/trigger/event/actionEventEmitter.js +10 -0
- package/pubmodules/trigger/event/flowEventEmitter.js +10 -0
- package/pubmodules/trigger/event/triggerEventEmitter.js +10 -0
- package/pubmodules/trigger/index.js +3 -0
- package/pubmodules/trigger/models/trigger.js +149 -0
- package/pubmodules/trigger/rulesTrigger.js +1180 -0
- package/pubmodules/trigger/start.js +114 -0
- package/pubmodules/trigger/triggerRoute.js +150 -0
- package/routes/department.js +51 -0
- package/routes/group.js +140 -0
- package/routes/project.js +52 -0
- package/routes/request.js +3 -2
- package/routes/subscription.js +140 -0
- package/routes/tag.js +138 -0
- package/services/faqBotHandler.js +2 -2
- package/services/faqBotSupport.js +0 -1
- package/services/faqService.js +1 -1
- package/services/modulesManager.js +16 -182
- package/services/subscriptionNotifier.js +485 -0
- package/template/email/assignedEmailMessage.html +1 -1
- package/template/email/assignedRequest.html +1 -1
- package/template/email/newMessage.html +1 -1
- package/template/email/passwordChanged.html +1 -1
- package/template/email/pooledEmailMessage.html +1 -1
- package/template/email/pooledRequest.html +1 -1
- package/template/email/resetPassword.html +2 -2
- package/template/email/ticket.html +1 -1
- package/views/messages.jade +1 -1
@@ -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;
|
@@ -1,10 +1,9 @@
|
|
1
1
|
|
2
2
|
var winston = require('../config/winston');
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
|
package/pubmodules/rasa/index.js
CHANGED
@@ -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
|
-
|
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
|
-
|
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.
|
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.
|
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());
|