@tiledesk/tiledesk-server 2.4.98 → 2.4.100

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,15 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.4.100
9
+ - Updated tybot-connector to 0.2.50
10
+ - Added new route for knowledge base
11
+
12
+ # 2.4.99
13
+ - Updated whatsapp-connector to 0.1.62
14
+ - Updated messenger-connector to 0.1.16
15
+ - Bug fix: globals are not exported when a chatbot is published
16
+
8
17
  # 2.4.98
9
18
  - Updated whatsapp-connector to 0.1.61
10
19
 
package/app.js CHANGED
@@ -114,6 +114,7 @@ var widgets = require('./routes/widget');
114
114
  var widgetsLoader = require('./routes/widgetLoader');
115
115
  var openai = require('./routes/openai');
116
116
  var kbsettings = require('./routes/kbsettings');
117
+ var kb = require('./routes/kb');
117
118
 
118
119
  // var admin = require('./routes/admin');
119
120
  var faqpub = require('./routes/faqpub');
@@ -561,6 +562,7 @@ app.use('/:projectid/segments',[passport.authenticate(['basic', 'jwt'], { sessio
561
562
 
562
563
  app.use('/:projectid/openai', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai);
563
564
  app.use('/:projectid/kbsettings', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], kbsettings);
565
+ app.use('/:projectid/kb', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('admin', ['bot','subscription'])], kb);
564
566
 
565
567
  app.use('/:projectid/logs', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], logs);
566
568
 
@@ -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.98",
4
+ "version": "2.4.100",
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",
package/routes/faq_kb.js CHANGED
@@ -637,19 +637,25 @@ router.post('/fork/:id_faq_kb', async (req, res) => {
637
637
  let public = req.query.public;
638
638
  winston.debug("public " + public);
639
639
 
640
+ let globals = req.query.globals;
641
+ winston.debug("export globals " + globals);
642
+ console.log("export globals? --> globals ", globals);
643
+
640
644
  let token = req.headers.authorization;
641
645
 
642
646
  let cs = req.app.get('chatbot_service')
643
647
 
644
- let chatbot = await cs.getBotById(id_faq_kb, public, api_url, chatbot_templates_api_url, token, current_project_id);
648
+ let chatbot = await cs.getBotById(id_faq_kb, public, api_url, chatbot_templates_api_url, token, current_project_id, globals);
645
649
  winston.debug("chatbot: ", chatbot)
646
-
650
+ console.log("/fork chatbot after getBotById: ", chatbot);
647
651
  if (!chatbot) {
648
652
  return res.status(500).send({ success: false, message: "Unable to get chatbot" });
649
653
  }
650
654
 
651
- if (chatbot.attributes) {
652
- delete chatbot.attributes.globals
655
+ if (!globals) {
656
+ if (chatbot.attributes) {
657
+ delete chatbot.attributes.globals
658
+ }
653
659
  }
654
660
 
655
661
  let savedChatbot = await cs.createBot(api_url, token, chatbot, landing_project_id);
@@ -976,6 +982,7 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), async (req, r
976
982
  router.get('/exportjson/:id_faq_kb', (req, res) => {
977
983
 
978
984
  winston.debug("exporting bot...")
985
+ console.log("exportjson req.query.globals: ", req.query.globals);
979
986
 
980
987
 
981
988
  let id_faq_kb = req.params.id_faq_kb;
@@ -992,8 +999,13 @@ router.get('/exportjson/:id_faq_kb', (req, res) => {
992
999
  // delete from exclude map intent_id
993
1000
  const intents = faqs.map(({ _id, id_project, topic, status, id_faq_kb, createdBy, createdAt, updatedAt, __v, ...keepAttrs }) => keepAttrs)
994
1001
 
995
- if (faq_kb.attributes) {
996
- delete faq_kb.attributes.globals;
1002
+ if (!req.query.globals) {
1003
+ console.log("Delete globals from attributes!")
1004
+ if (faq_kb.attributes) {
1005
+ delete faq_kb.attributes.globals;
1006
+ }
1007
+ } else {
1008
+ console.log("Keep globals")
997
1009
  }
998
1010
 
999
1011
  let json = {
package/routes/kb.js ADDED
@@ -0,0 +1,353 @@
1
+ var express = require('express');
2
+ var { KB } = require('../models/kb_setting');
3
+ var router = express.Router();
4
+ var winston = require('../config/winston');
5
+ const openaiService = require('../services/openaiService');
6
+
7
+
8
+ router.get('/', async (req, res) => {
9
+
10
+ let project_id = req.projectid;
11
+
12
+ KB.find({ id_project: project_id }, (err, kbs) => {
13
+ if (err) {
14
+ winston.error("Find all kbs error: ", err);
15
+ return res.status(500).send({ success: false, error: err });
16
+ }
17
+
18
+ winston.debug("KBs found: ", kbs);
19
+ return res.status(200).send(kbs);
20
+ })
21
+ })
22
+
23
+ router.get('/:kb_id', async (req, res) => {
24
+
25
+ let kb_id = req.params.kb_id;
26
+
27
+ KB.findById(kb_id, (err, kb) => {
28
+ if (err) {
29
+ winston.error("Find kb by id error: ", err);
30
+ return res.status(500).send({ success: false, error: err });
31
+ }
32
+
33
+ return res.status(200).send(kb);
34
+ })
35
+ })
36
+
37
+ router.post('/', async (req, res) => {
38
+
39
+
40
+ let project_id = req.projectid;
41
+ let body = req.body;
42
+ console.log("create new kb project_id " + project_id);
43
+ console.log("create new kb body ", body);
44
+
45
+ let new_kb = {
46
+ id_project: project_id,
47
+ name: body.name,
48
+ type: body.type,
49
+ source: body.source,
50
+ content: body.content,
51
+ namespace: body.namespace
52
+ }
53
+ if (!new_kb.namespace) {
54
+ new_kb.namespace = project_id;
55
+ }
56
+ winston.debug("adding kb: ", new_kb);
57
+
58
+
59
+ KB.findOneAndUpdate({ id_project: project_id, type: 'url', source: new_kb.source }, new_kb, { upsert: true, new: true, rawResult: true }, async (err, raw) => {
60
+ if (err) {
61
+ winston.error("findOneAndUpdate with upsert error: ", err);
62
+ res.status(500).send({ success: false, error: err });
63
+ }
64
+ else {
65
+
66
+ res.status(200).send(raw);
67
+
68
+ let json = {
69
+ id: raw.value._id,
70
+ type: raw.value.type,
71
+ source: raw.value.source,
72
+ content: "",
73
+ namespace: raw.value.namespace
74
+ }
75
+
76
+ if (raw.value.content) {
77
+ json.content = raw.value.content;
78
+ }
79
+
80
+ startScrape(json).then((response) => {
81
+ winston.verbose("startScrape response: ", response);
82
+ }).catch((err) => {
83
+ winston.error("startScrape err: ", err);
84
+ })
85
+
86
+ }
87
+ })
88
+
89
+ })
90
+
91
+ router.put('/:kb_id', async (req, res) => {
92
+
93
+ let kb_id = req.params.kb_id;
94
+ winston.verbose("update kb_id " + kb_id);
95
+
96
+ let update = {};
97
+
98
+ if (req.body.name != undefined) {
99
+ update.name = req.body.name;
100
+ }
101
+
102
+ if (req.body.status != undefined) {
103
+ update.status = req.body.status;
104
+ }
105
+
106
+ update.updatedAt = new Date();
107
+ winston.debug("kb update: ", update);
108
+
109
+ KB.findByIdAndUpdate(kb_id, update, { new: true }, (err, savedKb) => {
110
+
111
+ if (err) {
112
+ winston.error("KB findByIdAndUpdate error: ", err);
113
+ return res.status(500).send({ success: false, error: err });
114
+ }
115
+
116
+ if (!savedKb) {
117
+ winston.debug("Try to updating a non-existing kb");
118
+ return res.status(400).send({ success: false, message: "Content not found" })
119
+ }
120
+
121
+ res.status(200).send(savedKb)
122
+ })
123
+
124
+ })
125
+
126
+
127
+ // PROXY PUGLIA AI V2 - START
128
+ router.post('/scrape/single', async (req, res) => {
129
+
130
+ let data = req.body;
131
+ winston.debug("/scrape/single data: ", data);
132
+
133
+ KB.findById(data.id, (err, kb) => {
134
+ if (err) {
135
+ winston.error("findById error: ", err);
136
+ return res.status(500).send({ success: false, error: err });
137
+ }
138
+
139
+ else if (!kb) {
140
+ return res.status(404).send({ success: false, error: "Unable to find the kb requested" })
141
+ }
142
+ else {
143
+
144
+ let json = {
145
+ id: kb._id,
146
+ type: kb.type,
147
+ source: kb.source,
148
+ content: kb.content,
149
+ namespace: kb.namespace
150
+ }
151
+
152
+ startScrape(json).then((response) => {
153
+ winston.verbose("startScrape response: ", response);
154
+ res.status(200).send(response);
155
+ }).catch((err) => {
156
+ winston.error("startScrape err: ", err);
157
+ res.status(500).send({ success: false, error: err });
158
+ })
159
+
160
+ }
161
+ })
162
+
163
+ })
164
+
165
+ router.post('/scrape/status', async (req, res) => {
166
+
167
+ let data = req.body;
168
+ winston.debug("/scrapeStatus req.body: ", req.body);
169
+
170
+ let returnObject = false;
171
+
172
+ if (req.query &&
173
+ req.query.returnObject &&
174
+ (req.query.returnObject === true || req.query.returnObject === true)) {
175
+ returnObject = true;
176
+ }
177
+
178
+ openaiService.scrapeStatus(data).then((response) => {
179
+
180
+ winston.debug("scrapeStatus response.data: ", response.data);
181
+
182
+ let update = {};
183
+
184
+ if (response.data.status_code) {
185
+ update.status = response.data.status_code;
186
+ }
187
+
188
+ KB.findByIdAndUpdate(data.id, update, { new: true }, (err, savedKb) => {
189
+
190
+ if (err) {
191
+ winston.verbose("Status was successfully recovered, but the update on the db failed");
192
+
193
+ if (returnObject) {
194
+ return res.status(206).send({ warning: "Unable to udpate content on db", message: "The original reply was forwarded", data: response.data });
195
+ } else {
196
+ return res.status(200).send(response.data);
197
+ }
198
+ }
199
+
200
+ if (returnObject) {
201
+ return res.status(200).send(savedKb);
202
+ } else {
203
+ return res.status(200).send(response.data);
204
+ }
205
+ })
206
+
207
+ }).catch((err) => {
208
+ winston.error("scrapeStatus err: ", err);
209
+ let status = err.response.status;
210
+ res.status(status).send({ statusText: err.response.statusText, error: err.response.data.detail });
211
+ })
212
+ })
213
+
214
+ router.post('/qa', async (req, res) => {
215
+ let data = req.body;
216
+ winston.debug("/qa data: ", data);
217
+
218
+ if (!data.gptkey) {
219
+ let gptkey = process.env.GPTKEY;
220
+ if (!gptkey) {
221
+ return res.status(403).send({ success: false, error: "GPT apikey undefined" })
222
+ }
223
+ data.gptkey = gptkey;
224
+ }
225
+
226
+ openaiService.askNamespace(data).then((resp) => {
227
+ winston.debug("qa resp: ", resp.data);
228
+ res.status(200).send(resp.data);
229
+ }).catch((err) => {
230
+ winston.error("qa err: ", err);
231
+ let status = err.response.status;
232
+ res.status(status).send({ success: false, statusText: err.response.statusText, error: err.response.data.detail });
233
+ })
234
+ })
235
+
236
+ router.delete('/delete', async (req, res) => {
237
+
238
+ let data = req.body;
239
+ winston.debug("/delete data: ", data);
240
+
241
+ openaiService.deleteIndex(data).then((resp) => {
242
+ winston.debug("delete resp: ", resp.data);
243
+ res.status(200).send(resp.data);
244
+ }).catch((err) => {
245
+ winston.error("delete err: ", err);
246
+ let status = err.response.status;
247
+ res.status(status).send({ statusText: err.response.statusText, error: err.response.data.detail });
248
+ })
249
+
250
+ })
251
+
252
+ router.delete('/deleteall', async (req, res) => {
253
+
254
+ let data = req.body;
255
+ winston.debug('/delete all data: ', data);
256
+
257
+ openaiService.deleteNamespace(data).then((resp) => {
258
+ winston.debug("delete namespace resp: ", resp.data);
259
+ res.status(200).send(resp.data);
260
+ }).catch((err) => {
261
+ winston.error("delete namespace err: ", err);
262
+ let status = err.response.status;
263
+ res.status(status).send({ statusText: err.response.statusText, error: err.response.data.detail });
264
+ })
265
+ })
266
+ // PROXY PUGLIA AI V2 - END
267
+
268
+ router.delete('/:kb_id', async (req, res) => {
269
+
270
+ let project_id = req.projectid;
271
+ let kb_id = req.params.kb_id;
272
+ winston.verbose("delete kb_id " + kb_id);
273
+
274
+ let data = {
275
+ id: kb_id,
276
+ namespace: project_id
277
+ }
278
+
279
+ openaiService.deleteIndex(data).then((resp) => {
280
+ winston.debug("delete resp: ", resp.data);
281
+
282
+ if (resp.data.success === true) {
283
+ KB.findByIdAndDelete(kb_id, (err, deletedKb) => {
284
+
285
+ if (err) {
286
+ winston.error("Delete kb error: ", err);
287
+ return res.status(500).send({ success: false, error: err });
288
+ }
289
+ res.status(200).send(deletedKb);
290
+ })
291
+
292
+ } else {
293
+ winston.info("resp.data: ", resp.data);
294
+
295
+ KB.findOneAndDelete({ _id: kb_id, status: { $in: [-1, 3, 4] } }, (err, deletedKb) => {
296
+ if (err) {
297
+ winston.error("findOneAndDelete err: ", err);
298
+ return res.status(500).send({ success: false, error: "Unable to delete the content due to an error" })
299
+ }
300
+ else if (!deletedKb) {
301
+ winston.verbose("Unable to delete the content in indexing status")
302
+ return res.status(500).send({ success: false, error: "Unable to delete the content in indexing status" })
303
+ } else {
304
+ res.status(200).send(deletedKb);
305
+ }
306
+ })
307
+ }
308
+
309
+ }).catch((err) => {
310
+ let status = err.response.status;
311
+ res.status(status).send({ success: false, statusText: err.response.statusText, error: err.response.data.detail });
312
+ })
313
+
314
+ })
315
+
316
+ async function updateStatus(id, status) {
317
+ return new Promise((resolve) => {
318
+
319
+ KB.findByIdAndUpdate(id, { status: status }, (err, updatedKb) => {
320
+ if (err) {
321
+ resolve(false)
322
+ } else {
323
+ winston.debug("updatedKb: ", updatedKb)
324
+ resolve(true);
325
+ }
326
+ })
327
+ })
328
+ }
329
+
330
+ async function startScrape(data) {
331
+
332
+ if (!data.gptkey) {
333
+ let gptkey = process.env.GPTKEY;
334
+ if (!gptkey) {
335
+ return { error: "GPT apikey undefined" }
336
+ }
337
+ data.gptkey = gptkey;
338
+ }
339
+
340
+ return new Promise((resolve, reject) => {
341
+ openaiService.singleScrape(data).then(async (resp) => {
342
+ winston.debug("singleScrape resp: ", resp.data);
343
+ let status_updated = await updateStatus(data.id, 0);
344
+ winston.verbose("status of kb " + data.id + " updated: " + status_updated);
345
+ resolve(resp.data);
346
+ }).catch((err) => {
347
+ winston.error("singleScrape err: ", err);
348
+ reject(err);
349
+ })
350
+ })
351
+ }
352
+
353
+ module.exports = router;
@@ -1,5 +1,6 @@
1
1
  var express = require('express');
2
- var KBSettings = require('../models/kb_setting');
2
+ var { KBSettings } = require('../models/kb_setting');
3
+ var { KB } = require('../models/kb_setting');
3
4
  // var KB = require('../models/kb_setting')
4
5
  var router = express.Router();
5
6
  var winston = require('../config/winston');
@@ -98,11 +99,75 @@ router.delete('/:settings_id/:kb_id', async (req, res) => {
98
99
 
99
100
  })
100
101
 
102
+ // PROXY PUGLIA AI V2 - START
103
+ router.post('/scrape/single', async (req, res) => {
104
+
105
+ let data = req.body;
106
+ winston.debug("/scrape/single data: ", data);
107
+
108
+ let gptkey = process.env.GPTKEY;
109
+ if (!gptkey) {
110
+ return res.status(403).send({ success: false, error: "GPT apikey undefined"})
111
+ }
112
+
113
+ data.gptkey = gptkey;
114
+
115
+ openaiService.singleScrape(data).then((resp) => {
116
+ winston.debug("singleScrape resp: ", resp.data);
117
+ return res.status(200).send(resp.data);
118
+ }).catch((err) => {
119
+ winston.error("singleScrape err: ", err);
120
+ let status = err.response.status;
121
+ return res.status(status).send({ statusText: err.response.statusText, detail: err.response.data.detail });
122
+ })
123
+ })
124
+
125
+ router.post('/scrape/status', async (req, res) => {
126
+
127
+ let data = req.body;
128
+ winston.debug("/scrapeStatus req.body: ", req.body);
129
+
130
+ openaiService.scrapeStatus(data).then((response) => {
131
+
132
+ winston.debug("scrapeStatus response.data: ", response.data);
133
+ res.status(200).send(response.data);
134
+ }).catch((err) => {
135
+ winston.error("scrapeStatus err: ", err);
136
+ let status = err.response.status;
137
+ res.status(status).send({ statusText: err.response.statusText, detail: err.response.data.detail });
138
+ })
139
+ })
140
+
141
+ router.post('/ask', async (req, res) => {
142
+ let data = req.body;
143
+ winston.debug("/qa data: ", data);
144
+
145
+ if (!data.gptkey) {
146
+ let gptkey = process.env.GPTKEY;
147
+ if (!gptkey) {
148
+ return res.status(403).send({ success: false, error: "GPT apikey undefined"})
149
+ }
150
+ data.gptkey = gptkey;
151
+ }
152
+
153
+ openaiService.askNamespace(data).then((resp) => {
154
+ winston.debug("qa resp: ", resp.data);
155
+ res.status(200).send(resp.data);
156
+ }).catch((err) => {
157
+ winston.error("qa err: ", err);
158
+ let status = err.response.status;
159
+ res.status(status).send({ statusText: err.response.statusText, detail: err.response.data.detail });
160
+ })
161
+ })
162
+
163
+ // PROXY PUGLIA AI V2 - END
164
+
101
165
 
102
166
  // PROXY PUGLIA AI - START
103
167
  router.post('/qa', async (req, res) => {
104
168
  let data = req.body;
105
169
  winston.debug("/qa data: ", data);
170
+ winston.info("/qa data: ", data);
106
171
 
107
172
  openaiService.ask(data).then((resp) => {
108
173
  winston.debug("qa resp: ", resp.data);
@@ -110,6 +175,7 @@ router.post('/qa', async (req, res) => {
110
175
  }).catch((err) => {
111
176
  winston.error("qa err: ", err);
112
177
  let status = err.response.status;
178
+ winston.info("status on error: ", status)
113
179
  res.status(status).send({ statusText: err.response.statusText, detail: err.response.data.detail });
114
180
  })
115
181
  })
@@ -132,7 +198,7 @@ router.post('/startscrape', async (req, res) => {
132
198
 
133
199
  router.post('/checkstatus', async (req, res) => {
134
200
 
135
- // let data = req.body;
201
+ //let data = req.body;
136
202
  winston.debug("/checkstatus req.body: ", req.body);
137
203
 
138
204
  let full_url = req.body.full_url;
@@ -141,7 +207,7 @@ router.post('/checkstatus', async (req, res) => {
141
207
  }
142
208
 
143
209
  openaiService.checkStatus(data).then((resp) => {
144
- winston.debug("checkStatus resp: ", resp.data);
210
+ winston.debug("checkStatus resp: ", resp);
145
211
  winston.debug("checkStatus resp: ", resp.data);
146
212
  winston.debug("checkStatus resp: ", resp.data[full_url]);
147
213
 
@@ -168,7 +234,7 @@ router.post('/checkstatus', async (req, res) => {
168
234
  }
169
235
 
170
236
 
171
- res.status(200).send(return_data);
237
+ res.status(200).send(resp);
172
238
  }).catch((err) => {
173
239
  winston.error("checkstatus err: ", err);
174
240
  let status = err.response.status;
@@ -188,10 +254,14 @@ router.post('/:settings_id', async (req, res) => {
188
254
  return res.status(500).send({ success: false, error: err});
189
255
  } else {
190
256
 
191
- let new_kb = {
257
+ let new_kb = new KB({
192
258
  name: body.name,
193
- url: body.url
194
- }
259
+ url: body.url,
260
+ source: body.source,
261
+ type: body.type,
262
+ content: body.content,
263
+ namespace: body.namespace
264
+ })
195
265
  settings.kbs.push(new_kb);
196
266
 
197
267
  KBSettings.findByIdAndUpdate( settings_id, settings, { new: true }, (err, savedSettings) => {
@@ -199,7 +269,7 @@ router.post('/:settings_id', async (req, res) => {
199
269
  winston.err("findByIdAndUpdate error: ", err);
200
270
  res.status(500).send({ success: false, error: err });
201
271
  } else {
202
- res.status(200).send(savedSettings);
272
+ res.status(200).send(new_kb);
203
273
  }
204
274
  })
205
275
  }
package/routes/openai.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var express = require('express');
2
2
  var router = express.Router();
3
- var KBSettings = require('../models/kb_setting');
3
+ var { KBSettings } = require('../models/kb_setting');
4
4
  var openaiService = require('../services/openaiService');
5
5
  var winston = require('../config/winston');
6
6
 
@@ -12,7 +12,7 @@ class ChatbotService {
12
12
  winston.debug("[CHATBOT SERVICE] fork");
13
13
 
14
14
  return await axios({
15
- url: api_url + '/' + project_id + '/faq_kb/fork/'+id_faq_kb+"?projectid="+project_id+"&public=false",
15
+ url: api_url + '/' + project_id + '/faq_kb/fork/'+id_faq_kb+"?projectid="+project_id+"&public=false&globals=true",
16
16
  headers: {
17
17
  'Content-Type': 'application/json',
18
18
  'Authorization': token
@@ -29,15 +29,16 @@ class ChatbotService {
29
29
 
30
30
  }
31
31
 
32
- async getBotById(id_faq_kb, published, api_url, chatbot_templates_api_url, token, project_id) {
32
+ async getBotById(id_faq_kb, published, api_url, chatbot_templates_api_url, token, project_id, globals) {
33
33
 
34
34
  winston.debug("[CHATBOT SERVICE] getBotById");
35
+ console.log("getBotById globals: ", globals);
35
36
 
36
37
  // private bot
37
38
  if (published == "false") {
38
39
 
39
40
  return await axios({
40
- url: api_url + "/" + project_id + "/faq_kb/exportjson/" + id_faq_kb,
41
+ url: api_url + "/" + project_id + "/faq_kb/exportjson/" + id_faq_kb + "?globals=" + globals,
41
42
  headers: {
42
43
  'Content-Type': 'application/json',
43
44
  'Authorization': token
@@ -7,97 +7,203 @@ let openai_endpoint = process.env.OPENAI_ENDPOINT;
7
7
  let kb_endpoint = process.env.KB_ENDPOINT;
8
8
 
9
9
  class OpenaiService {
10
-
11
- // OPEN AI
12
- completions(data, gptkey) {
13
-
14
- winston.debug("[OPENAI SERVICE] openai endpoint: ", openai_endpoint);
15
-
16
- return new Promise((resolve, reject) => {
17
-
18
- axios({
19
- url: openai_endpoint + "/chat/completions",
20
- headers: {
21
- 'Content-Type': 'application/json',
22
- 'Authorization': "Bearer " + gptkey
23
- },
24
- data: data,
25
- method: 'POST'
26
- }).then((resbody) => {
27
- resolve(resbody);
28
- }).catch((err) => {
29
- reject(err);
30
- })
31
-
32
- })
33
-
34
- }
35
-
36
-
37
- // PUGLIA AI
38
- checkStatus(data) {
39
- winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
40
-
41
- return new Promise((resolve, reject) => {
42
-
43
- axios({
44
- url: kb_endpoint + "/scrape/status",
45
- headers: {
46
- 'Content-Type': 'application/json'
47
- },
48
- data: data,
49
- method: 'POST'
50
- }).then((resbody) => {
51
- resolve(resbody);
52
- }).catch((err) => {
53
- reject(err);
54
- })
55
-
56
- })
57
- }
58
-
59
- startScrape(data) {
60
- winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
61
-
62
- return new Promise((resolve, reject) => {
63
-
64
- axios({
65
- url: kb_endpoint + "/scrape",
66
- headers: {
67
- 'Content-Type': 'application/json'
68
- },
69
- data: data,
70
- method: 'POST'
71
- }).then((resbody) => {
72
- resolve(resbody);
73
- }).catch((err) => {
74
- reject(err);
75
- })
76
-
77
- })
78
- }
79
-
80
- ask(data) {
81
- winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
82
-
83
- return new Promise((resolve, reject) => {
84
-
85
- axios({
86
- url: kb_endpoint + "/qa",
87
- headers: {
88
- 'Content-Type': 'application/json'
89
- },
90
- data: data,
91
- method: 'POST'
92
- }).then((resbody) => {
93
- resolve(resbody);
94
- }).catch((err) => {
95
- console.log("err: ", err);
96
- reject(err);
97
- })
98
-
99
- })
100
- }
10
+
11
+ // OPEN AI
12
+ completions(data, gptkey) {
13
+
14
+ winston.debug("[OPENAI SERVICE] openai endpoint: ", openai_endpoint);
15
+
16
+ return new Promise((resolve, reject) => {
17
+
18
+ axios({
19
+ url: openai_endpoint + "/chat/completions",
20
+ headers: {
21
+ 'Content-Type': 'application/json',
22
+ 'Authorization': "Bearer " + gptkey
23
+ },
24
+ data: data,
25
+ method: 'POST'
26
+ }).then((resbody) => {
27
+ resolve(resbody);
28
+ }).catch((err) => {
29
+ reject(err);
30
+ })
31
+
32
+ })
33
+
34
+ }
35
+
36
+
37
+ // PUGLIA AI
38
+ checkStatus(data) {
39
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
40
+
41
+ return new Promise((resolve, reject) => {
42
+
43
+ axios({
44
+ url: kb_endpoint + "/scrape/status",
45
+ headers: {
46
+ 'Content-Type': 'application/json'
47
+ },
48
+ data: data,
49
+ method: 'POST'
50
+ }).then((resbody) => {
51
+ resolve(resbody);
52
+ }).catch((err) => {
53
+ reject(err);
54
+ })
55
+
56
+ })
57
+ }
58
+
59
+ startScrape(data) {
60
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
61
+
62
+ return new Promise((resolve, reject) => {
63
+
64
+ axios({
65
+ url: kb_endpoint + "/scrape",
66
+ headers: {
67
+ 'Content-Type': 'application/json'
68
+ },
69
+ data: data,
70
+ method: 'POST'
71
+ }).then((resbody) => {
72
+ resolve(resbody);
73
+ }).catch((err) => {
74
+ reject(err);
75
+ })
76
+
77
+ })
78
+ }
79
+
80
+ ask(data) {
81
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
82
+
83
+ return new Promise((resolve, reject) => {
84
+
85
+ axios({
86
+ url: kb_endpoint + "/qa",
87
+ headers: {
88
+ 'Content-Type': 'application/json'
89
+ },
90
+ data: data,
91
+ method: 'POST'
92
+ }).then((resbody) => {
93
+ resolve(resbody);
94
+ }).catch((err) => {
95
+ console.log("err: ", err);
96
+ reject(err);
97
+ })
98
+
99
+ })
100
+ }
101
+
102
+ // PUGLIA AI V2
103
+ singleScrape(data) {
104
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
105
+
106
+ return new Promise((resolve, reject) => {
107
+
108
+ axios({
109
+ url: kb_endpoint + "/scrape/single",
110
+ headers: {
111
+ 'Content-Type': 'application/json'
112
+ },
113
+ data: data,
114
+ method: 'POST'
115
+ }).then((resbody) => {
116
+ resolve(resbody);
117
+ }).catch((err) => {
118
+ reject(err);
119
+ })
120
+
121
+ })
122
+ }
123
+
124
+ scrapeStatus(data) {
125
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
126
+
127
+ return new Promise((resolve, reject) => {
128
+
129
+ axios({
130
+ url: kb_endpoint + "/scrape/status",
131
+ headers: {
132
+ 'Content-Type': 'application/json'
133
+ },
134
+ data: data,
135
+ method: 'POST'
136
+ }).then((resbody) => {
137
+ resolve(resbody);
138
+ }).catch((err) => {
139
+ reject(err);
140
+ })
141
+ })
142
+ }
143
+
144
+ askNamespace(data) {
145
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
146
+
147
+ return new Promise((resolve, reject) => {
148
+
149
+ axios({
150
+ url: kb_endpoint + "/qa",
151
+ headers: {
152
+ 'Content-Type': 'application/json'
153
+ },
154
+ data: data,
155
+ method: 'POST'
156
+ }).then((resbody) => {
157
+ resolve(resbody);
158
+ }).catch((err) => {
159
+ reject(err);
160
+ })
161
+
162
+ })
163
+ }
164
+
165
+
166
+ deleteIndex(data) {
167
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
168
+
169
+ return new Promise((resolve, reject) => {
170
+
171
+ axios({
172
+ url: kb_endpoint + "/delete/id",
173
+ headers: {
174
+ 'Content-Type': 'application/json'
175
+ },
176
+ data: data,
177
+ method: 'POST'
178
+ }).then((resbody) => {
179
+ resolve(resbody);
180
+ }).catch((err) => {
181
+ reject(err);
182
+ })
183
+ })
184
+ }
185
+
186
+ deleteNamespace(data) {
187
+ winston.debug("[OPENAI SERVICE] kb endpoint: ", kb_endpoint);
188
+
189
+ return new Promise((resolve, reject) => {
190
+
191
+ axios({
192
+ url: kb_endpoint + "/delete/namespace",
193
+ headers: {
194
+ 'Content-Type': 'application/json'
195
+ },
196
+ data: data,
197
+ method: 'POST'
198
+ }).then((resbody) => {
199
+ resolve(resbody);
200
+ }).catch((err) => {
201
+ reject(err);
202
+ })
203
+ })
204
+ }
205
+
206
+
101
207
  }
102
208
 
103
209
  var openaiService = new OpenaiService();
@@ -11,6 +11,12 @@ const existing_chatbot_mock = {
11
11
  createdAt: "2022-09-15T15:32:06.491Z",
12
12
  updatedAt: "2022-09-15T15:32:06.491Z",
13
13
  name: "Bot",
14
+ attributes: {
15
+ globals: {
16
+ "mykey1": "myvalue1",
17
+ "mykey2": "myvalue2"
18
+ }
19
+ },
14
20
  intents: [
15
21
  {
16
22
  "webhook_enabled": false,
@@ -947,6 +947,70 @@ describe('FaqKBRoute', () => {
947
947
  });
948
948
  }).timeout(20000);
949
949
 
950
+ // it('publishChatbot', (done) => {
951
+
952
+ // var email = "test-signup-" + Date.now() + "@email.com";
953
+ // var pwd = "pwd";
954
+
955
+ // userService.signup(email, pwd, "Test Firstname", "Test Lastname").then(function (savedUser) {
956
+ // projectService.create("current-project", savedUser._id).then(function (currentProject) {
957
+
958
+ // console.log("declare chatbot_service functions...")
959
+
960
+ // class chatbot_service {
961
+ // async fork(id, api_url, token, project_id) {
962
+ // console.log("chatbot_service test fork called")
963
+ // return { message: "Chatbot forked successfully", bot_id: savedChatbot._id }
964
+ // //return chatbot_mock.existing_chatbot_mock;
965
+ // }
966
+
967
+ // async getBotById(id, published, api_url, chatbot_templates_api_url, token, project_id, globals) {
968
+ // return chatbot_mock.existing_chatbot_mock;
969
+ // }
970
+
971
+ // async createBot(api_url, token, chatbot, project_id) {
972
+ // return chatbot_mock.empty_chatbot_mock
973
+ // }
974
+
975
+ // async importFaqs(api_url, id_faq_kb, token, chatbot, project_id) {
976
+ // return chatbot_mock.import_faqs_res_mock
977
+ // }
978
+ // }
979
+
980
+ // server.set('chatbot_service', new chatbot_service());
981
+ // console.log("chatbot_service functions declared")
982
+
983
+ // chai.request(server)
984
+ // .post('/' + currentProject._id + '/faq_kb')
985
+ // .auth(email, pwd)
986
+ // .send({ "name": "privateBot", type: "internal", language: 'en', public: "false", template: "blank" })
987
+ // .end((err, res) => {
988
+ // console.log("res.body: ", res.body);
989
+ // if (log) {
990
+ // }
991
+ // res.should.have.status(200);
992
+ // res.body.should.be.a('object');
993
+ // expect(res.body.name).to.equal("privateBot");
994
+ // expect(res.body.language).to.equal("en");
995
+ // let id_faq_kb = res.body._id;
996
+
997
+ // chai.request(server)
998
+ // .put('/' + currentProject._id + '/faq_kb/' + id_faq_kb + '/publish')
999
+ // .auth(email, pwd)
1000
+ // .set('Content-Type', 'application/json')
1001
+ // .end((err, res) => {
1002
+ // console.log("publish bot res.body: ", res.body);
1003
+ // res.should.have.status(200);
1004
+
1005
+ // done();
1006
+ // })
1007
+ // })
1008
+
1009
+
1010
+ // })
1011
+ // })
1012
+ // })
1013
+
950
1014
 
951
1015
  });
952
1016
 
@@ -0,0 +1,134 @@
1
+ //During the test the env variable is set to test
2
+ process.env.NODE_ENV = 'test';
3
+
4
+ var userService = require('../services/userService');
5
+ var projectService = require('../services/projectService');
6
+
7
+ let log = true;
8
+
9
+ //Require the dev-dependencies
10
+ let chai = require('chai');
11
+ let chaiHttp = require('chai-http');
12
+ let server = require('../app');
13
+ let should = chai.should();
14
+ var fs = require('fs');
15
+ const path = require('path');
16
+
17
+ // chai.config.includeStack = true;
18
+
19
+ var expect = chai.expect;
20
+ var assert = chai.assert;
21
+
22
+ chai.use(chaiHttp);
23
+
24
+ describe('KbRoute', () => {
25
+
26
+ describe('/create', () => {
27
+
28
+ it('createNewKb', (done) => {
29
+
30
+ var email = "test-signup-" + Date.now() + "@email.com";
31
+ var pwd = "pwd";
32
+
33
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
34
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
35
+
36
+ let kb = {
37
+ name: "example_name5",
38
+ type: "url",
39
+ source: "https://www.exampleurl5.com",
40
+ content: ""
41
+ }
42
+
43
+ chai.request(server)
44
+ .post('/' + savedProject._id + '/kb')
45
+ .auth(email, pwd)
46
+ .send(kb) // can be empty
47
+ .end((err, res) => {
48
+ if (log) { console.log("create kb res.body: ", res.body); }
49
+ res.should.have.status(200);
50
+ // res.body.should.be.a('object');
51
+ // expect(res.body.id_project).to.equal(savedProject._id.toString());
52
+
53
+ done();
54
+ // chai.request(server)
55
+ // .get('/' + savedProject._id + "/kbsettings")
56
+ // .auth(email, pwd)
57
+ // .end((err, res) => {
58
+ // if (log) { console.log("get kbsettings res.body: ", res.body); }
59
+ // res.should.have.status(200);
60
+ // res.body.should.be.a('object');
61
+ // expect(res.body.id_project).to.equal(savedProject._id.toString())
62
+ // expect(res.body.maxKbsNumber).to.equal(3);
63
+ // expect(res.body.maxPagesNumber).to.equal(1000);
64
+ // expect(res.body.kbs).is.an('array').that.is.empty;
65
+
66
+
67
+ // })
68
+
69
+ })
70
+
71
+ });
72
+ });
73
+
74
+ });
75
+
76
+ it('scrapeSingle', (done) => {
77
+
78
+ var email = "test-signup-" + Date.now() + "@email.com";
79
+ var pwd = "pwd";
80
+
81
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
82
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
83
+
84
+ let kb = {
85
+ name: "example_name6",
86
+ type: "url",
87
+ source: "https://www.exampleurl6.com",
88
+ content: ""
89
+ }
90
+
91
+ chai.request(server)
92
+ .post('/' + savedProject._id + '/kb')
93
+ .auth(email, pwd)
94
+ .send(kb) // can be empty
95
+ .end((err, res) => {
96
+ if (log) { console.log("create kb res.body: ", res.body); }
97
+ res.should.have.status(200);
98
+
99
+ let kbid = res.body.value._id;
100
+ console.log("kbid: ", kbid)
101
+ chai.request(server)
102
+ .post('/' + savedProject._id + "/kb/scrape/single")
103
+ .auth(email, pwd)
104
+ .send({ id: kbid })
105
+ .end((err, res) => {
106
+ if (log) { console.log("single scrape res.body: ", res.body); }
107
+ //res.should.have.status(200);
108
+ // res.body.should.be.a('object');
109
+ // expect(res.body.id_project).to.equal(savedProject._id.toString())
110
+ // expect(res.body.maxKbsNumber).to.equal(3);
111
+ // expect(res.body.maxPagesNumber).to.equal(1000);
112
+ // expect(res.body.kbs).is.an('array').that.is.empty;
113
+ done();
114
+
115
+ })
116
+
117
+
118
+ // res.body.should.be.a('object');
119
+ // expect(res.body.id_project).to.equal(savedProject._id.toString());
120
+
121
+
122
+
123
+
124
+ })
125
+
126
+ });
127
+ });
128
+
129
+ });
130
+
131
+ })
132
+ });
133
+
134
+
@@ -25,7 +25,7 @@ describe('KbSettingsRoute', () => {
25
25
 
26
26
  describe('/create', () => {
27
27
 
28
- it('create kb settings', (done) => {
28
+ it('createKbSettings', (done) => {
29
29
 
30
30
  var email = "test-signup-" + Date.now() + "@email.com";
31
31
  var pwd = "pwd";
@@ -65,7 +65,7 @@ describe('KbSettingsRoute', () => {
65
65
 
66
66
  });
67
67
 
68
- it('create kb settings if not exists', (done) => {
68
+ it('createKbSettingsIfNotExists', (done) => {
69
69
 
70
70
  var email = "test-signup-" + Date.now() + "@email.com";
71
71
  var pwd = "pwd";
@@ -93,7 +93,7 @@ describe('KbSettingsRoute', () => {
93
93
  });
94
94
 
95
95
 
96
- it('add kb to kb settings', (done) => {
96
+ it('addKbToKbSettings', (done) => {
97
97
 
98
98
  var email = "test-signup-" + Date.now() + "@email.com";
99
99
  var pwd = "pwd";
@@ -111,25 +111,27 @@ describe('KbSettingsRoute', () => {
111
111
  res.body.should.be.a('object');
112
112
  expect(res.body.id_project).to.equal(savedProject._id.toString());
113
113
 
114
+ let settings_id = res.body._id;
115
+
114
116
  chai.request(server)
115
- .post('/' + savedProject._id + "/kbsettings/" + res.body._id)
117
+ .post('/' + savedProject._id + "/kbsettings/" + settings_id)
116
118
  .auth(email, pwd)
117
119
  .send({ name: "exampleurl.com/kb/", url: "https://exampleurl.com/kb/" })
118
120
  .end((err, res) => {
119
121
  if (log) { console.log("add kb to kb settings res.body: ", res.body); }
120
122
  res.should.have.status(200);
121
123
  res.body.should.be.a('object');
122
- expect(res.body.kbs).to.have.length(1)
124
+ //expect(res.body.kbs).to.have.length(1)
123
125
 
124
126
  chai.request(server)
125
- .post('/' + savedProject._id + "/kbsettings/" + res.body._id)
127
+ .post('/' + savedProject._id + "/kbsettings/" + settings_id)
126
128
  .auth(email, pwd)
127
129
  .send({ name: "secondurl.com/support/", url: "https://secondurl.com/support/" })
128
130
  .end((err, res) => {
129
131
  if (log) { console.log("add kb to kb settings res.body: ", res.body); }
130
132
  res.should.have.status(200);
131
133
  res.body.should.be.a('object');
132
- expect(res.body.kbs).to.have.length(2)
134
+ //expect(res.body.kbs).to.have.length(2)
133
135
 
134
136
  done();
135
137
  })
@@ -142,7 +144,7 @@ describe('KbSettingsRoute', () => {
142
144
 
143
145
  });
144
146
 
145
- it('update kb settings', (done) => {
147
+ it('updateKbSettings', (done) => {
146
148
 
147
149
  var email = "test-signup-" + Date.now() + "@email.com";
148
150
  var pwd = "pwd";
@@ -178,7 +180,7 @@ describe('KbSettingsRoute', () => {
178
180
 
179
181
  });
180
182
 
181
- it('delete kb from list', (done) => {
183
+ it('deleteKbFromList', (done) => {
182
184
 
183
185
  var email = "test-signup-" + Date.now() + "@email.com";
184
186
  var pwd = "pwd";
@@ -206,9 +208,9 @@ describe('KbSettingsRoute', () => {
206
208
  if (log) { console.log("add kb to kb settings res.body: ", res.body); }
207
209
  res.should.have.status(200);
208
210
  res.body.should.be.a('object');
209
- expect(res.body.kbs).to.have.length(1)
211
+ //expect(res.body.kbs).to.have.length(1)
210
212
 
211
- let kb_to_delete_id = res.body.kbs[0]._id;
213
+ let kb_to_delete_id = res.body._id;
212
214
 
213
215
  chai.request(server)
214
216
  .post('/' + savedProject._id + "/kbsettings/" + settings_id)
@@ -218,7 +220,7 @@ describe('KbSettingsRoute', () => {
218
220
  if (log) { console.log("add kb to kb settings res.body: ", res.body); }
219
221
  res.should.have.status(200);
220
222
  res.body.should.be.a('object');
221
- expect(res.body.kbs).to.have.length(2)
223
+ //expect(res.body.kbs).to.have.length(2)
222
224
 
223
225
  chai.request(server)
224
226
  .delete('/' + savedProject._id + "/kbsettings/" + settings_id + "/" + kb_to_delete_id)