@tiledesk/tiledesk-server 2.2.28 → 2.2.31
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 +31 -4
- package/app.js +6 -3
- package/models/request.js +7 -1
- package/package.json +1 -1
- package/publiccode.yml +110 -0
- package/pubmodules/pubModulesManager.js +17 -0
- package/pubmodules/rasa/index.js +3 -0
- package/pubmodules/rasa/listener.js +51 -0
- package/pubmodules/rules/conciergeBot.js +1 -0
- package/routes/message.js +13 -8
- package/routes/project.js +6 -6
- package/routes/project_user.js +4 -4
- package/routes/user-request.js +311 -0
- package/routes/widget.js +30 -2
- package/services/emailService.js +38 -29
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# 2.2.31 (compatible with: Dashboard 2.2.37, Widget 5.0.25)
|
|
5
|
+
- Fix email template reading from project.
|
|
6
|
+
- Added transcript webpage for users without system messages
|
|
7
|
+
- Fix export messages to csv
|
|
8
|
+
- Fix ip address resolver
|
|
9
|
+
- Exclude poweredBy field from widget endpoint
|
|
10
|
+
- Bugfix when a conversation has a first_text with \agent
|
|
11
|
+
- Added rasa chatbot chatbot type
|
|
12
|
+
- Added visitor email and fullname in the fulltext index
|
|
13
|
+
|
|
14
|
+
# 2.2.30 -> PROD
|
|
15
|
+
- Log fix
|
|
16
|
+
|
|
17
|
+
# 2.2.29
|
|
18
|
+
- Added endpoint to find requests created by users and guests
|
|
19
|
+
- Log fix
|
|
20
|
+
|
|
21
|
+
# 2.2.28 (compatible with dasboard ver. 2.2.36)
|
|
22
|
+
- Operator.select returns context object that contains the temp request
|
|
3
23
|
- Added Serbian language to the widget
|
|
4
24
|
- Added tag field to the project_user
|
|
5
25
|
- Removed default BCC from email
|
|
@@ -7,15 +27,22 @@
|
|
|
7
27
|
- Faq template now support blank and example
|
|
8
28
|
- Organizzation support added
|
|
9
29
|
- ipFilter related to the project is now supported
|
|
30
|
+
- Added filter channel name for the request
|
|
31
|
+
- Added edit card for payment
|
|
32
|
+
- Fix concierge concierge bot for department selection
|
|
33
|
+
- Added filter to find a request by ticket_id
|
|
34
|
+
- Added filter to snap_lead_lead_id for request
|
|
35
|
+
- Added endpoint to close a request by guest
|
|
36
|
+
|
|
10
37
|
|
|
11
|
-
# 2.2.26
|
|
38
|
+
# 2.2.26 (compatible with dasboard ver. 2.2.35)
|
|
12
39
|
- Tag fix for 2.2.25
|
|
13
40
|
|
|
14
41
|
# 2.2.25
|
|
15
42
|
- New label prechat form
|
|
16
43
|
- Updated mongodb-runner from 4.8.1 to 4.8.3 to fix ssh key error
|
|
17
44
|
|
|
18
|
-
# 2.2.24
|
|
45
|
+
# 2.2.24
|
|
19
46
|
- webhook subscription can fetch temmates endpoint
|
|
20
47
|
- Added hasBot and createdAt index to the request model
|
|
21
48
|
|
package/app.js
CHANGED
|
@@ -320,7 +320,10 @@ var projectSetter = function (req, res, next) {
|
|
|
320
320
|
|
|
321
321
|
|
|
322
322
|
function customDetection (req) {
|
|
323
|
-
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
|
323
|
+
// const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
|
324
|
+
const ip = (req.headers['x-forwarded-for'] || '').split(',').pop().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
|
325
|
+
req.socket.remoteAddress
|
|
326
|
+
|
|
324
327
|
winston.info("standard ip: "+ip); // ip address of the user
|
|
325
328
|
return ip;
|
|
326
329
|
}
|
|
@@ -352,10 +355,10 @@ var projectIpFilter = function (req, res, next) {
|
|
|
352
355
|
}
|
|
353
356
|
|
|
354
357
|
var projectIpFilterEnabled = req.project.ipFilterEnabled;
|
|
355
|
-
winston.
|
|
358
|
+
winston.debug("project projectIpFilterEnabled: " +projectIpFilterEnabled)
|
|
356
359
|
|
|
357
360
|
var projectIpFilter = req.project.ipFilter
|
|
358
|
-
winston.
|
|
361
|
+
winston.debug("project ipFilter: " + projectIpFilter)
|
|
359
362
|
|
|
360
363
|
if (projectIpFilterEnabled === true && projectIpFilter && projectIpFilter.length > 0) {
|
|
361
364
|
var ip = ipfilter(projectIpFilter, { detectIp: customDetection, mode: 'allow' })
|
package/models/request.js
CHANGED
|
@@ -254,6 +254,7 @@ var RequestSchema = new Schema({
|
|
|
254
254
|
required: false
|
|
255
255
|
},
|
|
256
256
|
location: LocationSchema,
|
|
257
|
+
|
|
257
258
|
id_project: {
|
|
258
259
|
type: String,
|
|
259
260
|
required: true,
|
|
@@ -417,7 +418,9 @@ RequestSchema.index({ id_project: 1, request_id: 1 }
|
|
|
417
418
|
// https://docs.mongodb.com/manual/reference/text-search-languages/#text-search-languages
|
|
418
419
|
|
|
419
420
|
//TODO cambiare dummy con language? attento che il codice deve essere compatibile
|
|
420
|
-
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
RequestSchema.index({transcript: 'text', rating_message: 'text', subject: 'text', "tags.tag": 'text', "notes.text": 'text', "snapshot.lead.email": 'text', "snapshot.lead.fullname": 'text' },
|
|
421
424
|
{"name":"request_fulltext","default_language": defaultFullTextLanguage,"language_override": "dummy"}); // schema level
|
|
422
425
|
|
|
423
426
|
// let query = {id_project: operatorSelectedEvent.id_project, participants: { $exists: true, $ne: [] }};
|
|
@@ -431,6 +434,9 @@ RequestSchema.index({ id_project: 1, preflight:1, updatedAt: -1 }); // used quer
|
|
|
431
434
|
|
|
432
435
|
RequestSchema.index({ hasBot: 1, createdAt: 1 }); // suggested by atlas
|
|
433
436
|
|
|
437
|
+
RequestSchema.index({ id_project: 1, ticket_id: 1 });
|
|
438
|
+
|
|
439
|
+
|
|
434
440
|
|
|
435
441
|
// cannot index parallel arrays [agents] [participants] {"driv
|
|
436
442
|
// RequestSchema.index({ id_project: 1, status: 1, preflight:1, participants:1, "agents.id_user":1, updatedAt: -1 }); //NN LO APPLICA
|
package/package.json
CHANGED
package/publiccode.yml
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# This repository adheres to the publiccode.yml standard by including this
|
|
2
|
+
# metadata file that makes public software easily discoverable.
|
|
3
|
+
# More info at https://github.com/italia/publiccode.yml
|
|
4
|
+
|
|
5
|
+
publiccodeYmlVersion: '0.2'
|
|
6
|
+
categories:
|
|
7
|
+
- customer-service-and-support
|
|
8
|
+
- communications
|
|
9
|
+
- marketing
|
|
10
|
+
- mobile-marketing
|
|
11
|
+
description:
|
|
12
|
+
it:
|
|
13
|
+
apiDocumentation: 'https://developer.tiledesk.com/apis/rest-api'
|
|
14
|
+
documentation: 'https://gethelp.tiledesk.com'
|
|
15
|
+
features:
|
|
16
|
+
- live chat widget
|
|
17
|
+
- chatbot
|
|
18
|
+
- 'integration with DialogFlow, Rasa and all major AI solutions'
|
|
19
|
+
- ticketing
|
|
20
|
+
- multi-project management
|
|
21
|
+
- SLAs setting
|
|
22
|
+
- 'smart assignment of the queues '
|
|
23
|
+
- seamless conversation
|
|
24
|
+
- dashboard
|
|
25
|
+
- knowledge base
|
|
26
|
+
- mobile apps
|
|
27
|
+
genericName: Live chat with integrated chatbots
|
|
28
|
+
longDescription: |
|
|
29
|
+
To have fully satisfied customers is complex. Conversation’s actors
|
|
30
|
+
(chatbots and humans) should handoff to each other many times during a
|
|
31
|
+
chat to address customers needs.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
Tiledesk provides a solution **orchestrating instant, asynchronous and
|
|
35
|
+
multichannel communication among all stakeholders of a typical
|
|
36
|
+
conversational architecture**: chatbots, support operators, end users,
|
|
37
|
+
colleagues, applications, etc.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
**Main Features**:
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
- Live Chat Widget with full multichannel experience on Web and Mobile;
|
|
44
|
+
|
|
45
|
+
- Resolution Bot to automate customer support;
|
|
46
|
+
|
|
47
|
+
- Easy Integration with all major AI-platforms, cloud and Open source,
|
|
48
|
+
from DialogFlow to RASA;
|
|
49
|
+
|
|
50
|
+
- Ticketing Management system fully integrated into the platform and
|
|
51
|
+
instant conversation flow;
|
|
52
|
+
|
|
53
|
+
- Team Organization with multi-project management, SLAs setting, smart
|
|
54
|
+
assignment of the
|
|
55
|
+
queues, departments organization and much more;
|
|
56
|
+
- Seamless conversation to “jump” between different channels in a
|
|
57
|
+
transparent way for end
|
|
58
|
+
customers and agents;
|
|
59
|
+
- Chat Tools like typing indicator, off-line access, delivery receipts,
|
|
60
|
+
contact list and much more;
|
|
61
|
+
|
|
62
|
+
- Dashboard with real time analytics;
|
|
63
|
+
|
|
64
|
+
- Knowledge base.
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Tiledesk is an **open source **project, made with passion in Salento
|
|
69
|
+
(Southern Italy).
|
|
70
|
+
shortDescription: |-
|
|
71
|
+
Tiledesk delivers scalable customer service to your mobile apps and your
|
|
72
|
+
website. It is a conversational platform that connects chatbots and
|
|
73
|
+
humans
|
|
74
|
+
developmentStatus: stable
|
|
75
|
+
it:
|
|
76
|
+
conforme:
|
|
77
|
+
gdpr: false
|
|
78
|
+
lineeGuidaDesign: false
|
|
79
|
+
misureMinimeSicurezza: false
|
|
80
|
+
modelloInteroperabilita: false
|
|
81
|
+
countryExtensionVersion: '0.2'
|
|
82
|
+
piattaforme:
|
|
83
|
+
anpr: false
|
|
84
|
+
cie: false
|
|
85
|
+
pagopa: false
|
|
86
|
+
spid: false
|
|
87
|
+
landingURL: 'https://tiledesk.com/install'
|
|
88
|
+
legal:
|
|
89
|
+
license: AGPL-3.0-only
|
|
90
|
+
localisation:
|
|
91
|
+
availableLanguages:
|
|
92
|
+
- it
|
|
93
|
+
- en
|
|
94
|
+
- es
|
|
95
|
+
- fr
|
|
96
|
+
- pt
|
|
97
|
+
- de
|
|
98
|
+
- ru
|
|
99
|
+
- tr
|
|
100
|
+
localisationReady: true
|
|
101
|
+
maintenance:
|
|
102
|
+
contacts:
|
|
103
|
+
- name: Andrea Sponziello
|
|
104
|
+
type: internal
|
|
105
|
+
name: Tiledesk
|
|
106
|
+
platforms:
|
|
107
|
+
- web
|
|
108
|
+
releaseDate: '2022-06-15'
|
|
109
|
+
softwareType: standalone/web
|
|
110
|
+
url: 'https://github.com/Tiledesk/tiledesk-deployment'
|
|
@@ -18,6 +18,8 @@ class PubModulesManager {
|
|
|
18
18
|
this.messageTransformer = undefined;
|
|
19
19
|
|
|
20
20
|
this.scheduler = undefined;
|
|
21
|
+
|
|
22
|
+
this.rasa = undefined;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
|
|
@@ -140,6 +142,21 @@ class PubModulesManager {
|
|
|
140
142
|
}
|
|
141
143
|
|
|
142
144
|
|
|
145
|
+
try {
|
|
146
|
+
this.rasa = require('./rasa');
|
|
147
|
+
winston.debug("this.rasa:"+ this.rasa);
|
|
148
|
+
this.rasa.listener.listen();
|
|
149
|
+
winston.info("PubModulesManager initialized rasa.");
|
|
150
|
+
} catch(err) {
|
|
151
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
|
152
|
+
winston.info("PubModulesManager init rasa module not found");
|
|
153
|
+
}else {
|
|
154
|
+
winston.info("PubModulesManager error initializing init rasa module", err);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
143
160
|
|
|
144
161
|
|
|
145
162
|
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const botEvent = require('../../event/botEvent');
|
|
2
|
+
var Faq_kb = require("../../models/faq_kb");
|
|
3
|
+
var winston = require('../../config/winston');
|
|
4
|
+
|
|
5
|
+
const BOT_RASA_ENDPOINT = process.env.BOT_RASA_ENDPOINT;
|
|
6
|
+
winston.debug("BOT_RASA_ENDPOINT: " + BOT_RASA_ENDPOINT);
|
|
7
|
+
|
|
8
|
+
if (BOT_RASA_ENDPOINT) {
|
|
9
|
+
winston.info("Rasa endpoint: " + BOT_RASA_ENDPOINT);
|
|
10
|
+
} else {
|
|
11
|
+
winston.info("Rasa endpoint not configured");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Listener {
|
|
16
|
+
|
|
17
|
+
listen() {
|
|
18
|
+
|
|
19
|
+
winston.debug('rasa Listener listen');
|
|
20
|
+
|
|
21
|
+
var that = this;
|
|
22
|
+
|
|
23
|
+
botEvent.on('faqbot.create', function(bot) {
|
|
24
|
+
if (BOT_RASA_ENDPOINT) {
|
|
25
|
+
|
|
26
|
+
winston.info('bot.type:'+bot.type);
|
|
27
|
+
if (bot.type==="rasa") {
|
|
28
|
+
|
|
29
|
+
winston.info('qui.type:'+bot.type);
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
Faq_kb.findByIdAndUpdate(bot.id, {"url":BOT_RASA_ENDPOINT}, { new: true, upsert: true }, function (err, savedFaq_kb) {
|
|
33
|
+
|
|
34
|
+
// bot.save(function (err, savedFaq_kb) {
|
|
35
|
+
if (err) {
|
|
36
|
+
return winston.error('error saving faqkb rasa ', err)
|
|
37
|
+
}
|
|
38
|
+
winston.verbose('Saved faqkb rasa', savedFaq_kb.toObject())
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var listener = new Listener();
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
module.exports = listener;
|
|
@@ -338,6 +338,7 @@ devi mandare un messaggio welcome tu altrimenti il bot inserito successivamente
|
|
|
338
338
|
if (request.subject) {
|
|
339
339
|
touchText = request.subject;
|
|
340
340
|
}
|
|
341
|
+
touchText.replace("\\",""); //Bugfix when a conversation has a first_text with \agent
|
|
341
342
|
|
|
342
343
|
// messageService.send(sender, senderFullname, recipient, text, id_project, createdBy, attributes, type);
|
|
343
344
|
messageService.send(
|
package/routes/message.js
CHANGED
|
@@ -139,7 +139,7 @@ async (req, res) => {
|
|
|
139
139
|
.then(function(createdLead) {
|
|
140
140
|
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
|
|
143
143
|
var new_request = {
|
|
144
144
|
request_id: req.params.request_id,
|
|
145
145
|
project_user_id: project_user._id,
|
|
@@ -312,9 +312,20 @@ async (req, res) => {
|
|
|
312
312
|
// });
|
|
313
313
|
// });
|
|
314
314
|
|
|
315
|
+
router.get('/csv', function(req, res) {
|
|
316
|
+
|
|
317
|
+
// console.log("csv");
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
return Message.find({"recipient": req.params.request_id, id_project: req.projectid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
|
|
321
|
+
if (err) return next(err);
|
|
322
|
+
res.csv(messages, true);
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
315
326
|
router.get('/:messageid', function(req, res) {
|
|
316
327
|
|
|
317
|
-
console.log(req.body);
|
|
328
|
+
// console.log(req.body);
|
|
318
329
|
|
|
319
330
|
Message.findById(req.params.messageid, function(err, message) {
|
|
320
331
|
if (err) {
|
|
@@ -337,13 +348,7 @@ router.get('/', function(req, res) {
|
|
|
337
348
|
});
|
|
338
349
|
});
|
|
339
350
|
|
|
340
|
-
router.get('/csv', function(req, res) {
|
|
341
351
|
|
|
342
|
-
return Message.find({"recipient": req.params.request_id, id_project: req.projectid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
|
|
343
|
-
if (err) return next(err);
|
|
344
|
-
res.csv(messages, true);
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
352
|
|
|
348
353
|
|
|
349
354
|
module.exports = router;
|
package/routes/project.js
CHANGED
|
@@ -382,21 +382,21 @@ router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
|
|
|
382
382
|
|
|
383
383
|
|
|
384
384
|
//organization: if third sub domain iterate and put only project with organization==subdomain otherwise remove projects with org
|
|
385
|
-
winston.
|
|
385
|
+
winston.debug("orgUtil.ORGANIZATION_ENABLED: " + orgUtil.ORGANIZATION_ENABLED);
|
|
386
386
|
if (orgUtil.ORGANIZATION_ENABLED == true ) {
|
|
387
387
|
|
|
388
388
|
// winston.info("project_users", project_users);
|
|
389
|
-
winston.
|
|
389
|
+
winston.debug("project_users.length:"+ project_users.length);
|
|
390
390
|
|
|
391
391
|
let org = orgUtil.getOrg(req);
|
|
392
|
-
winston.
|
|
392
|
+
winston.debug("org:"+ org);
|
|
393
393
|
|
|
394
394
|
if (org!=undefined) {
|
|
395
|
-
winston.
|
|
395
|
+
winston.debug("org!=undefined");
|
|
396
396
|
|
|
397
397
|
var project_users = project_users.filter(function (projectUser) {
|
|
398
398
|
if (projectUser.id_project.organization && projectUser.id_project.organization === org ) {
|
|
399
|
-
winston.
|
|
399
|
+
winston.debug("keep");
|
|
400
400
|
return true;
|
|
401
401
|
}
|
|
402
402
|
});
|
|
@@ -430,7 +430,7 @@ router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
|
|
|
430
430
|
}*/
|
|
431
431
|
}
|
|
432
432
|
} else {
|
|
433
|
-
winston.
|
|
433
|
+
winston.debug("no")
|
|
434
434
|
}
|
|
435
435
|
|
|
436
436
|
|
package/routes/project_user.js
CHANGED
|
@@ -367,7 +367,7 @@ router.get('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
|
367
367
|
|
|
368
368
|
|
|
369
369
|
router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], async (req, res, next) => {
|
|
370
|
-
winston.
|
|
370
|
+
winston.debug("--> users search ");
|
|
371
371
|
|
|
372
372
|
if (!req.project) {
|
|
373
373
|
return res.status(404).send({ success: false, msg: 'Project not found.' });
|
|
@@ -376,10 +376,10 @@ router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session:
|
|
|
376
376
|
|
|
377
377
|
let query = {email: req.query.email};
|
|
378
378
|
|
|
379
|
-
winston.
|
|
379
|
+
winston.debug('query: ', query);
|
|
380
380
|
|
|
381
381
|
let user = await User.findOne(query).exec();
|
|
382
|
-
winston.
|
|
382
|
+
winston.debug('user: ', user);
|
|
383
383
|
|
|
384
384
|
if (!user) {
|
|
385
385
|
return res.status(404).send({ success: false, msg: 'Object not found.' });
|
|
@@ -387,7 +387,7 @@ router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session:
|
|
|
387
387
|
|
|
388
388
|
|
|
389
389
|
let project_user = await Project_user.findOne({id_user: user._id, id_project: req.projectid}).exec();
|
|
390
|
-
winston.
|
|
390
|
+
winston.debug('project_user: ', project_user);
|
|
391
391
|
|
|
392
392
|
if (!project_user) {
|
|
393
393
|
return res.status(403).json({msg: "Unauthorized. This is not a your teammate." });
|
package/routes/user-request.js
CHANGED
|
@@ -5,6 +5,7 @@ var winston = require('../config/winston');
|
|
|
5
5
|
const requestEvent = require('../event/requestEvent');
|
|
6
6
|
const { check, validationResult } = require('express-validator');
|
|
7
7
|
var requestService = require('../services/requestService');
|
|
8
|
+
var mongoose = require('mongoose');
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
router.patch('/:requestid/rating', function (req, res) {
|
|
@@ -70,4 +71,314 @@ router.put('/:requestid/closeg', function (req, res) {
|
|
|
70
71
|
|
|
71
72
|
});
|
|
72
73
|
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
router.get('/me', function (req, res, next) {
|
|
78
|
+
|
|
79
|
+
winston.debug("req projectid", req.projectid);
|
|
80
|
+
winston.debug("req.query.sort", req.query.sort);
|
|
81
|
+
winston.debug('REQUEST ROUTE - QUERY ', req.query)
|
|
82
|
+
|
|
83
|
+
const DEFAULT_LIMIT = 40;
|
|
84
|
+
|
|
85
|
+
var limit = DEFAULT_LIMIT; // Number of request per page
|
|
86
|
+
|
|
87
|
+
if (req.query.limit) {
|
|
88
|
+
limit = parseInt(req.query.limit);
|
|
89
|
+
}
|
|
90
|
+
if (limit > 100) {
|
|
91
|
+
limit = DEFAULT_LIMIT;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
var page = 0;
|
|
96
|
+
|
|
97
|
+
if (req.query.page) {
|
|
98
|
+
page = req.query.page;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var skip = page * limit;
|
|
102
|
+
winston.debug('REQUEST ROUTE - SKIP PAGE ', skip);
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
var user_id = req.user._id;
|
|
106
|
+
winston.debug('REQUEST ROUTE - user_id: '+user_id);
|
|
107
|
+
|
|
108
|
+
var isObjectId = mongoose.Types.ObjectId.isValid(user_id);
|
|
109
|
+
winston.debug("isObjectId:"+ isObjectId);
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
var query = { "id_project": req.projectid, "status": {$lt:1000}, preflight:false};
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if (isObjectId) {
|
|
116
|
+
query["snapshot.requester.id_user"] = user_id;
|
|
117
|
+
// query.id_user = mongoose.Types.ObjectId(contact_id);
|
|
118
|
+
} else {
|
|
119
|
+
query["snapshot.requester.uuid_user"] = user_id;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
// $or:[{"snapshot.requester.id_user": user_id}, {"snapshot.requester.uuid_user": user_id}]};
|
|
124
|
+
|
|
125
|
+
winston.debug('REQUEST ROUTE - query ', query);
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
if (req.query.dept_id) {
|
|
129
|
+
query.department = req.query.dept_id;
|
|
130
|
+
winston.debug('REQUEST ROUTE - QUERY DEPT ID', query.department);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (req.query.full_text) {
|
|
134
|
+
winston.debug('req.query.fulltext', req.query.full_text);
|
|
135
|
+
query.$text = { "$search": req.query.full_text };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
var history_search = false;
|
|
139
|
+
|
|
140
|
+
if (req.query.status) {
|
|
141
|
+
winston.debug('req.query.status', req.query.status);
|
|
142
|
+
query.status = req.query.status;
|
|
143
|
+
|
|
144
|
+
if (req.query.status == 1000 || req.query.status == "1000") {
|
|
145
|
+
history_search = true;
|
|
146
|
+
}
|
|
147
|
+
if (req.query.status==="all") {
|
|
148
|
+
history_search = true;
|
|
149
|
+
delete query.status;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// if (req.query.lead) {
|
|
154
|
+
// winston.debug('req.query.lead', req.query.lead);
|
|
155
|
+
// query.lead = req.query.lead;
|
|
156
|
+
// }
|
|
157
|
+
|
|
158
|
+
// USERS & BOTS
|
|
159
|
+
if (req.query.participant) {
|
|
160
|
+
winston.debug('req.query.participant', req.query.participant);
|
|
161
|
+
query.participants = req.query.participant;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
winston.debug('req.query.hasbot', req.query.hasbot);
|
|
165
|
+
if (req.query.hasbot!=undefined) {
|
|
166
|
+
winston.debug('req.query.hasbot', req.query.hasbot);
|
|
167
|
+
query.hasBot = req.query.hasbot;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// if (req.query.waiting_time_exists) { //non basta aggiungi anche che nn è null
|
|
171
|
+
// query.waiting_time = {"$exists": req.query.waiting_time_exists} //{$ne:null}
|
|
172
|
+
// winston.debug('REQUEST ROUTE - QUERY waiting_time_exists', query.waiting_time_exists);
|
|
173
|
+
// }
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
if (req.query.tags) {
|
|
177
|
+
winston.debug('req.query.tags', req.query.tags);
|
|
178
|
+
query["tags.tag"] = req.query.tags;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (req.query.location) {
|
|
182
|
+
query.location = req.query.location;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (req.query.ticket_id) {
|
|
186
|
+
query.ticket_id = req.query.ticket_id;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// if (req.query.request_id) {
|
|
190
|
+
// console.log('req.query.request_id', req.query.request_id);
|
|
191
|
+
// query.request_id = req.query.request_id;
|
|
192
|
+
// }
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
**! *** DATE RANGE USECASE 1 ***
|
|
196
|
+
* in the tiledesk dashboard's HISTORY PAGE
|
|
197
|
+
* WHEN THE TRIAL IS EXIPIRED OR THE SUBSCIPTION IS NOT ACTIVE
|
|
198
|
+
* THE SEARCH FOR DATE INTERVAL OF THE HISTORY OF REQUESTS ARE DISABLED AND
|
|
199
|
+
* ARE DISPLAYED ONLY THE REQUESTS OF THE LAST 14 DAYS
|
|
200
|
+
*/
|
|
201
|
+
if ( history_search === true && req.project && req.project.profile && (req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false)) {
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
var startdate = moment().subtract(14, "days").format("YYYY-MM-DD");
|
|
205
|
+
|
|
206
|
+
var enddate = moment().format("YYYY-MM-DD");
|
|
207
|
+
|
|
208
|
+
winston.debug('»»» REQUEST ROUTE - startdate ', startdate);
|
|
209
|
+
winston.debug('»»» REQUEST ROUTE - enddate ', enddate);
|
|
210
|
+
|
|
211
|
+
var enddatePlusOneDay= moment(new Date()).add(1, 'days').toDate()
|
|
212
|
+
winston.debug('»»» REQUEST ROUTE - enddate + 1 days: ', enddatePlusOneDay);
|
|
213
|
+
|
|
214
|
+
// var enddatePlusOneDay = "2019-09-17T00:00:00.000Z"
|
|
215
|
+
|
|
216
|
+
query.createdAt = { $gte: new Date(Date.parse(startdate)).toISOString(), $lte: new Date(enddatePlusOneDay).toISOString() }
|
|
217
|
+
winston.debug('REQUEST ROUTE - QUERY CREATED AT ', query.createdAt);
|
|
218
|
+
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
**! *** DATE RANGE USECASE 2 ***
|
|
223
|
+
* in the tiledesk dashboard's HISTORY PAGE
|
|
224
|
+
* WHEN THE USER SEARCH FOR DATE INTERVAL OF THE HISTORY OF REQUESTS
|
|
225
|
+
*/
|
|
226
|
+
if (req.query.start_date && req.query.end_date) {
|
|
227
|
+
winston.debug('REQUEST ROUTE - REQ QUERY start_date ', req.query.start_date);
|
|
228
|
+
winston.debug('REQUEST ROUTE - REQ QUERY end_date ', req.query.end_date);
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* USING TIMESTAMP in MS */
|
|
232
|
+
// var formattedStartDate = new Date(+req.query.start_date);
|
|
233
|
+
// var formattedEndDate = new Date(+req.query.end_date);
|
|
234
|
+
// query.createdAt = { $gte: formattedStartDate, $lte: formattedEndDate }
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* USING MOMENT */
|
|
238
|
+
var startDate = moment(req.query.start_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
239
|
+
var endDate = moment(req.query.end_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
240
|
+
|
|
241
|
+
winston.debug('REQUEST ROUTE - REQ QUERY FORMATTED START DATE ', startDate);
|
|
242
|
+
winston.debug('REQUEST ROUTE - REQ QUERY FORMATTED END DATE ', endDate);
|
|
243
|
+
|
|
244
|
+
// ADD ONE DAY TO THE END DAY
|
|
245
|
+
var date = new Date(endDate);
|
|
246
|
+
var newdate = new Date(date);
|
|
247
|
+
var endDate_plusOneDay = newdate.setDate(newdate.getDate() + 1);
|
|
248
|
+
winston.debug('REQUEST ROUTE - REQ QUERY FORMATTED END DATE + 1 DAY ', endDate_plusOneDay);
|
|
249
|
+
// var endDate_plusOneDay = moment('2018-09-03').add(1, 'd')
|
|
250
|
+
// var endDate_plusOneDay = endDate.add(1).day();
|
|
251
|
+
// var toDate = new Date(Date.parse(endDate_plusOneDay)).toISOString()
|
|
252
|
+
|
|
253
|
+
query.createdAt = { $gte: new Date(Date.parse(startDate)).toISOString(), $lte: new Date(endDate_plusOneDay).toISOString() }
|
|
254
|
+
winston.debug('REQUEST ROUTE - QUERY CREATED AT ', query.createdAt);
|
|
255
|
+
|
|
256
|
+
} else if (req.query.start_date && !req.query.end_date) {
|
|
257
|
+
winston.debug('REQUEST ROUTE - REQ QUERY END DATE IS EMPTY (so search only for start date)');
|
|
258
|
+
var startDate = moment(req.query.start_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
259
|
+
|
|
260
|
+
var range = { $gte: new Date(Date.parse(startDate)).toISOString() };
|
|
261
|
+
if (req.query.filterRangeField) {
|
|
262
|
+
query[req.query.filterRangeField] = range;
|
|
263
|
+
}else {
|
|
264
|
+
query.createdAt = range;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
winston.debug('REQUEST ROUTE - QUERY CREATED AT (only for start date)', query.createdAt);
|
|
268
|
+
}
|
|
269
|
+
// }
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
if (req.query.snap_department_routing) {
|
|
274
|
+
query["snapshot.department.routing"] = req.query.snap_department_routing;
|
|
275
|
+
winston.debug('REQUEST ROUTE - QUERY snap_department_routing', query.snap_department_routing);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (req.query.snap_department_default) {
|
|
279
|
+
query["snapshot.department.default"] = req.query.snap_department_default;
|
|
280
|
+
winston.debug('REQUEST ROUTE - QUERY snap_department_default', query.snap_department_default);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
if (req.query.snap_department_id_bot) {
|
|
285
|
+
query["snapshot.department.id_bot"] = req.query.snap_department_id_bot;
|
|
286
|
+
winston.debug('REQUEST ROUTE - QUERY snap_department_id_bot', query.snap_department_id_bot);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (req.query.snap_department_id_bot_exists) {
|
|
290
|
+
query["snapshot.department.id_bot"] = {"$exists": req.query.snap_department_id_bot_exists}
|
|
291
|
+
winston.debug('REQUEST ROUTE - QUERY snap_department_id_bot_exists', query.snap_department_id_bot_exists);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// if (req.query.snap_lead_lead_id) {
|
|
295
|
+
// query["snapshot.lead.lead_id"] = req.query.snap_lead_lead_id;
|
|
296
|
+
// winston.debug('REQUEST ROUTE - QUERY snap_lead_lead_id', query.snap_lead_lead_id);
|
|
297
|
+
// }
|
|
298
|
+
|
|
299
|
+
if (req.query.channel) {
|
|
300
|
+
query["channel.name"] = req.query.channel
|
|
301
|
+
winston.debug('REQUEST ROUTE - QUERY channel', query.channel);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
var direction = -1; //-1 descending , 1 ascending
|
|
306
|
+
if (req.query.direction) {
|
|
307
|
+
direction = req.query.direction;
|
|
308
|
+
}
|
|
309
|
+
winston.debug("direction", direction);
|
|
310
|
+
|
|
311
|
+
var sortField = "createdAt";
|
|
312
|
+
if (req.query.sort) {
|
|
313
|
+
sortField = req.query.sort;
|
|
314
|
+
}
|
|
315
|
+
winston.debug("sortField", sortField);
|
|
316
|
+
|
|
317
|
+
var sortQuery = {};
|
|
318
|
+
sortQuery[sortField] = direction;
|
|
319
|
+
|
|
320
|
+
winston.debug("sort query", sortQuery);
|
|
321
|
+
|
|
322
|
+
winston.verbose('REQUEST ROUTE - REQUEST FIND ', query);
|
|
323
|
+
|
|
324
|
+
// requestcachefarequi populaterequired
|
|
325
|
+
var q1 = Request.find(query).
|
|
326
|
+
skip(skip).limit(limit);
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
winston.debug('REQUEST ROUTE no_populate:' + req.query.no_populate);
|
|
330
|
+
|
|
331
|
+
if (req.query.no_populate != "true" && req.query.no_populate != true) {
|
|
332
|
+
winston.verbose('REQUEST ROUTE - no_polutate false ', req.headers);
|
|
333
|
+
q1.populate('department').
|
|
334
|
+
populate('participatingBots'). //nico già nn gli usa
|
|
335
|
+
populate('participatingAgents'). //nico già nn gli usa
|
|
336
|
+
populate('lead').
|
|
337
|
+
populate({path:'requester',populate:{path:'id_user'}}); //toglilo perche nico lo prende già da snapshot
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// cache(cacheUtil.defaultTTL, "requests-"+projectId).
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
// if (req.query.select_snapshot) {
|
|
344
|
+
// winston.info('select_snapshot');
|
|
345
|
+
// q1.select("+snapshot");
|
|
346
|
+
// // q1.select({ "snapshot": 1});
|
|
347
|
+
// }
|
|
348
|
+
|
|
349
|
+
q1.sort(sortQuery);
|
|
350
|
+
|
|
351
|
+
// winston.info('q1',q1);
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
q1.exec();
|
|
355
|
+
|
|
356
|
+
// TODO if ?onlycount=true do not perform find query but only
|
|
357
|
+
// set q1 to undefined; to skip query
|
|
358
|
+
|
|
359
|
+
var q2 = Request.countDocuments(query).exec();
|
|
360
|
+
|
|
361
|
+
var promises = [
|
|
362
|
+
q1,
|
|
363
|
+
q2
|
|
364
|
+
];
|
|
365
|
+
|
|
366
|
+
Promise.all(promises).then(function(results) {
|
|
367
|
+
var objectToReturn = {
|
|
368
|
+
perPage: limit,
|
|
369
|
+
count: results[1],
|
|
370
|
+
requests: results[0]
|
|
371
|
+
};
|
|
372
|
+
winston.debug('REQUEST ROUTE - objectToReturn ', objectToReturn);
|
|
373
|
+
return res.json(objectToReturn);
|
|
374
|
+
|
|
375
|
+
}).catch(function(err){
|
|
376
|
+
winston.error('REQUEST ROUTE - REQUEST FIND ERR ', err);
|
|
377
|
+
return res.status(500).send({ success: false, msg: 'Error getting requests.', err: err });
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
|
|
73
384
|
module.exports = router;
|
package/routes/widget.js
CHANGED
|
@@ -114,10 +114,38 @@ router.get('/', function(req, res, next) {
|
|
|
114
114
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
|
|
118
|
+
var getProject = function(req) {
|
|
119
|
+
winston.info('getProject.');
|
|
120
|
+
|
|
121
|
+
return new Promise(function (resolve, reject) {
|
|
122
|
+
|
|
123
|
+
//@DISABLED_CACHE .cache(cacheUtil.queryTTL, "projects:query:id:status:100:"+req.projectid+":select:-settings")
|
|
124
|
+
|
|
125
|
+
Project.findOne({_id: req.projectid, status: 100}).select('-settings -ipFilter -ipFilterEnabled').exec(function(err, project) {
|
|
126
|
+
// not use .lean I need project.trialExpired
|
|
127
|
+
|
|
128
|
+
if (err) {
|
|
129
|
+
return reject({err: "Project Not Found"});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (project && project.profile && (project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false)) {
|
|
133
|
+
winston.info('getProject remove poweredBy tag', project);
|
|
134
|
+
project.widget.poweredBy = undefined;
|
|
135
|
+
project.widget.baloonImage = undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return resolve(project);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
117
145
|
// TOOD add labels
|
|
118
146
|
Promise.all([
|
|
119
|
-
|
|
120
|
-
|
|
147
|
+
|
|
148
|
+
getProject(req)
|
|
121
149
|
,
|
|
122
150
|
availableUsers()
|
|
123
151
|
,
|
package/services/emailService.js
CHANGED
|
@@ -98,13 +98,13 @@ class EmailService {
|
|
|
98
98
|
this.host = process.env.EMAIL_HOST || config.host;
|
|
99
99
|
winston.info('EmailService host: ' + this.host);
|
|
100
100
|
|
|
101
|
-
this.secure = process.env.EMAIL_SECURE || false;
|
|
101
|
+
this.secure = process.env.EMAIL_SECURE || false;
|
|
102
102
|
winston.info('EmailService secure: ' + this.secure);
|
|
103
103
|
|
|
104
104
|
this.user = process.env.EMAIL_USERNAME || config.username;
|
|
105
105
|
winston.info('EmailService username: ' + this.user);
|
|
106
106
|
|
|
107
|
-
this.port = process.env.EMAIL_PORT;
|
|
107
|
+
this.port = process.env.EMAIL_PORT; //default is 587
|
|
108
108
|
winston.info('EmailService port: ' + this.port);
|
|
109
109
|
|
|
110
110
|
|
|
@@ -123,11 +123,19 @@ class EmailService {
|
|
|
123
123
|
var that = this;
|
|
124
124
|
winston.debug('EmailService readTemplate: '+ templateName + ' ' + JSON.stringify(settings));
|
|
125
125
|
|
|
126
|
+
|
|
126
127
|
if (settings && settings.email && settings.email.templates) {
|
|
128
|
+
|
|
127
129
|
var templates = settings.email.templates;
|
|
128
130
|
winston.debug('EmailService templates: ',templates);
|
|
129
|
-
|
|
131
|
+
|
|
132
|
+
var templateDbName = templateName.replace(".html", "");
|
|
133
|
+
winston.debug('EmailService templateDbName: '+templateDbName);
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
var template = templates[templateDbName];
|
|
130
137
|
winston.debug('EmailService template: '+template);
|
|
138
|
+
|
|
131
139
|
if (template) {
|
|
132
140
|
// that.callback(template);
|
|
133
141
|
return new Promise(function (resolve, reject) {
|
|
@@ -240,7 +248,6 @@ class EmailService {
|
|
|
240
248
|
};
|
|
241
249
|
|
|
242
250
|
winston.debug('mailOptions', mailOptions);
|
|
243
|
-
|
|
244
251
|
if (!mail.to) {
|
|
245
252
|
return winston.warn("EmailService send method. to field is not defined", mailOptions);
|
|
246
253
|
}
|
|
@@ -273,7 +280,7 @@ class EmailService {
|
|
|
273
280
|
|
|
274
281
|
var that = this;
|
|
275
282
|
|
|
276
|
-
var html = await this.
|
|
283
|
+
var html = await this.readTemplate('test.html',{ "email" : {"templates": {test: "123"}}});
|
|
277
284
|
|
|
278
285
|
var template = handlebars.compile(html);
|
|
279
286
|
|
|
@@ -282,7 +289,7 @@ class EmailService {
|
|
|
282
289
|
|
|
283
290
|
var html = template(replacements);
|
|
284
291
|
|
|
285
|
-
return that.send({to:to, subject:`
|
|
292
|
+
return that.send({to:to, subject:`Tiledesk test email`, config: configEmail, html: html, callback: callback});
|
|
286
293
|
|
|
287
294
|
}
|
|
288
295
|
|
|
@@ -399,10 +406,12 @@ class EmailService {
|
|
|
399
406
|
}
|
|
400
407
|
}
|
|
401
408
|
|
|
402
|
-
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
let subject = `[Tiledesk ${project ? project.name : '-'}] New Assigned Chat`;
|
|
403
412
|
|
|
404
413
|
if (request.subject) {
|
|
405
|
-
subject = `[
|
|
414
|
+
subject = `[Tiledesk ${project ? project.name : '-'}] ${request.subject}`;
|
|
406
415
|
}
|
|
407
416
|
|
|
408
417
|
// if (request.ticket_id) {
|
|
@@ -546,10 +555,10 @@ class EmailService {
|
|
|
546
555
|
}
|
|
547
556
|
|
|
548
557
|
|
|
549
|
-
let subject = `[
|
|
558
|
+
let subject = `[Tiledesk ${project ? project.name : '-'}] New message`;
|
|
550
559
|
|
|
551
560
|
if (request.subject) {
|
|
552
|
-
subject = `[
|
|
561
|
+
subject = `[Tiledesk ${project ? project.name : '-'}] ${request.subject}`;
|
|
553
562
|
}
|
|
554
563
|
if (request.ticket_id) {
|
|
555
564
|
subject = `[Ticket #${request.ticket_id}] New message`;
|
|
@@ -690,10 +699,10 @@ class EmailService {
|
|
|
690
699
|
}
|
|
691
700
|
}
|
|
692
701
|
|
|
693
|
-
let subject = `[
|
|
702
|
+
let subject = `[Tiledesk ${project ? project.name : '-'}] New Pooled Chat`;
|
|
694
703
|
|
|
695
704
|
if (request.subject) {
|
|
696
|
-
subject = `[
|
|
705
|
+
subject = `[Tiledesk ${project ? project.name : '-'}] ${request.subject}`;
|
|
697
706
|
}
|
|
698
707
|
// if (request.ticket_id) {
|
|
699
708
|
// subject = `[Ticket #${request.ticket_id}] New Pooled Chat`;
|
|
@@ -831,10 +840,10 @@ class EmailService {
|
|
|
831
840
|
}
|
|
832
841
|
|
|
833
842
|
|
|
834
|
-
let subject = `[
|
|
843
|
+
let subject = `[Tiledesk ${project ? project.name : '-'}] New Message`;
|
|
835
844
|
|
|
836
845
|
if (request.subject) {
|
|
837
|
-
subject = `[
|
|
846
|
+
subject = `[Tiledesk ${project ? project.name : '-'}] ${request.subject}`;
|
|
838
847
|
}
|
|
839
848
|
if (request.ticket_id) {
|
|
840
849
|
subject = `[Ticket #${request.ticket_id}] New Message`;
|
|
@@ -982,7 +991,7 @@ class EmailService {
|
|
|
982
991
|
replyTo: replyTo,
|
|
983
992
|
inReplyTo: inReplyTo,
|
|
984
993
|
references: references,
|
|
985
|
-
subject:`[
|
|
994
|
+
subject:`[Tiledesk ${project ? project.name : '-'}] New Offline Message`,
|
|
986
995
|
html:html,
|
|
987
996
|
config:configEmail,
|
|
988
997
|
headers: headers
|
|
@@ -997,7 +1006,7 @@ class EmailService {
|
|
|
997
1006
|
replyTo: replyTo,
|
|
998
1007
|
inReplyTo: inReplyTo,
|
|
999
1008
|
references: references,
|
|
1000
|
-
subject: `[
|
|
1009
|
+
subject: `[Tiledesk ${project ? project.name : '-'}] New Offline Message - notification`,
|
|
1001
1010
|
html:html,
|
|
1002
1011
|
headers: headers
|
|
1003
1012
|
});
|
|
@@ -1247,8 +1256,8 @@ class EmailService {
|
|
|
1247
1256
|
var html = template(replacements);
|
|
1248
1257
|
|
|
1249
1258
|
|
|
1250
|
-
that.send({to: to, subject: '[
|
|
1251
|
-
that.send({to:that.bcc, subject: '[
|
|
1259
|
+
that.send({to: to, subject: '[Tiledesk] Password reset request', html:html});
|
|
1260
|
+
that.send({to:that.bcc, subject: '[Tiledesk] Password reset request - notification', html:html });
|
|
1252
1261
|
|
|
1253
1262
|
}
|
|
1254
1263
|
|
|
@@ -1285,8 +1294,8 @@ class EmailService {
|
|
|
1285
1294
|
var html = template(replacements);
|
|
1286
1295
|
|
|
1287
1296
|
|
|
1288
|
-
that.send({to: to, subject:'[
|
|
1289
|
-
that.send({to: that.bcc, subject: '[
|
|
1297
|
+
that.send({to: to, subject:'[Tiledesk] Your password has been changed', html:html });
|
|
1298
|
+
that.send({to: that.bcc, subject: '[Tiledesk] Your password has been changed - notification', html: html });
|
|
1290
1299
|
|
|
1291
1300
|
}
|
|
1292
1301
|
|
|
@@ -1332,8 +1341,8 @@ class EmailService {
|
|
|
1332
1341
|
var html = template(replacements);
|
|
1333
1342
|
|
|
1334
1343
|
|
|
1335
|
-
that.send({to:to, subject: `[
|
|
1336
|
-
that.send({to: that.bcc, subject: `[
|
|
1344
|
+
that.send({to:to, subject: `[Tiledesk] You have been invited to the '${projectName}' project`, html:html});
|
|
1345
|
+
that.send({to: that.bcc, subject: `[Tiledesk] You have been invited to the '${projectName}' project - notification`, html: html});
|
|
1337
1346
|
}
|
|
1338
1347
|
|
|
1339
1348
|
// ok
|
|
@@ -1376,8 +1385,8 @@ class EmailService {
|
|
|
1376
1385
|
|
|
1377
1386
|
var html = template(replacements);
|
|
1378
1387
|
|
|
1379
|
-
that.send({to:to, subject: `[
|
|
1380
|
-
that.send({to: that.bcc, subject: `[
|
|
1388
|
+
that.send({to:to, subject: `[Tiledesk] You have been invited to the '${projectName}' project`, html:html });
|
|
1389
|
+
that.send({to: that.bcc, subject: `[Tiledesk] You have been invited to the '${projectName}' project - notification`, html: html});
|
|
1381
1390
|
|
|
1382
1391
|
}
|
|
1383
1392
|
|
|
@@ -1415,8 +1424,8 @@ class EmailService {
|
|
|
1415
1424
|
var html = template(replacements);
|
|
1416
1425
|
|
|
1417
1426
|
|
|
1418
|
-
that.send({to: to, subject: `[
|
|
1419
|
-
that.send({to: that.bcc, subject: `[
|
|
1427
|
+
that.send({to: to, subject: `[Tiledesk] Verify your email address`, html:html });
|
|
1428
|
+
that.send({to: that.bcc, subject: `[Tiledesk] Verify your email address `+to + " - notification", html:html });
|
|
1420
1429
|
|
|
1421
1430
|
}
|
|
1422
1431
|
|
|
@@ -1483,8 +1492,8 @@ async sendRequestTranscript(to, messages, request, project) {
|
|
|
1483
1492
|
winston.verbose("custom email setting found: ", configEmail);
|
|
1484
1493
|
}
|
|
1485
1494
|
|
|
1486
|
-
that.send({to:to, subject: '[
|
|
1487
|
-
that.send({to: that.bcc, subject: '[
|
|
1495
|
+
that.send({to:to, subject: '[Tiledesk] Transcript', html:html, config: configEmail});
|
|
1496
|
+
that.send({to: that.bcc, subject: '[Tiledesk] Transcript - notification', html:html });
|
|
1488
1497
|
|
|
1489
1498
|
}
|
|
1490
1499
|
|
|
@@ -1496,6 +1505,6 @@ async sendRequestTranscript(to, messages, request, project) {
|
|
|
1496
1505
|
|
|
1497
1506
|
var emailService = new EmailService();
|
|
1498
1507
|
|
|
1499
|
-
//emailService.sendTest("al@f21.it");
|
|
1508
|
+
// emailService.sendTest("al@f21.it");
|
|
1500
1509
|
|
|
1501
1510
|
module.exports = emailService;
|