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