@tiledesk/tiledesk-server 2.3.1 → 2.3.4

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.
@@ -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);