@tiledesk/tiledesk-server 2.3.2 → 2.3.5
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.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/pubmodules/activities/activityArchiver.js +1 -1
- package/pubmodules/emailNotification/requestNotification.js +184 -26
- package/routes/public-request.js +15 -0
- package/routes/request.js +20 -4
- package/services/emailService.js +189 -11
- package/services/leadService.js +2 -0
- package/template/email/newMessageFollower.html +236 -0
- package/views/messages.jade +1 -1
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
@@ -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("
|
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
|
-
|
63
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
237
|
-
|
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
|
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
|
-
|
533
|
-
|
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
|
|
package/routes/public-request.js
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
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){
|
package/services/emailService.js
CHANGED
@@ -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
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
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
|
-
//
|
1686
|
+
// emailService.sendTest("asd.");
|
1509
1687
|
|
1510
1688
|
module.exports = emailService;
|
package/services/leadService.js
CHANGED
@@ -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>
|
package/views/messages.jade
CHANGED
@@ -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('
|
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
|
|