@tiledesk/tiledesk-server 2.2.14 → 2.2.15

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
@@ -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