@tiledesk/tiledesk-server 2.1.40 → 2.2.3

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.
Files changed (91) hide show
  1. package/.circleci/config.yml +54 -0
  2. package/.env.sample +1 -1
  3. package/.github/workflows/docker-community-push-latest.yml +22 -0
  4. package/.github/workflows/{docker-image-push.yml → docker-image-en-tag-push.yml} +1 -1
  5. package/.github/workflows/docker-image-tag-community-tag-push.yml +21 -0
  6. package/.github/workflows/{docker-push-latest.yml → docker-push-en-push-latest.yml} +1 -1
  7. package/CHANGELOG.md +195 -1
  8. package/Dockerfile +1 -1
  9. package/Dockerfile-en +1 -1
  10. package/README.md +5 -7
  11. package/app.js +12 -1
  12. package/channels/channelManager.js +1 -1
  13. package/channels/chat21/chat21Contact.js +34 -8
  14. package/channels/chat21/chat21Handler.js +48 -5
  15. package/channels/chat21/chat21WebHook.js +34 -9
  16. package/channels/chat21/nativeauth.js +2 -2
  17. package/channels/chat21/package-lock.json +3013 -0
  18. package/config/email.js +2 -0
  19. package/config/global.js +3 -0
  20. package/config/labels/widget.json +170 -16
  21. package/event/messageEvent.js +18 -1
  22. package/middleware/passport.js +10 -4
  23. package/migrations/1619185894304-request-remove-duplicated-request-by-request_id--autosync.js +67 -0
  24. package/models/actionsConstants.js +7 -0
  25. package/models/department.js +3 -0
  26. package/models/faq.js +8 -2
  27. package/models/faq_kb.js +6 -0
  28. package/models/message.js +10 -4
  29. package/models/messageConstants.js +9 -3
  30. package/models/request.js +33 -3
  31. package/package.json +31 -28
  32. package/pubmodules/emailNotification/requestNotification.js +483 -56
  33. package/pubmodules/messageActions/messageActionsInterceptor.js +20 -7
  34. package/pubmodules/messageTransformer/index.js +5 -1
  35. package/pubmodules/messageTransformer/messageTransformerInterceptor.js +4 -2
  36. package/pubmodules/messageTransformer/microLanguageAttributesTransformerInterceptor.js +67 -0
  37. package/pubmodules/messageTransformer/microLanguageTransformerInterceptor.js +67 -0
  38. package/pubmodules/pubModulesManager.js +66 -13
  39. package/pubmodules/rules/conciergeBot.js +81 -49
  40. package/routes/auth.js +46 -11
  41. package/routes/campaigns.js +117 -25
  42. package/routes/department.js +2 -2
  43. package/routes/faq.js +19 -0
  44. package/routes/faq_kb.js +13 -4
  45. package/routes/faqpub.js +1 -1
  46. package/routes/files.js +17 -2
  47. package/routes/images.js +1 -1
  48. package/routes/jwt.js +0 -1
  49. package/routes/logs.js +26 -0
  50. package/routes/message.js +7 -2
  51. package/routes/messagesRoot.js +73 -16
  52. package/routes/project_user.js +36 -1
  53. package/routes/request.js +88 -12
  54. package/routes/requestUtilRoot.js +30 -0
  55. package/routes/urls.js +12 -0
  56. package/routes/users.js +5 -1
  57. package/services/BotSubscriptionNotifier.js +1 -0
  58. package/services/departmentService.js +29 -5
  59. package/services/emailService.js +1170 -239
  60. package/services/faqBotHandler.js +176 -61
  61. package/services/faqBotSupport.js +182 -117
  62. package/services/faqService.js +18 -14
  63. package/services/messageService.js +57 -9
  64. package/services/modulesManager.js +86 -23
  65. package/services/requestService.js +58 -17
  66. package/template/email/assignedEmailMessage.html +205 -0
  67. package/template/email/assignedRequest.html +44 -14
  68. package/template/email/beenInvitedExistingUser.html +2 -2
  69. package/template/email/beenInvitedNewUser.html +1 -1
  70. package/template/email/newMessage.html +31 -12
  71. package/template/email/passwordChanged.html +2 -3
  72. package/template/email/pooledEmailMessage.html +208 -0
  73. package/template/email/pooledRequest.html +41 -14
  74. package/template/email/resetPassword.html +2 -3
  75. package/template/email/sendTranscript.html +1 -1
  76. package/template/email/test.html +1 -1
  77. package/template/email/ticket.html +191 -0
  78. package/template/email/ticket.txt +11 -0
  79. package/template/email/verify.html +1 -1
  80. package/test/authentication.js +76 -4
  81. package/test/authenticationJwt.js +76 -2
  82. package/test/campaignsRoute.js +226 -0
  83. package/test/faqService.js +3 -3
  84. package/test/faqkbRoute.js +3 -2
  85. package/test/messageRootRoute.js +193 -0
  86. package/test/messageRoute.js +75 -0
  87. package/test/messageService.js +39 -2
  88. package/test/requestRoute.js +27 -9
  89. package/test/requestService.js +472 -11
  90. package/test-int/bot.js +673 -8
  91. package/websocket/webSocketServer.js +7 -4
@@ -12,6 +12,7 @@ var Message = require("../../models/message");
12
12
  const requestEvent = require('../../event/requestEvent');
13
13
  var winston = require('../../config/winston');
14
14
  var RoleConstants = require("../../models/roleConstants");
15
+ var ChannelConstants = require("../../models/channelConstants");
15
16
  var cacheUtil = require('../../utils/cacheUtil');
16
17
 
17
18
  const messageEvent = require('../../event/messageEvent');
@@ -19,9 +20,14 @@ var mongoose = require('mongoose');
19
20
  var jwt = require('jsonwebtoken');
20
21
  const uuidv4 = require('uuid/v4');
21
22
  var config = require('../../config/database');
23
+ var configGlobal = require('../../config/global');
22
24
 
23
25
  var widgetConfig = require('../../config/widget');
24
26
  var widgetTestLocation = process.env.WIDGET_TEST_LOCATION || widgetConfig.testLocation;
27
+ let configSecret = process.env.GLOBAL_SECRET || config.secret;
28
+
29
+ let apiUrl = process.env.API_URL || configGlobal.apiUrl;
30
+ winston.debug('********* RequestNotification apiUrl: ' + apiUrl);
25
31
 
26
32
  class RequestNotification {
27
33
 
@@ -30,28 +36,92 @@ listen() {
30
36
  var that = this;
31
37
 
32
38
 
33
- messageEvent.on("message.create", function(message) {
39
+
40
+ var messageCreateKey = 'message.create';
41
+ if (messageEvent.queueEnabled) {
42
+ messageCreateKey = 'message.create.queue';
43
+ }
44
+ winston.debug('RequestNotification messageCreateKey: ' + messageCreateKey);
45
+
46
+
47
+ messageEvent.on(messageCreateKey, function(message) {
34
48
 
35
49
  setImmediate(() => {
36
- // TODO aggiunta jwt widget login
37
50
  winston.debug("sendUserEmail", message);
38
- // if (process.env.SEND_OFFLINE_EMAIL) {
39
- // that.sendUserEmail(message.id_project, message);
40
- // }
51
+
52
+ if (message.attributes && message.attributes.subtype==='info') {
53
+ return winston.debug("not sending sendUserEmail for attributes.subtype info messages");
54
+ }
55
+
56
+
57
+ if (message.request && (message.request.channel.name===ChannelConstants.EMAIL || message.request.channel.name===ChannelConstants.FORM)) {
58
+
59
+ if (message.sender != message.request.lead.lead_id) {
60
+ winston.verbose("sending sendToUserEmailChannelEmail for EMAIL or FORM channel");
61
+ return that.sendToUserEmailChannelEmail(message.id_project, message);
62
+ } else {
63
+
64
+ if (message.text != message.request.first_text) {
65
+ winston.verbose("sending sendToAgentEmailChannelEmail for EMAIL or FORM channel");
66
+ return that.sendToAgentEmailChannelEmail(message.id_project, message);
67
+ } else {
68
+ winston.debug("sending sendToAgentEmailChannelEmail for EMAIL or FORM channel disabled for first text message")
69
+ }
70
+
71
+ }
72
+
73
+ } else {
74
+ winston.debug("sendUserEmail chat channel");
75
+ // controlla se sta funzionando
76
+ if (process.env.DISABLE_SEND_OFFLINE_EMAIL === "true" || process.env.DISABLE_SEND_OFFLINE_EMAIL === true ) {
77
+ return winston.debug("DISABLE_SEND_OFFLINE_EMAIL disabled");
78
+ }
79
+ // mandare email se ultimo messaggio > X MINUTI configurato in Notification . potresti usare request.updated_at ?
80
+ if (message.request && message.request.lead && message.sender != message.request.lead.lead_id) {
81
+ winston.debug("sendUserEmail", message);
82
+
83
+ // send an email only if offline and has an email
84
+ return that.sendUserEmail(message.id_project, message);
85
+ }
86
+
87
+ }
88
+
89
+
41
90
 
42
91
  });
43
92
  });
44
93
 
45
- requestEvent.on("request.create", function(request) {
94
+ var requestCreateKey = 'request.create';
95
+ if (requestEvent.queueEnabled) {
96
+ requestCreateKey = 'request.create.queue';
97
+ }
98
+ winston.debug('RequestNotification requestCreateKey: ' + requestCreateKey);
46
99
 
100
+ requestEvent.on(requestCreateKey, function(request) {
101
+ // winston.info('quiiiiiiiiiiiii');
47
102
  setImmediate(() => {
48
103
 
49
- that.sendAgentEmail(request.id_project, request);
104
+ /*
105
+ if (request && (request.channel.name===ChannelConstants.EMAIL || request.channel.name===ChannelConstants.FORM )) {
106
+ winston.verbose("sending sendEmailChannelTakingNotification for EMAIL or FORM channel");
107
+ that.sendEmailChannelTakingNotification(request.id_project, request)
108
+ }
109
+ */
110
+
111
+ that.sendAgentEmail(request.id_project, request);
112
+
50
113
  });
51
114
  });
52
115
 
53
116
 
54
- requestEvent.on("request.participants.update", function(data) {
117
+ var requestParticipantsUpdateKey = 'request.participants.update';
118
+ // this is not queued
119
+ // if (requestEvent.queueEnabled) {
120
+ // requestParticipantsUpdateKey = 'request.participants.update.queue';
121
+ // }
122
+ winston.debug('RequestNotification requestParticipantsUpdateKey: ' + requestParticipantsUpdateKey);
123
+
124
+ requestEvent.on(requestParticipantsUpdateKey, function(data) {
55
125
 
56
126
  winston.debug("requestEvent request.participants.update");
57
127
 
@@ -78,7 +148,13 @@ listen() {
78
148
 
79
149
  // TODO Send email also for addAgent and reassign. Alessio request for pooled only?
80
150
 
81
- requestEvent.on("request.close.extended", function(data) {
151
+ var requestCloseExtendedKey = 'request.close.extended';
152
+ // this is not queued
153
+ // if (requestEvent.queueEnabled) {
154
+ // requestCloseExtendedKey = 'request.close.extended.queue';
155
+ // }
156
+ winston.debug('RequestNotification requestCloseExtendedKey: ' + requestCloseExtendedKey);
157
+ requestEvent.on(requestCloseExtendedKey, function(data) {
82
158
  setImmediate(() => {
83
159
  var request = data.request;
84
160
  var notify = data.notify;
@@ -110,8 +186,8 @@ listen() {
110
186
 
111
187
  if (project_users && project_users.length>0) {
112
188
  project_users.forEach(project_user => {
113
- if (project_user.id_user) {
114
- return that.sendTranscriptByEmail(project_user.id_user.email, request_id, id_project);
189
+ if (project_user.id_user && project_user.id_user.email) {
190
+ return that.sendTranscriptByEmail(project_user.id_user.email, request_id, id_project, project);
115
191
  } else {
116
192
  }
117
193
  });
@@ -123,9 +199,9 @@ listen() {
123
199
  //send email to lead
124
200
  return Lead.findById(request.requester_id, function(err, lead){
125
201
  //if (lead && lead.email) {
126
- if (lead) {
127
- return that.sendTranscriptByEmail(lead.email, request_id, id_project);
128
- }
202
+ if (lead && lead.email) {
203
+ return that.sendTranscriptByEmail(lead.email, request_id, id_project, project);
204
+ }
129
205
 
130
206
  });
131
207
  //end send email to lead
@@ -142,6 +218,300 @@ listen() {
142
218
  });
143
219
  }
144
220
 
221
+
222
+ sendToUserEmailChannelEmail(projectid, message) {
223
+ try {
224
+
225
+ if (!message.request) {
226
+ return winston.debug("This is a direct message");
227
+ }
228
+
229
+ if (!message.request.lead || !message.request.lead.email) {
230
+ return winston.debug("The lead object is undefined or has empty email");
231
+ }
232
+
233
+ Project.findOne({_id: projectid, status: 100}).select("+settings").exec(function(err, project){
234
+ if (err) {
235
+ return winston.error(err);
236
+ }
237
+
238
+ if (!project) {
239
+ return winston.warn("Project not found", projectid);
240
+ }
241
+
242
+ // 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 ) {
243
+ // return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the conversations is blocked");
244
+ // }
245
+
246
+
247
+ // 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 ) {
248
+ // return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the offline conversation is disabled");
249
+ // }
250
+
251
+ let lead = message.request.lead;
252
+ winston.debug("sending channel emaol email to lead ", lead);
253
+
254
+
255
+ winston.debug("sending user email to "+ lead.email);
256
+
257
+ var signOptions = {
258
+ issuer: 'https://tiledesk.com',
259
+ subject: 'userexternal',
260
+ audience: 'https://tiledesk.com',
261
+ jwtid: uuidv4()
262
+ };
263
+
264
+
265
+ var recipient = lead.lead_id;
266
+ winston.debug("recipient:"+ recipient);
267
+
268
+ let userEmail = {_id: recipient, firstname: lead.fullname, lastname: lead.fullname, email: lead.email, attributes: lead.attributes};
269
+ winston.debug("userEmail ",userEmail);
270
+
271
+
272
+ var token = jwt.sign(userEmail, configSecret, signOptions);
273
+ winston.debug("token "+token);
274
+
275
+ var sourcePage = widgetTestLocation + "?tiledesk_projectid="
276
+ + projectid + "&project_name="+encodeURIComponent(project.name)
277
+
278
+ if (message.request.sourcePage) {
279
+ sourcePage = message.request.sourcePage;
280
+ }
281
+
282
+ if (sourcePage.indexOf("?")===-1) {
283
+ sourcePage = sourcePage + "?";
284
+ }
285
+
286
+ sourcePage = sourcePage
287
+ + "&tiledesk_recipientId="+message.request.request_id
288
+ + "&tiledesk_isOpen=true";
289
+
290
+
291
+ sourcePage = apiUrl + "/urls/redirect?path=" + encodeURIComponent(sourcePage)
292
+ winston.debug("sourcePage "+sourcePage);
293
+
294
+
295
+ var tokenQueryString;
296
+ if(sourcePage && sourcePage.indexOf('?')>-1) { //controllo superfluo visto che lo metto prima? ma lascio comunque per indipendenza
297
+ tokenQueryString = encodeURIComponent("&tiledesk_jwt=JWT "+token)
298
+ }else {
299
+ tokenQueryString = encodeURIComponent("?tiledesk_jwt=JWT "+token);
300
+ }
301
+ winston.debug("tokenQueryString: "+tokenQueryString);
302
+
303
+ emailService.sendEmailChannelNotification(message.request.lead.email, message, project, tokenQueryString, sourcePage);
304
+
305
+
306
+ });
307
+
308
+ } catch(e) {
309
+ winston.error("Error sending email", {error:e, projectid:projectid, message:message});
310
+ }
311
+ }
312
+
313
+
314
+
315
+
316
+ sendToAgentEmailChannelEmail(projectid, message) {
317
+ let savedRequest = message.request;
318
+ // send email
319
+ try {
320
+
321
+
322
+ Project.findOne({_id: projectid, status: 100}).select("+settings").exec(async function(err, project){
323
+ if (err) {
324
+ return winston.error(err);
325
+ }
326
+
327
+ if (!project) {
328
+ return winston.warn("Project not found", projectid);
329
+ } else {
330
+
331
+ winston.debug("project", project);
332
+
333
+ if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.blocked == true ) {
334
+ return winston.verbose("RequestNotification email notification for the project with id : " + projectid + " for all the conversations is blocked");
335
+ }
336
+
337
+ winston.debug("savedRequest", savedRequest);
338
+
339
+ // TODO fare il controllo anche sul dipartimento con modalità assigned o pooled
340
+ if (savedRequest.status==RequestConstants.UNASSIGNED) { //POOLED
341
+
342
+ if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.ticket && project.settings.email.notification.conversation.ticket.pooled == false ) {
343
+ return winston.info("RequestNotification email notification for the project with id : " + projectid + " for the pooled conversation ticket is disabled");
344
+ }
345
+
346
+ if (!savedRequest.snapshot) {
347
+ return winston.warn("RequestNotification savedRequest.snapshot is null :(. You are closing an old request?");
348
+ }
349
+
350
+
351
+
352
+
353
+ var snapshotAgents = await Request.findById(savedRequest.id).select({"snapshot":1}).exec();
354
+
355
+ winston.debug('snapshotAgents',snapshotAgents);
356
+
357
+
358
+ // winston.info("savedRequest.snapshot.agents", savedRequest.snapshot.agents);
359
+ // agents è selected false quindi nn va sicuro
360
+ if (!snapshotAgents.snapshot.agents) {
361
+ return winston.warn("RequestNotification snapshotAgents.snapshot.agents is null :(. You are closing an old request?", savedRequest);
362
+ }
363
+
364
+ // var allAgents = savedRequest.agents;
365
+ var allAgents = snapshotAgents.snapshot.agents;
366
+ // winston.debug("allAgents", allAgents);
367
+
368
+ allAgents.forEach(project_user => {
369
+ // winston.debug("project_user", project_user); //DON'T UNCOMMENT THIS. OTHERWISE this.agents.filter of models/request.js:availableAgentsCount has .filter not found.
370
+
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.pooled == false ) {
375
+ return winston.verbose("RequestNotification email notification for the user with id " + userid+ " the pooled conversation ticket is disabled");
376
+ }
377
+
378
+ User.findOne({_id: userid , status: 100})
379
+ .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.verbose("Sending sendNewPooledMessageNotification to user with email: "+ user.email);
388
+ if (user.emailverified) {
389
+ emailService.sendNewPooledMessageEmailNotification(user.email, savedRequest, project, message);
390
+ }else {
391
+ winston.verbose("User email not verified", user.email);
392
+ }
393
+ }
394
+ });
395
+
396
+
397
+ });
398
+
399
+ }
400
+
401
+ // TODO fare il controllo anche sul dipartimento con modalità assigned o pooled
402
+ else if (savedRequest.status==RequestConstants.ASSIGNED) { //ASSIGNED
403
+
404
+ if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.ticket && project.settings.email.notification.conversation.ticket.assigned == false ) {
405
+ return winston.verbose("RequestNotification email notification for the project with id : " + projectid + " for the assigned conversation ticket is disabled");
406
+ }
407
+
408
+
409
+ var assignedId = savedRequest.participants[0];
410
+
411
+ // winston.info("assignedId1:"+ assignedId);
412
+
413
+ // if (!assignedId) {
414
+ // console.log("attention90", savedRequest);
415
+ // }
416
+
417
+
418
+
419
+ Project_user.findOne( { id_user:assignedId, id_project: projectid, status: "active"}) //attento in 2.1.14.2
420
+ .exec(function (err, project_user) {
421
+
422
+ winston.debug("project_user notification", project_user);
423
+ if (project_user && 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.assigned && project_user.settings.email.notification.conversation.ticket.assigned.toyou == false ) {
424
+ return winston.info("RequestNotification email notification for the user with id : " + assignedId + " for the pooled conversation ticket is disabled");
425
+ }
426
+
427
+ // botprefix
428
+ if (assignedId.startsWith("bot_")) {
429
+ return ;
430
+ }
431
+
432
+ User.findOne({_id: assignedId, status: 100})
433
+ .cache(cacheUtil.defaultTTL, "users:id:"+assignedId)
434
+ .exec(function (err, user) {
435
+ if (err) {
436
+ winston.error("Error sending email to " + savedRequest.participants[0], err);
437
+ }
438
+ if (!user) {
439
+ winston.warn("User not found", savedRequest.participants[0]);
440
+ } else {
441
+ winston.verbose("Sending sendNewAssignedAgentMessageEmailNotification to user with email: "+ user.email);
442
+ // if (user.emailverified) { enable it? send anyway to improve engagment for new account
443
+ // attento cambia
444
+ emailService.sendNewAssignedAgentMessageEmailNotification(user.email, savedRequest, project, message);
445
+ // }
446
+ }
447
+ });
448
+
449
+ });
450
+
451
+ }
452
+
453
+
454
+
455
+ else {
456
+ return winston.debug("Other states");
457
+ }
458
+
459
+
460
+
461
+ }
462
+
463
+ });
464
+
465
+ } catch (e) {
466
+ winston.warn("Error sending email", {error:e, projectid:projectid, message: message, savedRequest:savedRequest}); //it's better to view error email at this stage
467
+ }
468
+ //end send email
469
+
470
+ }
471
+
472
+
473
+
474
+
475
+ //unused
476
+ sendEmailChannelTakingNotification(projectid, request) {
477
+ try {
478
+
479
+
480
+ if (!request.lead || !request.lead.email) {
481
+ return winston.debug("The lead object is undefined or has empty email");
482
+ }
483
+
484
+ Project.findOne({_id: projectid, status: 100}).select("+settings").exec(function(err, project){
485
+ if (err) {
486
+ return winston.error(err);
487
+ }
488
+
489
+ if (!project) {
490
+ return winston.warn("Project not found", projectid);
491
+ }
492
+
493
+ // 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 ) {
494
+ // return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the conversations is blocked");
495
+ // }
496
+
497
+
498
+ // 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 ) {
499
+ // return winston.info("RequestNotification offline email notification for the project with id : " + projectid + " for the offline conversation is disabled");
500
+ // }
501
+ emailService.sendEmailChannelTakingNotification(request.lead.email, request, project);
502
+
503
+
504
+ });
505
+
506
+ } catch(e) {
507
+ winston.error("Error sending email", {error:e, projectid:projectid, message:message});
508
+ }
509
+ }
510
+
511
+
512
+
513
+
514
+
145
515
  sendUserEmail(projectid, message) {
146
516
  try {
147
517
 
@@ -153,14 +523,13 @@ sendUserEmail(projectid, message) {
153
523
  return winston.debug("The lead object is undefined or has empty email");
154
524
  }
155
525
 
156
- Project.findOne({_id: projectid, status: 100}, function(err, project){
526
+ Project.findOne({_id: projectid, status: 100}).select("+settings").exec(function(err, project){
157
527
  if (err) {
158
528
  return winston.error(err);
159
529
  }
160
530
 
161
531
  if (!project) {
162
- // console.warn("Project not found", req.projectid);
163
- return console.warn("Project not found", projectid);
532
+ return winston.warn("Project not found", projectid);
164
533
  }
165
534
 
166
535
  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 ) {
@@ -204,9 +573,9 @@ sendUserEmail(projectid, message) {
204
573
 
205
574
  //send email to lead
206
575
  return Lead.findOne({lead_id: recipient}, function(err, lead){
207
- winston.debug("lead", lead);
576
+ winston.debug("lead", lead); //TODO lead is already present in request.lead
208
577
  if (lead && lead.email) {
209
- winston.info("sending user email to "+ lead.email);
578
+ winston.debug("sending user email to "+ lead.email);
210
579
 
211
580
  var signOptions = {
212
581
  issuer: 'https://tiledesk.com',
@@ -216,29 +585,40 @@ sendUserEmail(projectid, message) {
216
585
  };
217
586
 
218
587
  let userAnonym = {_id: recipient, firstname: lead.fullname, lastname: lead.fullname, email: lead.email, attributes: lead.attributes};
219
- winston.info("userAnonym ",userAnonym);
588
+ winston.debug("userAnonym ",userAnonym);
220
589
 
221
590
 
222
- var token = jwt.sign(userAnonym, config.secret, signOptions);
223
- winston.info("token "+token);
224
-
225
- var sourcePage = widgetTestLocation;
591
+ var token = jwt.sign(userAnonym, configSecret, signOptions);
592
+ winston.debug("token "+token);
226
593
 
594
+ var sourcePage = widgetTestLocation + "?tiledesk_projectid="
595
+ + projectid + "&project_name="+encodeURIComponent(project.name)
227
596
 
228
597
  if (message.request.sourcePage) {
229
- sourcePage = message.request.sourcePage;
598
+ sourcePage = message.request.sourcePage;
230
599
  }
231
600
 
232
- winston.info("sourcePage "+sourcePage);
601
+ if (sourcePage && sourcePage.indexOf("?")===-1) {
602
+ sourcePage = sourcePage + "?";
603
+ }
604
+
605
+ sourcePage = sourcePage
606
+ + "&tiledesk_recipientId="+message.request.request_id
607
+ + "&tiledesk_isOpen=true";
608
+
609
+ sourcePage = apiUrl + "/urls/redirect?path=" + encodeURIComponent(sourcePage)
610
+
611
+ winston.debug("sourcePage "+sourcePage);
233
612
 
234
613
  var tokenQueryString;
235
- if(sourcePage && sourcePage.indexOf('?')>-1) {
236
- tokenQueryString = "&tiledesk_customToken=JWT "+token
614
+ if(sourcePage && sourcePage.indexOf('?')>-1) { //controllo superfluo visto che lo metto prima? ma lascio comunque per indipendenza
615
+ tokenQueryString = encodeURIComponent("&tiledesk_jwt=JWT "+token)
237
616
  }else {
238
- tokenQueryString = "?tiledesk_customToken=JWT "+token
617
+ tokenQueryString = encodeURIComponent("?tiledesk_jwt=JWT "+token);
239
618
  }
240
-
241
- emailService.sendNewMessageNotification(lead.email, message, project, tokenQueryString);
619
+ winston.debug("tokenQueryString: "+tokenQueryString);
620
+
621
+ emailService.sendNewMessageNotification(lead.email, message, project, tokenQueryString, sourcePage);
242
622
  }
243
623
 
244
624
  });
@@ -256,19 +636,17 @@ sendUserEmail(projectid, message) {
256
636
  }
257
637
 
258
638
  sendAgentEmail(projectid, savedRequest) {
259
- // console.log("savedRequest23", savedRequest);
260
639
  // send email
261
640
  try {
262
641
 
263
642
 
264
- Project.findOne({_id: projectid, status: 100}, function(err, project){
643
+ Project.findOne({_id: projectid, status: 100}).select("+settings").exec( async function(err, project){
265
644
  if (err) {
266
645
  return winston.error(err);
267
646
  }
268
647
 
269
648
  if (!project) {
270
- // console.warn("Project not found", req.projectid);
271
- return console.warn("Project not found", projectid);
649
+ return winston.warn("Project not found", projectid);
272
650
  } else {
273
651
 
274
652
  winston.debug("project", project);
@@ -277,7 +655,7 @@ sendAgentEmail(projectid, savedRequest) {
277
655
  return winston.verbose("RequestNotification email notification for the project with id : " + projectid + " for all the conversations is blocked");
278
656
  }
279
657
 
280
- winston.debug("savedRequest", savedRequest);
658
+ winston.debug("savedRequest: " + JSON.stringify(savedRequest));
281
659
 
282
660
  // TODO fare il controllo anche sul dipartimento con modalità assigned o pooled
283
661
  if (savedRequest.status==RequestConstants.UNASSIGNED) { //POOLED
@@ -285,18 +663,40 @@ sendAgentEmail(projectid, savedRequest) {
285
663
  if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.pooled == false ) {
286
664
  return winston.info("RequestNotification email notification for the project with id : " + projectid + " for the pooled conversation is disabled");
287
665
  }
288
-
289
666
  if (!savedRequest.snapshot) {
290
- return winston.warn("RequestNotification savedRequest.snapshot is null :(");
667
+ return winston.warn("RequestNotification savedRequest.snapshot is null :(. You are closing an old request?");
668
+ }
669
+
670
+
671
+
672
+ var snapshotAgents = savedRequest; //riassegno varibile cosi nn cambio righe successive
673
+
674
+
675
+
676
+
677
+ // winston.info("savedRequest.snapshot.agents", savedRequest.snapshot.agents);
678
+ // agents è selected false quindi nn va sicuro
679
+ if (!snapshotAgents.snapshot.agents) {
680
+ //return winston.warn("RequestNotification snapshotAgents.snapshot.agents is null :(. You are closing an old request?", savedRequest);
681
+
682
+ // agents già c'è in quanto viene creato con departmentService.getOperator nella request.create ma nn c'è per request.participants.update
683
+ snapshotAgents = await Request.findById(savedRequest.id).select({"snapshot":1}).exec();
684
+ winston.debug('load snapshotAgents with Request.findById ');
291
685
  }
292
- if (!savedRequest.snapshot.agents) {
293
- return winston.warn("RequestNotification savedRequest.snapshot.agents is null :(", savedRequest);
686
+ winston.debug('snapshotAgents', snapshotAgents);
687
+
688
+ if (!snapshotAgents.snapshot.agents) {
689
+ return winston.warn("RequestNotification snapshotAgents.snapshot.agents is null :(. You are closing an old request?", savedRequest);
294
690
  }
691
+
295
692
  // var allAgents = savedRequest.agents;
296
- var allAgents = savedRequest.snapshot.agents;
297
- // winston.debug("allAgents", allAgents);
693
+ var allAgents = snapshotAgents.snapshot.agents;
694
+
695
+ // // var allAgents = savedRequest.agents;
696
+ // var allAgents = savedRequest.snapshot.agents;
697
+ // // winston.debug("allAgents", allAgents);
298
698
 
299
- allAgents.forEach(project_user => {
699
+ allAgents.forEach(project_user => {
300
700
  // winston.debug("project_user", project_user); //DON'T UNCOMMENT THIS. OTHERWISE this.agents.filter of models/request.js:availableAgentsCount has .filter not found.
301
701
 
302
702
 
@@ -315,7 +715,7 @@ sendAgentEmail(projectid, savedRequest) {
315
715
  if (!user) {
316
716
  winston.warn("User not found", userid);
317
717
  } else {
318
- winston.debug("Sending sendNewPooledRequestNotification to user with email: "+ user.email);
718
+ winston.verbose("Sending sendNewPooledRequestNotification to user with email: "+ user.email);
319
719
  if (user.emailverified) {
320
720
  emailService.sendNewPooledRequestNotification(user.email, savedRequest, project);
321
721
  }else {
@@ -347,19 +747,27 @@ sendAgentEmail(projectid, savedRequest) {
347
747
 
348
748
 
349
749
 
350
- Project_user.findOne( { id_user:assignedId, id_project: projectid, status: "active"}) //attento in 2.1.14.2
750
+ Project_user.findOne( { id_user:assignedId, id_project: projectid, status: "active"})
351
751
  .exec(function (err, project_user) {
352
752
 
753
+ // botprefix
754
+ if (assignedId.startsWith("bot_")) {
755
+ return ;
756
+ }
757
+
758
+ if (err) {
759
+ return winston.error("RequestNotification email notification error getting project_user", err);
760
+ }
353
761
  winston.debug("project_user notification", project_user);
354
762
  if (project_user && project_user.settings && project_user.settings.email && project_user.settings.email.notification && project_user.settings.email.notification.conversation && project_user.settings.email.notification.conversation.assigned && project_user.settings.email.notification.conversation.assigned.toyou == false ) {
355
763
  return winston.info("RequestNotification email notification for the user with id : " + assignedId + " for the pooled conversation is disabled");
356
764
  }
357
765
 
358
- // botprefix
359
- if (assignedId.startsWith("bot_")) {
360
- return ;
361
- }
766
+
362
767
 
768
+ if (!project_user) {
769
+ return winston.warn("RequestNotification email notification for the user with id : " + assignedId + " not found project_user");
770
+ }
363
771
  User.findOne({_id: assignedId, status: 100})
364
772
  .cache(cacheUtil.defaultTTL, "users:id:"+assignedId)
365
773
  .exec(function (err, user) {
@@ -367,11 +775,30 @@ sendAgentEmail(projectid, savedRequest) {
367
775
  winston.error("Error sending email to " + savedRequest.participants[0], err);
368
776
  }
369
777
  if (!user) {
370
- console.warn("User not found", savedRequest.participants[0]);
778
+ winston.warn("User not found", savedRequest.participants[0]);
371
779
  } else {
372
- winston.debug("Sending sendNewAssignedRequestNotification to user with email", user.email);
373
- // if (user.emailverified) { enable it? send anyway to improve engagment for new account
374
- emailService.sendNewAssignedRequestNotification(user.email, savedRequest, project);
780
+ winston.verbose("Sending sendNewAssignedRequestNotification to user with email", user.email);
781
+ // if (user.emailverified) { enable it? send anyway to improve engagment for new account
782
+
783
+
784
+ // var signOptions = {
785
+ // issuer: 'https://tiledesk.com',
786
+ // subject: 'user',
787
+ // audience: 'https://tiledesk.com',
788
+ // jwtid: uuidv4()
789
+ // };
790
+
791
+ // let userObject = {_id: user._id, firstname: user.firstname, lastname: user.lastname, email: user.email, attributes: user.attributes};
792
+ // winston.debug("userObject ",userObject);
793
+
794
+
795
+ // var agentToken = jwt.sign(userObject, configSecret, signOptions);
796
+ // winston.debug("agentToken "+agentToken);
797
+
798
+
799
+
800
+
801
+ emailService.sendNewAssignedRequestNotification(user.email, savedRequest, project);
375
802
  // }
376
803
  }
377
804
  });
@@ -404,7 +831,7 @@ sendAgentEmail(projectid, savedRequest) {
404
831
 
405
832
 
406
833
 
407
- sendTranscriptByEmail(sendTo, request_id, id_project) {
834
+ sendTranscriptByEmail(sendTo, request_id, id_project, project) {
408
835
  return new Promise(function (resolve, reject) {
409
836
  return Request.findOne({request_id: request_id, id_project: id_project})
410
837
  .populate('department')
@@ -434,8 +861,8 @@ sendAgentEmail(projectid, savedRequest) {
434
861
 
435
862
 
436
863
 
437
- emailService.sendRequestTranscript(sendTo, messages, request);
438
- winston.debug("sendTranscriptByEmail sent");
864
+ emailService.sendRequestTranscript(sendTo, messages, request, project);
865
+ winston.verbose("sendTranscriptByEmail sent");
439
866
  return resolve({sendTo: sendTo, messages: messages, request: request});
440
867
 
441
868