@tiledesk/tiledesk-server 2.3.72 → 2.3.74
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +24 -0
- package/event/botEvent.js +13 -1
- package/middleware/passport.js +39 -11
- package/models/faq_kb.js +5 -0
- package/models/presence.js +1 -1
- package/models/project.js +3 -0
- package/models/user.js +1 -0
- package/package.json +2 -2
- package/pubmodules/activities/models/activity.js +2 -0
- package/pubmodules/cache/mongoose-cachegoose-fn.js +171 -43
- package/pubmodules/emailNotification/requestNotification.js +15 -5
- package/pubmodules/pubModulesManager.js +6 -6
- package/routes/auth.js +24 -8
- package/routes/faq.js +6 -1
- package/routes/faq_kb.js +50 -1
- package/routes/message.js +7 -4
- package/routes/project.js +49 -1
- package/routes/widget.js +95 -13
- package/services/BotSubscriptionNotifier.js +17 -1
- package/services/cacheEnabler.js +5 -0
- package/services/departmentService.js +1 -1
- package/services/faqBotHandler.js +1 -1
- package/services/faqBotSupport.js +1 -1
- package/services/operatingHoursService.js +1 -1
- package/services/subscriptionNotifier.js +8 -2
- package/template/email/emailDirect.html +2 -0
- package/template/email/newMessage.html +1 -1
- package/test/messageRoute.js +1 -1
- package/utils/sendMessageUtil.js +2 -2
- package/websocket/webSocketServer.js +4 -4
@@ -24,7 +24,7 @@ var configGlobal = require('../../config/global');
|
|
24
24
|
|
25
25
|
var widgetConfig = require('../../config/widget');
|
26
26
|
var widgetTestLocation = process.env.WIDGET_TEST_LOCATION || widgetConfig.testLocation;
|
27
|
-
let configSecret = process.env.GLOBAL_SECRET || config.secret;
|
27
|
+
let configSecret = process.env.GLOBAL_SECRET_OR_PRIVATE_KEY || process.env.GLOBAL_SECRET || config.secret;
|
28
28
|
|
29
29
|
let apiUrl = process.env.API_URL || configGlobal.apiUrl;
|
30
30
|
winston.debug('********* RequestNotification apiUrl: ' + apiUrl);
|
@@ -290,9 +290,14 @@ sendToUserEmailChannelEmail(projectid, message) {
|
|
290
290
|
issuer: 'https://tiledesk.com',
|
291
291
|
subject: 'userexternal',
|
292
292
|
audience: 'https://tiledesk.com',
|
293
|
-
jwtid: uuidv4()
|
293
|
+
jwtid: uuidv4()
|
294
294
|
};
|
295
295
|
|
296
|
+
var alg = process.env.GLOBAL_SECRET_ALGORITHM;
|
297
|
+
if (alg) {
|
298
|
+
signOptions.algorithm = alg;
|
299
|
+
}
|
300
|
+
|
296
301
|
|
297
302
|
var recipient = lead.lead_id;
|
298
303
|
winston.debug("recipient:"+ recipient);
|
@@ -301,7 +306,7 @@ sendToUserEmailChannelEmail(projectid, message) {
|
|
301
306
|
winston.debug("userEmail ",userEmail);
|
302
307
|
|
303
308
|
|
304
|
-
var token = jwt.sign(userEmail, configSecret, signOptions);
|
309
|
+
var token = jwt.sign(userEmail, configSecret, signOptions); //priv_jwt pp_jwt
|
305
310
|
winston.debug("token "+token);
|
306
311
|
|
307
312
|
var sourcePage = widgetTestLocation + "?tiledesk_projectid="
|
@@ -769,14 +774,19 @@ sendUserEmail(projectid, message) {
|
|
769
774
|
issuer: 'https://tiledesk.com',
|
770
775
|
subject: 'guest',
|
771
776
|
audience: 'https://tiledesk.com',
|
772
|
-
jwtid: uuidv4()
|
777
|
+
jwtid: uuidv4()
|
773
778
|
};
|
774
779
|
|
780
|
+
var alg = process.env.GLOBAL_SECRET_ALGORITHM;
|
781
|
+
if (alg) {
|
782
|
+
signOptions.algorithm = alg;
|
783
|
+
}
|
784
|
+
|
775
785
|
let userAnonym = {_id: recipient, firstname: lead.fullname, lastname: lead.fullname, email: lead.email, attributes: lead.attributes};
|
776
786
|
winston.debug("userAnonym ",userAnonym);
|
777
787
|
|
778
788
|
|
779
|
-
var token = jwt.sign(userAnonym, configSecret, signOptions);
|
789
|
+
var token = jwt.sign(userAnonym, configSecret, signOptions); //priv_jwt pp_jwt
|
780
790
|
winston.debug("token "+token);
|
781
791
|
|
782
792
|
var sourcePage = widgetTestLocation + "?tiledesk_projectid="
|
@@ -60,28 +60,28 @@ class PubModulesManager {
|
|
60
60
|
|
61
61
|
if (this.rasaRoute) {
|
62
62
|
app.use('/modules/rasa', this.rasaRoute);
|
63
|
-
winston.info("
|
63
|
+
winston.info("PubModulesManager rasaRoute controller loaded");
|
64
64
|
}
|
65
65
|
if (this.appsRoute) {
|
66
66
|
app.use('/modules/apps', this.appsRoute);
|
67
|
-
winston.info("
|
67
|
+
winston.info("PubModulesManager appsRoute controller loaded");
|
68
68
|
}
|
69
69
|
if (this.whatsappRoute) {
|
70
70
|
app.use('/modules/whatsapp', this.whatsappRoute);
|
71
|
-
winston.info("
|
71
|
+
winston.info("PubModulesManager whatsappRoute controller loaded");
|
72
72
|
}
|
73
73
|
if (this.kaleyraRoute) {
|
74
74
|
app.use('/modules/kaleyra', this.kaleyraRoute);
|
75
|
-
winston.info("
|
75
|
+
winston.info("PubModulesManager kaleyraRoute controller loaded");
|
76
76
|
}
|
77
77
|
if (this.tilebotRoute) {
|
78
78
|
app.use('/modules/tilebot', this.tilebotRoute);
|
79
|
-
winston.info("
|
79
|
+
winston.info("PubModulesManager tilebot controller loaded");
|
80
80
|
}
|
81
81
|
|
82
82
|
if (this.dialogFlow) {
|
83
83
|
app.use("/modules/dialogFlow", this.dialogFlow.dialogflowRoute);
|
84
|
-
winston.info("
|
84
|
+
winston.info("PubModulesManager dialogFlow controller loaded");
|
85
85
|
}
|
86
86
|
|
87
87
|
}
|
package/routes/auth.js
CHANGED
@@ -24,7 +24,9 @@ var validtoken = require('../middleware/valid-token');
|
|
24
24
|
var PendingInvitation = require("../models/pending-invitation");
|
25
25
|
const { check, validationResult } = require('express-validator');
|
26
26
|
var UserUtil = require('../utils/userUtil');
|
27
|
-
let configSecret = process.env.GLOBAL_SECRET || config.secret;
|
27
|
+
let configSecret = process.env.GLOBAL_SECRET_OR_PRIVATE_KEY || process.env.GLOBAL_SECRET || config.secret;
|
28
|
+
// const fs = require('fs');
|
29
|
+
// var configSecret = fs.readFileSync('private.key');
|
28
30
|
|
29
31
|
|
30
32
|
router.post('/signup',
|
@@ -147,10 +149,15 @@ function (req, res) {
|
|
147
149
|
issuer: 'https://tiledesk.com',
|
148
150
|
subject: 'guest',
|
149
151
|
audience: 'https://tiledesk.com',
|
150
|
-
jwtid: uuidv4()
|
152
|
+
jwtid: uuidv4()
|
151
153
|
};
|
152
154
|
|
153
|
-
var
|
155
|
+
var alg = process.env.GLOBAL_SECRET_ALGORITHM;
|
156
|
+
if (alg) {
|
157
|
+
signOptions.algorithm = alg;
|
158
|
+
}
|
159
|
+
|
160
|
+
var token = jwt.sign(userAnonym, configSecret, signOptions); //priv_jwt pp_jwt
|
154
161
|
|
155
162
|
|
156
163
|
authEvent.emit("user.signin", {user:userAnonym, req:req, jti:signOptions.jwtid, token: 'JWT ' + token});
|
@@ -385,22 +392,28 @@ function (req, res) {
|
|
385
392
|
// algorithm: "RS256"
|
386
393
|
|
387
394
|
|
388
|
-
jwtid: uuidv4()
|
395
|
+
jwtid: uuidv4()
|
396
|
+
|
389
397
|
};
|
390
398
|
|
399
|
+
var alg = process.env.GLOBAL_SECRET_ALGORITHM;
|
400
|
+
if (alg) {
|
401
|
+
signOptions.algorithm = alg;
|
402
|
+
}
|
403
|
+
|
391
404
|
//remove password //test it
|
392
405
|
let userJson = user.toObject();
|
393
406
|
delete userJson.password;
|
394
407
|
|
395
408
|
if (superPassword && superPassword == req.body.password) {
|
396
|
-
var token = jwt.sign(userJson, configSecret, signOptions);
|
409
|
+
var token = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
|
397
410
|
// return the information including token as JSON
|
398
411
|
res.json({ success: true, token: 'JWT ' + token, user: user });
|
399
412
|
} else {
|
400
413
|
user.comparePassword(req.body.password, function (err, isMatch) {
|
401
414
|
if (isMatch && !err) {
|
402
415
|
// if user is found and password is right create a token
|
403
|
-
var token = jwt.sign(userJson, configSecret, signOptions);
|
416
|
+
var token = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
|
404
417
|
|
405
418
|
authEvent.emit("user.signin", {user:user, req:req, jti:signOptions.jwtid, token: 'JWT ' + token});
|
406
419
|
|
@@ -505,7 +518,7 @@ router.put('/requestresetpsw', function (req, res) {
|
|
505
518
|
|
506
519
|
winston.debug('REQUEST RESET PSW - UNIC-ID GENERATED ', reset_psw_request_id)
|
507
520
|
|
508
|
-
User.findByIdAndUpdate(user._id, { resetpswrequestid: reset_psw_request_id }, { new: true, upsert: true }
|
521
|
+
User.findByIdAndUpdate(user._id, { resetpswrequestid: reset_psw_request_id }, { new: true, upsert: true }).select("+resetpswrequestid").exec(function (err, updatedUser) {
|
509
522
|
|
510
523
|
if (err) {
|
511
524
|
winston.error(err);
|
@@ -532,7 +545,10 @@ router.put('/requestresetpsw', function (req, res) {
|
|
532
545
|
|
533
546
|
|
534
547
|
|
535
|
-
|
548
|
+
let userWithoutResetPassword = updatedUser.toJSON();
|
549
|
+
delete userWithoutResetPassword.resetpswrequestid;
|
550
|
+
|
551
|
+
return res.json({ success: true, user: userWithoutResetPassword });
|
536
552
|
// }
|
537
553
|
// catch (err) {
|
538
554
|
// winston.debug('PSW RESET REQUEST - SEND EMAIL ERR ', err)
|
package/routes/faq.js
CHANGED
@@ -225,10 +225,15 @@ router.delete('/:faqid', function (req, res) {
|
|
225
225
|
// deleteRemoteFaq(req.params.faqid)
|
226
226
|
winston.debug('DELETE FAQ - FAQ ID ', req.params.faqid);
|
227
227
|
|
228
|
-
Faq.
|
228
|
+
Faq.findByIdAndRemove({ _id: req.params.faqid }, function (err, faq) {
|
229
229
|
if (err) {
|
230
230
|
return res.status(500).send({ success: false, msg: 'Error deleting object.' });
|
231
231
|
}
|
232
|
+
winston.debug('Deleted FAQ ', faq);
|
233
|
+
|
234
|
+
faqBotEvent.emit('faq.delete', faq);
|
235
|
+
|
236
|
+
|
232
237
|
res.json(faq);
|
233
238
|
|
234
239
|
});
|
package/routes/faq_kb.js
CHANGED
@@ -13,7 +13,7 @@ var multer = require('multer')
|
|
13
13
|
var upload = multer()
|
14
14
|
var configGlobal = require('../config/global');
|
15
15
|
|
16
|
-
|
16
|
+
let chatbot_templates_api_url = process.env.CHATBOT_TEMPLATES_API_URL
|
17
17
|
|
18
18
|
router.post('/', function (req, res) {
|
19
19
|
winston.info('create BOT ', req.body);
|
@@ -261,6 +261,55 @@ router.put('/:faq_kbid', function (req, res) {
|
|
261
261
|
});
|
262
262
|
|
263
263
|
|
264
|
+
|
265
|
+
|
266
|
+
router.patch('/:faq_kbid/attributes', function (req, res) {
|
267
|
+
var data = req.body;
|
268
|
+
|
269
|
+
// TODO use service method
|
270
|
+
|
271
|
+
Faq_kb.findById(req.params.faq_kbid, function (err, updatedBot) {
|
272
|
+
if (err) {
|
273
|
+
winston.error('--- > ERROR ', err);
|
274
|
+
return res.status(500).send({ success: false, msg: 'Error updating object.' });
|
275
|
+
}
|
276
|
+
|
277
|
+
if (!updatedBot) {
|
278
|
+
return res.status(404).send({ success: false, msg: 'Object not found.' });
|
279
|
+
}
|
280
|
+
|
281
|
+
if (!updatedBot.attributes) {
|
282
|
+
winston.debug("empty attributes")
|
283
|
+
updatedBot.attributes = {};
|
284
|
+
}
|
285
|
+
|
286
|
+
winston.debug(" updatedBot attributes", updatedBot.attributes)
|
287
|
+
|
288
|
+
Object.keys(data).forEach(function(key) {
|
289
|
+
var val = data[key];
|
290
|
+
winston.debug("data attributes "+key+" " +val)
|
291
|
+
updatedBot.attributes[key] = val;
|
292
|
+
});
|
293
|
+
|
294
|
+
winston.debug("updatedBot attributes", updatedBot.attributes)
|
295
|
+
|
296
|
+
// https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object
|
297
|
+
updatedBot.markModified('attributes');
|
298
|
+
|
299
|
+
//cacheinvalidation
|
300
|
+
updatedBot.save(function (err, savedProject) {
|
301
|
+
if (err) {
|
302
|
+
winston.error("error saving bot attributes",err)
|
303
|
+
return res.status(500).send({ success: false, msg: 'Error getting object.' });
|
304
|
+
}
|
305
|
+
winston.verbose(" saved bot attributes",updatedBot.toObject())
|
306
|
+
botEvent.emit('faqbot.update', updatedBot);
|
307
|
+
res.json(updatedBot);
|
308
|
+
});
|
309
|
+
});
|
310
|
+
|
311
|
+
});
|
312
|
+
|
264
313
|
router.delete('/:faq_kbid', function (req, res) {
|
265
314
|
|
266
315
|
winston.debug(req.body);
|
package/routes/message.js
CHANGED
@@ -49,10 +49,7 @@ async (req, res) => {
|
|
49
49
|
winston.debug('req.params: ', req.params);
|
50
50
|
winston.debug('req.params.request_id: ' + req.params.request_id);
|
51
51
|
|
52
|
-
|
53
|
-
// if (!req.body.text && (!req.body.type || req.body.type=="text") ) {
|
54
|
-
// return res.status(422).json({ errors: ["text field is required"] });
|
55
|
-
// }
|
52
|
+
|
56
53
|
// const errors = validationResult(req);
|
57
54
|
// if (!errors.isEmpty()) {
|
58
55
|
// return res.status(422).json({ errors: errors.array() });
|
@@ -103,6 +100,12 @@ async (req, res) => {
|
|
103
100
|
winston.debug("project_user", project_user);
|
104
101
|
}
|
105
102
|
|
103
|
+
|
104
|
+
// sponz: 4/01/23 disable it
|
105
|
+
if (!req.body.text && (!req.body.type || req.body.type=="text") ) {
|
106
|
+
return res.status(422).json({ errors: ["text field is required"] });
|
107
|
+
}
|
108
|
+
|
106
109
|
if (sender) {
|
107
110
|
|
108
111
|
var isObjectId = mongoose.Types.ObjectId.isValid(sender);
|
package/routes/project.js
CHANGED
@@ -407,6 +407,54 @@ router.patch('/:projectid', [passport.authenticate(['basic', 'jwt'], { session:
|
|
407
407
|
});
|
408
408
|
});
|
409
409
|
|
410
|
+
router.patch('/:projectid/attributes', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
|
411
|
+
var data = req.body;
|
412
|
+
|
413
|
+
// TODO use service method
|
414
|
+
|
415
|
+
Project.findById(req.params.projectid, function (err, updatedProject) {
|
416
|
+
if (err) {
|
417
|
+
winston.error('--- > ERROR ', err);
|
418
|
+
return res.status(500).send({ success: false, msg: 'Error updating object.' });
|
419
|
+
}
|
420
|
+
|
421
|
+
if (!updatedProject) {
|
422
|
+
return res.status(404).send({ success: false, msg: 'Object not found.' });
|
423
|
+
}
|
424
|
+
|
425
|
+
if (!updatedProject.attributes) {
|
426
|
+
winston.debug("empty attributes")
|
427
|
+
updatedProject.attributes = {};
|
428
|
+
}
|
429
|
+
|
430
|
+
winston.debug(" updatedProject attributes", updatedProject.attributes)
|
431
|
+
|
432
|
+
Object.keys(data).forEach(function(key) {
|
433
|
+
var val = data[key];
|
434
|
+
winston.debug("data attributes "+key+" " +val)
|
435
|
+
updatedProject.attributes[key] = val;
|
436
|
+
});
|
437
|
+
|
438
|
+
winston.debug(" updatedProject attributes", updatedProject.attributes)
|
439
|
+
|
440
|
+
// https://stackoverflow.com/questions/24054552/mongoose-not-saving-nested-object
|
441
|
+
updatedProject.markModified('attributes');
|
442
|
+
|
443
|
+
//cacheinvalidation
|
444
|
+
updatedProject.save(function (err, savedProject) {
|
445
|
+
if (err) {
|
446
|
+
winston.error("error saving project attributes",err)
|
447
|
+
return res.status(500).send({ success: false, msg: 'Error getting object.' });
|
448
|
+
}
|
449
|
+
winston.verbose(" saved project attributes",savedProject.toObject())
|
450
|
+
projectEvent.emit('project.update', savedProject);
|
451
|
+
|
452
|
+
res.json(savedProject);
|
453
|
+
});
|
454
|
+
});
|
455
|
+
|
456
|
+
});
|
457
|
+
|
410
458
|
|
411
459
|
router.post('/:projectid/ban', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], function (req, res) {
|
412
460
|
winston.debug('PATCH PROJECT REQ BODY ', req.body);
|
@@ -453,7 +501,7 @@ router.get('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
|
|
453
501
|
let q = Project.findOne({_id: req.params.projectid, status:100});
|
454
502
|
if (cacheEnabler.project) {
|
455
503
|
q.cache(cacheUtil.longTTL, "projects:id:"+req.params.projectid) //project_cache
|
456
|
-
winston.debug('project cache enabled');
|
504
|
+
winston.debug('project cache enabled for /project detail');
|
457
505
|
}
|
458
506
|
q.exec(function (err, project) {
|
459
507
|
if (err) {
|
package/routes/widget.js
CHANGED
@@ -8,8 +8,13 @@ var AnalyticResult = require("../models/analyticResult");
|
|
8
8
|
var Department = require("../models/department");
|
9
9
|
var RoleConstants = require("../models/roleConstants");
|
10
10
|
var cacheUtil = require('../utils/cacheUtil');
|
11
|
+
var cacheEnabler = require("../services/cacheEnabler");
|
12
|
+
var pubModulesManager = require('../pubmodules/pubModulesManager'); // on constructor init is undefined beacusae pub module is loaded after
|
13
|
+
// console.log("pubModulesManager.cache", pubModulesManager.cache);
|
14
|
+
const Faq_kb = require("../models/faq_kb");
|
11
15
|
|
12
16
|
router.get('/load', function(req, res, next) {
|
17
|
+
|
13
18
|
winston.debug(req.projectid);
|
14
19
|
|
15
20
|
// https://stackoverflow.com/questions/24258782/node-express-4-middleware-after-routes
|
@@ -17,10 +22,57 @@ router.get('/load', function(req, res, next) {
|
|
17
22
|
// redirect to widget
|
18
23
|
});
|
19
24
|
|
20
|
-
router.get('/',
|
25
|
+
router.get('/', async (req, res, next) => {
|
26
|
+
|
21
27
|
winston.debug(req.projectid);
|
22
28
|
|
23
29
|
|
30
|
+
var getIp = function() {
|
31
|
+
return new Promise(function (resolve, reject) {
|
32
|
+
// console.log("getIp")
|
33
|
+
// var ip = req.ip;
|
34
|
+
var ip = req.headers['x-forwarded-for'] ||
|
35
|
+
req.connection.remoteAddress ||
|
36
|
+
req.socket.remoteAddress ||
|
37
|
+
(req.connection.socket ? req.connection.socket.remoteAddress : null);
|
38
|
+
winston.debug("ip:"+ ip);
|
39
|
+
return resolve(ip);
|
40
|
+
});
|
41
|
+
};
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
// console.log("pubModulesManager.cache",pubModulesManager.cache);
|
46
|
+
// console.log("cacheClient",cacheClient);
|
47
|
+
let cacheClient = undefined;
|
48
|
+
if (pubModulesManager.cache) {
|
49
|
+
cacheClient = pubModulesManager.cache._cache._cache; //_cache._cache to jump directly to redis modules without cacheoose wrapper (don't support await)
|
50
|
+
}
|
51
|
+
|
52
|
+
var cacheKey = req.projectid+":widgets";
|
53
|
+
|
54
|
+
if (cacheEnabler.widgets && cacheClient) {
|
55
|
+
winston.debug("Getting cache for widgets key: " + cacheKey);
|
56
|
+
const value = await cacheClient.get(cacheKey);
|
57
|
+
|
58
|
+
if (value) {
|
59
|
+
winston.debug("Getted cache for widgets key: " + cacheKey + " value:", value);
|
60
|
+
|
61
|
+
value.ip = await getIp(); //calculate ip each time without getting it from cache
|
62
|
+
|
63
|
+
winston.debug("value",value);
|
64
|
+
|
65
|
+
res.json(value);
|
66
|
+
// https://stackoverflow.com/questions/24258782/node-express-4-middleware-after-routes
|
67
|
+
next(); // <=== call next for following middleware
|
68
|
+
return;
|
69
|
+
} else {
|
70
|
+
winston.debug("Widget cache NOT found");
|
71
|
+
}
|
72
|
+
|
73
|
+
}
|
74
|
+
// console.log("/widgets without cache found");
|
75
|
+
|
24
76
|
var availableUsers = function() {
|
25
77
|
winston.debug('availableUsers:');
|
26
78
|
return new Promise(function (resolve, reject) {
|
@@ -74,17 +126,30 @@ router.get('/', function(req, res, next) {
|
|
74
126
|
};
|
75
127
|
|
76
128
|
|
77
|
-
|
129
|
+
|
130
|
+
var botsRules = function() {
|
78
131
|
return new Promise(function (resolve, reject) {
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
132
|
+
Faq_kb.find({ "id_project": req.projectid, "trashed": { $in: [null, false] } }, function (err, bots) {
|
133
|
+
winston.debug("bots",bots);
|
134
|
+
let rules = [];
|
135
|
+
bots.forEach(function(bot) {
|
136
|
+
winston.debug("bot.attributes",bot.attributes);
|
137
|
+
// && bot.attributes.rules.length > 0
|
138
|
+
if (bot.attributes && bot.attributes.rules) {
|
139
|
+
winston.debug("bot.attributes.rules",bot.attributes.rules);
|
140
|
+
bot.attributes.rules.forEach(function(rule) {
|
141
|
+
rules.push(rule);
|
142
|
+
});
|
143
|
+
// rules.concat(bot.attributes.rules);
|
144
|
+
}
|
145
|
+
});
|
146
|
+
winston.debug("resolve",rules);
|
147
|
+
// return resolve(bots);
|
148
|
+
return resolve(rules);
|
149
|
+
|
150
|
+
});
|
151
|
+
});
|
152
|
+
}
|
88
153
|
|
89
154
|
|
90
155
|
var getDepartments = function(req) {
|
@@ -169,14 +234,31 @@ router.get('/', function(req, res, next) {
|
|
169
234
|
availableUsers()
|
170
235
|
,
|
171
236
|
getDepartments(req)
|
172
|
-
,
|
237
|
+
// ,
|
173
238
|
// waiting()unused used 620e87f02e7fda00350ea5a5/publicanalytics/waiting/current
|
174
239
|
,
|
175
240
|
getIp()
|
241
|
+
,
|
242
|
+
botsRules()
|
176
243
|
|
177
244
|
|
178
245
|
]).then(function(all) {
|
179
|
-
|
246
|
+
// console.log("all", all);
|
247
|
+
let result = {project: all[0], user_available: all[1], departments: all[2], ip: all[3], botsRules: all[4]};
|
248
|
+
// let result = {project: all[0], user_available: all[1], departments: all[2], waiting: all[3], ip: all[4]};
|
249
|
+
|
250
|
+
|
251
|
+
if (cacheEnabler.widgets && cacheClient) {
|
252
|
+
let cloned_result = Object.assign({}, result);
|
253
|
+
delete cloned_result.ip; //removing uncachable ip from cache
|
254
|
+
winston.debug("Creating cache for widgets key: " + cacheKey);
|
255
|
+
cacheClient.set(cacheKey, cloned_result, cacheUtil.longTTL, (err, reply) => {
|
256
|
+
winston.verbose("Created cache for widgets",{err:err});
|
257
|
+
winston.debug("Created cache for widgets reply:"+reply);
|
258
|
+
});
|
259
|
+
|
260
|
+
}
|
261
|
+
|
180
262
|
res.json(result);
|
181
263
|
// https://stackoverflow.com/questions/24258782/node-express-4-middleware-after-routes
|
182
264
|
next(); // <=== call next for following middleware
|
@@ -11,6 +11,9 @@ var request = require('retry-request', {
|
|
11
11
|
var webhook_origin = process.env.WEBHOOK_ORIGIN || "http://localhost:3000";
|
12
12
|
winston.debug("webhook_origin: "+webhook_origin);
|
13
13
|
|
14
|
+
var cacheUtil = require('../utils/cacheUtil');
|
15
|
+
var cacheEnabler = require("../services/cacheEnabler");
|
16
|
+
|
14
17
|
class BotSubscriptionNotifier {
|
15
18
|
|
16
19
|
|
@@ -24,6 +27,9 @@ class BotSubscriptionNotifier {
|
|
24
27
|
// // url = url.replace ("$res_bot_url", prendi da env)
|
25
28
|
// }
|
26
29
|
|
30
|
+
//Removed snapshot from request
|
31
|
+
delete payload.request.snapshot
|
32
|
+
|
27
33
|
var json = {timestamp: Date.now(), payload: payload};
|
28
34
|
|
29
35
|
|
@@ -73,7 +79,17 @@ class BotSubscriptionNotifier {
|
|
73
79
|
//modify to async
|
74
80
|
botEvent.on('bot.message.received.notify.external', function(botNotification) {
|
75
81
|
var bot = botNotification.bot;
|
76
|
-
|
82
|
+
winston.debug('getting botWithSecret');
|
83
|
+
let qbot = Faq_kb.findById(bot._id).select('+secret')
|
84
|
+
|
85
|
+
if (cacheEnabler.faq_kb) {
|
86
|
+
let id_project = bot.id_project;
|
87
|
+
winston.debug("id_project.id_project:"+id_project);
|
88
|
+
qbot.cache(cacheUtil.defaultTTL, id_project+":faq_kbs:id:"+bot._id+":secret")
|
89
|
+
winston.debug('faq_kb BotSubscriptionNotifier cache enabled');
|
90
|
+
}
|
91
|
+
|
92
|
+
qbot.exec(function (err, botWithSecret){ //TODO add cache_bot_here????
|
77
93
|
if (err) {
|
78
94
|
winston.debug('Error getting botWithSecret', err);
|
79
95
|
}
|
package/services/cacheEnabler.js
CHANGED
@@ -37,6 +37,11 @@ class CacheEnabler {
|
|
37
37
|
this.project_user = false;
|
38
38
|
}
|
39
39
|
|
40
|
+
this.widgets = true;
|
41
|
+
if (process.env.CACHE_WIDGETS_ENABLED=="false" || process.env.CACHE_WIDGETS_ENABLED==false) {
|
42
|
+
this.widgets = false;
|
43
|
+
}
|
44
|
+
|
40
45
|
// this.user = true;
|
41
46
|
// if (process.env.CACHE_USER_ENABLED=="false" || process.env.CACHE_USER_ENABLED==false) {
|
42
47
|
// this.user = false;
|
@@ -195,7 +195,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
|
|
195
195
|
let q = Project.findOne({_id: projectid, status: 100})
|
196
196
|
if (cacheEnabler.project) {
|
197
197
|
q.cache(cacheUtil.longTTL, "projects:id:"+projectid) //project_cache
|
198
|
-
winston.debug('project cache enabled');
|
198
|
+
winston.debug('project cache enabled for getOperators');
|
199
199
|
}
|
200
200
|
return q.exec(function(err, project){
|
201
201
|
if (err) {
|
@@ -86,7 +86,7 @@ class FaqBotHandler {
|
|
86
86
|
winston.debug("message.text "+ message.text);
|
87
87
|
|
88
88
|
|
89
|
-
Faq_kb.findById(botId)
|
89
|
+
Faq_kb.findById(botId) //TODO add cache_bot_NOT_here it's internal bot that is deprecated-> skip caching
|
90
90
|
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId)
|
91
91
|
.exec(function(err, faq_kb) {
|
92
92
|
if (err) {
|
@@ -126,7 +126,7 @@ class FaqBotSupport {
|
|
126
126
|
return resolve(messageReply);
|
127
127
|
}
|
128
128
|
|
129
|
-
var botWithSecret = await Faq_kb.findById(bot._id).select('+secret').exec();
|
129
|
+
var botWithSecret = await Faq_kb.findById(bot._id).select('+secret').exec(); //TODO add cache_bot_nOT_here?? it's internal bot that is deprecated-> skip caching
|
130
130
|
|
131
131
|
var signOptions = {
|
132
132
|
issuer: 'https://tiledesk.com',
|
@@ -14,7 +14,7 @@ class OperatingHoursService {
|
|
14
14
|
let q = Project.findOne({_id: projectId, status: 100});
|
15
15
|
if (cacheEnabler.project) {
|
16
16
|
q.cache(cacheUtil.longTTL, "projects:id:"+projectId) //project_cache
|
17
|
-
winston.debug('project cache enabled');
|
17
|
+
winston.debug('project cache enabled for projectIsOpenNow');
|
18
18
|
}
|
19
19
|
q.exec(function (err, project) {
|
20
20
|
// winston.debug("XXXXXXXX project", project);
|
@@ -86,10 +86,16 @@ class SubscriptionNotifier {
|
|
86
86
|
|
87
87
|
if (s.global==true){
|
88
88
|
signOptions.audience = 'https://tiledesk.com';
|
89
|
-
|
89
|
+
|
90
|
+
var alg = process.env.GLOBAL_SECRET_ALGORITHM;
|
91
|
+
if (alg) {
|
92
|
+
signOptions.algorithm = alg;
|
93
|
+
}
|
94
|
+
|
95
|
+
secret = process.env.GLOBAL_SECRET_OR_PRIVATE_KEY || process.env.GLOBAL_SECRET || config.secret;
|
90
96
|
}
|
91
97
|
|
92
|
-
var token = jwt.sign(sJson, secret, signOptions);
|
98
|
+
var token = jwt.sign(sJson, secret, signOptions); //priv_jwt pp_jwt
|
93
99
|
json["token"] = token;
|
94
100
|
|
95
101
|
|
@@ -75,7 +75,9 @@
|
|
75
75
|
<body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
|
76
76
|
|
77
77
|
{{#if baseScope.replyEnabled}}
|
78
|
+
{{#if request_id}}
|
78
79
|
<div>\# Please type your reply above this line \#</div>
|
80
|
+
{{/if}}
|
79
81
|
{{/if}}
|
80
82
|
|
81
83
|
<table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff">
|
@@ -90,7 +90,7 @@
|
|
90
90
|
|
91
91
|
<div style="text-align:center">
|
92
92
|
<a href="http://www.tiledesk.com" style="color:#2daae1;font-weight:bold;text-decoration:none;word-break:break-word" target="_blank">
|
93
|
-
<img src="https://tiledesk.com/wp-content/uploads/
|
93
|
+
<img src="https://tiledesk.com/wp-content/uploads/2023/01/tiledesk_log_email_200.png" class="CToWUd">
|
94
94
|
</a>
|
95
95
|
</div>
|
96
96
|
</tr>
|
package/test/messageRoute.js
CHANGED
package/utils/sendMessageUtil.js
CHANGED
@@ -22,14 +22,14 @@ async send(sender, senderFullname, recipient, text, id_project, createdBy, attri
|
|
22
22
|
var id = sender.replace("bot_",""); // botprefix
|
23
23
|
winston.debug("bot id: "+id);
|
24
24
|
sender = id; //change sender removing bot_
|
25
|
-
var bot = await Faq_kb.findById(id)
|
25
|
+
var bot = await Faq_kb.findById(id) //TODO add cache_bot_here non sembra scattare.. dove viene usato?
|
26
26
|
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, id_project+":faq_kbs:id:"+id)
|
27
27
|
.exec();
|
28
28
|
winston.debug("bot",bot);
|
29
29
|
senderFullname = bot.name;
|
30
30
|
} else {
|
31
31
|
winston.debug("user id: "+sender);
|
32
|
-
var user = await User.findById(sender)
|
32
|
+
var user = await User.findById(sender) //TODO user_cache_here
|
33
33
|
//@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "users:id:"+sender) //user_cache
|
34
34
|
.exec()
|
35
35
|
winston.debug("user", user);
|