@tiledesk/tiledesk-server 2.2.39 → 2.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +14 -657
  3. package/README.md +17 -3
  4. package/app.js +14 -2
  5. package/channels/chat21/chat21WebHook.js +12 -1
  6. package/event/botEvent.js +1 -1
  7. package/event/subscriptionEvent.js +11 -0
  8. package/fonts/Roboto-Italic.ttf +0 -0
  9. package/fonts/Roboto-Medium.ttf +0 -0
  10. package/fonts/Roboto-MediumItalic.ttf +0 -0
  11. package/fonts/Roboto-Regular.ttf +0 -0
  12. package/middleware/passport.js +4 -1
  13. package/models/lead.js +2 -0
  14. package/models/request.js +38 -11
  15. package/models/subscriptionLog.js +34 -0
  16. package/models/tagLibrary.js +42 -0
  17. package/package.json +4 -11
  18. package/pubmodules/activities/activityArchiver.js +295 -0
  19. package/pubmodules/activities/index.js +3 -0
  20. package/pubmodules/activities/models/activity.js +88 -0
  21. package/pubmodules/activities/routes/activity.js +710 -0
  22. package/pubmodules/activities/test/activityRoute.js +85 -0
  23. package/pubmodules/analytics/analytics.js +1719 -0
  24. package/pubmodules/analytics/index.js +3 -0
  25. package/pubmodules/canned/cannedResponse.js +51 -0
  26. package/pubmodules/canned/cannedResponseRoute.js +157 -0
  27. package/pubmodules/canned/index.js +3 -0
  28. package/pubmodules/emailNotification/requestNotification.js +184 -26
  29. package/pubmodules/messageActions/messageActionsInterceptor.js +4 -2
  30. package/pubmodules/pubModulesManager.js +104 -5
  31. package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +3 -1
  32. package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +3 -1
  33. package/pubmodules/trigger/default.js +271 -0
  34. package/pubmodules/trigger/event/actionEventEmitter.js +10 -0
  35. package/pubmodules/trigger/event/flowEventEmitter.js +10 -0
  36. package/pubmodules/trigger/event/triggerEventEmitter.js +10 -0
  37. package/pubmodules/trigger/index.js +3 -0
  38. package/pubmodules/trigger/models/trigger.js +149 -0
  39. package/pubmodules/trigger/rulesTrigger.js +1181 -0
  40. package/pubmodules/trigger/start.js +114 -0
  41. package/pubmodules/trigger/triggerRoute.js +150 -0
  42. package/routes/department.js +51 -0
  43. package/routes/group.js +140 -0
  44. package/routes/lead.js +24 -1
  45. package/routes/message.js +6 -3
  46. package/routes/project.js +52 -0
  47. package/routes/public-request.js +265 -2
  48. package/routes/request.js +83 -11
  49. package/routes/subscription.js +140 -0
  50. package/routes/tag.js +138 -0
  51. package/routes/user-request.js +3 -2
  52. package/routes/widget.js +16 -1
  53. package/routes/widgetLoader.js +31 -0
  54. package/services/emailService.js +189 -11
  55. package/services/faqService.js +1 -1
  56. package/services/leadService.js +2 -0
  57. package/services/modulesManager.js +7 -188
  58. package/services/requestService.js +364 -6
  59. package/services/subscriptionNotifier.js +485 -0
  60. package/template/email/assignedEmailMessage.html +1 -1
  61. package/template/email/assignedRequest.html +1 -1
  62. package/template/email/newMessage.html +1 -1
  63. package/template/email/newMessageFollower.html +236 -0
  64. package/template/email/passwordChanged.html +1 -1
  65. package/template/email/pooledEmailMessage.html +1 -1
  66. package/template/email/pooledRequest.html +1 -1
  67. package/template/email/resetPassword.html +2 -2
  68. package/template/email/ticket.html +1 -1
  69. package/test/messageRoute.js +69 -0
  70. package/test/requestService.js +3 -1
  71. package/views/messages.jade +2 -2
@@ -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};
@@ -47,7 +47,7 @@ listen() {
47
47
  messageEvent.on(messageCreateKey, function(message) {
48
48
 
49
49
  setImmediate(() => {
50
- winston.debug("sendUserEmail", message);
50
+ winston.debug("messageEvent.on(messageCreateKey", message);
51
51
 
52
52
  if (message.attributes && message.attributes.subtype==='info') {
53
53
  return winston.debug("not sending sendUserEmail for attributes.subtype info messages");
@@ -56,17 +56,18 @@ listen() {
56
56
 
57
57
  if (message.request && (message.request.channel.name===ChannelConstants.EMAIL || message.request.channel.name===ChannelConstants.FORM)) {
58
58
 
59
+ //messages sent from admins or agents to requester
59
60
  if (message.sender != message.request.lead.lead_id) {
60
61
  winston.verbose("sending sendToUserEmailChannelEmail for EMAIL or FORM channel");
61
-
62
- if (message.attributes && message.attributes.subtype==='private') {
63
- return winston.debug("not sending sendToUserEmailChannelEmail for attributes.subtype private messages");
64
- }
65
- return that.sendToUserEmailChannelEmail(message.id_project, message);
66
- } else {
62
+
63
+ //send email notification to requester (send also to followers)
64
+ return that.sendToUserEmailChannelEmail(message.id_project, message);
65
+ } else { //messages sent from requester to agents or admins
67
66
 
68
67
  if (message.text != message.request.first_text) {
69
68
  winston.verbose("sending sendToAgentEmailChannelEmail for EMAIL or FORM channel");
69
+
70
+ //send email notification to admins and agents(send also to followers)
70
71
  return that.sendToAgentEmailChannelEmail(message.id_project, message);
71
72
  } else {
72
73
  winston.debug("sending sendToAgentEmailChannelEmail for EMAIL or FORM channel disabled for first text message")
@@ -76,16 +77,23 @@ listen() {
76
77
 
77
78
  } else {
78
79
  winston.debug("sendUserEmail chat channel");
79
- // controlla se sta funzionando
80
- if (process.env.DISABLE_SEND_OFFLINE_EMAIL === "true" || process.env.DISABLE_SEND_OFFLINE_EMAIL === true ) {
81
- return winston.debug("DISABLE_SEND_OFFLINE_EMAIL disabled");
82
- }
83
- // mandare email se ultimo messaggio > X MINUTI configurato in Notification . potresti usare request.updated_at ?
80
+
81
+ //TODO mandare email se ultimo messaggio > X MINUTI configurato in Notification . potresti usare request.updated_at ?
82
+
83
+
84
+
85
+ //messages sent from admins or agents
86
+ //send email notification to requester
84
87
  if (message.request && message.request.lead && message.sender != message.request.lead.lead_id) {
88
+ winston.debug("sendUserEmail");
85
89
  winston.debug("sendUserEmail", message);
86
90
 
87
- // send an email only if offline and has an email
91
+ // send an email only if offline and has an email (send also to followers)
88
92
  return that.sendUserEmail(message.id_project, message);
93
+ } else { //send email to followers
94
+
95
+ that.sendToFollower(message.id_project, message);
96
+
89
97
  }
90
98
 
91
99
  }
@@ -139,7 +147,6 @@ listen() {
139
147
 
140
148
 
141
149
 
142
-
143
150
  // requestEvent.on("request.update.preflight", function(request) {
144
151
 
145
152
  // winston.info("requestEvent request.update.preflight");
@@ -227,15 +234,19 @@ listen() {
227
234
 
228
235
 
229
236
  sendToUserEmailChannelEmail(projectid, message) {
237
+ winston.debug("sendToUserEmailChannelEmail");
238
+ var that = this;
230
239
  try {
231
240
 
232
241
  if (!message.request) {
233
242
  return winston.debug("This is a direct message");
234
243
  }
235
244
 
236
- if (!message.request.lead || !message.request.lead.email) {
237
- return winston.debug("The lead object is undefined or has empty email");
238
- }
245
+
246
+
247
+
248
+
249
+
239
250
 
240
251
  Project.findOne({_id: projectid, status: 100}).select("+settings").exec(function(err, project){
241
252
  if (err) {
@@ -245,6 +256,7 @@ sendToUserEmailChannelEmail(projectid, message) {
245
256
  if (!project) {
246
257
  return winston.warn("Project not found", projectid);
247
258
  }
259
+
248
260
 
249
261
  // if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.offline && project.settings.email.notification.conversation.offline.blocked == true ) {
250
262
  // return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the conversations is blocked");
@@ -256,7 +268,7 @@ sendToUserEmailChannelEmail(projectid, message) {
256
268
  // }
257
269
 
258
270
  let lead = message.request.lead;
259
- winston.debug("sending channel emaol email to lead ", lead);
271
+ winston.debug("sending channel email to lead ", lead);
260
272
 
261
273
 
262
274
  winston.debug("sending user email to "+ lead.email);
@@ -307,8 +319,24 @@ sendToUserEmailChannelEmail(projectid, message) {
307
319
  }
308
320
  winston.debug("tokenQueryString: "+tokenQueryString);
309
321
 
322
+
323
+
324
+ // winston.info("savedRequest.followers", savedRequest.followers);
325
+ // winston.info("savedRequest.followers.length:"+ savedRequest.followers.length);
326
+ that.notifyFollowers(message.request, project, message);
327
+
328
+
329
+ if (message.attributes && message.attributes.subtype==='private') {
330
+ return winston.debug("not sending sendToUserEmailChannelEmail for attributes.subtype private messages");
331
+ }
332
+
333
+ // nn va bene qui
334
+ if (!message.request.lead || !message.request.lead.email) {
335
+ return winston.debug("The lead object is undefined or has empty email");
336
+ }
337
+
310
338
  emailService.sendEmailChannelNotification(message.request.lead.email, message, project, tokenQueryString, sourcePage);
311
-
339
+
312
340
 
313
341
  });
314
342
 
@@ -318,9 +346,105 @@ sendToUserEmailChannelEmail(projectid, message) {
318
346
  }
319
347
 
320
348
 
349
+ async notifyFollowers(savedRequest, project, message) {
350
+
351
+ if (message.attributes && message.attributes.subtype==='info/support') {
352
+ return winston.debug("not sending notifyFollowers for attributes.subtype info/support messages");
353
+ }
354
+
355
+ if (message.attributes && message.attributes.subtype==='info') {
356
+ return winston.debug("not sending notifyFollowers for attributes.subtype info messages");
357
+ }
358
+
359
+ var reqWithFollowers = await Request.findById(savedRequest._id).populate('followers').exec();
360
+ winston.debug("reqWithFollowers");
361
+ winston.debug("reqWithFollowers",reqWithFollowers);
362
+ // console.log("reqWithFollowers",reqWithFollowers);
363
+
364
+ if (reqWithFollowers.followers && reqWithFollowers.followers.length>0) {
321
365
 
366
+ winston.debug("reqWithFollowers.followers.length: "+reqWithFollowers.followers.length);
367
+
368
+ reqWithFollowers.followers.forEach(project_user => {
369
+ winston.debug("project_user", project_user);
370
+ //TODO skip participants from followers
371
+
372
+ var userid = project_user.id_user;
373
+
374
+ if (project_user.settings && project_user.settings.email && project_user.settings.email.notification && project_user.settings.email.notification.conversation && project_user.settings.email.notification.conversation.ticket && project_user.settings.email.notification.conversation.ticket.follower == false ) {
375
+ return winston.verbose("RequestNotification email notification for the user with id " + userid+ " the follower conversation ticket is disabled");
376
+ }
377
+
378
+ User.findOne({_id: userid , status: 100})
379
+ //@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "users:id:"+userid)
380
+ .exec(function (err, user) {
381
+ if (err) {
382
+ // winston.debug(err);
383
+ }
384
+ if (!user) {
385
+ winston.warn("User not found", userid);
386
+ } else {
387
+ winston.info("Sending notifyFollowers to user with email: "+ user.email);
388
+ if (user.emailverified) {
389
+ emailService.sendFollowerNotification(user.email, message, project);
390
+ // emailService.sendEmailChannelNotification(user.email, message, project);
391
+
392
+ // emailService.sendNewAssignedAgentMessageEmailNotification(user.email, savedRequest, project, message);
393
+
394
+ }else {
395
+ winston.info("User email not verified", user.email);
396
+ }
397
+ }
398
+ });
399
+
400
+
401
+ });
402
+
403
+
404
+ }
405
+ }
406
+
407
+ sendToFollower(projectid, message) {
408
+ winston.debug("sendToFollower");
409
+ var that = this;
410
+ let savedRequest = message.request;
411
+ // send email
412
+ try {
413
+
414
+
415
+ Project.findOne({_id: projectid, status: 100}).select("+settings").exec(async function(err, project){
416
+ if (err) {
417
+ return winston.error(err);
418
+ }
419
+
420
+ if (!project) {
421
+ return winston.warn("Project not found", projectid);
422
+ } else {
423
+
424
+ winston.debug("project", project);
425
+
426
+ // if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.blocked == true ) {
427
+ // return winston.verbose("RequestNotification email notification for the project with id : " + projectid + " for all the conversations is blocked");
428
+ // }
429
+
430
+ winston.debug("savedRequest", savedRequest);
431
+
432
+
433
+
434
+ // winston.info("savedRequest.followers", savedRequest.followers);
435
+ // winston.info("savedRequest.followers.length:"+ savedRequest.followers.length);
436
+ that.notifyFollowers(message.request, project, message);
437
+
438
+
439
+ }
440
+ })
441
+ } catch (e) {
442
+ winston.warn("Error sending email", {error:e, projectid:projectid, message: message, savedRequest:savedRequest}); //it's better to view error email at this stage
443
+ }
444
+ }
322
445
 
323
446
  sendToAgentEmailChannelEmail(projectid, message) {
447
+ var that = this;
324
448
  let savedRequest = message.request;
325
449
  // send email
326
450
  try {
@@ -343,9 +467,17 @@ sendToAgentEmailChannelEmail(projectid, message) {
343
467
 
344
468
  winston.debug("savedRequest", savedRequest);
345
469
 
346
-
347
470
 
348
471
 
472
+ // winston.info("savedRequest.followers", savedRequest.followers);
473
+ // winston.info("savedRequest.followers.length:"+ savedRequest.followers.length);
474
+ that.notifyFollowers(message.request, project, message);
475
+
476
+
477
+
478
+ // UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'status' of undefined
479
+ // at /Users/andrealeo/dev/chat21/ti
480
+
349
481
  // TODO fare il controllo anche sul dipartimento con modalità assigned o pooled
350
482
  if (savedRequest.status==RequestConstants.UNASSIGNED) { //POOLED
351
483
 
@@ -523,15 +655,19 @@ sendEmailChannelTakingNotification(projectid, request) {
523
655
 
524
656
 
525
657
  sendUserEmail(projectid, message) {
658
+ winston.debug("sendUserEmail");
659
+ var that = this;
660
+
661
+
526
662
  try {
527
663
 
528
664
  if (!message.request) {
529
665
  return winston.debug("This is a direct message");
530
666
  }
667
+
531
668
 
532
- if (!message.request.lead || !message.request.lead.email) {
533
- return winston.debug("The lead object is undefined or has empty email");
534
- }
669
+
670
+
535
671
 
536
672
  Project.findOne({_id: projectid, status: 100}).select("+settings").exec(function(err, project){
537
673
  if (err) {
@@ -542,6 +678,28 @@ sendUserEmail(projectid, message) {
542
678
  return winston.warn("Project not found", projectid);
543
679
  }
544
680
 
681
+ winston.debug("notifyFollowers");
682
+ that.notifyFollowers(message.request, project, message);
683
+
684
+
685
+
686
+ if (process.env.DISABLE_SEND_OFFLINE_EMAIL === "true" || process.env.DISABLE_SEND_OFFLINE_EMAIL === true ) {
687
+ return winston.info("DISABLE_SEND_OFFLINE_EMAIL disabled");
688
+ }
689
+ if (message.attributes && message.attributes.subtype==='info/support') {
690
+ return winston.debug("not sending sendUserEmail for attributes.subtype info/support messages");
691
+ }
692
+
693
+ if (message.attributes && message.attributes.subtype==='info') {
694
+ return winston.debug("not sending sendUserEmail for attributes.subtype info messages");
695
+ }
696
+
697
+
698
+
699
+ if (!message.request.lead || !message.request.lead.email) {
700
+ return winston.info("The lead object is undefined or has empty email");
701
+ }
702
+
545
703
  if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.offline && project.settings.email.notification.conversation.offline.blocked == true ) {
546
704
  return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the conversations is blocked");
547
705
  }
@@ -550,8 +708,8 @@ sendUserEmail(projectid, message) {
550
708
  if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.offline && project.settings.email.notification.conversation.offline.enabled == false ) {
551
709
  return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the offline conversation is disabled");
552
710
  }
553
-
554
-
711
+
712
+
555
713
 
556
714
  var recipient = message.request.lead.lead_id;
557
715
  winston.debug("recipient:"+ recipient);
@@ -678,7 +836,7 @@ sendAgentEmail(projectid, savedRequest) {
678
836
  }
679
837
 
680
838
 
681
-
839
+
682
840
  var snapshotAgents = savedRequest; //riassegno varibile cosi nn cambio righe successive
683
841
 
684
842
 
@@ -149,8 +149,10 @@ class MessageActionsInterceptor {
149
149
  if (request) {
150
150
  // setTimeout(function() {
151
151
  // winston.info("delayed")
152
- // closeRequestByRequestId(request_id, id_project, notify) {
153
- requestService.closeRequestByRequestId(request.request_id, request.id_project );
152
+
153
+ // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
154
+ const closed_by = message.sender;
155
+ requestService.closeRequestByRequestId(request.request_id, request.id_project, false, true, closed_by );
154
156
  // }, 1500);
155
157
 
156
158