@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.
Files changed (126) hide show
  1. package/.github/workflows/docker-community-worker-push-latest.yml +23 -0
  2. package/.github/workflows/docker-image-tag-worker-community-tag-push.yml +22 -0
  3. package/CHANGELOG.md +361 -3
  4. package/Dockerfile-jobs +31 -0
  5. package/app.js +62 -69
  6. package/channels/chat21/chat21Handler.js +37 -6
  7. package/channels/chat21/chat21WebHook.js +62 -34
  8. package/channels/chat21/package-lock.json +663 -706
  9. package/channels/chat21/package.json +2 -2
  10. package/config/labels/widget.json +337 -136
  11. package/deploy.sh +2 -0
  12. package/event/messageEvent.js +110 -9
  13. package/jobs.js +80 -0
  14. package/jobsManager.js +47 -0
  15. package/middleware/has-role.js +10 -3
  16. package/middleware/ipFilter.js +220 -0
  17. package/middleware/passport.js +8 -2
  18. package/models/department.js +1 -1
  19. package/models/faq.js +77 -25
  20. package/models/faq_kb.js +19 -0
  21. package/models/message.js +10 -8
  22. package/models/project.js +10 -0
  23. package/models/project_user.js +10 -0
  24. package/models/request.js +12 -1
  25. package/package.json +12 -11
  26. package/pubmodules/activities/activityArchiver.js +216 -90
  27. package/pubmodules/activities/routes/activity.js +1 -1
  28. package/pubmodules/apps/index.js +8 -0
  29. package/pubmodules/apps/listener.js +27 -0
  30. package/pubmodules/cache/index.js +2 -0
  31. package/pubmodules/cache/mongoose-cachegoose-fn.js +630 -0
  32. package/pubmodules/canned/cannedResponse.js +4 -0
  33. package/pubmodules/canned/cannedResponseRoute.js +10 -5
  34. package/pubmodules/dialogflow/index.js +10 -0
  35. package/pubmodules/dialogflow/listener.js +66 -0
  36. package/pubmodules/emailNotification/requestNotification.js +58 -28
  37. package/pubmodules/events/eventRoute.js +49 -24
  38. package/pubmodules/messageTransformer/messageHandlebarsTransformerInterceptor.js +6 -1
  39. package/pubmodules/messageTransformer/messageTransformerInterceptor.js +10 -4
  40. package/pubmodules/pubModulesManager.js +173 -7
  41. package/pubmodules/queue/index.js +4 -0
  42. package/pubmodules/queue/reconnect.js +331 -0
  43. package/pubmodules/queue/reconnectFanout.js +256 -0
  44. package/pubmodules/rasa/listener.js +5 -5
  45. package/pubmodules/routing-queue/index.js +3 -0
  46. package/pubmodules/routing-queue/listener.js +328 -0
  47. package/pubmodules/rules/conciergeBot.js +2 -2
  48. package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +6 -1
  49. package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +7 -1
  50. package/pubmodules/tilebot/index.js +11 -0
  51. package/pubmodules/tilebot/listener.js +85 -0
  52. package/pubmodules/trigger/rulesTrigger.js +137 -14
  53. package/pubmodules/trigger/start.js +5 -1
  54. package/pubmodules/whatsapp/index.js +7 -0
  55. package/pubmodules/whatsapp/listener.js +32 -0
  56. package/routes/auth.js +7 -2
  57. package/routes/campaigns.js +3 -3
  58. package/routes/department.js +3 -2
  59. package/routes/email.js +32 -2
  60. package/routes/faq.js +37 -2
  61. package/routes/faq_kb.js +496 -133
  62. package/routes/faqpub.js +5 -0
  63. package/routes/lead.js +56 -0
  64. package/routes/message.js +196 -14
  65. package/routes/messagesRoot.js +39 -0
  66. package/routes/project.js +76 -4
  67. package/routes/project_user.js +11 -1
  68. package/routes/project_user_test.js +19 -0
  69. package/routes/request.js +134 -30
  70. package/routes/troubleshooting.js +12 -0
  71. package/routes/users-util.js +39 -0
  72. package/routes/users.js +1 -1
  73. package/routes/widget.js +64 -2
  74. package/services/BotSubscriptionNotifier.js +5 -0
  75. package/services/banUserNotifier.js +86 -0
  76. package/services/cacheEnabler.js +56 -0
  77. package/services/chatbotService.js +101 -0
  78. package/services/departmentService.js +25 -3
  79. package/services/emailService.js +170 -28
  80. package/services/faqBotHandler.js +2 -3
  81. package/services/faqService.js +28 -3
  82. package/services/geoService.js +36 -6
  83. package/services/labelService.js +1 -1
  84. package/services/leadService.js +3 -2
  85. package/services/messageService.js +4 -2
  86. package/services/modulesManager.js +23 -76
  87. package/services/operatingHoursService.js +9 -4
  88. package/services/requestService.js +75 -39
  89. package/services/subscriptionNotifier.js +9 -4
  90. package/services/trainingService.js +106 -0
  91. package/template/email/assignedEmailMessage.html +21 -11
  92. package/template/email/assignedRequest.html +21 -11
  93. package/template/email/beenInvitedExistingUser.html +16 -6
  94. package/template/email/beenInvitedNewUser.html +16 -6
  95. package/template/email/emailDirect.html +130 -0
  96. package/template/email/newMessage.html +18 -8
  97. package/template/email/newMessageFollower.html +22 -12
  98. package/template/email/passwordChanged.html +15 -5
  99. package/template/email/pooledEmailMessage.html +21 -11
  100. package/template/email/pooledRequest.html +20 -10
  101. package/template/email/resetPassword.html +15 -5
  102. package/template/email/sendTranscript.html +7 -4
  103. package/template/email/ticket.html +17 -7
  104. package/template/email/verify.html +15 -5
  105. package/test/cannedRoute.js +157 -0
  106. package/test/chatbot-mock.js +127 -0
  107. package/test/example-json-intents.txt +1 -0
  108. package/test/example-json.txt +1 -0
  109. package/test/example.json +1 -0
  110. package/test/faqRoute.js +353 -208
  111. package/test/faqkbRoute.js +669 -64
  112. package/test/imageRoute.js +1 -1
  113. package/test/messageRoute.js +387 -5
  114. package/test/requestRoute.js +6 -6
  115. package/test/requestService.js +55 -4
  116. package/test-int/cache-project.js +90 -0
  117. package/test-int/cache-project_user.js +88 -0
  118. package/utils/UIDGenerator.js +20 -0
  119. package/utils/cacheUtil.js +2 -2
  120. package/utils/orgUtil.js +3 -3
  121. package/utils/promiseUtil.js +31 -0
  122. package/utils/recipientEmailUtil.js +66 -0
  123. package/utils/sendEmailUtil.js +34 -0
  124. package/utils/sendMessageUtil.js +1 -1
  125. package/utils/stringUtil.js +12 -0
  126. 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('text').notEmpty(),
39
+ check('first_text').notEmpty(),
36
40
  ],
37
- function (req, res) {
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.params.request_id || 'support-group-' + req.projectid + "-" + uuidv4();
70
+ var request_id = req.body.request_id || 'support-group-' + req.projectid + "-" + UIDGenerator.generate();
71
+ winston.debug('request_id: ' + request_id);
62
72
 
63
- // createIfNotExistsWithLeadId(lead_id, fullname, email, id_project, createdBy, attributes) {
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
- // TODO USE NEW .create()
68
- // createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes) {
69
- return requestService.createWithIdAndRequester(request_id, req.projectuser._id, createdLead._id, req.projectid,
70
- req.body.text, req.body.departmentid, req.body.sourcePage,
71
- req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes, req.body.subject).then(function (savedRequest) {
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
- req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata).then(function(savedMessage){
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.info('REQUEST ROUTE - exec time: ' + (endExecTime-startExecTime));
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
- // cacherequest // requestcachefarequi populaterequired
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
- // .cache(cacheUtil.defaultTTL, "/"+req.projectid+"/requests/request_id/"+requestid)
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
- project.widget.poweredBy = undefined;
150
- project.widget.baloonImage = undefined;
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 }