@tiledesk/tiledesk-server 2.28.1 → 2.29.0
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 +9 -0
- package/app.js +5 -34
- package/controllers/chatbot.controller.js +599 -0
- package/controllers/intents.controller.js +139 -0
- package/errorCodes.js +2 -1
- package/event/botEvent.js +43 -3
- package/jobsManager.js +4 -1
- package/middleware/errorHandler.js +41 -0
- package/models/chatbotTemplates.js +4 -0
- package/models/faq.js +10 -0
- package/models/faq_kb.js +14 -0
- package/package.json +4 -4
- package/routes/faq_kb.js +630 -410
- package/services/chatbotService.js +84 -5
- package/services/faqService.js +129 -43
- package/template/chatbot/blank.js +21 -3
- package/template/chatbot/blank_subagent.js +139 -0
- package/template/chatbot/blank_voice.js +21 -4
- package/template/chatbot/blank_voice_twilio.js +21 -5
- package/template/chatbot/index.js +1 -0
- package/template/chatbot/subagent_notes.js +30 -0
- package/test/faqkbRoute.js +982 -523
- package/test/fixtures/example-json-with-subagents.txt +1 -0
- package/test/webhookRoute.js +2 -1
- package/utils/AppError.js +9 -0
- package/utils/asyncHandler.js +10 -0
package/routes/faq_kb.js
CHANGED
|
@@ -19,6 +19,10 @@ var roleChecker = require('../middleware/has-role');
|
|
|
19
19
|
const roleConstants = require('../models/roleConstants');
|
|
20
20
|
const errorCodes = require('../errorCodes');
|
|
21
21
|
const faq_kb = require('../models/faq_kb');
|
|
22
|
+
const chatbotController = require('../controllers/chatbot.controller');
|
|
23
|
+
const intentsController = require('../controllers/intents.controller');
|
|
24
|
+
const AppError = require('../utils/AppError');
|
|
25
|
+
const asyncHandler = require('../utils/asyncHandler');
|
|
22
26
|
|
|
23
27
|
let chatbot_templates_api_url = process.env.CHATBOT_TEMPLATES_API_URL
|
|
24
28
|
|
|
@@ -261,57 +265,100 @@ router.put('/:faq_kbid/publish', roleChecker.hasRole('admin'), async (req, res)
|
|
|
261
265
|
}
|
|
262
266
|
|
|
263
267
|
const api_url = process.env.API_URL || configGlobal.apiUrl;
|
|
264
|
-
winston.debug("fork --> base_url: " + api_url);
|
|
268
|
+
winston.debug("fork --> base_url: " + api_url);
|
|
265
269
|
|
|
266
|
-
|
|
267
|
-
winston.debug("current project id: " + current_project_id);
|
|
268
|
-
|
|
269
|
-
let token = req.headers.authorization;
|
|
270
|
-
|
|
271
|
-
let cs = req.app.get('chatbot_service')
|
|
270
|
+
const cs = req.app.get('chatbot_service');
|
|
272
271
|
|
|
273
272
|
try {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
const published = await cs.publish({
|
|
274
|
+
id_faq_kb,
|
|
275
|
+
chatbot_id,
|
|
276
|
+
api_url,
|
|
277
|
+
token: req.headers.authorization,
|
|
278
|
+
project_id: req.projectid,
|
|
279
|
+
user_id: req.user.id,
|
|
280
|
+
release_note,
|
|
281
|
+
req
|
|
282
|
+
});
|
|
280
283
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
winston.
|
|
284
|
-
|
|
284
|
+
return res.status(200).send({ message: "Chatbot published successfully", bot_id: published.bot_id });
|
|
285
|
+
} catch (e) {
|
|
286
|
+
winston.error("Error Unable publish chatbot: ", e);
|
|
287
|
+
return res.status(500).send({ success: false, message: "Unable publish chatbot" });
|
|
288
|
+
}
|
|
289
|
+
});
|
|
285
290
|
|
|
286
|
-
|
|
287
|
-
let TILEBOT_ENDPOINT = process.env.API_ENDPOINT ? process.env.API_ENDPOINT + "/modules/tilebot/ext/" : ("http://localhost:" + port + "/modules/tilebot/ext/");
|
|
291
|
+
router.put('/:faq_kbid/publish/multi', roleChecker.hasRole('admin'), asyncHandler(async (req, res) => {
|
|
288
292
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
+
const id_project = req.projectid;
|
|
294
|
+
const parent_id = req.params.faq_kbid;
|
|
295
|
+
const chatbots = req.body.chatbots;
|
|
296
|
+
const isValidChatbot = (chatbot) => chatbot && typeof chatbot === 'object' && !Array.isArray(chatbot) && typeof chatbot.id === 'string' && chatbot.id.trim();
|
|
293
297
|
|
|
294
|
-
|
|
295
|
-
|
|
298
|
+
if (!Array.isArray(chatbots) || chatbots.length === 0 || chatbots.some((chatbot) => !isValidChatbot(chatbot))) {
|
|
299
|
+
return res.status(400).send({ success: false, message: "chatbots must be a non-empty array of objects with an id" });
|
|
300
|
+
}
|
|
296
301
|
|
|
297
|
-
|
|
302
|
+
await chatbotController.getChatbot(parent_id, id_project);
|
|
303
|
+
await chatbotController.assertAreSubagents(
|
|
304
|
+
id_project,
|
|
305
|
+
parent_id,
|
|
306
|
+
chatbots.map((chatbot) => chatbot.id)
|
|
307
|
+
);
|
|
298
308
|
|
|
299
|
-
|
|
309
|
+
const api_url = process.env.API_URL || configGlobal.apiUrl;
|
|
310
|
+
const token = req.headers.authorization;
|
|
311
|
+
const user_id = req.user.id;
|
|
312
|
+
const release_note = req.body.release_note || "No comment";
|
|
313
|
+
const cs = req.app.get('chatbot_service');
|
|
314
|
+
const results = [];
|
|
315
|
+
|
|
316
|
+
for (const chatbot of chatbots) {
|
|
317
|
+
const id_faq_kb = chatbot.id;
|
|
318
|
+
try {
|
|
319
|
+
const published = await cs.publish({
|
|
320
|
+
id_faq_kb,
|
|
321
|
+
chatbot_id: id_faq_kb,
|
|
322
|
+
api_url,
|
|
323
|
+
token,
|
|
324
|
+
project_id: id_project,
|
|
325
|
+
user_id,
|
|
326
|
+
release_note: chatbot.release_note || release_note,
|
|
327
|
+
req
|
|
328
|
+
});
|
|
329
|
+
results.push({ id: id_faq_kb, success: true, bot_id: published.bot_id });
|
|
330
|
+
} catch (err) {
|
|
331
|
+
const error = err?.response?.data?.message || err?.response?.data?.error || err?.message || "Publish failed";
|
|
332
|
+
winston.error("Error publishing chatbot " + id_faq_kb + ": ", err);
|
|
333
|
+
results.push({ id: id_faq_kb, success: false, error });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
300
336
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
337
|
+
const failed = results.filter((result) => !result.success);
|
|
338
|
+
if (failed.length > 0) {
|
|
339
|
+
return res.status(500).send({
|
|
340
|
+
success: false,
|
|
341
|
+
message: "Some chatbots failed to publish",
|
|
342
|
+
results
|
|
306
343
|
});
|
|
307
|
-
|
|
308
|
-
return res.status(200).send({ message: "Chatbot published successfully", bot_id: forkedChatBotId });
|
|
309
|
-
|
|
310
|
-
} catch (e) {
|
|
311
|
-
winston.error("Error Unable publish chatbot: ", e);
|
|
312
|
-
return res.status(500).send({ success: false, message: "Unable publish chatbot" });
|
|
313
344
|
}
|
|
314
|
-
|
|
345
|
+
|
|
346
|
+
return res.status(200).send({
|
|
347
|
+
success: true,
|
|
348
|
+
message: "Chatbots published successfully",
|
|
349
|
+
results
|
|
350
|
+
});
|
|
351
|
+
}));
|
|
352
|
+
|
|
353
|
+
router.put('/:faq_kbid/restore/:publish_id', roleChecker.hasRole('admin'), asyncHandler(async (req, res) => {
|
|
354
|
+
const chatbot = await chatbotController.restoreFromPublished(
|
|
355
|
+
req.params.faq_kbid,
|
|
356
|
+
req.params.publish_id,
|
|
357
|
+
req.projectid,
|
|
358
|
+
req.user.id
|
|
359
|
+
);
|
|
360
|
+
return res.status(200).send(chatbot);
|
|
361
|
+
}));
|
|
315
362
|
|
|
316
363
|
router.put('/:faq_kbid', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscription']), function (req, res) {
|
|
317
364
|
|
|
@@ -459,29 +506,69 @@ router.patch('/:faq_kbid/attributes', roleChecker.hasRoleOrTypes('admin', ['bot'
|
|
|
459
506
|
|
|
460
507
|
});
|
|
461
508
|
|
|
462
|
-
router.delete('/:faq_kbid', roleChecker.hasRole('admin'), function (req, res) {
|
|
509
|
+
router.delete('/:faq_kbid', roleChecker.hasRole('admin'), asyncHandler(async function (req, res) {
|
|
463
510
|
|
|
464
511
|
winston.debug(req.body);
|
|
465
512
|
|
|
466
513
|
const chatbot_id = req.params.faq_kbid;
|
|
467
514
|
const id_project = req.projectid;
|
|
468
515
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
516
|
+
let chatbot;
|
|
517
|
+
try {
|
|
518
|
+
chatbot = await Faq_kb.findOne({ _id: chatbot_id, id_project: id_project });
|
|
519
|
+
} catch (err) {
|
|
520
|
+
winston.error("Error getting chatbot: ", err);
|
|
521
|
+
return res.status(500).send({ success: false, msg: 'Error getting chatbot.' });
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (!chatbot) {
|
|
525
|
+
return res.status(404).send({
|
|
526
|
+
success: false,
|
|
527
|
+
msg: "Chatbot not found with id " + chatbot_id + " for project " + id_project
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (chatbot.subtype === 'subagent') {
|
|
532
|
+
let referencingFaq;
|
|
533
|
+
try {
|
|
534
|
+
referencingFaq = await chatbotController.findSubagentCaller(chatbot, id_project);
|
|
535
|
+
} catch (err) {
|
|
536
|
+
winston.error("Error checking subagent references: ", err);
|
|
537
|
+
return res.status(500).send({ success: false, msg: 'Error checking subagent references.' });
|
|
472
538
|
}
|
|
473
539
|
|
|
474
|
-
if (
|
|
475
|
-
return res.status(
|
|
540
|
+
if (referencingFaq) {
|
|
541
|
+
return res.status(409).send({
|
|
542
|
+
success: false,
|
|
543
|
+
msg: "Cannot delete subagent because it is still referenced by another chatbot",
|
|
544
|
+
error_code: errorCodes.CHATBOT.ERRORS.SUBAGENT_IN_USE,
|
|
545
|
+
referenced_by: {
|
|
546
|
+
id_faq_kb: referencingFaq.id_faq_kb,
|
|
547
|
+
intent_display_name: referencingFaq.intent_display_name
|
|
548
|
+
}
|
|
549
|
+
});
|
|
476
550
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
});
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
let deletedFaqKb;
|
|
554
|
+
try {
|
|
555
|
+
deletedFaqKb = await Faq_kb.findOneAndDelete({ _id: chatbot_id, id_project: id_project });
|
|
556
|
+
} catch (err) {
|
|
557
|
+
winston.error("Error deleting chatbot: ", err);
|
|
558
|
+
return res.status(500).send({ success: false, msg: 'Error deleting object.' });
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
if (!deletedFaqKb) {
|
|
562
|
+
return res.status(404).send({ success: false, msg: "Chatbot not found with id " + chatbot_id + " for project " + id_project });
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* WARNING: faq_kb is the operation result, not the faq_kb object. The event subscriber will not receive the object as expected.
|
|
567
|
+
*/
|
|
568
|
+
botEvent.emit('faqbot.delete', deletedFaqKb);
|
|
569
|
+
botEvent.emit('faqbot.deleted', { req, chatbot: deletedFaqKb });
|
|
570
|
+
return res.status(200).send({ success: true, message: "Chatbot with id " + req.params.faq_kbid + " deleted successfully" });
|
|
571
|
+
}));
|
|
485
572
|
|
|
486
573
|
router.get('/:faq_kbid', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscription']), function (req, res) {
|
|
487
574
|
|
|
@@ -549,6 +636,26 @@ router.get('/:faq_kbid/published', roleChecker.hasRoleOrTypes('admin', ['bot', '
|
|
|
549
636
|
|
|
550
637
|
})
|
|
551
638
|
|
|
639
|
+
router.get('/:faq_kbid/subagents', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscription']), async function (req, res) {
|
|
640
|
+
|
|
641
|
+
const id_project = req.projectid;
|
|
642
|
+
const chatbot_id = req.params.faq_kbid;
|
|
643
|
+
|
|
644
|
+
let subagents;
|
|
645
|
+
try {
|
|
646
|
+
subagents = await Faq_kb.find({
|
|
647
|
+
id_project: id_project,
|
|
648
|
+
parent_id: chatbot_id,
|
|
649
|
+
trashed: { $in: [null, false] }
|
|
650
|
+
}).sort({ createdAt: -1 }).lean().exec();
|
|
651
|
+
return res.status(200).send(subagents);
|
|
652
|
+
} catch (err) {
|
|
653
|
+
winston.error("Error finding subagents: ", err);
|
|
654
|
+
return res.status(500).send({ success: false, error: "Error finding subagents from root " + chatbot_id });
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
})
|
|
658
|
+
|
|
552
659
|
router.get('/:faq_kbid/jwt', roleChecker.hasRoleOrTypes('admin', ['bot', 'subscription']), function (req, res) {
|
|
553
660
|
|
|
554
661
|
winston.debug(req.query);
|
|
@@ -613,7 +720,7 @@ router.get('/', roleChecker.hasRoleOrTypes('agent', ['bot', 'subscription']), fu
|
|
|
613
720
|
* if filter only for 'trashed = false',
|
|
614
721
|
* the bots created before the implementation of the 'trashed' property are not returned
|
|
615
722
|
*/
|
|
616
|
-
let query = { id_project: id_project, trashed: { $in: [null, false] } };
|
|
723
|
+
let query = { id_project: id_project, subtype: { $ne: "subagent" }, trashed: { $in: [null, false] } };
|
|
617
724
|
|
|
618
725
|
if (restricted_mode === true) {
|
|
619
726
|
query.agents_available = {
|
|
@@ -656,97 +763,151 @@ router.get('/', roleChecker.hasRoleOrTypes('agent', ['bot', 'subscription']), fu
|
|
|
656
763
|
})
|
|
657
764
|
});
|
|
658
765
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
766
|
+
// DEPRECATED: create shell via createBot, then import intents/subagents into it
|
|
767
|
+
// router.post('/fork/:id_faq_kb', roleChecker.hasRole('admin'), async (req, res) => {
|
|
768
|
+
//
|
|
769
|
+
// let id_faq_kb = req.params.id_faq_kb;
|
|
770
|
+
// winston.debug('id_faq_kb: ' + id_faq_kb);
|
|
771
|
+
//
|
|
772
|
+
// const api_url = process.env.API_URL || configGlobal.apiUrl;
|
|
773
|
+
// winston.debug("fork --> base_url: " + api_url); // check if correct
|
|
774
|
+
//
|
|
775
|
+
// let current_project_id = req.projectid;
|
|
776
|
+
// winston.debug("current project id: " + current_project_id);
|
|
777
|
+
//
|
|
778
|
+
// let landing_project_id = req.query.projectid;
|
|
779
|
+
// winston.debug("landing project id " + landing_project_id)
|
|
780
|
+
//
|
|
781
|
+
// let public = req.query.public;
|
|
782
|
+
// winston.debug("public " + public);
|
|
783
|
+
//
|
|
784
|
+
// let globals = req.query.globals;
|
|
785
|
+
// winston.debug("export globals " + globals);
|
|
786
|
+
//
|
|
787
|
+
// let token = req.headers.authorization;
|
|
788
|
+
//
|
|
789
|
+
// let cs = req.app.get('chatbot_service')
|
|
790
|
+
// let chatbot;
|
|
791
|
+
// try {
|
|
792
|
+
// chatbot = await cs.getBotById(id_faq_kb, public, api_url, chatbot_templates_api_url, token, current_project_id, globals);
|
|
793
|
+
// } catch (err) {
|
|
794
|
+
// return res.status(500).send({ success: false, error: "Unable to get chatbot to be forked"});
|
|
795
|
+
// }
|
|
796
|
+
//
|
|
797
|
+
// if (!chatbot) {
|
|
798
|
+
// return res.status(500).send({ success: false, message: "Unable to get chatbot to be forked" });
|
|
799
|
+
// }
|
|
800
|
+
//
|
|
801
|
+
// if (!globals) {
|
|
802
|
+
// if (chatbot.attributes) {
|
|
803
|
+
// delete chatbot.attributes.globals
|
|
804
|
+
// }
|
|
805
|
+
// }
|
|
806
|
+
//
|
|
807
|
+
// delete chatbot.modified;
|
|
808
|
+
//
|
|
809
|
+
// chatbot.template = "empty";
|
|
810
|
+
//
|
|
811
|
+
// let savedChatbot
|
|
812
|
+
// try {
|
|
813
|
+
// savedChatbot = await cs.createBot(api_url, token, chatbot, landing_project_id);
|
|
814
|
+
// winston.debug("savedChatbot: ", savedChatbot)
|
|
815
|
+
// } catch(err) {
|
|
816
|
+
// winston.error("Error creating new chatbot: ", err);
|
|
817
|
+
// return res.status(500).send({ success: false, message: "An error occurred during chatbot creation"});
|
|
818
|
+
// }
|
|
819
|
+
//
|
|
820
|
+
// if (!savedChatbot) {
|
|
821
|
+
// return res.status(500).send({ success: false, message: "Unable to create new chatbot" });
|
|
822
|
+
// }
|
|
823
|
+
//
|
|
824
|
+
// let import_result
|
|
825
|
+
// try {
|
|
826
|
+
// // Imports parent intents and linked subagents (with their intents) into the new parent.
|
|
827
|
+
// import_result = await cs.importFaqs(api_url, savedChatbot._id, token, chatbot, landing_project_id);
|
|
828
|
+
// winston.debug("imported: ", import_result);
|
|
829
|
+
// } catch(err) {
|
|
830
|
+
// winston.error("Error importing chatbot content on fork: ", err);
|
|
831
|
+
// return res.status(500).send({ success: false, message: "Error importing chatbot content (intents/subagents)"});
|
|
832
|
+
// }
|
|
833
|
+
//
|
|
834
|
+
// if (import_result?.success == false) {
|
|
835
|
+
// return res.status(500).send({ success: false, message: "Unable to import chatbot content in the new chatbot" });
|
|
836
|
+
// }
|
|
837
|
+
//
|
|
838
|
+
// return res.status(200).send({ message: "Chatbot forked successfully", bot_id: savedChatbot._id });
|
|
839
|
+
//
|
|
840
|
+
// })
|
|
841
|
+
|
|
842
|
+
// Export source chatbot, then import with create=true (parent + intents + linked subagents)
|
|
843
|
+
router.post('/fork/:id_faq_kb', roleChecker.hasRole('admin'), asyncHandler(async (req, res) => {
|
|
844
|
+
|
|
845
|
+
const id_faq_kb = req.params.id_faq_kb;
|
|
664
846
|
const api_url = process.env.API_URL || configGlobal.apiUrl;
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
847
|
+
const current_project_id = req.projectid;
|
|
848
|
+
const landing_project_id = req.query.projectid;
|
|
849
|
+
const public = req.query.public;
|
|
850
|
+
const globals = req.query.globals;
|
|
851
|
+
const token = req.headers.authorization;
|
|
852
|
+
const user_id = req.user.id;
|
|
853
|
+
|
|
854
|
+
winston.debug('fork id_faq_kb: ' + id_faq_kb);
|
|
855
|
+
winston.debug("fork --> base_url: " + api_url);
|
|
668
856
|
winston.debug("current project id: " + current_project_id);
|
|
669
|
-
|
|
670
|
-
let landing_project_id = req.query.projectid;
|
|
671
|
-
winston.debug("landing project id " + landing_project_id)
|
|
672
|
-
|
|
673
|
-
let public = req.query.public;
|
|
857
|
+
winston.debug("landing project id " + landing_project_id);
|
|
674
858
|
winston.debug("public " + public);
|
|
675
|
-
|
|
676
|
-
let globals = req.query.globals;
|
|
677
859
|
winston.debug("export globals " + globals);
|
|
678
860
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
let cs = req.app.get('chatbot_service')
|
|
861
|
+
const cs = req.app.get('chatbot_service');
|
|
682
862
|
let chatbot;
|
|
683
863
|
try {
|
|
684
864
|
chatbot = await cs.getBotById(id_faq_kb, public, api_url, chatbot_templates_api_url, token, current_project_id, globals);
|
|
685
865
|
} catch (err) {
|
|
686
|
-
return res.status(500).send({ success: false, error: "Unable to get chatbot to be forked"});
|
|
866
|
+
return res.status(500).send({ success: false, error: "Unable to get chatbot to be forked" });
|
|
687
867
|
}
|
|
688
868
|
|
|
689
869
|
if (!chatbot) {
|
|
690
870
|
return res.status(500).send({ success: false, message: "Unable to get chatbot to be forked" });
|
|
691
871
|
}
|
|
692
872
|
|
|
693
|
-
if (!globals) {
|
|
694
|
-
|
|
695
|
-
delete chatbot.attributes.globals
|
|
696
|
-
}
|
|
873
|
+
if (!globals && chatbot.attributes) {
|
|
874
|
+
delete chatbot.attributes.globals;
|
|
697
875
|
}
|
|
698
|
-
|
|
699
|
-
delete chatbot.modified;
|
|
700
876
|
|
|
701
|
-
chatbot.
|
|
702
|
-
|
|
703
|
-
let savedChatbot
|
|
704
|
-
try {
|
|
705
|
-
savedChatbot = await cs.createBot(api_url, token, chatbot, landing_project_id);
|
|
706
|
-
winston.debug("savedChatbot: ", savedChatbot)
|
|
707
|
-
} catch(err) {
|
|
708
|
-
winston.error("Error creating new chatbot: ", err);
|
|
709
|
-
return res.status(500).send({ success: false, message: "An error occurred during chatbot creation"});
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
if (!savedChatbot) {
|
|
713
|
-
return res.status(500).send({ success: false, message: "Unable to create new chatbot" });
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
let import_result
|
|
717
|
-
try {
|
|
718
|
-
import_result = await cs.importFaqs(api_url, savedChatbot._id, token, chatbot, landing_project_id);
|
|
719
|
-
winston.debug("imported: ", import_result);
|
|
720
|
-
} catch(err) {
|
|
721
|
-
winston.error("Error importing intents on new chatbot: ", err);
|
|
722
|
-
return res.status(500).send({ success: false, message: "Error importing intents in the chatbot"});
|
|
723
|
-
}
|
|
877
|
+
delete chatbot.modified;
|
|
724
878
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
879
|
+
// Publish passes skipSubagents so actions keep the development subagent id.
|
|
880
|
+
// A plain fork still clones subagents into the copy.
|
|
881
|
+
const skipSubagents = req.query.skipSubagents === 'true';
|
|
882
|
+
|
|
883
|
+
const savedChatbot = await chatbotController.import(
|
|
884
|
+
chatbot,
|
|
885
|
+
landing_project_id,
|
|
886
|
+
null,
|
|
887
|
+
true,
|
|
888
|
+
false,
|
|
889
|
+
false,
|
|
890
|
+
user_id,
|
|
891
|
+
skipSubagents
|
|
892
|
+
);
|
|
728
893
|
|
|
729
894
|
if (req.query.for_publish !== 'true') {
|
|
730
895
|
botEvent.emit('faqbot.created', { req, chatbot: savedChatbot, id_project: landing_project_id });
|
|
731
896
|
}
|
|
732
897
|
|
|
733
898
|
return res.status(200).send({ message: "Chatbot forked successfully", bot_id: savedChatbot._id });
|
|
899
|
+
}))
|
|
734
900
|
|
|
735
|
-
|
|
901
|
+
router.post('/importjson/:id_faq_kb', roleChecker.hasRole('admin'), upload.single('uploadFile'), asyncHandler(async (req, res) => {
|
|
736
902
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
winston.debug('import with option create: ' + req.query.create);
|
|
745
|
-
winston.debug('import with option replace: ' + req.query.replace);
|
|
746
|
-
winston.debug('import with option overwrite: ' + req.query.overwrite);
|
|
903
|
+
const chatbot_id = req.params.id_faq_kb;
|
|
904
|
+
const id_project = req.projectid;
|
|
905
|
+
const create = req.query.create === 'true';
|
|
906
|
+
const replace = req.query.replace === 'true';
|
|
907
|
+
const overwrite = req.query.overwrite === 'true';
|
|
908
|
+
const user_id = req.user.id;
|
|
747
909
|
|
|
748
|
-
let json_string;
|
|
749
|
-
let json;
|
|
910
|
+
let json, json_string;
|
|
750
911
|
if (req.file) {
|
|
751
912
|
json_string = req.file.buffer.toString('utf-8');
|
|
752
913
|
json = JSON.parse(json_string);
|
|
@@ -754,313 +915,372 @@ router.post('/importjson/:id_faq_kb', roleChecker.hasRole('admin'), upload.singl
|
|
|
754
915
|
json = req.body;
|
|
755
916
|
}
|
|
756
917
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
// **** CREATE TRUE option ****
|
|
761
|
-
// ****************************
|
|
762
|
-
if (req.query.create === 'true') {
|
|
763
|
-
// if (json.subtype && (json.subtype === 'webhook' || json.subtype === 'copilot')) {
|
|
764
|
-
// json.template = 'empty';
|
|
765
|
-
// }
|
|
766
|
-
json.template = 'empty';
|
|
767
|
-
let savedChatbot = await faqService.create(req.projectid, req.user.id, json)
|
|
768
|
-
.catch((err) => {
|
|
769
|
-
winston.error("Error creating new chatbot")
|
|
770
|
-
return res.status(400).send({ succes: false, message: "Error creatings new chatbot", error: err })
|
|
771
|
-
})
|
|
772
|
-
|
|
773
|
-
// Edit attributes.rules
|
|
774
|
-
let attributes = json.attributes;
|
|
775
|
-
if (attributes &&
|
|
776
|
-
attributes.rules &&
|
|
777
|
-
attributes.rules.length > 0) {
|
|
778
|
-
|
|
779
|
-
await attributes.rules.forEach((rule) => {
|
|
780
|
-
if (rule.do &&
|
|
781
|
-
rule.do[0] &&
|
|
782
|
-
rule.do[0].message &&
|
|
783
|
-
rule.do[0].message.participants &&
|
|
784
|
-
rule.do[0].message.participants[0]) {
|
|
785
|
-
rule.do[0].message.participants[0] = "bot_" + savedChatbot._id
|
|
786
|
-
winston.debug("attributes rule new participant: ", rule.do[0].message.participants[0])
|
|
787
|
-
}
|
|
788
|
-
})
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
let chatbot_edited = { attributes: attributes };
|
|
792
|
-
|
|
793
|
-
let updatedChatbot = await Faq_kb.findByIdAndUpdate(savedChatbot._id, chatbot_edited, { new: true }).catch((err) => {
|
|
794
|
-
winston.error("Error updating chatbot attributes: ", err);
|
|
795
|
-
winston.debug("Skip Error updating chatbot attributes: ", err);
|
|
796
|
-
// return res.status(400).send({ success: false, message: "Error updating chatbot attributes", error: err })
|
|
797
|
-
})
|
|
798
|
-
|
|
799
|
-
botEvent.emit('faqbot.create', savedChatbot);
|
|
800
|
-
botEvent.emit('faqbot.created', { req, chatbot: savedChatbot });
|
|
801
|
-
|
|
802
|
-
if (json.intents) {
|
|
803
|
-
|
|
804
|
-
json.intents.forEach(async (intent) => {
|
|
805
|
-
|
|
806
|
-
let new_faq = {
|
|
807
|
-
id_faq_kb: savedChatbot._id,
|
|
808
|
-
id_project: req.projectid,
|
|
809
|
-
createdBy: req.user.id,
|
|
810
|
-
intent_display_name: intent.intent_display_name,
|
|
811
|
-
intent_id: intent.intent_id,
|
|
812
|
-
question: intent.question,
|
|
813
|
-
answer: intent.answer,
|
|
814
|
-
reply: intent.reply,
|
|
815
|
-
form: intent.form,
|
|
816
|
-
enabled: intent.enabled,
|
|
817
|
-
webhook_enabled: intent.webhook_enabled,
|
|
818
|
-
language: intent.language,
|
|
819
|
-
actions: intent.actions,
|
|
820
|
-
attributes: intent.attributes
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
let faq = await Faq.create(new_faq).catch((err) => {
|
|
824
|
-
if (err.code == 11000) { // should never happen
|
|
825
|
-
winston.error("Duplicate intent_display_name.");
|
|
826
|
-
winston.debug("Skip duplicated intent_display_name"); // Don't stop the flow
|
|
827
|
-
} else {
|
|
828
|
-
winston.error("Error saving new faq: ", err)
|
|
829
|
-
}
|
|
830
|
-
})
|
|
831
|
-
|
|
832
|
-
if (faq) {
|
|
833
|
-
winston.debug("new intent created")
|
|
834
|
-
faqBotEvent.emit('faq.create', faq);
|
|
835
|
-
}
|
|
836
|
-
})
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
if (updatedChatbot) {
|
|
840
|
-
return res.status(200).send(updatedChatbot)
|
|
841
|
-
} else {
|
|
842
|
-
return res.status(200).send(savedChatbot)
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
// *****************************
|
|
846
|
-
// **** CREATE FALSE option ****
|
|
847
|
-
// *****************************
|
|
848
|
-
else {
|
|
849
|
-
|
|
850
|
-
if (!chatbot_id) {
|
|
851
|
-
return res.status(400).send({ success: false, message: "With replace or overwrite option a id_faq_kb must be provided" })
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
let chatbot = await Faq_kb.findOne({ _id: chatbot_id, id_project: id_project }).catch((err) => {
|
|
855
|
-
winston.error("Error finding chatbot with id " + chatbot_id);
|
|
856
|
-
return res.status(404).send({ success: false, message: "Error finding chatbot with id " + chatbot_id, error: err });
|
|
857
|
-
})
|
|
858
|
-
|
|
859
|
-
if (!chatbot) {
|
|
860
|
-
winston.error("Chatbot not found with id " + chatbot_id + " for project " + id_project);
|
|
861
|
-
return res.status(404).send({ success: false, message: "Chatbot not found with id " + chatbot_id + " for project " + id_project });
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
if (json.webhook_enabled) {
|
|
865
|
-
chatbot.webhook_enabled = json.webhook_enabled;
|
|
866
|
-
}
|
|
867
|
-
if (json.webhook_url) {
|
|
868
|
-
chatbot.webhook_url = json.webhook_url;
|
|
869
|
-
}
|
|
870
|
-
if (json.language) {
|
|
871
|
-
chatbot.language = json.language;
|
|
872
|
-
}
|
|
873
|
-
if (json.name) {
|
|
874
|
-
chatbot.name = json.name;
|
|
875
|
-
}
|
|
876
|
-
if (json.description) {
|
|
877
|
-
chatbot.description = json.description;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
if (json.attributes) {
|
|
881
|
-
let attributes = json.attributes;
|
|
882
|
-
if (attributes.rules &&
|
|
883
|
-
attributes.rules.length > 0) {
|
|
884
|
-
await attributes.rules.forEach((rule) => {
|
|
885
|
-
if (rule.do &&
|
|
886
|
-
rule.do[0] &&
|
|
887
|
-
rule.do[0].message &&
|
|
888
|
-
rule.do[0].message.participants &&
|
|
889
|
-
rule.do[0].message.participants[0]) {
|
|
890
|
-
rule.do[0].message.participants[0] = "bot_" + chatbot._id
|
|
891
|
-
winston.debug("attributes rule new participant: " + rule.do[0].message.participants[0])
|
|
892
|
-
}
|
|
893
|
-
})
|
|
894
|
-
chatbot.attributes = json.attributes;
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
let updatedChatbot = await Faq_kb.findByIdAndUpdate(chatbot._id, chatbot, { new: true }).catch((err) => {
|
|
899
|
-
winston.error("Error updating chatbot");
|
|
900
|
-
return res.status(400).send({ success: false, message: "Error updating chatbot", error: err })
|
|
901
|
-
})
|
|
902
|
-
|
|
903
|
-
botEvent.emit('faqbot.update', updatedChatbot);
|
|
904
|
-
|
|
905
|
-
// *****************************
|
|
906
|
-
// **** REPLACE TRUE option ****
|
|
907
|
-
// *****************************
|
|
908
|
-
if (req.query.replace === 'true') {
|
|
909
|
-
let result = await Faq.deleteMany({ id_faq_kb: chatbot._id }).catch((err) => {
|
|
910
|
-
winston.error("Unable to delete all existing faqs with id_faq_kb " + chatbot._id);
|
|
911
|
-
})
|
|
912
|
-
|
|
913
|
-
winston.verbose("All faq for chatbot " + chatbot._id + " deleted successfully")
|
|
914
|
-
winston.debug("DeleteMany faqs result ", result);
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
if (json.intents) {
|
|
918
|
-
await json.intents.forEach(async (intent) => {
|
|
919
|
-
|
|
920
|
-
let new_faq = {
|
|
921
|
-
id_faq_kb: updatedChatbot._id,
|
|
922
|
-
id_project: req.projectid,
|
|
923
|
-
createdBy: req.user.id,
|
|
924
|
-
intent_display_name: intent.intent_display_name,
|
|
925
|
-
intent_id: intent.intent_id,
|
|
926
|
-
question: intent.question,
|
|
927
|
-
answer: intent.answer,
|
|
928
|
-
reply: intent.reply,
|
|
929
|
-
form: intent.form,
|
|
930
|
-
enabled: intent.enabled,
|
|
931
|
-
webhook_enabled: intent.webhook_enabled,
|
|
932
|
-
language: intent.language,
|
|
933
|
-
actions: intent.actions,
|
|
934
|
-
attributes: intent.attributes
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
// *******************************
|
|
938
|
-
// **** OVERWRITE TRUE option ****
|
|
939
|
-
// *******************************
|
|
940
|
-
if (req.query.overwrite == "true") {
|
|
941
|
-
|
|
942
|
-
let savingResult = await Faq.findOneAndUpdate({ id_faq_kb: chatbot._id, intent_display_name: intent.intent_display_name }, new_faq, { new: true, upsert: true, rawResult: true }).catch((err) => {
|
|
943
|
-
winston.error("Unable to create faq: ", err);
|
|
944
|
-
})
|
|
945
|
-
|
|
946
|
-
if (savingResult) {
|
|
947
|
-
if (savingResult.lastErrorObject.updatedExisting === true) {
|
|
948
|
-
winston.verbose("updated existing intent")
|
|
949
|
-
faqBotEvent.emit('faq.update', savingResult.value);
|
|
950
|
-
} else {
|
|
951
|
-
winston.verbose("new intent created")
|
|
952
|
-
faqBotEvent.emit('faq.create', savingResult.value);
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
// ********************************
|
|
957
|
-
// **** OVERWRITE FALSE option ****
|
|
958
|
-
// ********************************
|
|
959
|
-
} else {
|
|
960
|
-
|
|
961
|
-
let faq = await Faq.create(new_faq).catch((err) => {
|
|
962
|
-
if (err.code == 11000) {
|
|
963
|
-
winston.error("Duplicate intent_display_name.");
|
|
964
|
-
winston.verbose("Skip duplicated intent_display_name");
|
|
965
|
-
} else {
|
|
966
|
-
winston.error("Error creating new intent: ", err);
|
|
967
|
-
}
|
|
968
|
-
})
|
|
969
|
-
|
|
970
|
-
if (faq) {
|
|
971
|
-
winston.debug("new intent created: ", faq)
|
|
972
|
-
faqBotEvent.emit('faq.create', faq);
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
})
|
|
976
|
-
}
|
|
977
|
-
|
|
978
|
-
if (updatedChatbot) {
|
|
979
|
-
return res.send(updatedChatbot);
|
|
980
|
-
} else {
|
|
981
|
-
return res.send(chatbot);
|
|
982
|
-
}
|
|
918
|
+
const chatbot = await chatbotController.import(json, id_project, chatbot_id, create, replace, overwrite, user_id);
|
|
919
|
+
if (create) {
|
|
920
|
+
botEvent.emit('faqbot.created', { req, chatbot });
|
|
983
921
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
922
|
+
return res.status(200).send(chatbot);
|
|
923
|
+
}))
|
|
924
|
+
|
|
925
|
+
// router.post('/importjson/:id_faq_kb', roleChecker.hasRole('admin'), upload.single('uploadFile'), async (req, res) => {
|
|
926
|
+
|
|
927
|
+
// let chatbot_id = req.params.id_faq_kb;
|
|
928
|
+
// let id_project = req.projectid;
|
|
929
|
+
|
|
930
|
+
// winston.debug('import on id_faq_kb: ' + chatbot_id);
|
|
931
|
+
|
|
932
|
+
// winston.debug('import with option create: ' + req.query.create);
|
|
933
|
+
// winston.debug('import with option replace: ' + req.query.replace);
|
|
934
|
+
// winston.debug('import with option overwrite: ' + req.query.overwrite);
|
|
935
|
+
|
|
936
|
+
// let json_string;
|
|
937
|
+
// let json;
|
|
938
|
+
// if (req.file) {
|
|
939
|
+
// json_string = req.file.buffer.toString('utf-8');
|
|
940
|
+
// json = JSON.parse(json_string);
|
|
941
|
+
// } else {
|
|
942
|
+
// json = req.body;
|
|
943
|
+
// }
|
|
944
|
+
|
|
945
|
+
// winston.debug("json source " + json_string)
|
|
946
|
+
|
|
947
|
+
// // ****************************
|
|
948
|
+
// // **** CREATE TRUE option ****
|
|
949
|
+
// // ****************************
|
|
950
|
+
// if (req.query.create === 'true') {
|
|
951
|
+
// // if (json.subtype && (json.subtype === 'webhook' || json.subtype === 'copilot')) {
|
|
952
|
+
// // json.template = 'empty';
|
|
953
|
+
// // }
|
|
954
|
+
// json.template = 'empty';
|
|
955
|
+
// let savedChatbot = await faqService.create(req.projectid, req.user.id, json)
|
|
956
|
+
// .catch((err) => {
|
|
957
|
+
// winston.error("Error creating new chatbot")
|
|
958
|
+
// return res.status(400).send({ succes: false, message: "Error creatings new chatbot", error: err })
|
|
959
|
+
// })
|
|
960
|
+
|
|
961
|
+
// // Edit attributes.rules
|
|
962
|
+
// let attributes = json.attributes;
|
|
963
|
+
// if (attributes &&
|
|
964
|
+
// attributes.rules &&
|
|
965
|
+
// attributes.rules.length > 0) {
|
|
966
|
+
|
|
967
|
+
// await attributes.rules.forEach((rule) => {
|
|
968
|
+
// if (rule.do &&
|
|
969
|
+
// rule.do[0] &&
|
|
970
|
+
// rule.do[0].message &&
|
|
971
|
+
// rule.do[0].message.participants &&
|
|
972
|
+
// rule.do[0].message.participants[0]) {
|
|
973
|
+
// rule.do[0].message.participants[0] = "bot_" + savedChatbot._id
|
|
974
|
+
// winston.debug("attributes rule new participant: ", rule.do[0].message.participants[0])
|
|
975
|
+
// }
|
|
976
|
+
// })
|
|
977
|
+
// }
|
|
978
|
+
|
|
979
|
+
// let chatbot_edited = { attributes: attributes };
|
|
980
|
+
|
|
981
|
+
// let updatedChatbot = await Faq_kb.findByIdAndUpdate(savedChatbot._id, chatbot_edited, { new: true }).catch((err) => {
|
|
982
|
+
// winston.error("Error updating chatbot attributes: ", err);
|
|
983
|
+
// winston.debug("Skip Error updating chatbot attributes: ", err);
|
|
984
|
+
// // return res.status(400).send({ success: false, message: "Error updating chatbot attributes", error: err })
|
|
985
|
+
// })
|
|
986
|
+
|
|
987
|
+
// botEvent.emit('faqbot.create', savedChatbot);
|
|
988
|
+
|
|
989
|
+
// if (json.intents) {
|
|
990
|
+
|
|
991
|
+
// json.intents.forEach(async (intent) => {
|
|
992
|
+
|
|
993
|
+
// let new_faq = {
|
|
994
|
+
// id_faq_kb: savedChatbot._id,
|
|
995
|
+
// id_project: req.projectid,
|
|
996
|
+
// createdBy: req.user.id,
|
|
997
|
+
// intent_display_name: intent.intent_display_name,
|
|
998
|
+
// intent_id: intent.intent_id,
|
|
999
|
+
// question: intent.question,
|
|
1000
|
+
// answer: intent.answer,
|
|
1001
|
+
// reply: intent.reply,
|
|
1002
|
+
// form: intent.form,
|
|
1003
|
+
// enabled: intent.enabled,
|
|
1004
|
+
// webhook_enabled: intent.webhook_enabled,
|
|
1005
|
+
// language: intent.language,
|
|
1006
|
+
// actions: intent.actions,
|
|
1007
|
+
// attributes: intent.attributes
|
|
1008
|
+
// }
|
|
1009
|
+
|
|
1010
|
+
// let faq = await Faq.create(new_faq).catch((err) => {
|
|
1011
|
+
// if (err.code == 11000) { // should never happen
|
|
1012
|
+
// winston.error("Duplicate intent_display_name.");
|
|
1013
|
+
// winston.debug("Skip duplicated intent_display_name"); // Don't stop the flow
|
|
1014
|
+
// } else {
|
|
1015
|
+
// winston.error("Error saving new faq: ", err)
|
|
1016
|
+
// }
|
|
1017
|
+
// })
|
|
1018
|
+
|
|
1019
|
+
// if (faq) {
|
|
1020
|
+
// winston.debug("new intent created")
|
|
1021
|
+
// faqBotEvent.emit('faq.create', faq);
|
|
1022
|
+
// }
|
|
1023
|
+
// })
|
|
1024
|
+
// }
|
|
1025
|
+
|
|
1026
|
+
// if (updatedChatbot) {
|
|
1027
|
+
// return res.status(200).send(updatedChatbot)
|
|
1028
|
+
// } else {
|
|
1029
|
+
// return res.status(200).send(savedChatbot)
|
|
1030
|
+
// }
|
|
1031
|
+
// }
|
|
1032
|
+
// // *****************************
|
|
1033
|
+
// // **** CREATE FALSE option ****
|
|
1034
|
+
// // *****************************
|
|
1035
|
+
// else {
|
|
1036
|
+
|
|
1037
|
+
// if (!chatbot_id) {
|
|
1038
|
+
// return res.status(400).send({ success: false, message: "With replace or overwrite option a id_faq_kb must be provided" })
|
|
1039
|
+
// }
|
|
1040
|
+
|
|
1041
|
+
// let chatbot = await Faq_kb.findOne({ _id: chatbot_id, id_project: id_project }).catch((err) => {
|
|
1042
|
+
// winston.error("Error finding chatbot with id " + chatbot_id);
|
|
1043
|
+
// return res.status(404).send({ success: false, message: "Error finding chatbot with id " + chatbot_id, error: err });
|
|
1044
|
+
// })
|
|
1045
|
+
|
|
1046
|
+
// if (!chatbot) {
|
|
1047
|
+
// winston.error("Chatbot not found with id " + chatbot_id + " for project " + id_project);
|
|
1048
|
+
// return res.status(404).send({ success: false, message: "Chatbot not found with id " + chatbot_id + " for project " + id_project });
|
|
1049
|
+
// }
|
|
1050
|
+
|
|
1051
|
+
// if (json.webhook_enabled) {
|
|
1052
|
+
// chatbot.webhook_enabled = json.webhook_enabled;
|
|
1053
|
+
// }
|
|
1054
|
+
// if (json.webhook_url) {
|
|
1055
|
+
// chatbot.webhook_url = json.webhook_url;
|
|
1056
|
+
// }
|
|
1057
|
+
// if (json.language) {
|
|
1058
|
+
// chatbot.language = json.language;
|
|
1059
|
+
// }
|
|
1060
|
+
// if (json.name) {
|
|
1061
|
+
// chatbot.name = json.name;
|
|
1062
|
+
// }
|
|
1063
|
+
// if (json.description) {
|
|
1064
|
+
// chatbot.description = json.description;
|
|
1065
|
+
// }
|
|
1066
|
+
|
|
1067
|
+
// if (json.attributes) {
|
|
1068
|
+
// let attributes = json.attributes;
|
|
1069
|
+
// if (attributes.rules &&
|
|
1070
|
+
// attributes.rules.length > 0) {
|
|
1071
|
+
// await attributes.rules.forEach((rule) => {
|
|
1072
|
+
// if (rule.do &&
|
|
1073
|
+
// rule.do[0] &&
|
|
1074
|
+
// rule.do[0].message &&
|
|
1075
|
+
// rule.do[0].message.participants &&
|
|
1076
|
+
// rule.do[0].message.participants[0]) {
|
|
1077
|
+
// rule.do[0].message.participants[0] = "bot_" + chatbot._id
|
|
1078
|
+
// winston.debug("attributes rule new participant: " + rule.do[0].message.participants[0])
|
|
1079
|
+
// }
|
|
1080
|
+
// })
|
|
1081
|
+
// chatbot.attributes = json.attributes;
|
|
1082
|
+
// }
|
|
1083
|
+
// }
|
|
1084
|
+
|
|
1085
|
+
// let updatedChatbot = await Faq_kb.findByIdAndUpdate(chatbot._id, chatbot, { new: true }).catch((err) => {
|
|
1086
|
+
// winston.error("Error updating chatbot");
|
|
1087
|
+
// return res.status(400).send({ success: false, message: "Error updating chatbot", error: err })
|
|
1088
|
+
// })
|
|
1089
|
+
|
|
1090
|
+
// botEvent.emit('faqbot.update', updatedChatbot);
|
|
1091
|
+
|
|
1092
|
+
// // *****************************
|
|
1093
|
+
// // **** REPLACE TRUE option ****
|
|
1094
|
+
// // *****************************
|
|
1095
|
+
// if (req.query.replace === 'true') {
|
|
1096
|
+
// let result = await Faq.deleteMany({ id_faq_kb: chatbot._id }).catch((err) => {
|
|
1097
|
+
// winston.error("Unable to delete all existing faqs with id_faq_kb " + chatbot._id);
|
|
1098
|
+
// })
|
|
1099
|
+
|
|
1100
|
+
// winston.verbose("All faq for chatbot " + chatbot._id + " deleted successfully")
|
|
1101
|
+
// winston.debug("DeleteMany faqs result ", result);
|
|
1102
|
+
// }
|
|
1103
|
+
|
|
1104
|
+
// if (json.intents) {
|
|
1105
|
+
// await json.intents.forEach(async (intent) => {
|
|
1106
|
+
|
|
1107
|
+
// let new_faq = {
|
|
1108
|
+
// id_faq_kb: updatedChatbot._id,
|
|
1109
|
+
// id_project: req.projectid,
|
|
1110
|
+
// createdBy: req.user.id,
|
|
1111
|
+
// intent_display_name: intent.intent_display_name,
|
|
1112
|
+
// intent_id: intent.intent_id,
|
|
1113
|
+
// question: intent.question,
|
|
1114
|
+
// answer: intent.answer,
|
|
1115
|
+
// reply: intent.reply,
|
|
1116
|
+
// form: intent.form,
|
|
1117
|
+
// enabled: intent.enabled,
|
|
1118
|
+
// webhook_enabled: intent.webhook_enabled,
|
|
1119
|
+
// language: intent.language,
|
|
1120
|
+
// actions: intent.actions,
|
|
1121
|
+
// attributes: intent.attributes
|
|
1122
|
+
// }
|
|
1123
|
+
|
|
1124
|
+
// // *******************************
|
|
1125
|
+
// // **** OVERWRITE TRUE option ****
|
|
1126
|
+
// // *******************************
|
|
1127
|
+
// if (req.query.overwrite == "true") {
|
|
1128
|
+
|
|
1129
|
+
// let savingResult = await Faq.findOneAndUpdate({ id_faq_kb: chatbot._id, intent_display_name: intent.intent_display_name }, new_faq, { new: true, upsert: true, rawResult: true }).catch((err) => {
|
|
1130
|
+
// winston.error("Unable to create faq: ", err);
|
|
1131
|
+
// })
|
|
1132
|
+
|
|
1133
|
+
// if (savingResult) {
|
|
1134
|
+
// if (savingResult.lastErrorObject.updatedExisting === true) {
|
|
1135
|
+
// winston.verbose("updated existing intent")
|
|
1136
|
+
// faqBotEvent.emit('faq.update', savingResult.value);
|
|
1137
|
+
// } else {
|
|
1138
|
+
// winston.verbose("new intent created")
|
|
1139
|
+
// faqBotEvent.emit('faq.create', savingResult.value);
|
|
1140
|
+
// }
|
|
1141
|
+
// }
|
|
1142
|
+
|
|
1143
|
+
// // ********************************
|
|
1144
|
+
// // **** OVERWRITE FALSE option ****
|
|
1145
|
+
// // ********************************
|
|
1146
|
+
// } else {
|
|
1147
|
+
|
|
1148
|
+
// let faq = await Faq.create(new_faq).catch((err) => {
|
|
1149
|
+
// if (err.code == 11000) {
|
|
1150
|
+
// winston.error("Duplicate intent_display_name.");
|
|
1151
|
+
// winston.verbose("Skip duplicated intent_display_name");
|
|
1152
|
+
// } else {
|
|
1153
|
+
// winston.error("Error creating new intent: ", err);
|
|
1154
|
+
// }
|
|
1155
|
+
// })
|
|
1156
|
+
|
|
1157
|
+
// if (faq) {
|
|
1158
|
+
// winston.debug("new intent created: ", faq)
|
|
1159
|
+
// faqBotEvent.emit('faq.create', faq);
|
|
1160
|
+
// }
|
|
1161
|
+
// }
|
|
1162
|
+
// })
|
|
1163
|
+
// }
|
|
1164
|
+
|
|
1165
|
+
// if (updatedChatbot) {
|
|
1166
|
+
// return res.send(updatedChatbot);
|
|
1167
|
+
// } else {
|
|
1168
|
+
// return res.send(chatbot);
|
|
1169
|
+
// }
|
|
1170
|
+
// }
|
|
1171
|
+
// })
|
|
1172
|
+
|
|
1173
|
+
router.get('/exportjson/:id_faq_kb', roleChecker.hasRole('admin'), asyncHandler(async (req, res) => {
|
|
989
1174
|
|
|
990
1175
|
const chatbot_id = req.params.id_faq_kb;
|
|
991
1176
|
const id_project = req.projectid;
|
|
1177
|
+
const exportGlobals = req.query.globals === 'true';
|
|
1178
|
+
const intentsOnly = req.query.intentsOnly === 'true';
|
|
992
1179
|
|
|
993
|
-
|
|
994
|
-
if (err) {
|
|
995
|
-
winston.error('GET FAQ-KB ERROR ', err)
|
|
996
|
-
return res.status(500).send({ success: false, msg: 'Error getting bot.' });
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
if (!faq_kb) {
|
|
1000
|
-
return res.status(404).send({ success: false, msg: "Chatbot not found with id " + chatbot_id });
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
const isPublic = faq_kb.public === true;
|
|
1004
|
-
const isOwner = faq_kb.id_project === id_project;
|
|
1180
|
+
const chatbot = await chatbotController.getChatbotById(chatbot_id);
|
|
1005
1181
|
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
msg: "Chatbot not found with id " + chatbot_id + " for project " + id_project
|
|
1010
|
-
});
|
|
1011
|
-
}
|
|
1182
|
+
if (!chatbotController.canAccess(chatbot, id_project)) {
|
|
1183
|
+
throw new AppError(403, `Unauthorized to access chatbot with id ${chatbot_id} for project ${id_project}`);
|
|
1184
|
+
}
|
|
1012
1185
|
|
|
1013
|
-
|
|
1186
|
+
let intents = await intentsController.getIntents(chatbot_id);
|
|
1014
1187
|
|
|
1015
|
-
|
|
1188
|
+
if (!exportGlobals) {
|
|
1189
|
+
winston.verbose("Delete globals from attributes")
|
|
1190
|
+
delete chatbot.attributes?.globals;
|
|
1191
|
+
}
|
|
1016
1192
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1193
|
+
let subagents = await chatbotController.findSubagents(chatbot_id, id_project);
|
|
1194
|
+
await Promise.all(subagents.map(async (subagent) => {
|
|
1195
|
+
subagent.intents = await intentsController.getIntents(subagent._id);
|
|
1196
|
+
}));
|
|
1019
1197
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1198
|
+
let exportData = chatbotController.export(chatbot, intents, intentsOnly, subagents);
|
|
1199
|
+
let filename = intentsOnly ? "intents.json" : "bot.json";
|
|
1200
|
+
res.set({ "Content-Disposition": `attachment; filename="${filename}"` });
|
|
1201
|
+
return res.send(exportData);
|
|
1026
1202
|
|
|
1027
|
-
|
|
1028
|
-
webhook_enabled: faq_kb.webhook_enabled,
|
|
1029
|
-
webhook_url: faq_kb.webhook_url,
|
|
1030
|
-
language: faq_kb.language,
|
|
1031
|
-
name: faq_kb.name,
|
|
1032
|
-
slug: faq_kb.slug,
|
|
1033
|
-
type: faq_kb.type,
|
|
1034
|
-
subtype: faq_kb.subtype,
|
|
1035
|
-
description: faq_kb.description,
|
|
1036
|
-
attributes: faq_kb.attributes,
|
|
1037
|
-
intents: intents
|
|
1038
|
-
}
|
|
1203
|
+
}))
|
|
1039
1204
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
intents: intents
|
|
1043
|
-
}
|
|
1044
|
-
let intents_string = JSON.stringify(intents_obj);
|
|
1045
|
-
res.set({ "Content-Disposition": "attachment; filename=\"intents.json\"" });
|
|
1046
|
-
return res.send(intents_string);
|
|
1205
|
+
// DEPRECATED
|
|
1206
|
+
// router.get('/exportjson/:id_faq_kb', roleChecker.hasRole('admin'), (req, res) => {
|
|
1047
1207
|
|
|
1048
|
-
|
|
1208
|
+
// winston.debug("exporting bot...")
|
|
1049
1209
|
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
// }
|
|
1053
|
-
let json_string = JSON.stringify(json);
|
|
1054
|
-
res.set({ "Content-Disposition": "attachment; filename=\"bot.json\"" });
|
|
1055
|
-
return res.send(json_string);
|
|
1056
|
-
}
|
|
1210
|
+
// const chatbot_id = req.params.id_faq_kb;
|
|
1211
|
+
// const id_project = req.projectid;
|
|
1057
1212
|
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1213
|
+
// Faq_kb.findOne({ _id: chatbot_id }, (err, faq_kb) => {
|
|
1214
|
+
// if (err) {
|
|
1215
|
+
// winston.error('GET FAQ-KB ERROR ', err)
|
|
1216
|
+
// return res.status(500).send({ success: false, msg: 'Error getting bot.' });
|
|
1217
|
+
// }
|
|
1218
|
+
|
|
1219
|
+
// if (!faq_kb) {
|
|
1220
|
+
// return res.status(404).send({ success: false, msg: "Chatbot not found with id " + chatbot_id });
|
|
1221
|
+
// }
|
|
1222
|
+
|
|
1223
|
+
// const isPublic = faq_kb.public === true;
|
|
1224
|
+
// const isOwner = faq_kb.id_project === id_project;
|
|
1225
|
+
|
|
1226
|
+
// if (!isPublic && !isOwner) {
|
|
1227
|
+
// return res.status(403).send({
|
|
1228
|
+
// success: false,
|
|
1229
|
+
// msg: "Chatbot not found with id " + chatbot_id + " for project " + id_project
|
|
1230
|
+
// });
|
|
1231
|
+
// }
|
|
1232
|
+
|
|
1233
|
+
// winston.debug('FAQ-KB: ', faq_kb)
|
|
1234
|
+
|
|
1235
|
+
// faqService.getAll(chatbot_id).then((faqs) => {
|
|
1236
|
+
|
|
1237
|
+
// // delete from exclude map intent_id
|
|
1238
|
+
// const intents = faqs.map(({ _id, id_project, topic, status, chatbot_id, createdBy, createdAt, updatedAt, __v, ...keepAttrs }) => keepAttrs)
|
|
1239
|
+
|
|
1240
|
+
// if (!req.query.globals) {
|
|
1241
|
+
// winston.verbose("Delete globals from attributes!")
|
|
1242
|
+
// if (faq_kb.attributes) {
|
|
1243
|
+
// delete faq_kb.attributes.globals;
|
|
1244
|
+
// }
|
|
1245
|
+
// }
|
|
1246
|
+
|
|
1247
|
+
// let json = {
|
|
1248
|
+
// webhook_enabled: faq_kb.webhook_enabled,
|
|
1249
|
+
// webhook_url: faq_kb.webhook_url,
|
|
1250
|
+
// language: faq_kb.language,
|
|
1251
|
+
// name: faq_kb.name,
|
|
1252
|
+
// slug: faq_kb.slug,
|
|
1253
|
+
// type: faq_kb.type,
|
|
1254
|
+
// subtype: faq_kb.subtype,
|
|
1255
|
+
// description: faq_kb.description,
|
|
1256
|
+
// attributes: faq_kb.attributes,
|
|
1257
|
+
// intents: intents
|
|
1258
|
+
// }
|
|
1259
|
+
|
|
1260
|
+
// if (req.query.intentsOnly == 'true') {
|
|
1261
|
+
// let intents_obj = {
|
|
1262
|
+
// intents: intents
|
|
1263
|
+
// }
|
|
1264
|
+
// let intents_string = JSON.stringify(intents_obj);
|
|
1265
|
+
// res.set({ "Content-Disposition": "attachment; filename=\"intents.json\"" });
|
|
1266
|
+
// return res.send(intents_string);
|
|
1267
|
+
|
|
1268
|
+
// } else {
|
|
1269
|
+
|
|
1270
|
+
// // if (req.query.file == "false") {
|
|
1271
|
+
// // return res.status(200).send(json);
|
|
1272
|
+
// // }
|
|
1273
|
+
// let json_string = JSON.stringify(json);
|
|
1274
|
+
// res.set({ "Content-Disposition": "attachment; filename=\"bot.json\"" });
|
|
1275
|
+
// return res.send(json_string);
|
|
1276
|
+
// }
|
|
1277
|
+
|
|
1278
|
+
// }).catch((err) => {
|
|
1279
|
+
// winston.error('GET FAQ ERROR: ', err)
|
|
1280
|
+
// return res.status(500).send({ success: false, msg: 'Error getting faqs.' });
|
|
1281
|
+
// })
|
|
1282
|
+
// })
|
|
1283
|
+
// })
|
|
1064
1284
|
|
|
1065
1285
|
router.post('/:faq_kbid/training', roleChecker.hasRole('admin'), function (req, res) {
|
|
1066
1286
|
|