@tiledesk/tiledesk-server 2.3.6 → 2.3.7-1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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 }
|