@tiledesk/tiledesk-server 2.3.1 → 2.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
 
@@ -84,7 +84,9 @@ findUnresponsiveRequests() {
84
84
  requests.forEach(request => {
85
85
  winston.debug("********unresponsive request ", request);
86
86
 
87
- return requestService.closeRequestByRequestId(request.request_id, request.id_project, false, false).then(function(updatedStatusRequest) {
87
+ // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
88
+ const closed_by = "_bot_unresponsive";
89
+ return requestService.closeRequestByRequestId(request.request_id, request.id_project, false, false, closed_by).then(function(updatedStatusRequest) {
88
90
  winston.verbose("CloseAgentUnresponsiveRequestTask: Request closed with request_id: " + request.request_id);
89
91
  // winston.info("Request closed",updatedStatusRequest);
90
92
  }).catch(function(err) {
@@ -95,7 +95,9 @@ findUnresponsiveRequests() {
95
95
 
96
96
  winston.debug("********unresponsive request ", request);
97
97
 
98
- return requestService.closeRequestByRequestId(request.request_id, request.id_project, false, false).then(function(updatedStatusRequest) {
98
+ // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
99
+ const closed_by = "_bot_unresponsive";
100
+ return requestService.closeRequestByRequestId(request.request_id, request.id_project, false, false, closed_by).then(function(updatedStatusRequest) {
99
101
  winston.info("CloseBotUnresponsiveRequestTask: Request closed with request_id: " + request.request_id);
100
102
  // winston.info("Request closed",updatedStatusRequest);
101
103
  }).catch(function(err) {
@@ -341,8 +341,9 @@ class RulesTrigger {
341
341
  var id_project = eventTrigger.event.id_project;
342
342
  winston.debug('runAction action id_project: ' + id_project);
343
343
 
344
- // closeRequestByRequestId(request_id, id_project) {
345
- requestService.closeRequestByRequestId(request_id, id_project);
344
+ // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
345
+ const closed_by = "_trigger";
346
+ requestService.closeRequestByRequestId(request_id, id_project, false, true, closed_by);
346
347
 
347
348
  } catch(e) {
348
349
  winston.error("Error runAction", e);
package/routes/lead.js CHANGED
@@ -80,6 +80,15 @@ router.put('/:leadid', function (req, res) {
80
80
 
81
81
 
82
82
  leadEvent.emit('lead.update', updatedLead);
83
+
84
+ if (req.body.fullname!=undefined) {
85
+ leadEvent.emit('lead.fullname.update', updatedLead);
86
+ }
87
+
88
+ if (req.body.email!=undefined) {
89
+ leadEvent.emit('lead.email.update', updatedLead);
90
+ }
91
+
83
92
  res.json(updatedLead);
84
93
  });
85
94
  });
@@ -187,6 +196,11 @@ router.get('/csv', function (req, res, next) {
187
196
 
188
197
  winston.debug("sort query", sortQuery);
189
198
 
199
+ // TODO ORDER BY SCORE
200
+ // return Faq.find(query, {score: { $meta: "textScore" } })
201
+ // .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
202
+
203
+
190
204
  // Lead.find({ "id_project": req.projectid }, function (err, leads, next) {
191
205
  return Lead.find(query, '-attributes -__v').
192
206
  skip(skip).limit(limit).
@@ -258,6 +272,8 @@ router.get('/', function (req, res) {
258
272
  query.fullname = { "$exists": true };
259
273
  }
260
274
 
275
+ // aggiungi filtro per data
276
+
261
277
  if (req.query.status) {
262
278
  query.status = req.query.status;
263
279
  }
@@ -277,6 +293,13 @@ router.get('/', function (req, res) {
277
293
 
278
294
  winston.debug("sort query", sortQuery);
279
295
 
296
+ // TODO ORDER BY SCORE
297
+ // return Faq.find(query, {score: { $meta: "textScore" } })
298
+ // .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
299
+
300
+
301
+ // aggiungi filtro per data marco
302
+
280
303
  return Lead.find(query).
281
304
  skip(skip).limit(limit).
282
305
  sort(sortQuery).
@@ -288,7 +311,7 @@ router.get('/', function (req, res) {
288
311
 
289
312
  // blocked to 1000 TODO increases it
290
313
  // collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead
291
- return Lead.count(query, function (err, totalRowCount) {
314
+ return Lead.countDocuments(query, function (err, totalRowCount) {
292
315
 
293
316
  var objectToReturn = {
294
317
  perPage: limit,
package/routes/message.js CHANGED
@@ -51,6 +51,7 @@ async (req, res) => {
51
51
  return res.status(422).json({ errors: errors.array() });
52
52
  }
53
53
 
54
+
54
55
  var project_user = req.projectuser;
55
56
  var sender = req.body.sender;
56
57
  var fullname = req.body.senderFullname || req.user.fullName;
@@ -159,7 +160,8 @@ async (req, res) => {
159
160
  location: req.body.location,
160
161
  participants: req.body.participants,
161
162
  lead: createdLead, requester: project_user,
162
- priority: req.body.priority
163
+ priority: req.body.priority,
164
+ followers: req.body.followers,
163
165
  };
164
166
 
165
167
  return requestService.create(new_request).then(function (savedRequest) {
@@ -188,7 +190,8 @@ async (req, res) => {
188
190
  .populate('lead')
189
191
  .populate('department')
190
192
  .populate('participatingBots')
191
- .populate('participatingAgents')
193
+ .populate('participatingAgents')
194
+ // .populate('followers')
192
195
  .populate({path:'requester',populate:{path:'id_user'}})
193
196
  .execPopulate(function (err, savedRequestPopulated){
194
197
 
@@ -247,6 +250,7 @@ async (req, res) => {
247
250
  .populate('department')
248
251
  .populate('participatingBots')
249
252
  .populate('participatingAgents')
253
+ // .populate('followers')
250
254
  .populate({path:'requester',populate:{path:'id_user'}})
251
255
  .execPopulate(function (err, requestPopulated){
252
256
 
@@ -286,7 +290,6 @@ async (req, res) => {
286
290
 
287
291
 
288
292
 
289
-
290
293
  // router.put('/:messageid', function(req, res) {
291
294
 
292
295
  // console.log(req.body);