@tiledesk/tiledesk-server 2.2.14 → 2.2.15

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ # 2.2.15
2
+
3
+ - Added catch messageService.send for bot
4
+ - Added external searcher for bot( ex. Rasa proxy)
5
+ - Faq language fix taken from bot language for create single and import from csv
6
+ - Lower case reset password fix
7
+ - Added alias /bots for /faq_kb AGGIORNA DOC
8
+
9
+ # 2.2.14
10
+ - Fix Tiledesk Queue 1.1.11 with authEvent.queueEnabled = true
11
+
1
12
  # 2.2.13
2
13
  - Send message validation with empty text
3
14
 
package/app.js CHANGED
@@ -341,7 +341,8 @@ app.use('/:projectid/faqpub', faqpub);
341
341
 
342
342
  //deprecated
343
343
  app.use('/:projectid/faq_kb', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq_kb);
344
- app.use('/:projectid/bot', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq_kb);
344
+ // aggiorna doc
345
+ app.use('/:projectid/bots', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], faq_kb);
345
346
 
346
347
 
347
348
 
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.2.14",
4
+ "version": "2.2.15",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -0,0 +1,10 @@
1
+ {
2
+ "text": "question",
3
+ "intent": { "name": "brutteparole", "confidence": 0.9257488250732422 },
4
+ "entities": [],
5
+ "text_tokens": [ [ 0, 8 ] ],
6
+ "intent_ranking": [
7
+ { "name": "brutteparole", "confidence": 0.9257488250732422 },
8
+ { "name": "eta", "confidence": 0.0742512047290802 }
9
+ ]
10
+ }
package/routes/auth.js CHANGED
@@ -476,8 +476,12 @@ router.get('/pendinginvitationsnoauth/:pendinginvitationid', function (req, res)
476
476
  router.put('/requestresetpsw', function (req, res) {
477
477
 
478
478
  winston.debug('REQUEST RESET PSW - EMAIL REQ BODY ', req.body);
479
+
480
+ var email = req.body.email.toLowerCase();
481
+ winston.debug("email", email);
482
+
479
483
  // auttype
480
- User.findOne({ email: req.body.email, status: 100
484
+ User.findOne({ email: email, status: 100
481
485
  // , authType: 'email_password'
482
486
  }, function (err, user) {
483
487
  if (err) {
package/routes/faq.js CHANGED
@@ -1,6 +1,7 @@
1
1
  var express = require('express');
2
2
  var router = express.Router();
3
3
  var Faq = require("../models/faq");
4
+ var Faq_kb = require("../models/faq_kb");
4
5
  var multer = require('multer')
5
6
  var upload = multer()
6
7
  const faqBotEvent = require('../event/faqBotEvent');
@@ -31,6 +32,16 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
31
32
  // PARSE CSV
32
33
 
33
34
 
35
+
36
+ Faq_kb.findById(id_faq_kb).exec(function(err, faq_kb) {
37
+ if (err) {
38
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
39
+ }
40
+ if (!faq_kb) {
41
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
42
+ }
43
+ winston.debug('faq_kb ', faq_kb.toJSON());
44
+
34
45
  // getFaqKbKeyById(req.body.id_faq_kb, function (remote_faqkb_key) {
35
46
 
36
47
  parsecsv.parseString(csv, { headers: false, delimiter: delimiter })
@@ -57,6 +68,7 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
57
68
  intent_id:intent_id,
58
69
  intent_display_name: intent_display_name,
59
70
  webhook_enabled: webhook_enabled_boolean,
71
+ language: faq_kb.language,
60
72
  id_project: req.projectid,
61
73
  createdBy: req.user.id,
62
74
  updatedBy: req.user.id
@@ -81,45 +93,56 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
81
93
  winston.error("PARSE ERROR uploadcsv", err);
82
94
  res.json({ success: false, msg: 'Parsing error' });
83
95
  });
84
- // });
96
+ });
85
97
  });
86
98
 
87
99
 
88
100
  router.post('/', function (req, res) {
89
101
 
90
102
  winston.debug(req.body);
91
- var newFaq = new Faq({
92
- id_faq_kb: req.body.id_faq_kb,
93
- question: req.body.question,
94
- answer: req.body.answer,
95
- id_project: req.projectid,
96
- topic: req.body.topic,
97
- webhook_enabled: req.body.webhook_enabled,
98
- intent_display_name: req.body.intent_display_name,
99
- createdBy: req.user.id,
100
- updatedBy: req.user.id
101
- });
102
103
 
103
- newFaq.save(function (err, savedFaq) {
104
+ Faq_kb.findById(req.body.id_faq_kb).exec(function(err, faq_kb) {
104
105
  if (err) {
105
- if (err.code == 11000) {
106
- return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
107
- } else {
108
- winston.debug('--- > ERROR ', err)
109
- return res.status(500).send({ success: false, msg: 'Error saving object.' });
110
- }
106
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
111
107
  }
112
- winston.debug('1. ID OF THE NEW FAQ CREATED ', savedFaq._id)
113
- winston.debug('1. QUESTION OF THE NEW FAQ CREATED ', savedFaq.question)
114
- winston.debug('1. ANSWER OF THE NEW FAQ CREATED ', savedFaq.answer)
115
- winston.debug('1. ID FAQKB GET IN THE OBJECT OF NEW FAQ CREATED ', savedFaq.id_faq_kb);
108
+ if (!faq_kb) {
109
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
110
+ }
111
+ winston.debug('faq_kb ', faq_kb.toJSON());
112
+
113
+ var newFaq = new Faq({
114
+ id_faq_kb: req.body.id_faq_kb,
115
+ question: req.body.question,
116
+ answer: req.body.answer,
117
+ id_project: req.projectid,
118
+ topic: req.body.topic,
119
+ language: faq_kb.language,
120
+ webhook_enabled: req.body.webhook_enabled,
121
+ intent_display_name: req.body.intent_display_name,
122
+ createdBy: req.user.id,
123
+ updatedBy: req.user.id
124
+ });
116
125
 
117
- faqBotEvent.emit('faq.create', savedFaq);
126
+ newFaq.save(function (err, savedFaq) {
127
+ if (err) {
128
+ if (err.code == 11000) {
129
+ return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
130
+ } else {
131
+ winston.debug('--- > ERROR ', err)
132
+ return res.status(500).send({ success: false, msg: 'Error saving object.' });
133
+ }
134
+ }
135
+ winston.debug('1. ID OF THE NEW FAQ CREATED ', savedFaq._id)
136
+ winston.debug('1. QUESTION OF THE NEW FAQ CREATED ', savedFaq.question)
137
+ winston.debug('1. ANSWER OF THE NEW FAQ CREATED ', savedFaq.answer)
138
+ winston.debug('1. ID FAQKB GET IN THE OBJECT OF NEW FAQ CREATED ', savedFaq.id_faq_kb);
118
139
 
119
- res.json(savedFaq);
140
+ faqBotEvent.emit('faq.create', savedFaq);
120
141
 
121
-
142
+ res.json(savedFaq);
122
143
 
144
+
145
+ });
123
146
  });
124
147
  });
125
148
 
package/routes/faq_kb.js CHANGED
@@ -6,8 +6,10 @@ var Department = require("../models/department");
6
6
  var faqService = require("../services/faqService");
7
7
  const botEvent = require('../event/botEvent');
8
8
  var winston = require('../config/winston');
9
+ var httpUtil = require("../utils/httpUtil");
9
10
 
10
11
  router.post('/', function (req, res) {
12
+ winston.info('create BOT ', req.body);
11
13
  // create(name, url, projectid, user_id, type, description) {
12
14
  faqService.create(req.body.name, req.body.url, req.projectid, req.user.id, req.body.type, req.body.description, undefined, undefined,
13
15
  req.body.language).then(function(savedFaq_kb) {
@@ -18,6 +20,106 @@ router.post('/', function (req, res) {
18
20
  });
19
21
 
20
22
 
23
+ router.post('/train', function (req, res) {
24
+
25
+ winston.info('train BOT ', req.body);
26
+
27
+ Faq_kb.findById(req.body.id_faq_kb).exec(function(err, faq_kb) {
28
+ if (err) {
29
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
30
+ }
31
+ if (!faq_kb) {
32
+ return res.status(404).send({ success: false, msg: 'Object not found.' });
33
+ }
34
+ winston.debug('faq_kb ', faq_kb.toJSON());
35
+
36
+ winston.debug('faq_kb.type :'+ faq_kb.type);
37
+ if (faq_kb.type =="internal" && faq_kb.url) {
38
+
39
+
40
+
41
+ var train = {
42
+ language:faq_kb.language,
43
+ nlu:[]
44
+ };
45
+ winston.info("train", train);
46
+
47
+
48
+ var query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb};
49
+
50
+ Faq.find(query)
51
+ .limit(10000)
52
+ .lean().
53
+ exec(async (err, faqs) => {
54
+ if (err) {
55
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
56
+ }
57
+ if (faqs && faqs.length>0) {
58
+ winston.info("faqs exact", faqs);
59
+
60
+ faqs.forEach(function(f) {
61
+ var intent = {
62
+ intent:f.intent_display_name,
63
+ examples:[]
64
+ }
65
+ var questions = f.question.split("\n");
66
+ winston.info("questions", questions);
67
+
68
+ questions.forEach(function(q) {
69
+ winston.info("q", q);
70
+ intent.examples.push(q);
71
+ });
72
+ winston.info("intent", intent);
73
+ train.nlu.push(intent);
74
+ });
75
+ winston.info("train", train);
76
+
77
+ try {
78
+ var trainHttp = await httpUtil.call(faq_kb.url+"/trainandload", undefined, train, "POST");
79
+ }catch(e) {
80
+ winston.error("error training", e);
81
+ }
82
+
83
+
84
+ return res.json({train:train, httpResponse:trainHttp});
85
+ // return res.json(trainHttp);
86
+ }else {
87
+ return res.status(400).send({ success: false, msg: 'no faq to train on external bot.' });
88
+ }
89
+ });
90
+ } else {
91
+ winston.debug('external query: ');
92
+ return res.status(400).send({ success: false, msg: 'you can train a standard internal bot or an external bot.' });
93
+ }
94
+
95
+ });
96
+
97
+ /*
98
+ {
99
+ "language":"it",
100
+ "nlu":[
101
+ {
102
+ "intent":"eta",
103
+ "examples":[
104
+ "quanti anni hai",
105
+ "dimmi la tua età",
106
+ "quanto sei grande",
107
+ "parlami della tua età"
108
+ ]
109
+ },
110
+ {
111
+ "intent":"brutteparole",
112
+ "examples":[
113
+ "non dire parolacce",
114
+ "le brutte parole non dovrebbero dirsi"
115
+ ]
116
+ }
117
+ ]
118
+ }
119
+ */
120
+
121
+ });
122
+
21
123
 
22
124
  router.post('/askbot', function (req, res) {
23
125
 
@@ -12,6 +12,10 @@ var eventService = require('../pubmodules/events/eventService');
12
12
  var mongoose = require('mongoose');
13
13
  const { TiledeskChatbotUtil } = require('@tiledesk/tiledesk-chatbot-util');
14
14
  const ActionsConstants = require('../models/actionsConstants');
15
+ var httpUtil = require('../utils/httpUtil');
16
+
17
+ var webhook_origin = process.env.WEBHOOK_ORIGIN || "http://localhost:3000";
18
+ winston.debug("webhook_origin: "+webhook_origin);
15
19
 
16
20
  class FaqBotHandler {
17
21
 
@@ -137,7 +141,7 @@ class FaqBotHandler {
137
141
 
138
142
  Faq.find(query)
139
143
  .lean().
140
- exec(function (err, faqs) {
144
+ exec(async (err, faqs) => {
141
145
  if (err) {
142
146
  return winston.error("Error getting faq object.",err);
143
147
  }
@@ -209,7 +213,13 @@ class FaqBotHandler {
209
213
  messageService.send(sender, botName, message.recipient, command_parsed.command,
210
214
  message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
211
215
  winston.debug("agent_handoff faqs agent sent ", savedMessage.toObject());
212
- });
216
+ }).catch(function(err){
217
+ winston.log({
218
+ level: 'error',
219
+ message: 'Error sending message bot: '+ JSON.stringify(err) ,
220
+ label: message.id_project
221
+ });
222
+ });
213
223
  // PATCH: Chat clients (i.e. web widget) remove messages with text = null
214
224
  // command_parsed.text contains the eventual text before the \agent command
215
225
  // or 'all the message text' if \agent was not found
@@ -224,7 +234,13 @@ class FaqBotHandler {
224
234
  messageService.send(sender, botName, message.recipient, bot_answer.text,
225
235
  message.id_project, sender, attr, bot_answer.type, bot_answer.metadata, bot_answer.language).then(function(savedMessage){
226
236
  winston.debug("faqbot message botAns ", savedMessage.toObject());
227
- });
237
+ }).catch(function(err){
238
+ winston.log({
239
+ level: 'error',
240
+ message: 'Error sending message bot: '+ JSON.stringify(err) ,
241
+ label: message.id_project
242
+ });
243
+ });
228
244
  // }
229
245
 
230
246
 
@@ -238,20 +254,57 @@ class FaqBotHandler {
238
254
 
239
255
  } else {
240
256
 
257
+
241
258
  query = { "id_project": message.id_project, "id_faq_kb": faq_kb._id};
242
-
243
- var search_obj = {"$search": message.text};
259
+ var mongoproject = undefined;
260
+ var sort = undefined;
244
261
 
245
- if (faq_kb.language) {
246
- search_obj["$language"] = faq_kb.language;
247
- }
248
- query.$text = search_obj;
249
- winston.debug("fulltext search query", query);
262
+ //make http request external
263
+ if (faq_kb.url) {
264
+
265
+
266
+ var url = faq_kb.url+"/parse";
267
+ winston.verbose("fulltext search external url " + url);
250
268
 
251
- Faq.find(query, {score: { $meta: "textScore" } })
252
- .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
269
+ var json = {text: message.text, language: faq_kb.language, id_project: message.id_project, id_faq_kb: faq_kb._id};
270
+ winston.verbose("fulltext search external json", json);
271
+
272
+ var headers = {
273
+ 'Content-Type' : 'application/json',
274
+ 'User-Agent': 'tiledesk-bot',
275
+ 'Origin': webhook_origin
276
+ };
277
+
278
+ var res = await httpUtil.call(url, headers, json, "POST")
279
+ winston.verbose("res", res);
280
+
281
+ if (res && res.intent && res.intent.name) {
282
+ var intent_name = res.intent.name;
283
+ winston.verbose("intent_name", intent_name);
284
+ //filtra su intent name
285
+ query.intent_display_name = intent_name;
286
+ winston.info("query",query);
287
+
288
+ }
289
+ } else {
290
+
291
+ var search_obj = {"$search": message.text};
292
+
293
+ if (faq_kb.language) {
294
+ search_obj["$language"] = faq_kb.language;
295
+ }
296
+ query.$text = search_obj;
297
+ winston.info("fulltext search query", query);
298
+
299
+ mongoproject = {score: { $meta: "textScore" } };
300
+ sort = { score: { $meta: "textScore" } } //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
301
+ }
302
+
303
+
304
+ Faq.find(query, mongoproject)
305
+ .sort(sort)
253
306
  .lean().
254
- exec(function (err, faqs) {
307
+ exec(async (err, faqs) => {
255
308
  if (err) {
256
309
  return winston.error('Error getting fulltext objects.', err);
257
310
  }
@@ -266,6 +319,53 @@ class FaqBotHandler {
266
319
  if (faqs && faqs.length>0 && faqs[0].answer) {
267
320
  answerObj = faqs[0];
268
321
 
322
+
323
+ // non fare la ricerca fulltext
324
+ //make http request external
325
+ /*
326
+ if (faq_kb.url) {
327
+
328
+
329
+ var url = faq_kb.url+"/parse";
330
+ winston.verbose("fulltext search external url " + url);
331
+
332
+ var json = {text: message.text, language: faq_kb.language, id_project: message.id_project, id_faq_kb: faq_kb._id};
333
+ winston.verbose("fulltext search external json", json);
334
+
335
+ var headers = {
336
+ 'Content-Type' : 'application/json',
337
+ 'User-Agent': 'tiledesk-bot',
338
+ 'Origin': webhook_origin
339
+ };
340
+
341
+ var res = await httpUtil.call(url, headers, json, "POST")
342
+ console.log("res", res);
343
+
344
+ if (res && res.intent && res.intent.name) {
345
+ var intent_name = res.intent.name;
346
+ console.log("intent_name", intent_name);
347
+ //filtra su intent name
348
+ var queryExternal = { id_project: message.id_project, id_faq_kb: faq_kb._id, intent_display_name: intent_name};
349
+ winston.verbose("queryExternal",queryExternal);
350
+
351
+ var faqExternal = await Faq.findOne(queryExternal)
352
+ .lean().
353
+ exec();
354
+
355
+ winston.verbose("faqExternal",faqExternal);
356
+
357
+ if (faqExternal) {
358
+ answerObj = faqExternal;
359
+ }
360
+
361
+ }
362
+ }
363
+ */
364
+
365
+
366
+
367
+
368
+
269
369
  // qui
270
370
  faqBotSupport.getParsedMessage(answerObj.answer, message, faq_kb, answerObj).then(function(bot_answer) {
271
371
 
@@ -315,7 +415,14 @@ class FaqBotHandler {
315
415
  messageService.send(sender, botName, message.recipient, command_parsed.command,
316
416
  message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
317
417
  winston.debug("agent_handoff faqs agent sent ", savedMessage.toObject());
318
- });
418
+ }).catch(function(err){
419
+ winston.log({
420
+ level: 'error',
421
+ message: 'Error sending message bot: '+ JSON.stringify(err) ,
422
+ label: message.id_project
423
+ });
424
+ });
425
+
319
426
  // PATCH: Chat clients (i.e. web widget) remove messages with text = null
320
427
  // command_parsed.text contains the eventual text before the \agent command
321
428
  // or 'all the message text' if \agent was not found
@@ -330,7 +437,13 @@ class FaqBotHandler {
330
437
  message.id_project, sender, attr, bot_answer.type, bot_answer.metadata, bot_answer.language).then(function(savedMessage){
331
438
 
332
439
  winston.debug("faqbot message sending ", savedMessage.toObject());
333
- });
440
+ }).catch(function(err){
441
+ winston.log({
442
+ level: 'error',
443
+ message: 'Error sending message bot: '+ JSON.stringify(err) ,
444
+ label: message.id_project
445
+ });
446
+ });
334
447
  });
335
448
 
336
449
 
@@ -408,7 +521,13 @@ class FaqBotHandler {
408
521
  messageService.send(sender, botName, message.recipient, command_parsed.command,
409
522
  message.id_project, sender, {subtype: "info"}, 'text', undefined).then(function(savedMessage){
410
523
  winston.debug("agent_handoff faqs agent sent ", savedMessage.toObject());
411
- });
524
+ }).catch(function(err){
525
+ winston.log({
526
+ level: 'error',
527
+ message: 'Error sending message bot: '+ JSON.stringify(err) ,
528
+ label: message.id_project
529
+ });
530
+ });
412
531
  // PATCH: Chat clients (i.e. web widget) remove messages with text = null
413
532
  // command_parsed.text contains the eventual text before the \agent command
414
533
  // or 'all the message text' if \agent was not found
@@ -423,6 +542,13 @@ class FaqBotHandler {
423
542
  messageService.send(sender, botName, message.recipient, botAns.text,
424
543
  message.id_project, sender, attr, botAns.type, botAns.metadata, botAns.language).then(function(savedMessage){
425
544
  winston.debug("faqbot message botAns " ,savedMessage.toObject());
545
+ })
546
+ .catch(function(err){
547
+ winston.log({
548
+ level: 'error',
549
+ message: 'Error sending message bot: '+ JSON.stringify(err) + " " + JSON.stringify(botAns.text) ,
550
+ label: message.id_project
551
+ });
426
552
  });
427
553
  }
428
554