@tiledesk/tiledesk-server 2.3.6 → 2.3.7-1.2
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/.github/workflows/docker-community-worker-push-latest.yml +23 -0
- package/.github/workflows/docker-image-tag-worker-community-tag-push.yml +22 -0
- package/CHANGELOG.md +361 -3
- package/Dockerfile-jobs +31 -0
- package/app.js +62 -69
- package/channels/chat21/chat21Handler.js +37 -6
- package/channels/chat21/chat21WebHook.js +62 -34
- package/channels/chat21/package-lock.json +663 -706
- package/channels/chat21/package.json +2 -2
- package/config/labels/widget.json +337 -136
- package/deploy.sh +2 -0
- package/event/messageEvent.js +110 -9
- package/jobs.js +80 -0
- package/jobsManager.js +47 -0
- package/middleware/has-role.js +10 -3
- package/middleware/ipFilter.js +220 -0
- package/middleware/passport.js +8 -2
- package/models/department.js +1 -1
- package/models/faq.js +77 -25
- package/models/faq_kb.js +19 -0
- package/models/message.js +10 -8
- package/models/project.js +10 -0
- package/models/project_user.js +10 -0
- package/models/request.js +12 -1
- package/package.json +12 -11
- package/pubmodules/activities/activityArchiver.js +216 -90
- package/pubmodules/activities/routes/activity.js +1 -1
- package/pubmodules/apps/index.js +8 -0
- package/pubmodules/apps/listener.js +27 -0
- package/pubmodules/cache/index.js +2 -0
- package/pubmodules/cache/mongoose-cachegoose-fn.js +630 -0
- package/pubmodules/canned/cannedResponse.js +4 -0
- package/pubmodules/canned/cannedResponseRoute.js +10 -5
- package/pubmodules/dialogflow/index.js +10 -0
- package/pubmodules/dialogflow/listener.js +66 -0
- package/pubmodules/emailNotification/requestNotification.js +58 -28
- package/pubmodules/events/eventRoute.js +49 -24
- package/pubmodules/messageTransformer/messageHandlebarsTransformerInterceptor.js +6 -1
- package/pubmodules/messageTransformer/messageTransformerInterceptor.js +10 -4
- package/pubmodules/pubModulesManager.js +173 -7
- package/pubmodules/queue/index.js +4 -0
- package/pubmodules/queue/reconnect.js +331 -0
- package/pubmodules/queue/reconnectFanout.js +256 -0
- package/pubmodules/rasa/listener.js +5 -5
- package/pubmodules/routing-queue/index.js +3 -0
- package/pubmodules/routing-queue/listener.js +328 -0
- package/pubmodules/rules/conciergeBot.js +2 -2
- package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +6 -1
- package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +7 -1
- package/pubmodules/tilebot/index.js +11 -0
- package/pubmodules/tilebot/listener.js +85 -0
- package/pubmodules/trigger/rulesTrigger.js +137 -14
- package/pubmodules/trigger/start.js +5 -1
- package/pubmodules/whatsapp/index.js +7 -0
- package/pubmodules/whatsapp/listener.js +32 -0
- package/routes/auth.js +7 -2
- package/routes/campaigns.js +3 -3
- package/routes/department.js +3 -2
- package/routes/email.js +32 -2
- package/routes/faq.js +37 -2
- package/routes/faq_kb.js +496 -133
- package/routes/faqpub.js +5 -0
- package/routes/lead.js +56 -0
- package/routes/message.js +196 -14
- package/routes/messagesRoot.js +39 -0
- package/routes/project.js +76 -4
- package/routes/project_user.js +11 -1
- package/routes/project_user_test.js +19 -0
- package/routes/request.js +134 -30
- package/routes/troubleshooting.js +12 -0
- package/routes/users-util.js +39 -0
- package/routes/users.js +1 -1
- package/routes/widget.js +64 -2
- package/services/BotSubscriptionNotifier.js +5 -0
- package/services/banUserNotifier.js +86 -0
- package/services/cacheEnabler.js +56 -0
- package/services/chatbotService.js +101 -0
- package/services/departmentService.js +25 -3
- package/services/emailService.js +170 -28
- package/services/faqBotHandler.js +2 -3
- package/services/faqService.js +28 -3
- package/services/geoService.js +36 -6
- package/services/labelService.js +1 -1
- package/services/leadService.js +3 -2
- package/services/messageService.js +4 -2
- package/services/modulesManager.js +23 -76
- package/services/operatingHoursService.js +9 -4
- package/services/requestService.js +75 -39
- package/services/subscriptionNotifier.js +9 -4
- package/services/trainingService.js +106 -0
- package/template/email/assignedEmailMessage.html +21 -11
- package/template/email/assignedRequest.html +21 -11
- package/template/email/beenInvitedExistingUser.html +16 -6
- package/template/email/beenInvitedNewUser.html +16 -6
- package/template/email/emailDirect.html +130 -0
- package/template/email/newMessage.html +18 -8
- package/template/email/newMessageFollower.html +22 -12
- package/template/email/passwordChanged.html +15 -5
- package/template/email/pooledEmailMessage.html +21 -11
- package/template/email/pooledRequest.html +20 -10
- package/template/email/resetPassword.html +15 -5
- package/template/email/sendTranscript.html +7 -4
- package/template/email/ticket.html +17 -7
- package/template/email/verify.html +15 -5
- package/test/cannedRoute.js +157 -0
- package/test/chatbot-mock.js +127 -0
- package/test/example-json-intents.txt +1 -0
- package/test/example-json.txt +1 -0
- package/test/example.json +1 -0
- package/test/faqRoute.js +353 -208
- package/test/faqkbRoute.js +669 -64
- package/test/imageRoute.js +1 -1
- package/test/messageRoute.js +387 -5
- package/test/requestRoute.js +6 -6
- package/test/requestService.js +55 -4
- package/test-int/cache-project.js +90 -0
- package/test-int/cache-project_user.js +88 -0
- package/utils/UIDGenerator.js +20 -0
- package/utils/cacheUtil.js +2 -2
- package/utils/orgUtil.js +3 -3
- package/utils/promiseUtil.js +31 -0
- package/utils/recipientEmailUtil.js +66 -0
- package/utils/sendEmailUtil.js +34 -0
- package/utils/sendMessageUtil.js +1 -1
- package/utils/stringUtil.js +12 -0
- package/websocket/webSocketServer.js +33 -10
package/routes/request.js
CHANGED
|
@@ -16,6 +16,10 @@ var MessageConstants = require("../models/messageConstants");
|
|
|
16
16
|
var Message = require("../models/message");
|
|
17
17
|
var cacheUtil = require('../utils/cacheUtil');
|
|
18
18
|
var RequestConstants = require("../models/requestConstants");
|
|
19
|
+
var cacheEnabler = require("../services/cacheEnabler");
|
|
20
|
+
var Project_user = require("../models/project_user");
|
|
21
|
+
var Lead = require("../models/lead");
|
|
22
|
+
var UIDGenerator = require("../utils/UIDGenerator");
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
csv = require('csv-express');
|
|
@@ -32,9 +36,9 @@ const { check, validationResult } = require('express-validator');
|
|
|
32
36
|
// TODO make a synchronous chat21 version (with query parameter?) with request.support_group.create
|
|
33
37
|
router.post('/',
|
|
34
38
|
[
|
|
35
|
-
check('
|
|
39
|
+
check('first_text').notEmpty(),
|
|
36
40
|
],
|
|
37
|
-
|
|
41
|
+
async (req, res) => {
|
|
38
42
|
|
|
39
43
|
var startTimestamp = new Date();
|
|
40
44
|
winston.debug("request create timestamp: " + startTimestamp);
|
|
@@ -54,41 +58,113 @@ function (req, res) {
|
|
|
54
58
|
winston.debug("req.projectuser", req.projectuser);
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
var project_user = req.projectuser;
|
|
62
|
+
|
|
63
|
+
var sender = req.body.sender;
|
|
64
|
+
var fullname = req.body.senderFullname || req.user.fullName;
|
|
65
|
+
var email = req.body.email || req.user.email;
|
|
66
|
+
|
|
58
67
|
let messageStatus = req.body.status || MessageConstants.CHAT_MESSAGE_STATUS.SENDING;
|
|
59
68
|
winston.debug('messageStatus: ' + messageStatus);
|
|
60
69
|
|
|
61
|
-
var request_id = req.
|
|
70
|
+
var request_id = req.body.request_id || 'support-group-' + req.projectid + "-" + UIDGenerator.generate();
|
|
71
|
+
winston.debug('request_id: ' + request_id);
|
|
62
72
|
|
|
63
|
-
|
|
64
|
-
return leadService.createIfNotExistsWithLeadId(req.body.sender || req.user._id, req.body.senderFullname || req.user.fullName , req.body.email || req.user.email, req.projectid, null, req.body.attributes || req.user.attributes)
|
|
65
|
-
.then(function(createdLead) {
|
|
73
|
+
if (sender) {
|
|
66
74
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
75
|
+
var isObjectId = mongoose.Types.ObjectId.isValid(sender);
|
|
76
|
+
winston.debug("isObjectId:"+ isObjectId);
|
|
77
|
+
|
|
78
|
+
var queryProjectUser = {id_project:req.projectid, status: "active" };
|
|
79
|
+
|
|
80
|
+
if (isObjectId) {
|
|
81
|
+
queryProjectUser.id_user = sender;
|
|
82
|
+
} else {
|
|
83
|
+
queryProjectUser.uuid_user = sender;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
winston.debug("queryProjectUser", queryProjectUser);
|
|
87
|
+
|
|
88
|
+
project_user = await Project_user.findOne(queryProjectUser).populate({path:'id_user', select:{'firstname':1, 'lastname':1, 'email':1}})
|
|
89
|
+
winston.debug("project_user", project_user);
|
|
90
|
+
|
|
91
|
+
if (!project_user) {
|
|
92
|
+
return res.status(403).send({success: false, msg: 'Unauthorized. Project_user not found with user id : '+ sender });
|
|
93
|
+
}
|
|
72
94
|
|
|
95
|
+
if ( project_user.id_user) {
|
|
96
|
+
fullname = project_user.id_user.fullName;
|
|
97
|
+
winston.debug("pu fullname: "+ fullname);
|
|
98
|
+
email = project_user.id_user.email;
|
|
99
|
+
winston.debug("pu email: "+ email);
|
|
100
|
+
} else if (project_user.uuid_user) {
|
|
101
|
+
var lead = await Lead.findOne({lead_id: project_user.uuid_user, id_project: req.projectid});
|
|
102
|
+
winston.debug("lead: ",lead);
|
|
103
|
+
if (lead) {
|
|
104
|
+
fullname = lead.fullname;
|
|
105
|
+
winston.debug("lead fullname: "+ fullname);
|
|
106
|
+
email = lead.email;
|
|
107
|
+
winston.debug("lead email: "+ email);
|
|
108
|
+
}else {
|
|
109
|
+
winston.warn("lead not found: " + JSON.stringify({lead_id: project_user.uuid_user, id_project: req.projectid}));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
} else {
|
|
113
|
+
winston.warn("pu fullname and email empty");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
}
|
|
73
117
|
|
|
74
|
-
// createWithId(request_id, requester_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes) {
|
|
75
|
-
// return requestService.createWithId(req.params.request_id, req.body.sender, req.projectid,
|
|
76
|
-
// req.body.text, req.body.departmentid, req.body.sourcePage,
|
|
77
|
-
// req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes).then(function (savedRequest) {
|
|
78
118
|
|
|
119
|
+
// createIfNotExistsWithLeadId(lead_id, fullname, email, id_project, createdBy, attributes) {
|
|
120
|
+
return leadService.createIfNotExistsWithLeadId(sender || req.user._id, fullname, email, req.projectid, null, req.body.attributes || req.user.attributes)
|
|
121
|
+
.then(function(createdLead) {
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
var new_request = {
|
|
126
|
+
request_id: request_id,
|
|
127
|
+
project_user_id: req.projectuser._id,
|
|
128
|
+
lead_id: createdLead._id,
|
|
129
|
+
id_project:req.projectid,
|
|
130
|
+
first_text: req.body.first_text,
|
|
131
|
+
departmentid: req.body.departmentid,
|
|
132
|
+
sourcePage:req.body.sourcePage,
|
|
133
|
+
language: req.body.language,
|
|
134
|
+
userAgent:req.body.userAgent,
|
|
135
|
+
status:null,
|
|
136
|
+
createdBy: req.user._id,
|
|
137
|
+
attributes: req.body.attributes,
|
|
138
|
+
subject: req.body.subject,
|
|
139
|
+
preflight:undefined,
|
|
140
|
+
channel: req.body.channel,
|
|
141
|
+
location: req.body.location,
|
|
142
|
+
participants: req.body.participants,
|
|
143
|
+
lead: createdLead, requester: project_user,
|
|
144
|
+
priority: req.body.priority,
|
|
145
|
+
followers: req.body.followers,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return requestService.create(new_request).then(function (savedRequest) {
|
|
149
|
+
// createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes) {
|
|
150
|
+
// return requestService.createWithIdAndRequester(request_id, req.projectuser._id, createdLead._id, req.projectid,
|
|
151
|
+
// req.body.text, req.body.departmentid, req.body.sourcePage,
|
|
152
|
+
// req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes, req.body.subject).then(function (savedRequest) {
|
|
79
153
|
|
|
154
|
+
|
|
155
|
+
// return messageService.create(sender || req.user._id, fullname, request_id, req.body.text,
|
|
156
|
+
// req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata, req.body.language, undefined, req.body.channel).then(function(savedMessage){
|
|
157
|
+
|
|
80
158
|
// create(sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata) {
|
|
81
|
-
return messageService.create(req.body.sender || req.user._id, req.body.senderFullname || req.user.fullName, request_id, req.body.text,
|
|
82
|
-
|
|
159
|
+
// return messageService.create(req.body.sender || req.user._id, req.body.senderFullname || req.user.fullName, request_id, req.body.text,
|
|
160
|
+
// req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata).then(function(savedMessage){
|
|
83
161
|
|
|
84
|
-
// return requestService.incrementMessagesCountByRequestId(savedRequest.request_id, savedRequest.id_project).then(function(savedRequestWithIncrement) {
|
|
85
|
-
|
|
86
162
|
|
|
87
163
|
winston.debug('res.json(savedRequest)');
|
|
88
164
|
var endTimestamp = new Date();
|
|
89
165
|
winston.verbose("request create end: " + (endTimestamp - startTimestamp));
|
|
90
166
|
return res.json(savedRequest);
|
|
91
|
-
});
|
|
167
|
+
// });
|
|
92
168
|
// });
|
|
93
169
|
});
|
|
94
170
|
|
|
@@ -162,6 +238,20 @@ router.patch('/:requestid', function (req, res) {
|
|
|
162
238
|
update.priority = req.body.priority;
|
|
163
239
|
}
|
|
164
240
|
|
|
241
|
+
if (req.body.smartAssignment!=undefined) {
|
|
242
|
+
update.smartAssignment = req.body.smartAssignment;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (req.body.workingStatus!=undefined) {
|
|
246
|
+
update.workingStatus = req.body.workingStatus;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
if (req.body.channelName) {
|
|
251
|
+
update["channel.name"] = req.body.channelName;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
|
|
165
255
|
|
|
166
256
|
winston.verbose("Request patch update",update);
|
|
167
257
|
|
|
@@ -198,7 +288,7 @@ router.put('/:requestid/close', function (req, res) {
|
|
|
198
288
|
|
|
199
289
|
// closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
|
|
200
290
|
const closed_by = req.user.id;
|
|
201
|
-
return requestService.closeRequestByRequestId(req.params.requestid, req.projectid, false, true, closed_by).then(function(closedRequest) {
|
|
291
|
+
return requestService.closeRequestByRequestId(req.params.requestid, req.projectid, false, true, closed_by, req.body.force).then(function(closedRequest) {
|
|
202
292
|
|
|
203
293
|
winston.verbose("request closed", closedRequest);
|
|
204
294
|
|
|
@@ -710,6 +800,10 @@ router.get('/', function (req, res, next) {
|
|
|
710
800
|
winston.debug('REQUEST ROUTE - QUERY DEPT ID', query.department);
|
|
711
801
|
}
|
|
712
802
|
|
|
803
|
+
if (req.query.requester_email) {
|
|
804
|
+
query["snapshot.lead.email"] = req.query.requester_email;
|
|
805
|
+
}
|
|
806
|
+
|
|
713
807
|
if (req.query.full_text) {
|
|
714
808
|
winston.debug('req.query.fulltext', req.query.full_text);
|
|
715
809
|
query.$text = { "$search": req.query.full_text };
|
|
@@ -778,8 +872,8 @@ router.get('/', function (req, res, next) {
|
|
|
778
872
|
* THE SEARCH FOR DATE INTERVAL OF THE HISTORY OF REQUESTS ARE DISABLED AND
|
|
779
873
|
* ARE DISPLAYED ONLY THE REQUESTS OF THE LAST 14 DAYS
|
|
780
874
|
*/
|
|
781
|
-
//secondo me qui manca un parentesi tonda per gli or
|
|
782
|
-
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)) {
|
|
875
|
+
//fixato. secondo me qui manca un parentesi tonda per gli or
|
|
876
|
+
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))) {
|
|
783
877
|
|
|
784
878
|
|
|
785
879
|
var startdate = moment().subtract(14, "days").format("YYYY-MM-DD");
|
|
@@ -882,6 +976,11 @@ router.get('/', function (req, res, next) {
|
|
|
882
976
|
winston.debug('REQUEST ROUTE - QUERY snap_lead_email', query.snap_lead_email);
|
|
883
977
|
}
|
|
884
978
|
|
|
979
|
+
if (req.query.smartAssignment) {
|
|
980
|
+
query.smartAssignment = req.query.smartAssignment;
|
|
981
|
+
winston.debug('REQUEST ROUTE - QUERY smartAssignment', query.smartAssignment);
|
|
982
|
+
}
|
|
983
|
+
|
|
885
984
|
if (req.query.channel) {
|
|
886
985
|
if (req.query.channel === "offline") {
|
|
887
986
|
query["channel.name"] = {"$in" : ["email", "form"]}
|
|
@@ -992,7 +1091,7 @@ router.get('/', function (req, res, next) {
|
|
|
992
1091
|
winston.debug('REQUEST ROUTE - objectToReturn ', objectToReturn);
|
|
993
1092
|
|
|
994
1093
|
const endExecTime = new Date();
|
|
995
|
-
winston.
|
|
1094
|
+
winston.verbose('REQUEST ROUTE - exec time: ' + (endExecTime-startExecTime));
|
|
996
1095
|
|
|
997
1096
|
return res.json(objectToReturn);
|
|
998
1097
|
|
|
@@ -1234,17 +1333,22 @@ router.get('/:requestid', function (req, res) {
|
|
|
1234
1333
|
var requestid = req.params.requestid;
|
|
1235
1334
|
winston.debug("get request by id: "+requestid);
|
|
1236
1335
|
|
|
1237
|
-
|
|
1238
|
-
Request.findOne({request_id: requestid, id_project: req.projectid})
|
|
1336
|
+
|
|
1337
|
+
let q = Request.findOne({request_id: requestid, id_project: req.projectid})
|
|
1239
1338
|
// .select("+snapshot.agents")
|
|
1240
1339
|
.populate('lead')
|
|
1241
1340
|
.populate('department')
|
|
1242
1341
|
.populate('participatingBots')
|
|
1243
1342
|
.populate('participatingAgents')
|
|
1244
|
-
.populate({path:'requester',populate:{path:'id_user'}})
|
|
1245
|
-
|
|
1343
|
+
.populate({path:'requester',populate:{path:'id_user'}});
|
|
1344
|
+
|
|
1345
|
+
// if (cacheEnabler.request) { cache disabled beacuse cacheoose don't support .populate without lean. here cache is not important
|
|
1346
|
+
// q.cache(cacheUtil.defaultTTL, req.projectid+":requests:request_id:"+requestid) //request_cache
|
|
1347
|
+
// winston.debug('request cache enabled');
|
|
1348
|
+
// }
|
|
1349
|
+
//
|
|
1246
1350
|
// .populate({path:'requester',populate:{path:'id_user', select:{'firstname':1, 'lastname':1}}})
|
|
1247
|
-
.exec(function(err, request) {
|
|
1351
|
+
q.exec(function(err, request) {
|
|
1248
1352
|
if (err) {
|
|
1249
1353
|
winston.error("error getting request by id ", err);
|
|
1250
1354
|
return res.status(500).send({ success: false, msg: 'Error getting object.' });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
var express = require('express');
|
|
2
|
+
var router = express.Router();
|
|
3
|
+
var winston = require('../config/winston');
|
|
4
|
+
|
|
5
|
+
router.get('/headers', function(req, res) {
|
|
6
|
+
winston.info("req.headers", req.headers);
|
|
7
|
+
// TODO chech if query is null
|
|
8
|
+
res.json(req.headers);
|
|
9
|
+
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
module.exports = router;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var express = require('express');
|
|
2
|
+
var router = express.Router();
|
|
3
|
+
|
|
4
|
+
var User = require("../models/user");
|
|
5
|
+
var winston = require('../config/winston');
|
|
6
|
+
var mongoose = require('mongoose');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// sponz: realizza mini servizio senza sec
|
|
13
|
+
router.get('/:userid', function (req, res) {
|
|
14
|
+
winston.debug("users");
|
|
15
|
+
var userid = req.params.userid;
|
|
16
|
+
|
|
17
|
+
var isObjectId = mongoose.Types.ObjectId.isValid(userid);
|
|
18
|
+
winston.debug("isObjectId:"+ isObjectId);
|
|
19
|
+
|
|
20
|
+
if (!isObjectId) {
|
|
21
|
+
return res.status(404).send({ success: false, msg: 'User id not found' });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
User.findById(userid, 'firstname lastname _id', function (err, user) {
|
|
25
|
+
if (err) {
|
|
26
|
+
winston.error('Error getting object.',err);
|
|
27
|
+
return res.status(500).send({ success: false, msg: 'Error getting object.' });
|
|
28
|
+
}
|
|
29
|
+
if (!user) {
|
|
30
|
+
winston.warn("Object not found with id " +userid);
|
|
31
|
+
return res.status(404).send({ success: false, msg: 'Object not found.' });
|
|
32
|
+
}
|
|
33
|
+
winston.debug("GET USER BY ID RES JSON", user);
|
|
34
|
+
res.json(user);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
module.exports = router;
|
package/routes/users.js
CHANGED
|
@@ -25,7 +25,7 @@ router.put('/', function (req, res) {
|
|
|
25
25
|
|
|
26
26
|
User.findByIdAndUpdate(req.user.id, update, { new: true, upsert: true }, function (err, updatedUser) {
|
|
27
27
|
if (err) {
|
|
28
|
-
winston.error(err);
|
|
28
|
+
winston.error("Error putting user",err);
|
|
29
29
|
return res.status(500).send({ success: false, msg: err });
|
|
30
30
|
}
|
|
31
31
|
|
package/routes/widget.js
CHANGED
|
@@ -146,8 +146,12 @@ router.get('/', function(req, res, next) {
|
|
|
146
146
|
//secondo me qui manca un parentesi tonda per gli or
|
|
147
147
|
if (project && project.profile && ((project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false))) {
|
|
148
148
|
winston.debug('getProject remove poweredBy tag', project);
|
|
149
|
-
|
|
150
|
-
project.widget
|
|
149
|
+
|
|
150
|
+
if (project.widget) {
|
|
151
|
+
project.widget.poweredBy = undefined;
|
|
152
|
+
project.widget.baloonImage = undefined;
|
|
153
|
+
}
|
|
154
|
+
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
return resolve(project);
|
|
@@ -190,7 +194,65 @@ router.get('/', function(req, res, next) {
|
|
|
190
194
|
|
|
191
195
|
|
|
192
196
|
|
|
197
|
+
router.get('/ip', function(req, res, next) {
|
|
193
198
|
|
|
199
|
+
var xforwarded = req.headers['x-forwarded-for'];
|
|
200
|
+
winston.info('xforwarded'+ xforwarded);
|
|
201
|
+
|
|
202
|
+
var connectionRemoteAddress = req.connection.remoteAddress;
|
|
203
|
+
winston.info('connectionRemoteAddress'+ connectionRemoteAddress);
|
|
204
|
+
|
|
205
|
+
var socketRemoteAddress = req.socket.remoteAddress;
|
|
206
|
+
winston.info('socketRemoteAddress'+ socketRemoteAddress);
|
|
207
|
+
|
|
208
|
+
if (req.connection.socket ) {
|
|
209
|
+
var connectionSocketRemoteAddress = req.connection.socket.remoteAddress;
|
|
210
|
+
winston.info('connectionSocketRemoteAddress'+ connectionSocketRemoteAddress);
|
|
211
|
+
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
var ip = req.headers['x-forwarded-for'] ||
|
|
216
|
+
req.connection.remoteAddress ||
|
|
217
|
+
req.socket.remoteAddress ||
|
|
218
|
+
(req.connection.socket ? req.connection.socket.remoteAddress : null);
|
|
219
|
+
winston.info("ip:"+ ip);
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
const ipStandard = (req.headers['x-forwarded-for'] || '').split(',').shift().trim() || //https://stackoverflow.com/questions/8107856/how-to-determine-a-users-ip-address-in-node
|
|
225
|
+
req.socket.remoteAddress
|
|
226
|
+
|
|
227
|
+
winston.info("standard ip: "+ipStandard); // ip address of the user
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
// const parseIp = (req) =>
|
|
232
|
+
// req.headers['x-forwarded-for']?.split(',').shift()
|
|
233
|
+
// || req.socket?.remoteAddress
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
let parseIp = req.socket.remoteAddress;
|
|
238
|
+
|
|
239
|
+
const xFor = req.headers['x-forwarded-for'];
|
|
240
|
+
winston.info("parseIp xFor: "+xFor);
|
|
241
|
+
|
|
242
|
+
if (xFor ) {
|
|
243
|
+
const xForArr = xFor.split(',');
|
|
244
|
+
if (xForArr && xForArr.length>0) {
|
|
245
|
+
parseIp = xForArr.shift();
|
|
246
|
+
winston.info("parseIp xFor parseIp: "+parseIp);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
winston.info("parseIp: "+parseIp); // ip address of the user
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
res.json( {ip:ip, ipStandard:ipStandard, parseIp: parseIp} );
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
});
|
|
194
256
|
|
|
195
257
|
|
|
196
258
|
|
|
@@ -20,6 +20,10 @@ class BotSubscriptionNotifier {
|
|
|
20
20
|
|
|
21
21
|
var url = bot.url;
|
|
22
22
|
|
|
23
|
+
// if (url.startsWith("$ext_url")) {
|
|
24
|
+
// // url = url.replace ("$res_bot_url", prendi da env)
|
|
25
|
+
// }
|
|
26
|
+
|
|
23
27
|
var json = {timestamp: Date.now(), payload: payload};
|
|
24
28
|
|
|
25
29
|
|
|
@@ -53,6 +57,7 @@ class BotSubscriptionNotifier {
|
|
|
53
57
|
|
|
54
58
|
}, function(err, result, json){
|
|
55
59
|
winston.verbose("SENT notify for bot with url " + url + " with err " + err);
|
|
60
|
+
winston.debug("SENT notify for bot with url ", result);
|
|
56
61
|
if (err) {
|
|
57
62
|
winston.error("Error sending notify for bot with url " + url + " with err " + err);
|
|
58
63
|
//TODO Reply with error
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
var messageService = require("./messageService");
|
|
2
|
+
var projectEvent = require("../event/projectEvent");
|
|
3
|
+
|
|
4
|
+
var winston = require('../config/winston');
|
|
5
|
+
|
|
6
|
+
var MessageConstants = require("../models/messageConstants");
|
|
7
|
+
|
|
8
|
+
class BanUserNotifier {
|
|
9
|
+
|
|
10
|
+
listen() {
|
|
11
|
+
projectEvent.on("project.update.user.ban", function(data) {
|
|
12
|
+
var project=data.project;
|
|
13
|
+
var banInfo = data.banInfo;
|
|
14
|
+
|
|
15
|
+
winston.debug("User Banned");
|
|
16
|
+
|
|
17
|
+
var message = {
|
|
18
|
+
sender: 'system',
|
|
19
|
+
senderFullname: 'Bot',
|
|
20
|
+
recipient: banInfo.id,
|
|
21
|
+
recipientFullname: banInfo.id,
|
|
22
|
+
text: "User Banned",
|
|
23
|
+
id_project: project._id,
|
|
24
|
+
createdBy: "system",
|
|
25
|
+
attributes: {subtype:"info", messagelabel: {key: "USER_BANNED"} },
|
|
26
|
+
channel_type: MessageConstants.CHANNEL_TYPE.DIRECT,
|
|
27
|
+
status: MessageConstants.CHAT_MESSAGE_STATUS.SENDING,
|
|
28
|
+
// channel: {name: "chat21"}
|
|
29
|
+
};
|
|
30
|
+
messageService.save(message);
|
|
31
|
+
winston.info("User banned", message);
|
|
32
|
+
// messageService.send(
|
|
33
|
+
// 'system',
|
|
34
|
+
// 'Bot',
|
|
35
|
+
// banInfo.id,
|
|
36
|
+
// "User Banned",
|
|
37
|
+
// project._id,
|
|
38
|
+
// 'system',
|
|
39
|
+
// {subtype:"info"},
|
|
40
|
+
// undefined,
|
|
41
|
+
// undefined
|
|
42
|
+
// );
|
|
43
|
+
});
|
|
44
|
+
projectEvent.on("project.update.user.unban", function(data) {
|
|
45
|
+
var project=data.project;
|
|
46
|
+
var banInfo = data.banInfo;
|
|
47
|
+
|
|
48
|
+
winston.debug("User UnBanned: "+banInfo);
|
|
49
|
+
|
|
50
|
+
// var message = {
|
|
51
|
+
// sender: 'system',
|
|
52
|
+
// senderFullname: 'Bot',
|
|
53
|
+
// recipient: banInfo,
|
|
54
|
+
// recipientFullname: banInfo,
|
|
55
|
+
// text: "User Unbanned",
|
|
56
|
+
// id_project: project._id,
|
|
57
|
+
// createdBy: "system",
|
|
58
|
+
// attributes: {subtype:"info", messagelabel: {key: "USER_BANNED"}},
|
|
59
|
+
// channel_type: MessageConstants.CHANNEL_TYPE.DIRECT,
|
|
60
|
+
// status: MessageConstants.CHAT_MESSAGE_STATUS.SENDING,
|
|
61
|
+
// };
|
|
62
|
+
// messageService.save(message);
|
|
63
|
+
// winston.info("User UnBanned", message);
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
// messageService.send(
|
|
69
|
+
// 'system',
|
|
70
|
+
// 'Bot',
|
|
71
|
+
// banInfo.id,
|
|
72
|
+
// "User Unbanned",
|
|
73
|
+
// project._id,
|
|
74
|
+
// 'system',
|
|
75
|
+
// {subtype:"info"},
|
|
76
|
+
// undefined,
|
|
77
|
+
// undefined
|
|
78
|
+
// );
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
var banUserNotifier = new BanUserNotifier();
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
module.exports = banUserNotifier;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
class CacheEnabler {
|
|
3
|
+
constructor() {
|
|
4
|
+
|
|
5
|
+
// long TTL
|
|
6
|
+
this.trigger = true;
|
|
7
|
+
if (process.env.CACHE_TRIGGER_ENABLED=="false" || process.env.CACHE_TRIGGER_ENABLED==false) {
|
|
8
|
+
this.trigger = false;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// long TTL
|
|
12
|
+
this.subscription = true;
|
|
13
|
+
if (process.env.CACHE_SUBSCRIPTION_ENABLED=="false" || process.env.CACHE_SUBSCRIPTION_ENABLED==false) {
|
|
14
|
+
this.subscription = false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//default TTL
|
|
18
|
+
this.project = true;
|
|
19
|
+
if (process.env.CACHE_PROJECT_ENABLED=="false" || process.env.CACHE_PROJECT_ENABLED==false) {
|
|
20
|
+
this.project = false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//default TTL
|
|
24
|
+
this.request = true;
|
|
25
|
+
if (process.env.CACHE_REQUEST_ENABLED=="false" || process.env.CACHE_REQUEST_ENABLED==false) {
|
|
26
|
+
this.request = false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
this.faq_kb = true;
|
|
30
|
+
if (process.env.CACHE_FAQ_KB_ENABLED=="false" || process.env.CACHE_FAQ_KB_ENABLED==false) {
|
|
31
|
+
this.faq_kb = false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
this.project_user = true;
|
|
36
|
+
if (process.env.CACHE_PROJECT_USER_ENABLED=="false" || process.env.CACHE_PROJECT_USER_ENABLED==false) {
|
|
37
|
+
this.project_user = false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// this.user = true;
|
|
41
|
+
// if (process.env.CACHE_USER_ENABLED=="false" || process.env.CACHE_USER_ENABLED==false) {
|
|
42
|
+
// this.user = false;
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
// this.message = true;
|
|
46
|
+
// if (process.env.CACHE_MESSAGE_ENABLED=="false" || process.env.CACHE_MESSAGE_ENABLED==false) {
|
|
47
|
+
// this.message = false;
|
|
48
|
+
// }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
var cacheEnabler = new CacheEnabler();
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
module.exports = cacheEnabler;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const axios = require("axios").default;
|
|
2
|
+
const winston = require('../config/winston');
|
|
3
|
+
var Faq_kb = require("../models/faq_kb");
|
|
4
|
+
|
|
5
|
+
class ChatbotService {
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async getBotById(id_faq_kb, published, api_url, chatbot_templates_api_url, token, project_id) {
|
|
13
|
+
|
|
14
|
+
winston.info("[CHATBOT SERVICE] getBotById");
|
|
15
|
+
|
|
16
|
+
// private bot
|
|
17
|
+
if (published == "false") {
|
|
18
|
+
|
|
19
|
+
return await axios({
|
|
20
|
+
url: api_url + "/" + project_id + "/faq_kb/exportjson/" + id_faq_kb,
|
|
21
|
+
headers: {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
'Authorization': token
|
|
24
|
+
},
|
|
25
|
+
method: 'GET'
|
|
26
|
+
}).then((resbody) => {
|
|
27
|
+
winston.info("(CHATBOT SERVICE) forking private chatbot " + resbody.data.name)
|
|
28
|
+
let chatbot = resbody.data;
|
|
29
|
+
return chatbot;
|
|
30
|
+
}).catch((err) => {
|
|
31
|
+
winston.error('(CHATBOT SERVICE) FAQ_KB EXPORTJSON ERROR ' + err);
|
|
32
|
+
return err;
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// public bot
|
|
36
|
+
} else {
|
|
37
|
+
|
|
38
|
+
return await axios({
|
|
39
|
+
url: chatbot_templates_api_url + "/" + id_faq_kb,
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json'
|
|
42
|
+
},
|
|
43
|
+
method: 'GET'
|
|
44
|
+
}).then((resbody) => {
|
|
45
|
+
winston.info("(CHATBOT SERVICE) forking public chatbot " + resbody.data.name);
|
|
46
|
+
let chatbot = resbody.data;
|
|
47
|
+
return chatbot
|
|
48
|
+
}).catch((err) => {
|
|
49
|
+
winston.error('(CHATBOT SERVICE) FAQ_KB CHATBOT TEMPLATES ERROR ' + err);
|
|
50
|
+
return err;
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async createBot(api_url, token, chatbot, project_id) {
|
|
57
|
+
|
|
58
|
+
winston.info("[CHATBOT SERVICE] createBot");
|
|
59
|
+
|
|
60
|
+
return await axios({
|
|
61
|
+
url: api_url + '/' + project_id + '/faq_kb/',
|
|
62
|
+
headers: {
|
|
63
|
+
'Content-Type': 'application/json',
|
|
64
|
+
'Authorization': token
|
|
65
|
+
},
|
|
66
|
+
data: chatbot,
|
|
67
|
+
method: 'POST'
|
|
68
|
+
}).then((resbody) => {
|
|
69
|
+
winston.debug("(CHATBOT SERVICE) createBot resbody: ", resbody.data);
|
|
70
|
+
return resbody.data;
|
|
71
|
+
}).catch((err) => {
|
|
72
|
+
winston.error("(CHATBOT SERVICE) CREATE NEW CHATBOT ERROR " + err);
|
|
73
|
+
return err;
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async importFaqs(api_url, id_faq_kb, token, chatbot, project_id) {
|
|
79
|
+
|
|
80
|
+
winston.info("[CHATBOT SERVICE] importFaqs");
|
|
81
|
+
|
|
82
|
+
return await axios({
|
|
83
|
+
url: api_url + '/' + project_id + '/faq_kb/importjson/' + id_faq_kb + "?intentsOnly=true",
|
|
84
|
+
headers: {
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'Authorization': token
|
|
87
|
+
},
|
|
88
|
+
data: chatbot,
|
|
89
|
+
method: 'POST'
|
|
90
|
+
}).then((resbody) => {
|
|
91
|
+
winston.debug("(CHATBOT SERVICE) importFaqs resbody: ", resbody.data);
|
|
92
|
+
return resbody.data;
|
|
93
|
+
}).catch((err) => {
|
|
94
|
+
winston.error("(CHATBOT SERVICE) IMPORT FAQS ERROR " + err);
|
|
95
|
+
return err;
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = { ChatbotService }
|