@tiledesk/tiledesk-server 2.4.52 → 2.4.53

Sign up to get free protection for your applications and to get access to all the features.
package/app.js CHANGED
@@ -112,7 +112,7 @@ var jwtroute = require('./routes/jwt');
112
112
  var key = require('./routes/key');
113
113
  var widgets = require('./routes/widget');
114
114
  var widgetsLoader = require('./routes/widgetLoader');
115
- var openai_kbs = require('./routes/openai_kbs');
115
+ var openai = require('./routes/openai');
116
116
  var kbsettings = require('./routes/kbsettings');
117
117
 
118
118
  // var admin = require('./routes/admin');
@@ -551,7 +551,7 @@ app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session:
551
551
 
552
552
  app.use('/:projectid/properties',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], property);
553
553
 
554
- app.use('/:projectid/openai_kbs', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai_kbs);
554
+ app.use('/:projectid/openai', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai);
555
555
  app.use('/:projectid/kbsettings', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], kbsettings);
556
556
 
557
557
 
package/models/faq.js CHANGED
@@ -7,6 +7,12 @@ const uuidv4 = require('uuid/v4');
7
7
  var defaultFullTextLanguage = process.env.DEFAULT_FULLTEXT_INDEX_LANGUAGE || "none";
8
8
 
9
9
  var FaqSchema = new Schema({
10
+ _id: {
11
+ type: mongoose.Schema.Types.ObjectId,
12
+ index: true,
13
+ required: true,
14
+ auto: true,
15
+ },
10
16
  id_faq_kb: {
11
17
  type: String,
12
18
  index: true
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.52",
4
+ "version": "2.4.53",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -44,7 +44,7 @@
44
44
  "@tiledesk/tiledesk-kaleyra-proxy": "^0.1.7",
45
45
  "@tiledesk/tiledesk-messenger-connector": "0.1.9",
46
46
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
47
- "@tiledesk/tiledesk-tybot-connector": "^0.1.93",
47
+ "@tiledesk/tiledesk-tybot-connector": "^0.1.94",
48
48
  "@tiledesk/tiledesk-whatsapp-connector": "^0.1.51",
49
49
  "amqplib": "^0.5.5",
50
50
  "app-root-path": "^3.0.0",
package/routes/faq.js CHANGED
@@ -147,6 +147,7 @@ router.post('/', function (req, res) {
147
147
  winston.debug('faq_kb ', faq_kb.toJSON());
148
148
 
149
149
  var newFaq = new Faq({
150
+ _id: req.body._id,
150
151
  id_faq_kb: req.body.id_faq_kb,
151
152
  question: req.body.question,
152
153
  answer: req.body.answer,
@@ -203,6 +204,8 @@ router.patch('/:faqid/attributes', function (req, res) {
203
204
  let data = req.body;
204
205
  winston.debug("data: ", data);
205
206
 
207
+ // aggiugnere controllo su intent_id qui
208
+
206
209
  Faq.findById(req.params.faqid, function (err, updatedFaq) {
207
210
  if (err) {
208
211
  winston.error('Find Faq by id ERROR: ', err);
@@ -253,6 +256,7 @@ router.patch('/:faqid/attributes', function (req, res) {
253
256
  router.put('/:faqid', function (req, res) {
254
257
 
255
258
  winston.debug('UPDATE FAQ ', req.body);
259
+ let faqid = req.params.faqid;
256
260
 
257
261
  var update = {};
258
262
 
@@ -296,45 +300,84 @@ router.put('/:faqid', function (req, res) {
296
300
  update.attributes = req.body.attributes;
297
301
  }
298
302
 
299
- Faq.findByIdAndUpdate(req.params.faqid, update, { new: true, upsert: true }, function (err, updatedFaq) {
300
- if (err) {
301
- if (err.code == 11000) {
302
- return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
303
- } else {
304
- return res.status(500).send({ success: false, msg: 'Error updating object.' });
303
+ if (faqid.startsWith("intentId")) {
304
+ let intent_id = faqid.substring(8);
305
+ Faq.findOneAndUpdate({ intent_id: intent_id }, update, { new: true, upsert: true}, (err, updatedFaq) => {
306
+ if (err) {
307
+ if (err.code == 11000) {
308
+ return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
309
+ } else {
310
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
311
+ }
305
312
  }
306
- }
307
313
 
308
- faqBotEvent.emit('faq.update', updatedFaq);
309
- faqBotEvent.emit('faq_train.update', updatedFaq.id_faq_kb);
314
+ faqBotEvent.emit('faq.update', updatedFaq);
315
+ faqBotEvent.emit('faq_train.update', updatedFaq.id_faq_kb);
316
+
317
+ res.status(200).send(updatedFaq);
318
+ })
310
319
 
311
- res.json(updatedFaq);
320
+ } else {
321
+ Faq.findByIdAndUpdate(req.params.faqid, update, { new: true, upsert: true }, function (err, updatedFaq) {
322
+ if (err) {
323
+ if (err.code == 11000) {
324
+ return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
325
+ } else {
326
+ return res.status(500).send({ success: false, msg: 'Error updating object.' });
327
+ }
328
+ }
329
+
330
+ faqBotEvent.emit('faq.update', updatedFaq);
331
+ faqBotEvent.emit('faq_train.update', updatedFaq.id_faq_kb);
332
+
333
+ res.status(200).send(updatedFaq);
334
+ // updateRemoteFaq(updatedFaq)
335
+ });
336
+ }
312
337
 
313
- // updateRemoteFaq(updatedFaq)
314
- });
315
338
  });
316
339
 
317
340
 
318
341
  // DELETE REMOTE AND LOCAL FAQ
319
342
  router.delete('/:faqid', function (req, res) {
320
343
 
321
- // deleteRemoteFaq(req.params.faqid)
322
344
  winston.debug('DELETE FAQ - FAQ ID ', req.params.faqid);
323
345
 
324
- Faq.findByIdAndRemove({ _id: req.params.faqid }, function (err, faq) {
325
- if (err) {
326
- return res.status(500).send({ success: false, msg: 'Error deleting object.' });
327
- }
328
- winston.debug('Deleted FAQ ', faq);
329
-
330
- faqBotEvent.emit('faq.delete', faq);
331
- faqBotEvent.emit('faq_train.delete', faq.id_faq_kb);
346
+ let faqid = req.params.faqid;
347
+
348
+ if (faqid.startsWith("intentId")) {
349
+ console.log("faqid is an intent_id")
350
+ let intent_id = faqid.substring(8);
351
+ console.log("faq intent_id: ", intent_id);
332
352
 
333
- res.json(faq);
353
+ Faq.findOneAndDelete({ intent_id: intent_id }, (err, faq) => {
354
+ if (err) {
355
+ return res.status(500).send({ success: false, msg: "Error deleting object." });
356
+ }
334
357
 
335
- });
358
+ winston.debug('Deleted FAQ ', faq);
359
+
360
+ faqBotEvent.emit('faq.delete', faq);
361
+ faqBotEvent.emit('faq_train.delete', faq.id_faq_kb);
362
+
363
+ res.status(200).send(faq);
336
364
 
365
+ })
337
366
 
367
+ } else {
368
+ Faq.findByIdAndRemove({ _id: req.params.faqid }, function (err, faq) {
369
+ if (err) {
370
+ return res.status(500).send({ success: false, msg: 'Error deleting object.' });
371
+ }
372
+ winston.debug('Deleted FAQ ', faq);
373
+
374
+ faqBotEvent.emit('faq.delete', faq);
375
+ faqBotEvent.emit('faq_train.delete', faq.id_faq_kb);
376
+
377
+ res.status(200).send(faq);
378
+
379
+ });
380
+ }
338
381
  });
339
382
 
340
383
  // EXPORT FAQ TO CSV
package/routes/faq_kb.js CHANGED
@@ -639,6 +639,7 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), async (req, r
639
639
 
640
640
  winston.debug("json source " + json_string)
641
641
 
642
+ // intentOnly still existing?
642
643
  if (req.query.intentsOnly && req.query.intentsOnly == "true") {
643
644
 
644
645
  winston.debug("intents only")
@@ -658,7 +659,8 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), async (req, r
658
659
  enabled: intent.enabled,
659
660
  webhook_enabled: intent.webhook_enabled,
660
661
  language: intent.language,
661
- actions: intent.actions
662
+ actions: intent.actions,
663
+ attributes: intent.attributes
662
664
  }
663
665
 
664
666
  // overwrite duplicated intents
@@ -746,7 +748,8 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), async (req, r
746
748
  enabled: intent.enabled,
747
749
  webhook_enabled: intent.webhook_enabled,
748
750
  language: intent.language,
749
- actions: intent.actions
751
+ actions: intent.actions,
752
+ attributes: intent.attributes
750
753
  }
751
754
 
752
755
  // TO DELETE: no used when req.query.create = 'true'
@@ -869,7 +872,8 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), async (req, r
869
872
  enabled: intent.enabled,
870
873
  webhook_enabled: intent.webhook_enabled,
871
874
  language: intent.language,
872
- actions: intent.actions
875
+ actions: intent.actions,
876
+ attributes: intent.attributes
873
877
  }
874
878
 
875
879
  // overwrite duplicated intents
@@ -0,0 +1,112 @@
1
+ var express = require('express');
2
+ var router = express.Router();
3
+ var KBSettings = require('../models/kb_setting');
4
+ var openaiService = require('../services/openaiService');
5
+ var winston = require('../config/winston');
6
+
7
+ router.post('/', async (req, res) => {
8
+
9
+ let project_id = req.projectid;
10
+ let body = req.body;
11
+
12
+ console.log("### --> body: ", body);
13
+
14
+ KBSettings.findOne({ id_project: project_id }, (err, kbSettings) => {
15
+ console.log("kbSettings: ", kbSettings);
16
+
17
+ if (!kbSettings) {
18
+ return res.status(400).send({ success: false, message: "Missing gptkey parameter (settings not exist)" })
19
+ }
20
+
21
+ let gptkey = kbSettings.gptkey;
22
+
23
+ if (!gptkey) {
24
+ return res.status(400).send({ success: false, message: "Missing gptkey parameter" })
25
+ }
26
+
27
+ // attua modifiche
28
+ let json = {
29
+ "model": body.model,
30
+ "messages": [
31
+ {
32
+ "role": "user",
33
+ "content": body.question
34
+ }
35
+ ],
36
+ "max_tokens": body.max_tokens,
37
+ "temperature": body.temperature
38
+ }
39
+
40
+ let message = { role: "", content: "" };
41
+ if (body.context) {
42
+ message.role = "system";
43
+ message.content = body.context;
44
+ json.messages.unshift(message);
45
+ }
46
+ console.log("openai preview --> json: ", json);
47
+
48
+ openaiService.completions(json, gptkey).then((response) => {
49
+ // winston.debug("completions response: ", response);
50
+ res.status(200).send(response.data);
51
+ }).catch((err) => {
52
+ console.log("err: ", err);
53
+ // winston.error("completions error: ", err);
54
+ res.status(500).send(err)
55
+ })
56
+
57
+ })
58
+ })
59
+
60
+ // router.get('/', async (req, res) => {
61
+
62
+ // let project_id = req.projectid;
63
+
64
+ // OpenaiKbs.find({ id_project: project_id }, (err, kbs) => {
65
+ // if (err) {
66
+ // console.error("find all kbs error: ", err);
67
+ // return res.status(500).send({ success: false, error: err });
68
+ // } else {
69
+ // return res.status(200).send(kbs);
70
+ // }
71
+ // })
72
+ // })
73
+
74
+ // router.post('/', async (req, res) => {
75
+
76
+ // let body = req.body;
77
+
78
+ // let new_kbs = new OpenaiKbs({
79
+ // name: body.name,
80
+ // url: body.url,
81
+ // id_project: req.projectid,
82
+ // gptkey: req.body.gptkey
83
+ // })
84
+
85
+ // new_kbs.save(function (err, savedKbs) {
86
+ // if (err) {
87
+ // console.error("save new kbs error: ", err);
88
+ // return res.status(500).send({ success: false, error: err});
89
+ // } else {
90
+ // return res.status(200).send(savedKbs);
91
+ // }
92
+ // })
93
+ // })
94
+
95
+ // router.put('/', async (req, res) => {
96
+ // // to be implemented
97
+ // })
98
+
99
+ // router.delete('/:kbs_id', async (req, res) => {
100
+ // let kbs_id = req.params.kbs_id;
101
+
102
+ // OpenaiKbs.findOneAndDelete( { _id: kbs_id }, (err, kbDeleted) => {
103
+ // if (err) {
104
+ // console.error("find one and delete kbs error: ", err);
105
+ // return res.status(500).send({ success: false, error: err});
106
+ // } else {
107
+ // return res.status(200).send({ success: true, message: 'Knowledge Base deleted successfully', openai_kb: kbDeleted });
108
+ // }
109
+ // })
110
+ // })
111
+
112
+ module.exports = router;
package/routes/users.js CHANGED
@@ -185,5 +185,29 @@ router.get('/', function (req, res) {
185
185
  });
186
186
  });
187
187
 
188
+ router.post('/loginemail', function (req, res) {
189
+
190
+ winston.debug("/loginemail... req.body: ", req.body);
191
+ let user_id = req.user._id;
192
+ let token = req.headers.authorization;
193
+
194
+ let project_id = req.body.id_project;
195
+ if (!project_id) {
196
+ res.status(500).send({ success: false, error: "missing 'id_project' field" })
197
+ }
198
+
199
+ User.findById(user_id, (err, user) => {
200
+ if (err) {
201
+ return res.status(404).send({ success: false, message: "No user found" });
202
+ }
203
+ winston.debug("user found: ", user);
204
+
205
+ emailService.sendEmailRedirectOnDesktop(user.email, token, project_id, user.email)
206
+ return res.status(200).send("Sending email...")
207
+ })
208
+
209
+
210
+ })
211
+
188
212
 
189
213
  module.exports = router;
@@ -1851,6 +1851,39 @@ async sendRequestTranscript(to, messages, request, project) {
1851
1851
 
1852
1852
  }
1853
1853
 
1854
+ async sendEmailRedirectOnDesktop(to, token, project_id) {
1855
+ winston.debug("sendEmailRedirectOnDesktop: " + to);
1856
+
1857
+ var that = this;
1858
+
1859
+ let html = await this.readTemplate('redirectToDesktopEmail.html');
1860
+
1861
+ let envTemplate = process.env.EMAIL_REDIRECT_TO_DESKTOP_TEMPLATE
1862
+ winston.debug("envTemplate: " + envTemplate);
1863
+
1864
+ if (envTemplate) {
1865
+ html = envTemplate;
1866
+ }
1867
+
1868
+ winston.debug("html: " + html);
1869
+
1870
+ let template = handlebars.compile(html);
1871
+
1872
+ let baseScope = JSON.parse(JSON.stringify(that));
1873
+ delete baseScope.pass;
1874
+
1875
+ let replacements = {
1876
+ baseScope: baseScope,
1877
+ token: token,
1878
+ project_id: project_id
1879
+ }
1880
+
1881
+ html = template(replacements);
1882
+
1883
+ that.send({ to: to, subject: "Join Tiledesk from Desktop", html: html });
1884
+
1885
+ }
1886
+
1854
1887
  parseText(text, payload) {
1855
1888
 
1856
1889
 
@@ -0,0 +1,41 @@
1
+ var winston = require('../config/winston');
2
+ const axios = require("axios").default;
3
+ var configGlobal = require('../config/global');
4
+ require('dotenv').config();
5
+
6
+ let openai_endpoint = process.env.OPENAI_ENDPOINT;
7
+
8
+ class OpenaiService {
9
+
10
+ completions(data, gptkey) {
11
+
12
+ console.log("****** Serivcesssssssss openai_endpoint: ", openai_endpoint);
13
+
14
+ return new Promise((resolve, reject) => {
15
+
16
+ axios({
17
+ url: openai_endpoint + "/chat/completions",
18
+ headers: {
19
+ 'Content-Type': 'application/json',
20
+ 'Authorization': "Bearer " + gptkey
21
+ },
22
+ data: data,
23
+ method: 'POST'
24
+ }).then((resbody) => {
25
+ //winston.debug("[Openai] completions resbody: ", resbody.data);
26
+ resolve(resbody);
27
+ }).catch((err) => {
28
+ console.log("err: ", err);
29
+ // winston.error("[Openai] completions error: ", err);
30
+ reject(err);
31
+ })
32
+
33
+ })
34
+
35
+ }
36
+
37
+ }
38
+
39
+ var openaiService = new OpenaiService();
40
+
41
+ module.exports = openaiService;