@tiledesk/tiledesk-server 2.3.49 → 2.3.50
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 +4 -0
- package/app.js +2 -1
- package/package.json +4 -1
- package/pubmodules/apps/index.js +8 -0
- package/pubmodules/apps/listener.js +27 -0
- package/pubmodules/kaleyra/index.js +6 -0
- package/pubmodules/kaleyra/listener.js +32 -0
- package/pubmodules/pubModulesManager.js +67 -0
- package/pubmodules/whatsapp/index.js +7 -0
- package/pubmodules/whatsapp/listener.js +32 -0
- package/routes/email.js +26 -2
- package/services/emailService.js +97 -6
- package/template/email/beenInvitedExistingUser.html +1 -1
- package/template/email/beenInvitedNewUser.html +1 -1
- package/template/email/emailDirect.html +121 -0
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.48)
|
7
7
|
|
8
|
+
# Untagged
|
9
|
+
- Added new email sending endpoint
|
10
|
+
- Emails endpoint is now usable by agents
|
11
|
+
|
8
12
|
# 2.3.49 -> PROD
|
9
13
|
- @tiledesk/tiledesk-tybot-connector": "^0.1.22
|
10
14
|
|
package/app.js
CHANGED
@@ -481,7 +481,8 @@ app.use('/:projectid/labels', [fetchLabels],labels);
|
|
481
481
|
|
482
482
|
app.use('/:projectid/campaigns',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], campaigns);
|
483
483
|
|
484
|
-
app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('
|
484
|
+
app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], email);
|
485
|
+
|
485
486
|
|
486
487
|
|
487
488
|
|
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.
|
4
|
+
"version": "2.3.50",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -36,6 +36,9 @@
|
|
36
36
|
"@tiledesk-ent/tiledesk-server-enterprise": "^1.0.0"
|
37
37
|
},
|
38
38
|
"dependencies": {
|
39
|
+
"@tiledesk/tiledesk-apps": "^1.0.6",
|
40
|
+
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.19",
|
41
|
+
"@tiledesk/tiledesk-kaleyra-proxy": "^0.1.5",
|
39
42
|
"@tiledesk/tiledesk-chat21-app": "^1.1.7",
|
40
43
|
"@tiledesk/tiledesk-chatbot-util": "^0.8.33",
|
41
44
|
"@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
|
@@ -0,0 +1,27 @@
|
|
1
|
+
const apps = require("@tiledesk/tiledesk-apps");
|
2
|
+
var winston = require('../../config/winston');
|
3
|
+
|
4
|
+
class Listener {
|
5
|
+
|
6
|
+
listen(config) {
|
7
|
+
|
8
|
+
winston.info("Apps Listener listen");
|
9
|
+
|
10
|
+
if (config.databaseUri) {
|
11
|
+
winston.debug("apps config databaseUri: " + config.databaseUri);
|
12
|
+
}
|
13
|
+
|
14
|
+
apps.startApp({
|
15
|
+
ACCESS_TOKEN_SECRET: process.env.APPS_ACCESS_TOKEN_SECRET || 'nodeauthsecret',
|
16
|
+
MONGODB_URI: process.env.APPS_MONGODB_URI || config.databaseUri,
|
17
|
+
}, () => {
|
18
|
+
winston.info("Tiledesk Apps proxy server succesfully started.")
|
19
|
+
})
|
20
|
+
|
21
|
+
}
|
22
|
+
|
23
|
+
}
|
24
|
+
|
25
|
+
var listener = new Listener();
|
26
|
+
|
27
|
+
module.exports = listener;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
const kaleyra = require("@tiledesk/tiledesk-kaleyra-proxy");
|
2
|
+
var winston = require('../../config/winston');
|
3
|
+
var configGlobal = require('../../config/global');
|
4
|
+
|
5
|
+
const apiUrl = process.env.API_URL || configGlobal.apiUrl;
|
6
|
+
winston.info("Kaleyra apiUrl: " + apiUrl);
|
7
|
+
|
8
|
+
class Listener {
|
9
|
+
|
10
|
+
listen(config) {
|
11
|
+
winston.info("Kaleyra Listener listen");
|
12
|
+
if (config.databaseUri) {
|
13
|
+
winston.debug("kaleyra config databaseUri: " + config.databaseUri);
|
14
|
+
}
|
15
|
+
|
16
|
+
kaleyra.startApp({
|
17
|
+
MONGODB_URL: config.databaseUri,
|
18
|
+
API_URL: apiUrl,
|
19
|
+
BASE_URL: apiUrl + "/modules/kaleyra",
|
20
|
+
APPS_API_URL: apiUrl + "/modules/apps",
|
21
|
+
KALEYRA_API_URL: process.env.KALEYRA_API_URL,
|
22
|
+
API_KEY: process.env.API_KEY,
|
23
|
+
log: process.env.KALEYRA_LOG
|
24
|
+
}, () => {
|
25
|
+
winston.info("Tiledesk Kaleyra proxy server succesfully started.");
|
26
|
+
})
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
var listener = new Listener();
|
31
|
+
|
32
|
+
module.exports = listener;
|
@@ -21,6 +21,15 @@ class PubModulesManager {
|
|
21
21
|
this.rasa = undefined;
|
22
22
|
this.rasaRoute = undefined;
|
23
23
|
|
24
|
+
this.apps = undefined;
|
25
|
+
this.appsRoute = undefined;
|
26
|
+
|
27
|
+
this.whatsapp = undefined;
|
28
|
+
this.whatsappRoute = undefined;
|
29
|
+
|
30
|
+
this.kaleyra = undefined;
|
31
|
+
this.kaleyraRoute = undefined;
|
32
|
+
|
24
33
|
this.activityArchiver = undefined;
|
25
34
|
this.activityRoute = undefined;
|
26
35
|
|
@@ -53,6 +62,18 @@ class PubModulesManager {
|
|
53
62
|
app.use('/modules/rasa', this.rasaRoute);
|
54
63
|
winston.info("ModulesManager rasaRoute controller loaded");
|
55
64
|
}
|
65
|
+
if (this.appsRoute) {
|
66
|
+
app.use('/modules/apps', this.appsRoute);
|
67
|
+
winston.info("ModulesManager appsRoute controller loaded");
|
68
|
+
}
|
69
|
+
if (this.whatsappRoute) {
|
70
|
+
app.use('/modules/whatsapp', this.whatsappRoute);
|
71
|
+
winston.info("ModulesManager whatsappRoute controller loaded");
|
72
|
+
}
|
73
|
+
if (this.kaleyraRoute) {
|
74
|
+
app.use('/modules/kaleyra', this.kaleyraRoute);
|
75
|
+
winston.info("ModulesManager kaleyraRoute controller loaded");
|
76
|
+
}
|
56
77
|
if (this.tilebotRoute) {
|
57
78
|
app.use('/modules/tilebot', this.tilebotRoute);
|
58
79
|
winston.info("ModulesManager tilebot controller loaded");
|
@@ -217,7 +238,53 @@ class PubModulesManager {
|
|
217
238
|
}
|
218
239
|
}
|
219
240
|
|
241
|
+
try {
|
242
|
+
this.apps = require('./apps');
|
243
|
+
winston.debug("this.apps: " + this.apps);
|
244
|
+
this.apps.listener.listen(config);
|
245
|
+
|
246
|
+
this.appsRoute = this.apps.appsRoute;
|
247
|
+
|
248
|
+
winston.info("PubModulesManager initialized apps.");
|
249
|
+
} catch(err) {
|
250
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
251
|
+
winston.info("PubModulesManager init apps module not found");
|
252
|
+
}else {
|
253
|
+
winston.info("PubModulesManager error initializing init apps module", err);
|
254
|
+
}
|
255
|
+
}
|
256
|
+
|
257
|
+
try {
|
258
|
+
this.whatsapp = require('./whatsapp');
|
259
|
+
winston.debug("this.whatsapp: " + this.whatsapp);
|
260
|
+
this.whatsapp.listener.listen(config);
|
220
261
|
|
262
|
+
this.whatsappRoute = this.whatsapp.whatsappRoute;
|
263
|
+
|
264
|
+
winston.info("PubModulesManager initialized apps.");
|
265
|
+
} catch(err) {
|
266
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
267
|
+
winston.info("PubModulesManager init apps module not found");
|
268
|
+
}else {
|
269
|
+
winston.info("PubModulesManager error initializing init apps module", err);
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
try {
|
274
|
+
this.kaleyra = require('./kaleyra');
|
275
|
+
winston.debug("this.kaleyra: " + this.kaleyra);
|
276
|
+
this.kaleyra.listener.listen(config);
|
277
|
+
|
278
|
+
this.kaleyraRoute = this.kaleyra.kaleyraRoute;
|
279
|
+
|
280
|
+
winston.info("PubModulesManager initialized apps.");
|
281
|
+
} catch(err) {
|
282
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
283
|
+
winston.info("PubModulesManager init apps module not found");
|
284
|
+
}else {
|
285
|
+
winston.info("PubModulesManager error initializing init apps module", err);
|
286
|
+
}
|
287
|
+
}
|
221
288
|
|
222
289
|
try {
|
223
290
|
this.activityArchiver = require('./activities').activityArchiver;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
const whatsapp = require("@tiledesk/tiledesk-whatsapp-connector");
|
2
|
+
var winston = require('../../config/winston');
|
3
|
+
var configGlobal = require('../../config/global');
|
4
|
+
|
5
|
+
const apiUrl = process.env.API_URL || configGlobal.apiUrl;
|
6
|
+
winston.info('Whatsapp apiUrl: ' + apiUrl);
|
7
|
+
|
8
|
+
class Listener {
|
9
|
+
|
10
|
+
listen(config) {
|
11
|
+
winston.info("WhatsApp Listener listen");
|
12
|
+
if (config.databaseUri) {
|
13
|
+
winston.debug("whatsapp config databaseUri: " + config.databaseUri);
|
14
|
+
}
|
15
|
+
|
16
|
+
whatsapp.startApp({
|
17
|
+
MONGODB_URL: config.databaseUri,
|
18
|
+
API_URL: apiUrl,
|
19
|
+
GRAPH_URL: process.env.META_GRAPH_URL || config.graphUrl,
|
20
|
+
BASE_URL: apiUrl + "/modules/whatsapp",
|
21
|
+
APPS_API_URL: apiUrl + "/modules/apps",
|
22
|
+
log: process.env.WHATSAPP_LOG
|
23
|
+
}, () => {
|
24
|
+
winston.info("Tiledesk WhatsApp Connector proxy server succesfully started.");
|
25
|
+
})
|
26
|
+
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
var listener = new Listener();
|
31
|
+
|
32
|
+
module.exports = listener;
|
package/routes/email.js
CHANGED
@@ -17,10 +17,10 @@ router.get('/templates/:templateid',
|
|
17
17
|
router.post('/test/send',
|
18
18
|
async (req, res) => {
|
19
19
|
let to = req.body.to;
|
20
|
-
winston.
|
20
|
+
winston.debug("to",to);
|
21
21
|
|
22
22
|
let configEmail = req.body.config;
|
23
|
-
winston.
|
23
|
+
winston.debug("configEmail", configEmail);
|
24
24
|
|
25
25
|
emailService.sendTest(to, configEmail, function(err,obj) {
|
26
26
|
// winston.info("sendTest rest", err, obj);
|
@@ -29,4 +29,28 @@ router.post('/test/send',
|
|
29
29
|
|
30
30
|
});
|
31
31
|
|
32
|
+
|
33
|
+
router.post('/send',
|
34
|
+
async (req, res) => {
|
35
|
+
let to = req.body.to;
|
36
|
+
winston.info("to: " + to);
|
37
|
+
|
38
|
+
let text = req.body.text;
|
39
|
+
winston.info("text: " + text);
|
40
|
+
|
41
|
+
let request_id = req.body.request_id;
|
42
|
+
winston.info("request_id: " + request_id);
|
43
|
+
|
44
|
+
let subject = req.body.subject;
|
45
|
+
winston.info("subject: " + subject);
|
46
|
+
|
47
|
+
winston.info("req.project", req.project);
|
48
|
+
|
49
|
+
//sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage)
|
50
|
+
emailService.sendEmailDirect(to, text, req.project, request_id, subject, undefined, undefined);
|
51
|
+
|
52
|
+
res.json({"queued": true});
|
53
|
+
|
54
|
+
});
|
55
|
+
|
32
56
|
module.exports = router;
|
package/services/emailService.js
CHANGED
@@ -1030,7 +1030,7 @@ class EmailService {
|
|
1030
1030
|
|
1031
1031
|
}
|
1032
1032
|
|
1033
|
-
|
1033
|
+
|
1034
1034
|
|
1035
1035
|
async sendEmailChannelNotification(to, message, project, tokenQueryString, sourcePage) {
|
1036
1036
|
|
@@ -1360,10 +1360,6 @@ class EmailService {
|
|
1360
1360
|
}
|
1361
1361
|
|
1362
1362
|
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
1363
|
/*
|
1368
1364
|
sendEmailChannelTakingNotification(to, request, project, tokenQueryString) {
|
1369
1365
|
|
@@ -1411,6 +1407,102 @@ class EmailService {
|
|
1411
1407
|
}
|
1412
1408
|
*/
|
1413
1409
|
|
1410
|
+
|
1411
|
+
|
1412
|
+
|
1413
|
+
|
1414
|
+
|
1415
|
+
|
1416
|
+
async sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage) {
|
1417
|
+
|
1418
|
+
var that = this;
|
1419
|
+
|
1420
|
+
|
1421
|
+
if (project.toJSON) {
|
1422
|
+
project = project.toJSON();
|
1423
|
+
}
|
1424
|
+
|
1425
|
+
var html = await this.readTemplate('emailDirect.html', project.settings);
|
1426
|
+
|
1427
|
+
var envTemplate = process.env.EMAIL_DIRECT_HTML_TEMPLATE;
|
1428
|
+
winston.debug("envTemplate: " + envTemplate);
|
1429
|
+
|
1430
|
+
if (envTemplate) {
|
1431
|
+
html = envTemplate;
|
1432
|
+
}
|
1433
|
+
|
1434
|
+
winston.debug("html: " + html);
|
1435
|
+
|
1436
|
+
var template = handlebars.compile(html);
|
1437
|
+
|
1438
|
+
var baseScope = JSON.parse(JSON.stringify(that));
|
1439
|
+
delete baseScope.pass;
|
1440
|
+
|
1441
|
+
|
1442
|
+
let msgText = text;
|
1443
|
+
msgText = encode(msgText);
|
1444
|
+
if (this.markdown) {
|
1445
|
+
msgText = marked(msgText);
|
1446
|
+
}
|
1447
|
+
|
1448
|
+
winston.debug("msgText: " + msgText);
|
1449
|
+
winston.debug("baseScope: " + JSON.stringify(baseScope));
|
1450
|
+
|
1451
|
+
|
1452
|
+
var replacements = {
|
1453
|
+
project: project,
|
1454
|
+
seamlessPage: sourcePage,
|
1455
|
+
msgText: msgText,
|
1456
|
+
tokenQueryString: tokenQueryString,
|
1457
|
+
baseScope: baseScope
|
1458
|
+
};
|
1459
|
+
|
1460
|
+
var html = template(replacements);
|
1461
|
+
winston.debug("html: " + html);
|
1462
|
+
|
1463
|
+
|
1464
|
+
let replyTo;
|
1465
|
+
if (this.replyEnabled) {
|
1466
|
+
replyTo = request_id + this.inboundDomainDomainWithAt;
|
1467
|
+
}
|
1468
|
+
|
1469
|
+
let from;
|
1470
|
+
let configEmail;
|
1471
|
+
if (project && project.settings && project.settings.email) {
|
1472
|
+
if (project.settings.email.config) {
|
1473
|
+
configEmail = project.settings.email.config;
|
1474
|
+
winston.verbose("custom email configEmail setting found: ", configEmail);
|
1475
|
+
}
|
1476
|
+
if (project.settings.email.from) {
|
1477
|
+
from = project.settings.email.from;
|
1478
|
+
winston.verbose("custom from email setting found: "+ from);
|
1479
|
+
}
|
1480
|
+
}
|
1481
|
+
|
1482
|
+
|
1483
|
+
// if (message.request && message.request.lead && message.request.lead.email) {
|
1484
|
+
// winston.info("message.request.lead.email: " + message.request.lead.email);
|
1485
|
+
// replyTo = replyTo + ", "+ message.request.lead.email;
|
1486
|
+
// }
|
1487
|
+
|
1488
|
+
// if (!subject) {
|
1489
|
+
// subject = "Tiledesk"
|
1490
|
+
// }
|
1491
|
+
|
1492
|
+
that.send({
|
1493
|
+
from:from,
|
1494
|
+
to:to,
|
1495
|
+
replyTo: replyTo,
|
1496
|
+
subject:subject,
|
1497
|
+
text:html,
|
1498
|
+
html:html,
|
1499
|
+
config:configEmail,
|
1500
|
+
});
|
1501
|
+
|
1502
|
+
}
|
1503
|
+
|
1504
|
+
|
1505
|
+
|
1414
1506
|
// ok
|
1415
1507
|
async sendPasswordResetRequestEmail(to, resetPswRequestId, userFirstname, userLastname) {
|
1416
1508
|
|
@@ -1693,6 +1785,5 @@ async sendRequestTranscript(to, messages, request, project) {
|
|
1693
1785
|
|
1694
1786
|
var emailService = new EmailService();
|
1695
1787
|
|
1696
|
-
// emailService.sendTest("abc@abc.it");
|
1697
1788
|
|
1698
1789
|
module.exports = emailService;
|
@@ -94,7 +94,7 @@
|
|
94
94
|
{{currentUserFirstname}} {{currentUserLastname}} has invited you to the TileDesk project <strong> {{projectName}}</strong>
|
95
95
|
</h2>
|
96
96
|
|
97
|
-
<br> <br
|
97
|
+
<br> <br><strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">Hi {{invitedUserFirstname}} {{invitedUserLastname}},</strong>
|
98
98
|
|
99
99
|
<br> <br>
|
100
100
|
I invited you to take on the role of {{invitedUserRole}} of the TileDesk <strong> {{projectName}}</strong> project
|
@@ -95,7 +95,7 @@
|
|
95
95
|
{{currentUserFirstname}} {{currentUserLastname}} has invited you to the Tiledesk project <strong> {{projectName}}</strong>
|
96
96
|
</h2>
|
97
97
|
|
98
|
-
<br> <br
|
98
|
+
<br> <br><strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{to}},</strong>
|
99
99
|
|
100
100
|
<br> <br>
|
101
101
|
I invited you to take on the role of {{invitedUserRole}} of the Tiledesk <strong> {{projectName}}</strong> project
|
@@ -0,0 +1,121 @@
|
|
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
|
+
<img src="https://tiledesk.com/wp-content/uploads/2022/09/tiledeesk_log_email.png" style="max-width:200px;outline:none;text-decoration:none;border:none;height:auto;margin-left:0px;" class="CToWUd">
|
80
|
+
</a>
|
81
|
+
</div>
|
82
|
+
</td>
|
83
|
+
</tr>
|
84
|
+
|
85
|
+
|
86
|
+
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
87
|
+
<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">
|
88
|
+
<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;">
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
94
|
+
<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">
|
95
|
+
<div style="white-space: pre-wrap;">{{{msgText}}}</div>
|
96
|
+
</td>
|
97
|
+
</tr>
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
103
|
+
<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">
|
104
|
+
</td>
|
105
|
+
</tr>
|
106
|
+
</table>
|
107
|
+
</td>
|
108
|
+
</tr>
|
109
|
+
</table>
|
110
|
+
<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;">
|
111
|
+
<table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
112
|
+
<tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
|
113
|
+
<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">
|
114
|
+
<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>
|
115
|
+
<!-- <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> -->
|
116
|
+
</td>
|
117
|
+
</tr>
|
118
|
+
</table>
|
119
|
+
|
120
|
+
</body>
|
121
|
+
</html>
|