@tiledesk/tiledesk-server 2.3.2 → 2.3.5

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
 
2
2
 
3
+ # 2.3.2
4
+ - Dowload trascript as csv, pdf and txt endpoint
5
+ - Added closed_by field to the request model
6
+ - Added followers field to the request model
7
+ - Added lead index
8
+ - Added widget v5 code loader /widgets/v5/:project_id -> heroku blocca cache-control
9
+ - Bugfix Cannot read property 'profile' of null
10
+ - Added filter by channel offline and online
11
+ - Updated Rasa Connector to 1.0.7
12
+ - Send info message on lead.fullaname.update
13
+
14
+
3
15
  # 2.3.1
4
16
  - changed tiledesk logo for emails
5
17
  - open modules: analytics, activity log, multi tenancy, departments, groups, canned responses, tags, triggers, webhooks
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-server",
3
3
  "description": "The Tiledesk server module",
4
- "version": "2.3.2",
4
+ "version": "2.3.5",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -76,7 +76,7 @@ class ActivityArchiver {
76
76
 
77
77
  authEvent.on('project_user.update', function(event) {
78
78
  setImmediate(() => {
79
- console.log("project_user.update");
79
+ // console.log("project_user.update");
80
80
  /*
81
81
  2019-11-20T10:40:52.686991+00:00 app[web.1]: TypeError: Cannot read property '_id' of undefined
82
82
  */
@@ -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
 
@@ -86,6 +86,9 @@ var printer = new PdfPrinter(fonts);
86
86
  delete element.attributes;
87
87
  });
88
88
 
89
+ res.setHeader('Content-Type', 'applictext/csv');
90
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.csv');
91
+
89
92
  return res.csv(messages, true);
90
93
  });
91
94
 
@@ -170,6 +173,11 @@ var printer = new PdfPrinter(fonts);
170
173
 
171
174
  var pdfDoc = printer.createPdfKitDocument(docDefinition);
172
175
  // pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
176
+
177
+ res.setHeader('Content-Type', 'application/pdf');
178
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.pdf');
179
+
180
+
173
181
  pdfDoc.pipe(res);
174
182
  pdfDoc.end();
175
183
 
@@ -287,6 +295,10 @@ var printer = new PdfPrinter(fonts);
287
295
 
288
296
  var pdfDoc = printer.createPdfKitDocument(docDefinition);
289
297
  // pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
298
+
299
+ res.setHeader('Content-Type', 'application/pdf');
300
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.pdf');
301
+
290
302
  pdfDoc.pipe(res);
291
303
  pdfDoc.end();
292
304
 
@@ -328,6 +340,9 @@ var printer = new PdfPrinter(fonts);
328
340
  });
329
341
 
330
342
 
343
+ res.setHeader('Content-Type', 'applictext/csv');
344
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.csv');
345
+
331
346
  return res.csv(messages, true);
332
347
  });
333
348
 
package/routes/request.js CHANGED
@@ -656,6 +656,8 @@ router.delete('/id/:id', function (req, res) {
656
656
 
657
657
  router.get('/', function (req, res, next) {
658
658
 
659
+ const startExecTime = new Date();
660
+
659
661
  winston.debug("req projectid", req.projectid);
660
662
  winston.debug("req.query.sort", req.query.sort);
661
663
  winston.debug('REQUEST ROUTE - QUERY ', req.query)
@@ -910,14 +912,17 @@ router.get('/', function (req, res, next) {
910
912
 
911
913
  winston.debug("sort query", sortQuery);
912
914
 
913
- winston.verbose('REQUEST ROUTE - REQUEST FIND ', query);
915
+ winston.debug('REQUEST ROUTE - REQUEST FIND ', query);
914
916
 
915
917
  var projection = undefined;
916
918
 
917
919
  if (req.query.full_text) {
918
- winston.debug('fulltext projection');
919
920
 
920
- projection = {score: { $meta: "textScore" } };
921
+ if (req.query.no_textscore!= "true" && req.query.no_textscore!= true) {
922
+ winston.info('fulltext projection on');
923
+ projection = {score: { $meta: "textScore" } };
924
+ }
925
+
921
926
  }
922
927
  // requestcachefarequi populaterequired
923
928
  var q1 = Request.find(query, projection).
@@ -949,7 +954,9 @@ router.get('/', function (req, res, next) {
949
954
 
950
955
  if (req.query.full_text) {
951
956
  winston.debug('fulltext sort');
952
- q1.sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
957
+ if (req.query.no_textscore!= "true" && req.query.no_textscore!= true) {
958
+ q1.sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
959
+ }
953
960
  } else {
954
961
  q1.sort(sortQuery);
955
962
  }
@@ -965,6 +972,11 @@ router.get('/', function (req, res, next) {
965
972
 
966
973
  var q2 = Request.countDocuments(query).exec();
967
974
 
975
+ if (req.query.no_count && req.query.no_count =="true") {
976
+ winston.info('REQUEST ROUTE - no_count ');
977
+ q2 = 0;
978
+ }
979
+
968
980
  var promises = [
969
981
  q1,
970
982
  q2
@@ -978,6 +990,10 @@ router.get('/', function (req, res, next) {
978
990
  };
979
991
  winston.debug('REQUEST ROUTE - objectToReturn ');
980
992
  winston.debug('REQUEST ROUTE - objectToReturn ', objectToReturn);
993
+
994
+ const endExecTime = new Date();
995
+ winston.info('REQUEST ROUTE - exec time: ' + (endExecTime-startExecTime));
996
+
981
997
  return res.json(objectToReturn);
982
998
 
983
999
  }).catch(function(err){
@@ -191,20 +191,24 @@ class EmailService {
191
191
  user: configEmail.user,
192
192
  pass: configEmail.pass
193
193
  },
194
+ // secureConnection: false,
195
+ // tls:{
196
+ // ciphers:'SSLv3'
197
+ // },
194
198
 
195
- // openssl genrsa -out dkim_private.pem 2048
199
+ // openssl genrsa -out dkim_private.pem 2048
196
200
  // openssl rsa -in dkim_private.pem -pubout -outform der 2>/dev/null | openssl base64 -A
197
201
  // ->
198
202
  // v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunT2EopDAYnHwAOHd33KhlzjUXJfhmA+fK+cG85i9Pm33oyv1NoGrOynsni0PO6j7oRxxHqs6EMDOw4I/Q0C7aWn20oBomJZehTOkCV2xpuPKESiRktCe/MIZqbkRdypis4jSkFfFFkBHwgkAg5tb11E9elJap0ed/lN5/XlpGedqoypKxp+nEabgYO5mBMMNKRvbHx0eQttRYyIaNkTuMbAaqs4y3TkHOpGvZTJsvUonVMGAstSCfUmXnjF38aKpgyTausTSsxHbaxh3ieUB4ex+svnvsJ4Uh5Skklr+bxLVEHeJN55rxmV67ytLg5XCRWqdKIcJHFvSlm2YwJfcwIDAQABMacAL
199
203
  // testdkim._domainkey.tiledesk.com. 86400 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunT2EopDAYnHwAOHd33KhlzjUXJfhmA+fK+cG85i9Pm33oyv1NoGrOynsni0PO6j7oRxxHqs6EMDOw4I/Q0C7aWn20oBomJZehTOkCV2xpuPKESiRktCe/MIZqbkRdypis4jSkFfFFkBHwgkAg5tb11E9elJap0ed/lN5/XlpGedqoypKxp+nEabgYO5mBMMNKRvbHx0eQttRYyIaNkTuMbAaqs4y3TkHOpGvZTJsvUonVMGAstSCfUmXnjF38aKpgyTausTSsxHbaxh3ieUB4ex+svnvsJ4Uh5Skklr+bxLVEHeJN55rxmV67ytLg5XCRWqdKIcJHFvSlm2YwJfcwIDAQABMacAL"
200
204
 
201
- dkim: {
202
- domainName: "example.com",
203
- keySelector: "2017",
204
- privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
205
- cacheDir: "/tmp",
206
- cacheTreshold: 100 * 1024
207
- }
205
+ // dkim: {
206
+ // domainName: "example.com",
207
+ // keySelector: "2017",
208
+ // privateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBg...",
209
+ // cacheDir: "/tmp",
210
+ // cacheTreshold: 100 * 1024
211
+ // }
208
212
  };
209
213
 
210
214
  winston.debug("getTransport transport: ",transport);
@@ -406,7 +410,9 @@ class EmailService {
406
410
  }
407
411
  }
408
412
 
409
-
413
+ // troncare nome utnete e nome progetto a max 10 caratteri
414
+ // cambiare in [Nicky:Dashboard Support] Assigned Chat
415
+ // serve per aggiornare native... fai aggiornamento
410
416
 
411
417
  let subject = `[Tiledesk ${project ? project.name : '-'}] New Assigned Chat`;
412
418
 
@@ -958,11 +964,12 @@ class EmailService {
958
964
 
959
965
  let inReplyTo;
960
966
  let references;
967
+ winston.debug("message.request.attributes", message.request.attributes);
961
968
  if (message.request.attributes) {
962
969
  if (message.request.attributes.email_messageId) {
963
970
  inReplyTo = message.request.attributes.email_messageId;
964
971
  }
965
- if (message.attributes.email_references) {
972
+ if (message.request.attributes.email_references) {
966
973
  references = message.request.attributes.email_references;
967
974
  }
968
975
  }
@@ -1176,6 +1183,177 @@ class EmailService {
1176
1183
  }
1177
1184
 
1178
1185
 
1186
+
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+
1193
+
1194
+
1195
+ async sendFollowerNotification(to, message, project) {
1196
+
1197
+ var that = this;
1198
+
1199
+
1200
+ if (project.toJSON) {
1201
+ project = project.toJSON();
1202
+ }
1203
+
1204
+ var html = await this.readTemplate('newMessageFollower.html', project.settings);
1205
+
1206
+
1207
+ var envTemplate = process.env.EMAIL_FOLLOWER_HTML_TEMPLATE;
1208
+ winston.debug("envTemplate: " + envTemplate);
1209
+
1210
+ if (envTemplate) {
1211
+ html = envTemplate;
1212
+ }
1213
+
1214
+ winston.debug("html: " + html);
1215
+
1216
+ var template = handlebars.compile(html);
1217
+
1218
+ var baseScope = JSON.parse(JSON.stringify(that));
1219
+ delete baseScope.pass;
1220
+
1221
+
1222
+ let msgText = message.text;//.replace(/[\n\r]/g, '<br>');
1223
+ msgText = encode(msgText);
1224
+ if (this.markdown) {
1225
+ msgText = marked(msgText);
1226
+ }
1227
+
1228
+ winston.debug("msgText: " + msgText);
1229
+ winston.debug("baseScope: " + JSON.stringify(baseScope));
1230
+
1231
+
1232
+ var replacements = {
1233
+ message: message,
1234
+ project: project,
1235
+ msgText: msgText,
1236
+ baseScope: baseScope
1237
+ };
1238
+
1239
+ var html = template(replacements);
1240
+ winston.debug("html: " + html);
1241
+
1242
+ const fs = require('fs');
1243
+ fs.writeFileSync('tem1111.html', html);
1244
+
1245
+
1246
+
1247
+ let messageId = message._id + "@" + MESSAGE_ID_DOMAIN;
1248
+
1249
+ let replyTo;
1250
+ if (this.replyEnabled) {
1251
+ replyTo = message.request.request_id + this.inboundDomainDomainWithAt;
1252
+ }
1253
+
1254
+ let headers;
1255
+ if (message.request) {
1256
+
1257
+ messageId = message.request.request_id + "+" + messageId;
1258
+
1259
+ if (message.request.attributes && message.request.attributes.email_replyTo) {
1260
+ replyTo = message.request.attributes.email_replyTo;
1261
+ }
1262
+
1263
+ headers = {"X-TILEDESK-PROJECT-ID": project._id, "X-TILEDESK-REQUEST-ID": message.request.request_id, "X-TILEDESK-TICKET-ID":message.request.ticket_id };
1264
+
1265
+ winston.verbose("messageId: " + messageId);
1266
+ winston.verbose("replyTo: " + replyTo);
1267
+ winston.verbose("email headers", headers);
1268
+ }
1269
+
1270
+
1271
+ let inReplyTo;
1272
+ let references;
1273
+ let cc;
1274
+ let ccString;
1275
+
1276
+ if (message.request && message.request.attributes) {
1277
+ winston.debug("email message.request.attributes: ", message.request.attributes);
1278
+
1279
+ if (message.request.attributes.email_messageId) {
1280
+ inReplyTo = message.request.attributes.email_messageId;
1281
+ }
1282
+ if (message.request.attributes.email_references) {
1283
+ references = message.request.attributes.email_references;
1284
+ }
1285
+
1286
+ if (message.request.attributes.email_cc) {
1287
+ cc = message.request.attributes.email_cc;
1288
+ }
1289
+ winston.debug("email message.request.attributes.email_ccStr: "+ message.request.attributes.email_ccStr);
1290
+ if (message.request.attributes.email_ccStr!=undefined) {
1291
+ ccString = message.request.attributes.email_ccStr;
1292
+ winston.debug("email set ccString");
1293
+ }
1294
+ }
1295
+ winston.verbose("email inReplyTo: "+ inReplyTo);
1296
+ winston.verbose("email references: "+ references);
1297
+ winston.verbose("email cc: ", cc);
1298
+ winston.verbose("email ccString: "+ ccString);
1299
+
1300
+ let from;
1301
+ let configEmail;
1302
+ if (project && project.settings && project.settings.email) {
1303
+ if (project.settings.email.config) {
1304
+ configEmail = project.settings.email.config;
1305
+ winston.verbose("custom email configEmail setting found: ", configEmail);
1306
+ }
1307
+ if (project.settings.email.from) {
1308
+ from = project.settings.email.from;
1309
+ winston.verbose("custom from email setting found: "+ from);
1310
+ }
1311
+ }
1312
+
1313
+
1314
+
1315
+
1316
+ that.send({
1317
+ messageId: messageId,
1318
+ // sender: message.senderFullname, //must be an email
1319
+ from:from,
1320
+ to:to,
1321
+ cc: ccString,
1322
+ replyTo: replyTo,
1323
+ inReplyTo: inReplyTo,
1324
+ references: references,
1325
+ // subject:`${message.request ? message.request.subject : '-'}`,
1326
+ subject:`${message.request ? message.request.ticket_id : '-'}`, //gmail uses subject
1327
+ text:html,
1328
+ html:html,
1329
+ config:configEmail,
1330
+ headers:headers
1331
+ });
1332
+
1333
+ // // messageId = "notification" + messageId;
1334
+
1335
+ // // that.send({
1336
+ // // messageId: messageId,
1337
+ // // // sender: message.senderFullname, //must be an email
1338
+ // // to: that.bcc,
1339
+ // // replyTo: replyTo,
1340
+ // // inReplyTo: inReplyTo,
1341
+ // // references: references,
1342
+ // // // subject: `${message.request ? message.request.subject : '-'} - notification`,
1343
+ // // subject: `${message.request ? message.request.subject : '-'} - notification`,
1344
+ // // text:html,
1345
+ // // html:html,
1346
+ // // headers:headers
1347
+ // // });
1348
+
1349
+
1350
+ }
1351
+
1352
+
1353
+
1354
+
1355
+
1356
+
1179
1357
  /*
1180
1358
  sendEmailChannelTakingNotification(to, request, project, tokenQueryString) {
1181
1359
 
@@ -1505,6 +1683,6 @@ async sendRequestTranscript(to, messages, request, project) {
1505
1683
 
1506
1684
  var emailService = new EmailService();
1507
1685
 
1508
- // emailService.sendTest("al@f21.it");
1686
+ // emailService.sendTest("asd.");
1509
1687
 
1510
1688
  module.exports = emailService;
@@ -128,6 +128,8 @@ class LeadService {
128
128
 
129
129
 
130
130
  leadEvent.emit('lead.update', updatedLead);
131
+ leadEvent.emit('lead.email.update', updatedLead);
132
+ leadEvent.emit('lead.fullname.update', updatedLead);
131
133
  return resolve(updatedLead);
132
134
  });
133
135
  });
@@ -0,0 +1,236 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html lang="en" xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
3
+
4
+ <head>
5
+ <meta name="viewport" content="width=device-width" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
+ <title>New Ticket from TileDesk</title>
8
+
9
+ <style type="text/css">
10
+ img {
11
+ max-width: 100%;
12
+ margin-left:16px;
13
+ margin-bottom:16px;
14
+ text-align:center !important;
15
+ }
16
+ body {
17
+ -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em;
18
+ }
19
+ body {
20
+ background-color: #f6f6f6;
21
+ }
22
+
23
+ @media only screen and (max-width: 640px) {
24
+ body {
25
+ padding: 0 !important;
26
+ }
27
+ h1 {
28
+ font-weight: 800 !important; margin: 20px 0 5px !important;
29
+ text-align:center !important;
30
+ }
31
+ h2 {
32
+ font-weight: 800 !important; margin: 20px 0 5px !important;
33
+ }
34
+ h3 {
35
+ font-weight: 800 !important; margin: 20px 0 5px !important;
36
+ }
37
+ h4 {
38
+ font-weight: 800 !important; margin: 20px 0 5px !important;
39
+ }
40
+ h1 {
41
+ font-size: 22px !important;
42
+ }
43
+ h2 {
44
+ font-size: 18px !important;
45
+ }
46
+ h3 {
47
+ font-size: 16px !important;
48
+ }
49
+ .container {
50
+ padding: 0 !important; width: 100% !important;
51
+ }
52
+ .content {
53
+ padding: 0 !important;
54
+ }
55
+ .content-wrap {
56
+ padding: 10px !important;
57
+ }
58
+ .invoice {
59
+ width: 100% !important;
60
+ }
61
+ }
62
+ </style>
63
+ </head>
64
+
65
+ <body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
66
+
67
+ {{#if baseScope.replyEnabled}}
68
+ <div>\# Please type your reply above this line \#</div>
69
+ {{/if}}
70
+
71
+ <table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff">
72
+
73
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
74
+ <td class="alert alert-warning" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; margin: 0;" align="center" valign="top">
75
+
76
+ <div style="text-align:center">
77
+ <a href="http://www.tiledesk.com" style="color:#2daae1;font-weight:bold;text-decoration:none;word-break:break-word" target="_blank">
78
+ <img src="https://tiledesk.com/wp-content/uploads/2022/07/tiledesk_v2.png" style="width:20%;outline:none;text-decoration:none;border:none;min-height:36px" class="CToWUd">
79
+ </a>
80
+ </div>
81
+ </td>
82
+ </tr>
83
+
84
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
85
+
86
+ <td class="alert alert-warning" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; margin: 0;" align="center" valign="top">
87
+ <div>
88
+ <h2>You are a follower of the ticket number: #{{message.request.ticket_id}}</h2>
89
+ </div>
90
+
91
+ </td>
92
+ </tr>
93
+
94
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
95
+ <td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
96
+ <table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
97
+
98
+
99
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
100
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
101
+ Sender: <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{message.senderFullname}}</strong>
102
+ </td>
103
+ </tr>
104
+
105
+
106
+
107
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
108
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
109
+ {{#ifEquals message.type "text"}}
110
+ <div style="white-space: pre-wrap;">{{{msgText}}}</div>
111
+ {{/ifEquals}}
112
+ {{#ifEquals message.type "image"}}
113
+ <img src="{{message.metadata.src}}"/>
114
+ {{#if msgText}}
115
+ <div style="white-space: pre-wrap;">{{{msgText}}}</div>
116
+ {{/if}}
117
+ {{/ifEquals}}
118
+ {{#ifEquals message.type "file"}}
119
+ <a href="{{message.metadata.src}}">{{message.metadata.name}}</a>
120
+ {{/ifEquals}}
121
+ {{#ifEquals message.type "frame"}}
122
+ <a href="{{message.metadata.src}}">{{message.metadata.name}}</a>
123
+ {{#if msgText}}
124
+ <div style="white-space: pre-wrap;">{{{msgText}}}</div>
125
+ {{/if}}
126
+ {{/ifEquals}}
127
+
128
+ {{#if message.attributes}}
129
+ {{#if message.attributes.attachment}}
130
+ {{#if message.attributes.attachment.buttons}}
131
+ {{#each message.attributes.attachment.buttons}}
132
+ {{#ifEquals this.type "url"}}
133
+ <li><a href="{{this.link}}" class="dynamic_button">{{this.value}}</a></li>
134
+ {{else}}
135
+ <li><a href="mailto:{{../message.request.request_id}}@{{../baseScope.inboundDomain}}?subject=Re:%20{{../message.request.subject}}&body={{this.value}}" class="dynamic_button">{{this.value}}</a></li>
136
+ {{/ifEquals}}
137
+ {{/each}}
138
+
139
+
140
+ {{/if}}
141
+ {{/if}}
142
+ {{/if}}
143
+
144
+ <!-- {{#if message.attributes.intent_info}}
145
+ {{#if message.attributes.intent_info.others}}
146
+ Others:
147
+ {{#each message.attributes.intent_info.others}}
148
+ <li><span>{{this.answer}}</span></li>
149
+ {{/each}}
150
+ {{/if}}
151
+ {{/if}} -->
152
+
153
+
154
+
155
+
156
+
157
+ </td>
158
+ </tr>
159
+
160
+
161
+
162
+
163
+
164
+
165
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
166
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
167
+ Project name : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{project.name}}</strong>
168
+ </td>
169
+ </tr>
170
+
171
+
172
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
173
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
174
+ Department name : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{message.request.department.name}}</strong>
175
+ </td>
176
+ </tr>
177
+
178
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
179
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
180
+ Source page : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{message.request.sourcePage}}</strong>
181
+ </td>
182
+ </tr>
183
+
184
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
185
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
186
+ Contact name : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{message.request.lead.fullname}}</strong>
187
+ </td>
188
+ </tr>
189
+
190
+
191
+
192
+
193
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
194
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
195
+ Channel : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
196
+
197
+ {{#ifEquals message.request.channel.name "chat21"}}
198
+ Chat
199
+ {{else}}
200
+ {{message.request.channel.name}}
201
+ {{/ifEquals}}
202
+
203
+
204
+ </strong>
205
+ </td>
206
+ </tr>
207
+
208
+
209
+
210
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
211
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
212
+ Priority : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{message.request.priority}}</strong>
213
+ </td>
214
+ </tr>
215
+
216
+
217
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
218
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
219
+ </td>
220
+ </tr>
221
+ </table>
222
+ </td>
223
+ </tr>
224
+ </table>
225
+ <div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
226
+ <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
227
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
228
+ <td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top">
229
+ <span><a href="http://www.tiledesk.com" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;" > Tiledesk.com </a></span>
230
+ <!-- <br><span><a href="%unsubscribe_url%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">Unsubscribe</a></span> -->
231
+ </td>
232
+ </tr>
233
+ </table>
234
+
235
+ </body>
236
+ </html>
@@ -10,7 +10,7 @@ block content
10
10
 
11
11
  each message in messages
12
12
  p(class="transcript-p")
13
- span(class="transcript-chat-date") [#{message.createdAt.toLocaleString('it', { timeZone: 'UTC' })}]
13
+ span(class="transcript-chat-date") [#{message.createdAt.toLocaleString('en', { timeZone: 'UTC' })}]
14
14
  span(class="transcript-chat-sender") #{message.senderFullname}:
15
15
  span(class="transcript-chat-msg") #{message.text}
16
16