@tiledesk/tiledesk-server 2.4.99 → 2.4.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.4.101
9
+ - Added new route for knowledge base
10
+ - Bug fix: conflicts with old knowledge base
11
+
12
+ # 2.4.100
13
+ - Updated tybot-connector to 0.2.50
14
+ - Added new route for knowledge base
15
+
8
16
  # 2.4.99
9
17
  - Updated whatsapp-connector to 0.1.62
10
18
  - Updated messenger-connector to 0.1.16
package/app.js CHANGED
@@ -81,6 +81,15 @@ mongoose.set('useFindAndModify', false); // https://mongoosejs.com/docs/deprecat
81
81
  mongoose.set('useCreateIndex', true);
82
82
  mongoose.set('useUnifiedTopology', false);
83
83
 
84
+ // CONNECT REDIS - CHECK IT
85
+ const { TdCache } = require('./utils/TdCache');
86
+ let tdCache = new TdCache({
87
+ host: process.env.CACHE_REDIS_HOST,
88
+ port: process.env.CACHE_REDIS_PORT,
89
+ password: process.env.CACHE_REDIS_PASSWORD
90
+ });
91
+
92
+ tdCache.connect();
84
93
 
85
94
  // ROUTES DECLARATION
86
95
  var troubleshooting = require('./routes/troubleshooting');
@@ -113,7 +122,10 @@ var key = require('./routes/key');
113
122
  var widgets = require('./routes/widget');
114
123
  var widgetsLoader = require('./routes/widgetLoader');
115
124
  var openai = require('./routes/openai');
125
+ var quotes = require('./routes/quotes');
126
+ var integration = require('./routes/integration')
116
127
  var kbsettings = require('./routes/kbsettings');
128
+ var kb = require('./routes/kb');
117
129
 
118
130
  // var admin = require('./routes/admin');
119
131
  var faqpub = require('./routes/faqpub');
@@ -157,7 +169,7 @@ botEvent.listen(); //queued but disabled
157
169
 
158
170
  var trainingService = require('./services/trainingService');
159
171
  trainingService.start();
160
-
172
+
161
173
  // job_here
162
174
 
163
175
  var geoService = require('./services/geoService');
@@ -195,6 +207,10 @@ var IPFilter = require('./middleware/ipFilter');
195
207
  var BanUserNotifier = require('./services/banUserNotifier');
196
208
  BanUserNotifier.listen();
197
209
  const { ChatbotService } = require('./services/chatbotService');
210
+ const { QuoteManager } = require('./services/QuoteManager');
211
+
212
+ let qm = new QuoteManager({ tdCache: tdCache });
213
+ qm.start();
198
214
 
199
215
  var modulesManager = undefined;
200
216
  try {
@@ -223,13 +239,13 @@ if (process.env.CREATE_INITIAL_DATA !== "false") {
223
239
 
224
240
  var app = express();
225
241
 
226
-
227
-
228
242
  // view engine setup
229
243
  app.set('views', path.join(__dirname, 'views'));
230
244
  app.set('view engine', 'jade');
231
245
 
232
246
  app.set('chatbot_service', new ChatbotService())
247
+ app.set('redis_client', tdCache);
248
+ app.set('quote_manager', qm);
233
249
 
234
250
 
235
251
  // TODO DELETE IT IN THE NEXT RELEASE
@@ -254,7 +270,6 @@ if (process.env.ENABLE_ALTERNATIVE_CORS_MIDDLEWARE === "true") {
254
270
  // app.use(morgan('combined'));
255
271
 
256
272
 
257
-
258
273
  // app.use(bodyParser.json());
259
274
 
260
275
  // https://stackoverflow.com/questions/18710225/node-js-get-raw-request-body-using-express
@@ -296,6 +311,7 @@ if (process.env.DISABLE_SESSION_STRATEGY==true || process.env.DISABLE_SESSION_S
296
311
 
297
312
  if (process.env.ENABLE_REDIS_SESSION==true || process.env.ENABLE_REDIS_SESSION=="true" ) {
298
313
 
314
+ console.log("Starting redis...") // errors occurs
299
315
  // Initialize client.
300
316
  // let redisClient = createClient()
301
317
  // redisClient.connect().catch(console.error)
@@ -342,6 +358,24 @@ app.options('*', cors());
342
358
  // const customRedisRateLimiter = require("./rateLimiter").customRedisRateLimiter;
343
359
  // app.use(customRedisRateLimiter);
344
360
 
361
+ // MIDDLEWARE FOR REQUESTS QUOTE
362
+ // app.use('/:projectid/requests', function (req, res, next) {
363
+
364
+ // console.log("MIDDLEWARE FIRED ---> REQUESTS");
365
+ // console.log("(Requests Middleware) method: ", req.method);
366
+ // if (req.method === 'POST') {
367
+
368
+ // let quoteManager = new QuoteManager({ project: mockProject, tdCache: mockTdCache } )
369
+
370
+ // } else {
371
+ // next();
372
+ // }
373
+
374
+
375
+ // });
376
+
377
+
378
+
345
379
  if (process.env.ROUTELOGGER_ENABLED==="true") {
346
380
  winston.info("RouterLogger enabled ");
347
381
  app.use(function (req, res, next) {
@@ -385,10 +419,10 @@ if (process.env.ROUTELOGGER_ENABLED==="true") {
385
419
  app.get('/', function (req, res) {
386
420
  res.send('Hello from Tiledesk server. It\'s UP. See the documentation here http://developer.tiledesk.com');
387
421
  });
388
-
389
422
 
390
423
 
391
424
 
425
+
392
426
  var projectIdSetter = function (req, res, next) {
393
427
  var projectid = req.params.projectid;
394
428
  winston.debug("projectIdSetter projectid: "+ projectid);
@@ -438,8 +472,6 @@ var projectSetter = function (req, res, next) {
438
472
  }
439
473
 
440
474
 
441
-
442
-
443
475
  // app.use('/admin', admin);
444
476
 
445
477
  //oauth2
@@ -559,8 +591,14 @@ app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session:
559
591
  app.use('/:projectid/properties',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], property);
560
592
  app.use('/:projectid/segments',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], segment);
561
593
 
562
- app.use('/:projectid/openai', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai);
594
+ // app.use('/:projectid/openai', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai);
595
+ app.use('/:projectid/openai', openai);
596
+ app.use('/:projectid/quotes', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], quotes)
597
+
598
+ app.use('/:projectid/integration', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], integration )
599
+
563
600
  app.use('/:projectid/kbsettings', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], kbsettings);
601
+ app.use('/:projectid/kb', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('admin', ['bot','subscription'])], kb);
564
602
 
565
603
  app.use('/:projectid/logs', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], logs);
566
604
 
@@ -599,7 +637,7 @@ app.use(function (err, req, res, next) {
599
637
 
600
638
 
601
639
 
602
-
640
+ // mettere middleware qui per le quote
603
641
 
604
642
 
605
643
 
@@ -0,0 +1,13 @@
1
+
2
+ const EventEmitter = require('events');
3
+
4
+ class EmailEvent extends EventEmitter {
5
+ constructor() {
6
+ super();
7
+ this.queueEnabled = false;
8
+ }
9
+ }
10
+
11
+ const emailEvent = new EmailEvent();
12
+
13
+ module.exports = emailEvent;
@@ -0,0 +1,13 @@
1
+ const EventEmitter = require('events');
2
+
3
+ let winston = require('../config/winston');
4
+
5
+ class IntegrationEvent extends EventEmitter {
6
+ constructor() {
7
+ super();
8
+ }
9
+ }
10
+
11
+ const integrationEvent = new IntegrationEvent();
12
+
13
+ module.exports = integrationEvent;
@@ -0,0 +1,23 @@
1
+ var mongoose = require('mongoose');
2
+ var Schema = mongoose.Schema;
3
+ var winston = require('../config/winston');
4
+
5
+ var IntegrationsSchema = new Schema({
6
+ id_project: {
7
+ type: String,
8
+ required: true,
9
+ index: true
10
+ },
11
+ name: {
12
+ type: String,
13
+ required: true
14
+ },
15
+ value: {
16
+ type: Object,
17
+ required: true,
18
+ default: {}
19
+ }
20
+ })
21
+
22
+
23
+ module.exports = mongoose.model('integration', IntegrationsSchema);
@@ -3,18 +3,42 @@ var Schema = mongoose.Schema;
3
3
  var winston = require('../config/winston');
4
4
 
5
5
  var KBSchema = new Schema({
6
+ id_project: {
7
+ type: String,
8
+ required: true,
9
+ },
6
10
  name: {
7
11
  type: String,
8
12
  required: true
9
13
  },
10
14
  url: {
11
15
  type: String,
12
- required: true
16
+ required: false
17
+ },
18
+ source: {
19
+ type: String,
20
+ required: false
21
+ },
22
+ type: {
23
+ type: String,
24
+ required: false
25
+ },
26
+ content: {
27
+ type: String,
28
+ required: false
29
+ },
30
+ namespace: {
31
+ type: String,
32
+ required: false
13
33
  },
14
34
  createdAt: {
15
35
  type: Date,
16
36
  default: Date.now,
17
37
  },
38
+ updatedAt: {
39
+ type: Date,
40
+ default: Date.now
41
+ },
18
42
  status: {
19
43
  type: Number,
20
44
  required: false,
@@ -44,5 +68,12 @@ var KBSettingSchema = new Schema({
44
68
  });
45
69
 
46
70
 
47
- module.exports = mongoose.model('KBSettings', KBSettingSchema);
48
- // module.exports = mongoose.model('KB', KBSchema)
71
+ //module.exports = mongoose.model('KBSettings', KBSettingSchema);
72
+ const KBSettings = mongoose.model('KBSettings', KBSettingSchema);
73
+ const KB = mongoose.model('KB', KBSchema)
74
+
75
+ module.exports = {
76
+ KBSettings: KBSettings,
77
+ KB: KB
78
+ }
79
+
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-server",
3
3
  "description": "The Tiledesk server module",
4
- "version": "2.4.99",
4
+ "version": "2.4.101",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -45,7 +45,7 @@
45
45
  "@tiledesk/tiledesk-messenger-connector": "^0.1.15",
46
46
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
47
47
  "@tiledesk/tiledesk-telegram-connector": "^0.1.10",
48
- "@tiledesk/tiledesk-tybot-connector": "^0.2.49",
48
+ "@tiledesk/tiledesk-tybot-connector": "^0.2.50",
49
49
  "@tiledesk/tiledesk-whatsapp-connector": "^0.1.61",
50
50
  "@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.7",
51
51
  "@tiledesk/tiledesk-chatbot-templates": "^0.1.2",
@@ -6,6 +6,7 @@
6
6
  var departmentEvent = require("../../event/departmentEvent");
7
7
  var authEvent = require("../../event/authEvent");
8
8
  var labelEvent = require("../../event/labelEvent");
9
+ var integrationEvent = require("../../event/integrationEvent");
9
10
 
10
11
  var triggerEventEmitter = require("../trigger/event/triggerEventEmitter");
11
12
  var subscriptionEvent = require("../../event/subscriptionEvent");
@@ -725,6 +726,17 @@
725
726
  });
726
727
  });
727
728
 
729
+ // l'evento è relativo a tutte le integrazioni, è sufficiente solo un evento
730
+ // per create, update, delete di una singola creation
731
+ integrationEvent.on("integration.update", (integrations, id_project) => {
732
+ let key = "project:" + id_project + ":integrations";
733
+ winston.verbose("Creating cache for integration.create with key: " + key);
734
+ client.set(key, integrations, cacheUtil.longTTL, (err, reply) => {
735
+ winston.verbose("Created cache for integration.create", {err: err} );
736
+ winston.debug("Created cache for integration.create reply", reply);
737
+ })
738
+ })
739
+
728
740
  // fai cache per subscription.create, .update .delete
729
741
 
730
742
 
@@ -118,6 +118,7 @@ listen() {
118
118
  // send an email only if offline and has an email (send also to followers)
119
119
  return that.sendUserEmail(message.id_project, message);
120
120
  } else { //send email to followers
121
+ winston.debug("send direct email****");
121
122
 
122
123
  that.sendToFollower(message.id_project, message);
123
124
 
package/routes/auth.js CHANGED
@@ -296,12 +296,14 @@ router.post('/signinWithCustomToken', [
296
296
 
297
297
  var newUser;
298
298
  try {
299
- newUser = await userService.signup(req.user.email, uuidv4(), req.user.firstname, req.user.lastname, false);
299
+
300
+ // Bug with email in camelcase
301
+ newUser = await userService.signup(req.user.email.toLowerCase(), uuidv4(), req.user.firstname, req.user.lastname, false);
300
302
  } catch(e) {
301
303
  winston.debug('error signup already exists??: ')
302
304
 
303
305
  if (e.code = "E11000") {
304
- newUser = await User.findOne({email: req.user.email , status: 100}).exec();
306
+ newUser = await User.findOne({email: req.user.email.toLowerCase(), status: 100}).exec();
305
307
  winston.debug('signup found')
306
308
 
307
309
  }
@@ -373,7 +375,11 @@ router.post('/signinWithCustomToken', [
373
375
 
374
376
  }
375
377
 
376
- return res.json({ success: true, token: 'JWT ' + returnToken, user: userToReturn });
378
+ if (returnToken.indexOf("JWT")==0) {
379
+ returnToken = "JWT " + returnToken;
380
+ }
381
+
382
+ return res.json({ success: true, token: returnToken, user: userToReturn });
377
383
  });
378
384
  } else {
379
385
  winston.debug('project user already exists ');
@@ -381,7 +387,7 @@ router.post('/signinWithCustomToken', [
381
387
  if (project_user.status==="active") {
382
388
 
383
389
  if (req.user.role && (req.user.role === RoleConstants.OWNER || req.user.role === RoleConstants.ADMIN || req.user.role === RoleConstants.AGENT)) {
384
- let userFromDB = await User.findOne({email: req.user.email , status: 100}).exec();
390
+ let userFromDB = await User.findOne({email: req.user.email.toLowerCase(), status: 100}).exec();
385
391
 
386
392
  var signOptions = {
387
393
  issuer: 'https://tiledesk.com',
@@ -402,7 +408,10 @@ router.post('/signinWithCustomToken', [
402
408
  let returnToken = jwt.sign(userJson, configSecret, signOptions); //priv_jwt pp_jwt
403
409
 
404
410
 
405
- return res.json({ success: true, token: "JWT " + returnToken, user: userFromDB });
411
+ if (returnToken.indexOf("JWT")==0) {
412
+ returnToken = "JWT " + returnToken;
413
+ }
414
+ return res.json({ success: true, token: returnToken, user: userFromDB });
406
415
  // return res.json({ success: true, token: req.headers["authorization"], user: userFromDB });
407
416
 
408
417
 
package/routes/email.js CHANGED
@@ -327,8 +327,10 @@ router.post('/internal/send',
327
327
 
328
328
  winston.info("Sending an email with text : " + text + " to " + to);
329
329
 
330
- //sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage, payload)
331
- emailService.sendEmailDirect(newto, text, req.project, request_id, subject, undefined, undefined, undefined, replyto);
330
+ let quoteManager = req.app.get('quote_manager');
331
+
332
+ //sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage, payload)
333
+ emailService.sendEmailDirect(newto, text, req.project, request_id, subject, undefined, undefined, undefined, replyto, quoteManager);
332
334
 
333
335
  res.json({"queued": true});
334
336
 
package/routes/faq.js CHANGED
@@ -467,6 +467,7 @@ router.put('/:faqid', function (req, res) {
467
467
  // DELETE REMOTE AND LOCAL FAQ
468
468
  router.delete('/:faqid', function (req, res) {
469
469
 
470
+ console.log("delete called")
470
471
  winston.debug('DELETE FAQ - FAQ ID ', req.params.faqid);
471
472
 
472
473
  let faqid = req.params.faqid;
@@ -0,0 +1,199 @@
1
+ let express = require('express');
2
+ let router = express.Router();
3
+ var winston = require('../config/winston');
4
+ let Integration = require('../models/integrations');
5
+ const cacheEnabler = require('../services/cacheEnabler');
6
+ var cacheUtil = require('../utils/cacheUtil');
7
+ const integrationEvent = require('../event/integrationEvent');
8
+
9
+
10
+ // Get all integration for a project id
11
+ router.get('/', async (req, res) => {
12
+
13
+ let id_project = req.projectid;
14
+ winston.debug("Get all integration for the project " + id_project);
15
+
16
+ let i = Integration.find({ id_project: id_project });
17
+ if (cacheEnabler.integrations) {
18
+ // cacheUtil.longTTL is 1 hour (default), evaluate 1 month (2592000 s)
19
+ i.cache(cacheUtil.longTTL, "project:" + id_project + ":integrations");
20
+ winston.debug('integration cache enabled for get all integrations');
21
+ }
22
+ i.exec((err, integrations) => {
23
+ if (err) {
24
+ winston.error("Error getting integrations: ", err);
25
+ return res.status(500).send({ success: false, message: "Error getting integrations "});
26
+ }
27
+ res.status(200).send(integrations);
28
+ })
29
+ // without cache
30
+ // Integration.find({ id_project: id_project }, (err, integrations) => {
31
+ // if (err) {
32
+ // console.error("Error finding all integrations for the project " + id_project + " - err: " + err);
33
+ // return res.status(404).send({ success: false, err: err })
34
+ // }
35
+ // console.log("Integrations found: ", integrations);
36
+ // res.status(200).send(integrations);
37
+ // })
38
+ })
39
+
40
+ // Get one integration
41
+ router.get('/:integration_id', async (req, res) => {
42
+
43
+ let integration_id = req.params.integration_id;
44
+ winston.debug("Get integration with id " + integration_id);
45
+
46
+ Integration.findById(integration_id, (err, integration) => {
47
+ if (err) {
48
+ winston.error("Error find integration by id: ", err);
49
+ return res.status(404).send({ success: false, err: err });
50
+ }
51
+ res.status(200).send(integration);
52
+ })
53
+
54
+ })
55
+
56
+ router.get('/name/:integration_name', async (req, res) => {
57
+
58
+ let id_project = req.projectid;
59
+ winston.debug("Get all integration for the project " + id_project);
60
+
61
+ let integration_name = req.params.integration_name;
62
+ winston.debug("Get integration with id " + integration_name);
63
+
64
+ Integration.findOne({ id_project: id_project, name: integration_name }, (err, integration) => {
65
+ if (err) {
66
+ winston.error("Error find integration by name: ", err);
67
+ return res.status(404).send({ success: false, err: err });
68
+ }
69
+
70
+ if (!integration) {
71
+ winston.debug("Integration not found");
72
+ return res.status(200).send("Integration not found");
73
+ }
74
+
75
+ res.status(200).send(integration);
76
+ })
77
+ })
78
+
79
+ // Add new integration
80
+ router.post('/', async (req, res) => {
81
+
82
+ let id_project = req.projectid;
83
+ winston.debug("Add new integration ", req.body);
84
+
85
+
86
+ let newIntegration = {
87
+ id_project: id_project,
88
+ name: req.body.name
89
+ }
90
+ if (req.body.value) {
91
+ newIntegration.value = req.body.value;
92
+ }
93
+
94
+ Integration.findOneAndUpdate({ id_project: id_project, name: req.body.name }, newIntegration, { new: true, upsert: true, setDefaultsOnInsert: false}, (err, savedIntegration) => {
95
+ if (err) {
96
+ winston.error("Error creating new integration ", err);
97
+ return res.status(404).send({ success: false, err: err })
98
+ }
99
+
100
+ winston.debug("New integration created: ", savedIntegration);
101
+
102
+ Integration.find({ id_project: id_project }, (err, integrations) => {
103
+ if (err) {
104
+ winston.error("Error getting all integrations");
105
+ } else {
106
+ integrationEvent.emit('integration.update', integrations, id_project);
107
+ }
108
+ })
109
+
110
+ res.status(200).send(savedIntegration);
111
+ })
112
+
113
+ // let newIntegration = new Integration({
114
+ // id_project: id_project,
115
+ // name: req.body.name,
116
+ // value: req.body.value
117
+ // })
118
+
119
+ // newIntegration.save((err, savedIntegration) => {
120
+ // if (err) {
121
+ // console.error("Error creating new integration ", err);
122
+ // return res.status(404).send({ success: false, err: err })
123
+ // }
124
+
125
+ // console.log("New integration created: ", savedIntegration);
126
+
127
+ // Integration.find({ id_project: id_project }, (err, integrations) => {
128
+ // if (err) {
129
+ // console.error("Error getting all integrations");
130
+ // } else {
131
+ // console.log("emit integration.create event")
132
+ // integrationEvent.emit('integration.create', integrations, id_project);
133
+ // }
134
+
135
+ // })
136
+
137
+ // res.status(200).send(savedIntegration);
138
+
139
+ // })
140
+
141
+ })
142
+
143
+ router.put('/:integration_id', async (req, res) => {
144
+
145
+ let id_project = req.projectid;
146
+ let integration_id = req.params.integration_id;
147
+
148
+ let update = {};
149
+ if (req.body.name != undefined) {
150
+ update.name = req.body.name;
151
+ }
152
+ if (req.body.value != undefined) {
153
+ update.value = req.body.value
154
+ }
155
+
156
+ Integration.findByIdAndUpdate(integration_id, update, { new: true, upsert: true }, (err, savedIntegration) => {
157
+ if (err) {
158
+ winston.error("Error find by id and update integration: ", err);
159
+ return res.status({ success: false, error: err })
160
+ }
161
+
162
+ Integration.find({ id_project: id_project }, (err, integrations) => {
163
+ if (err) {
164
+ winston.error("Error getting all integrations");
165
+ } else {
166
+ integrationEvent.emit('integration.update', integrations, id_project);
167
+ }
168
+ })
169
+
170
+ res.status(200).send(savedIntegration);
171
+ })
172
+ })
173
+
174
+ router.delete('/:integration_id', async (req, res) => {
175
+
176
+ let id_project = req.projectid;
177
+ let integration_id = req.params.integration_id;
178
+
179
+ Integration.findByIdAndDelete(integration_id, (err, result) => {
180
+ if (err) {
181
+ winston.error("Error find by id and delete integration: ", err);
182
+ return res.status({ success: false, error: err })
183
+ }
184
+
185
+ Integration.find({ id_project: id_project }, (err, integrations) => {
186
+ if (err) {
187
+ winston.error("Error getting all integrations");
188
+ } else {
189
+ integrationEvent.emit('integration.update', integrations, id_project);
190
+ }
191
+ })
192
+
193
+ res.status(200).send({ success: true, messages: "Integration deleted successfully"});
194
+
195
+ })
196
+ })
197
+
198
+
199
+ module.exports = router;