@tiledesk/tiledesk-server 2.3.53 → 2.3.55
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 +13 -3
- package/app.js +3 -0
- package/models/department.js +1 -1
- package/package.json +2 -2
- package/pubmodules/trigger/rulesTrigger.js +98 -1
- package/routes/department.js +1 -1
- package/routes/faq.js +1 -1
- package/routes/faq_kb.js +141 -39
- package/routes/request.js +1 -1
- package/services/chatbotService.js +101 -0
- package/test/chatbot-mock.js +127 -0
- package/test/example-json.txt +1 -1
- package/test/faqkbRoute.js +369 -47
- package/utils/sendEmailUtil.js +34 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
💥 TILEDESK SERVER v2.3.
|
|
3
|
+
💥 TILEDESK SERVER v2.3.55 💥
|
|
4
4
|
🚀 TAGGED AND PUBLISHED ON NPM 🚀
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
|
6
|
-
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.
|
|
6
|
+
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.55)
|
|
7
|
+
|
|
8
|
+
# 2.3.55 -> PROD
|
|
9
|
+
- Tybot updated to 0.1.28
|
|
10
|
+
|
|
11
|
+
# 2.3.54
|
|
12
|
+
- Added HIDE_CLOSE_REQUEST_ERRORS env variable
|
|
13
|
+
- Added email.send trigger action
|
|
14
|
+
- Added participants parameter for trigger action
|
|
15
|
+
- Added status -1 for department model to hide department for dashboard and widget. It can be used for chatbot
|
|
16
|
+
- Added template engine to send email trigger action
|
|
7
17
|
|
|
8
18
|
# 2.3.51
|
|
9
19
|
- Added message.received as trigger event
|
|
@@ -19,7 +29,7 @@
|
|
|
19
29
|
- Updated widget.json file
|
|
20
30
|
- Fixed template for: beenInvitedNewUser.html beenInvitedExistingUser.html
|
|
21
31
|
|
|
22
|
-
# 2.3.49
|
|
32
|
+
# 2.3.49
|
|
23
33
|
- @tiledesk/tiledesk-tybot-connector": "^0.1.22
|
|
24
34
|
|
|
25
35
|
# 2.3.48
|
package/app.js
CHANGED
|
@@ -172,6 +172,7 @@ var IPFilter = require('./middleware/ipFilter');
|
|
|
172
172
|
|
|
173
173
|
// job_here
|
|
174
174
|
var BanUserNotifier = require('./services/banUserNotifier');
|
|
175
|
+
const { ChatbotService } = require('./services/chatbotService');
|
|
175
176
|
BanUserNotifier.listen();
|
|
176
177
|
|
|
177
178
|
var modulesManager = undefined;
|
|
@@ -207,6 +208,8 @@ var app = express();
|
|
|
207
208
|
app.set('views', path.join(__dirname, 'views'));
|
|
208
209
|
app.set('view engine', 'jade');
|
|
209
210
|
|
|
211
|
+
app.set('chatbot_service', new ChatbotService())
|
|
212
|
+
|
|
210
213
|
|
|
211
214
|
// TODO DELETE IT IN THE NEXT RELEASE
|
|
212
215
|
if (process.env.ENABLE_ALTERNATIVE_CORS_MIDDLEWARE === "true") {
|
package/models/department.js
CHANGED
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.3.
|
|
4
|
+
"version": "2.3.55",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "node ./bin/www",
|
|
7
7
|
"pretest": "mongodb-runner start",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@tiledesk/tiledesk-chatbot-util": "^0.8.33",
|
|
43
43
|
"@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
|
|
44
44
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
|
45
|
-
"@tiledesk/tiledesk-tybot-connector": "^0.1.
|
|
45
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.1.28",
|
|
46
46
|
"@tiledesk/tiledesk-dialogflow-connector": "^1.7.4",
|
|
47
47
|
"app-root-path": "^3.0.0",
|
|
48
48
|
"bcrypt-nodejs": "0.0.3",
|
|
@@ -18,9 +18,11 @@ var leadService = require('../../services/leadService');
|
|
|
18
18
|
var LeadConstants = require('../../models/leadConstants');
|
|
19
19
|
var operatingHoursService = require("../../services/operatingHoursService");
|
|
20
20
|
var sendMessageUtil = require("../../utils/sendMessageUtil");
|
|
21
|
+
var sendEmailUtil = require("../../utils/sendEmailUtil");
|
|
21
22
|
var cacheUtil = require("../../utils/cacheUtil");
|
|
22
23
|
var cacheEnabler = require("../../services/cacheEnabler");
|
|
23
24
|
var UIDGenerator = require("../../utils/UIDGenerator");
|
|
25
|
+
const RequestConstants = require('../../models/requestConstants');
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
class RulesTrigger {
|
|
@@ -201,6 +203,85 @@ class RulesTrigger {
|
|
|
201
203
|
|
|
202
204
|
|
|
203
205
|
|
|
206
|
+
triggerEventEmitter.on('email.send', function(eventTrigger) {
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
|
|
210
|
+
winston.debug('runAction eventTrigger.eventSuccess:', eventTrigger.eventSuccess);
|
|
211
|
+
var trigger = eventTrigger.trigger;
|
|
212
|
+
winston.debug('runAction trigger', trigger.toObject());
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
var action = eventTrigger.action;
|
|
216
|
+
winston.debug('runAction action', action.toObject());
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
var fullname = action.parameters.fullName || "BOT";
|
|
220
|
+
winston.debug('runAction action fullname: ' + fullname);
|
|
221
|
+
|
|
222
|
+
var subject = action.parameters.fullName || "New Email";
|
|
223
|
+
winston.debug('runAction action subject: ' + subject);
|
|
224
|
+
|
|
225
|
+
var sender = "system";
|
|
226
|
+
|
|
227
|
+
if (action.parameters.sender) {
|
|
228
|
+
sender = action.parameters.sender;
|
|
229
|
+
}
|
|
230
|
+
winston.debug('runAction action sender: ' + sender);
|
|
231
|
+
|
|
232
|
+
var text = action.parameters.text;
|
|
233
|
+
winston.debug('runAction action text: ' + text);
|
|
234
|
+
|
|
235
|
+
var attributes = {};
|
|
236
|
+
|
|
237
|
+
// var attributes = action.parameters.attributes;
|
|
238
|
+
// winston.debug('runAction action attributes: ' + attributes);
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
var recipient;
|
|
242
|
+
if (eventTrigger.eventKey=="request.create" || eventTrigger.eventKey=="request.participants.join") {
|
|
243
|
+
recipient = eventTrigger.event.request_id;
|
|
244
|
+
}
|
|
245
|
+
if (eventTrigger.eventKey=="message.create.from.requester" || eventTrigger.eventKey=="message.received") {
|
|
246
|
+
recipient = eventTrigger.event.recipient;
|
|
247
|
+
}
|
|
248
|
+
if (eventTrigger.eventKey=="event.emit") {
|
|
249
|
+
winston.debug('runAction action event.emit: ', eventTrigger.event.toObject());
|
|
250
|
+
|
|
251
|
+
//TODO funziona?
|
|
252
|
+
recipient = eventTrigger.event.project_user.id_user;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// console.log("eventTrigger.event", eventTrigger.event);
|
|
256
|
+
|
|
257
|
+
winston.debug('runAction action recipient: ' + recipient);
|
|
258
|
+
|
|
259
|
+
var id_project = eventTrigger.event.id_project;
|
|
260
|
+
winston.debug('runAction action id_project: ' + id_project);
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
var message = eventTrigger.event;
|
|
264
|
+
winston.debug('runAction action message: ', message);
|
|
265
|
+
|
|
266
|
+
if (eventTrigger.event.request && eventTrigger.event.request.lead && eventTrigger.event.request.lead.email) {
|
|
267
|
+
var to = eventTrigger.event.request.lead.email;
|
|
268
|
+
winston.debug('to ' + to);
|
|
269
|
+
|
|
270
|
+
// sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage) {
|
|
271
|
+
sendEmailUtil.sendEmailDirect(to, text, id_project, recipient, subject, message);
|
|
272
|
+
} else {
|
|
273
|
+
winston.info('email.send trigger. Lead email is undefined ');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
} catch(e) {
|
|
278
|
+
winston.error("Error runAction", e);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
|
|
204
285
|
|
|
205
286
|
|
|
206
287
|
triggerEventEmitter.on('request.department.route', function(eventTrigger) {
|
|
@@ -683,6 +764,8 @@ class RulesTrigger {
|
|
|
683
764
|
var departmentid = action.parameters.departmentid;
|
|
684
765
|
winston.debug('runAction action departmentid: ' + departmentid);
|
|
685
766
|
|
|
767
|
+
var participants = action.parameters.participants;
|
|
768
|
+
winston.debug('runAction action participants: ' + participants);
|
|
686
769
|
// var attributes = action.parameters.attributes;
|
|
687
770
|
// winston.debug('runAction action attributes: ' + attributes);
|
|
688
771
|
|
|
@@ -768,10 +851,24 @@ class RulesTrigger {
|
|
|
768
851
|
departmentid = eventAttributes.department;
|
|
769
852
|
}
|
|
770
853
|
|
|
854
|
+
|
|
855
|
+
|
|
771
856
|
if (eventAttributes.text) {
|
|
772
857
|
text = eventAttributes.text;
|
|
773
858
|
}
|
|
774
859
|
|
|
860
|
+
// console.log("eventAttributes.participants.length"+ eventAttributes.participants.length);
|
|
861
|
+
if (eventAttributes.participants && eventAttributes.participants.length>0) {
|
|
862
|
+
participants = eventAttributes.participants;
|
|
863
|
+
if (participants[0].indexOf("bot_")>-1) {
|
|
864
|
+
text = "\\start"; //if participants is passed than the bot reply to the first message "welcome" so I changed "welcome" with "\start"
|
|
865
|
+
}
|
|
866
|
+
// status = RequestConstants.ASSIGNED;
|
|
867
|
+
// console.log("eventAttributes.participants",eventAttributes.participants);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// console.log("text", text);
|
|
871
|
+
|
|
775
872
|
if (eventAttributes.status) {
|
|
776
873
|
status = eventAttributes.status;
|
|
777
874
|
}
|
|
@@ -864,7 +961,7 @@ class RulesTrigger {
|
|
|
864
961
|
|
|
865
962
|
var new_request = {
|
|
866
963
|
request_id: request_id, project_user_id: project_user_id, lead_id: createdLead._id, id_project: id_project,
|
|
867
|
-
first_text: text, departmentid: departmentid, sourcePage: sourcePage,
|
|
964
|
+
first_text: text, participants: participants, departmentid: departmentid, sourcePage: sourcePage,
|
|
868
965
|
language: language, userAgent: userAgent, status: status, createdBy: id_user,
|
|
869
966
|
attributes: attributes, subject: undefined, preflight: preflight, channel: undefined, location: undefined,
|
|
870
967
|
lead: createdLead, requester: puser
|
package/routes/department.js
CHANGED
|
@@ -175,7 +175,7 @@ router.get('/allstatus', [passport.authenticate(['basic', 'jwt'], { session: fal
|
|
|
175
175
|
|
|
176
176
|
winston.debug("## GET ALL DEPTS req.project ", req.project)
|
|
177
177
|
|
|
178
|
-
var query = { "id_project": req.projectid };
|
|
178
|
+
var query = { "id_project": req.projectid, status: { $gte: 0 } }; // nascondi quelli con status = hidden (-1) for dashboard
|
|
179
179
|
//secondo me qui manca un parentesi tonda per gli or
|
|
180
180
|
if (req.project && req.project.profile && (req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false)) {
|
|
181
181
|
|
package/routes/faq.js
CHANGED
|
@@ -189,7 +189,7 @@ router.put('/:faqid', function (req, res) {
|
|
|
189
189
|
update.enabled = req.body.enabled;
|
|
190
190
|
}
|
|
191
191
|
if (req.body.reply!=undefined) {
|
|
192
|
-
update.reply = req.body.
|
|
192
|
+
update.reply = req.body.reply;
|
|
193
193
|
}
|
|
194
194
|
if (req.body.form!=undefined) {
|
|
195
195
|
update.form = req.body.form;
|
package/routes/faq_kb.js
CHANGED
|
@@ -11,6 +11,9 @@ var httpUtil = require("../utils/httpUtil");
|
|
|
11
11
|
const { forEach } = require('lodash');
|
|
12
12
|
var multer = require('multer')
|
|
13
13
|
var upload = multer()
|
|
14
|
+
var configGlobal = require('../config/global');
|
|
15
|
+
|
|
16
|
+
var chatbot_templates_api_url = "https://chatbot-templates.herokuapp.com/chatbots/public/templates"
|
|
14
17
|
|
|
15
18
|
|
|
16
19
|
router.post('/', function (req, res) {
|
|
@@ -339,55 +342,129 @@ router.get('/', function (req, res) {
|
|
|
339
342
|
|
|
340
343
|
});
|
|
341
344
|
|
|
345
|
+
router.post('/fork/:id_faq_kb', async (req, res) => {
|
|
346
|
+
|
|
347
|
+
let id_faq_kb = req.params.id_faq_kb;
|
|
348
|
+
winston.info('id_faq_kb: ' + id_faq_kb);
|
|
349
|
+
|
|
350
|
+
const api_url = process.env.API_URL || configGlobal.apiUrl;
|
|
351
|
+
winston.info("fork --> base_url: " + api_url); // check if correct
|
|
352
|
+
|
|
353
|
+
let current_project_id = req.projectid;
|
|
354
|
+
winston.info("current project id: " + current_project_id);
|
|
355
|
+
|
|
356
|
+
let landing_project_id = req.query.projectid;
|
|
357
|
+
winston.info("landing project id " + landing_project_id)
|
|
358
|
+
|
|
359
|
+
let new_bot_name = req.query.name;
|
|
360
|
+
winston.info("new bot name: " + new_bot_name);
|
|
361
|
+
|
|
362
|
+
let public = req.query.public;
|
|
363
|
+
winston.info("public " + public);
|
|
364
|
+
|
|
365
|
+
let token = req.headers.authorization;
|
|
366
|
+
|
|
367
|
+
let cs = req.app.get('chatbot_service')
|
|
368
|
+
|
|
369
|
+
let chatbot = await cs.getBotById(id_faq_kb, public, api_url, chatbot_templates_api_url, token, current_project_id);
|
|
370
|
+
winston.debug("chatbot: ", chatbot)
|
|
371
|
+
|
|
372
|
+
if (!chatbot) {
|
|
373
|
+
return res.status(500).send({ success: false, message: "Unable to get chatbot" });
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
//chatbot.name = new_bot_name;
|
|
377
|
+
|
|
378
|
+
let savedChatbot = await cs.createBot(api_url, token, chatbot, landing_project_id);
|
|
379
|
+
winston.info("savedChatbot: ", savedChatbot)
|
|
380
|
+
|
|
381
|
+
if (!savedChatbot) {
|
|
382
|
+
return res.status(500).send({ success: false, message: "Unable to create new chatbot" });
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
let import_result = await cs.importFaqs(api_url, savedChatbot._id, token, chatbot, landing_project_id);
|
|
386
|
+
winston.info("imported: ", import_result);
|
|
387
|
+
|
|
388
|
+
if (import_result.success == "false") {
|
|
389
|
+
return res.status(500).send({ success: false, message: "Unable to import intents in the new chatbot" });
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return res.status(200).send({ message: "Chatbot forked successfully", bot_id: savedChatbot._id });
|
|
393
|
+
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
|
|
342
397
|
router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) => {
|
|
343
398
|
|
|
344
399
|
let id_faq_kb = req.params.id_faq_kb;
|
|
345
400
|
winston.debug('id_faq_kb: ', id_faq_kb);
|
|
346
401
|
|
|
347
|
-
let json_string
|
|
348
|
-
|
|
402
|
+
let json_string;
|
|
403
|
+
let json;
|
|
404
|
+
if (req.file) {
|
|
405
|
+
json_string = req.file.buffer.toString('utf-8');
|
|
406
|
+
json = JSON.parse(json_string);
|
|
407
|
+
} else {
|
|
408
|
+
json = req.body;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
winston.info("json_string: " + json_string);
|
|
349
412
|
|
|
350
413
|
if (req.query.intentsOnly == "true") {
|
|
351
414
|
|
|
352
415
|
winston.info("intents only")
|
|
353
416
|
|
|
354
|
-
const json = JSON.parse(json_string)
|
|
355
|
-
console.log("\n intents --> \n")
|
|
356
|
-
console.log(json)
|
|
357
|
-
|
|
358
417
|
json.intents.forEach((intent) => {
|
|
359
418
|
|
|
360
|
-
|
|
419
|
+
let new_faq = {
|
|
361
420
|
id_faq_kb: id_faq_kb,
|
|
362
421
|
id_project: req.projectid,
|
|
363
422
|
createdBy: req.user.id,
|
|
423
|
+
intent_display_name: intent.intent_display_name,
|
|
364
424
|
question: intent.question,
|
|
365
425
|
answer: intent.answer,
|
|
366
426
|
reply: intent.reply,
|
|
367
427
|
form: intent.form,
|
|
368
428
|
enabled: intent.enabled,
|
|
369
429
|
webhook_enabled: intent.webhook_enabled,
|
|
370
|
-
language: intent.language
|
|
371
|
-
|
|
372
|
-
})
|
|
430
|
+
language: intent.language
|
|
431
|
+
}
|
|
373
432
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (err
|
|
378
|
-
|
|
433
|
+
// overwrite duplicated intents
|
|
434
|
+
if (req.query.overwrite == "true") {
|
|
435
|
+
Faq.findOneAndUpdate({ id_faq_kb: id_faq_kb, intent_display_name: intent.intent_display_name }, new_faq, { new: true, upsert: true, rawResult: true }, (err, savingResult) => {
|
|
436
|
+
if (err) {
|
|
437
|
+
winston.error("findOneAndUpdate (upsert) FAQ ERROR ", err);
|
|
379
438
|
} else {
|
|
380
|
-
|
|
381
|
-
|
|
439
|
+
if (savingResult.lastErrorObject.updatedExisting == true) {
|
|
440
|
+
winston.info("updated existing intent")
|
|
441
|
+
faqBotEvent.emit('faq.update', savingResult.value);
|
|
442
|
+
} else {
|
|
443
|
+
winston.info("new intent crated")
|
|
444
|
+
faqBotEvent.emit('faq.create', savingResult.value);
|
|
445
|
+
}
|
|
382
446
|
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
}
|
|
447
|
+
})
|
|
448
|
+
|
|
449
|
+
// don't overwrite duplicated intents
|
|
450
|
+
} else {
|
|
451
|
+
Faq.create(new_faq, (err, savedFaq) => {
|
|
452
|
+
if (err) {
|
|
453
|
+
winston.debug("create new FAQ ERROR ", err);
|
|
454
|
+
if (err.code == 11000) {
|
|
455
|
+
winston.error("Duplicate intent_display_name.");
|
|
456
|
+
winston.info("Skip duplicated intent_display_name");
|
|
457
|
+
} else {
|
|
458
|
+
winston.info("new intent crated")
|
|
459
|
+
faqBotEvent.emit('faq.create', savedFaq);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
})
|
|
463
|
+
}
|
|
387
464
|
|
|
388
465
|
})
|
|
389
466
|
|
|
390
|
-
return res.status(200).send({ success: true, msg: "Intents imported successfully"})
|
|
467
|
+
return res.status(200).send({ success: true, msg: "Intents imported successfully" })
|
|
391
468
|
|
|
392
469
|
} else {
|
|
393
470
|
|
|
@@ -427,33 +504,54 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) =>
|
|
|
427
504
|
|
|
428
505
|
json.intents.forEach((intent) => {
|
|
429
506
|
|
|
430
|
-
|
|
507
|
+
let new_faq = {
|
|
431
508
|
id_faq_kb: updatedFaq_kb._id,
|
|
432
509
|
id_project: req.projectid,
|
|
433
510
|
createdBy: req.user.id,
|
|
511
|
+
intent_display_name: intent.intent_display_name,
|
|
434
512
|
question: intent.question,
|
|
435
513
|
answer: intent.answer,
|
|
436
514
|
reply: intent.reply,
|
|
437
515
|
form: intent.form,
|
|
438
516
|
enabled: intent.enabled,
|
|
439
517
|
webhook_enabled: intent.webhook_enabled,
|
|
440
|
-
language: intent.language
|
|
441
|
-
|
|
442
|
-
})
|
|
518
|
+
language: intent.language
|
|
519
|
+
}
|
|
443
520
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
if (err
|
|
448
|
-
|
|
521
|
+
// overwrite duplicated intents
|
|
522
|
+
if (req.query.overwrite == "true") {
|
|
523
|
+
Faq.findOneAndUpdate({ id_faq_kb: id_faq_kb, intent_display_name: intent.intent_display_name }, new_faq, { new: true, upsert: true, rawResult: true }, (err, savingResult) => {
|
|
524
|
+
if (err) {
|
|
525
|
+
winston.error("findOneAndUpdate (upsert) FAQ ERROR ", err);
|
|
449
526
|
} else {
|
|
450
|
-
|
|
451
|
-
|
|
527
|
+
|
|
528
|
+
if (savingResult.lastErrorObject.updatedExisting == true) {
|
|
529
|
+
winston.info("updated existing intent")
|
|
530
|
+
faqBotEvent.emit('faq.update', savingResult.value);
|
|
531
|
+
} else {
|
|
532
|
+
winston.info("new intent crated")
|
|
533
|
+
faqBotEvent.emit('faq.create', savingResult.value);
|
|
534
|
+
}
|
|
535
|
+
|
|
452
536
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
537
|
+
|
|
538
|
+
})
|
|
539
|
+
|
|
540
|
+
// don't overwrite duplicated intents
|
|
541
|
+
} else {
|
|
542
|
+
Faq.create(new_faq, (err, savedFaq) => {
|
|
543
|
+
if (err) {
|
|
544
|
+
winston.debug("create new FAQ ERROR ", err);
|
|
545
|
+
if (err.code == 11000) {
|
|
546
|
+
winston.error("Duplicate intent_display_name.");
|
|
547
|
+
winston.info("Skip duplicated intent_display_name");
|
|
548
|
+
} else {
|
|
549
|
+
winston.info("new intent crated")
|
|
550
|
+
faqBotEvent.emit('faq.create', savedFaq);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
})
|
|
554
|
+
}
|
|
457
555
|
|
|
458
556
|
})
|
|
459
557
|
|
|
@@ -499,12 +597,16 @@ router.get('/exportjson/:id_faq_kb', (req, res) => {
|
|
|
499
597
|
intents: intents
|
|
500
598
|
}
|
|
501
599
|
let intents_string = JSON.stringify(intents_obj);
|
|
502
|
-
res.set({ "Content-Disposition": "attachment; filename=\"intents.
|
|
600
|
+
res.set({ "Content-Disposition": "attachment; filename=\"intents.json\"" });
|
|
503
601
|
return res.send(intents_string);
|
|
504
602
|
|
|
505
603
|
} else {
|
|
604
|
+
|
|
605
|
+
// if (req.query.file == "false") {
|
|
606
|
+
// return res.status(200).send(json);
|
|
607
|
+
// }
|
|
506
608
|
let json_string = JSON.stringify(json);
|
|
507
|
-
res.set({ "Content-Disposition": "attachment; filename=\"bot.
|
|
609
|
+
res.set({ "Content-Disposition": "attachment; filename=\"bot.json\"" });
|
|
508
610
|
return res.send(json_string);
|
|
509
611
|
}
|
|
510
612
|
|
package/routes/request.js
CHANGED
|
@@ -67,7 +67,7 @@ async (req, res) => {
|
|
|
67
67
|
let messageStatus = req.body.status || MessageConstants.CHAT_MESSAGE_STATUS.SENDING;
|
|
68
68
|
winston.debug('messageStatus: ' + messageStatus);
|
|
69
69
|
|
|
70
|
-
var request_id = req.
|
|
70
|
+
var request_id = req.body.request_id || 'support-group-' + req.projectid + "-" + UIDGenerator.generate();
|
|
71
71
|
winston.debug('request_id: ' + request_id);
|
|
72
72
|
|
|
73
73
|
if (sender) {
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const axios = require("axios").default;
|
|
2
|
+
const winston = require('../config/winston');
|
|
3
|
+
var Faq_kb = require("../models/faq_kb");
|
|
4
|
+
|
|
5
|
+
class ChatbotService {
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async getBotById(id_faq_kb, published, api_url, chatbot_templates_api_url, token, project_id) {
|
|
13
|
+
|
|
14
|
+
winston.info("[CHATBOT SERVICE] getBotById");
|
|
15
|
+
|
|
16
|
+
// private bot
|
|
17
|
+
if (published == "false") {
|
|
18
|
+
|
|
19
|
+
return await axios({
|
|
20
|
+
url: api_url + "/" + project_id + "/faq_kb/exportjson/" + id_faq_kb,
|
|
21
|
+
headers: {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
'Authorization': token
|
|
24
|
+
},
|
|
25
|
+
method: 'GET'
|
|
26
|
+
}).then((resbody) => {
|
|
27
|
+
winston.info("(CHATBOT SERVICE) forking private chatbot " + resbody.data.name)
|
|
28
|
+
let chatbot = resbody.data;
|
|
29
|
+
return chatbot;
|
|
30
|
+
}).catch((err) => {
|
|
31
|
+
winston.error('(CHATBOT SERVICE) FAQ_KB EXPORTJSON ERROR ' + err);
|
|
32
|
+
return err;
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// public bot
|
|
36
|
+
} else {
|
|
37
|
+
|
|
38
|
+
return await axios({
|
|
39
|
+
url: chatbot_templates_api_url + "/" + id_faq_kb,
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json'
|
|
42
|
+
},
|
|
43
|
+
method: 'GET'
|
|
44
|
+
}).then((resbody) => {
|
|
45
|
+
winston.info("(CHATBOT SERVICE) forking public chatbot " + resbody.data);
|
|
46
|
+
let chatbot = resbody.data;
|
|
47
|
+
return chatbot
|
|
48
|
+
}).catch((err) => {
|
|
49
|
+
winston.error('(CHATBOT SERVICE) FAQ_KB CHATBOT TEMPLATES ERROR ' + err);
|
|
50
|
+
return err;
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async createBot(api_url, token, chatbot, project_id) {
|
|
57
|
+
|
|
58
|
+
winston.info("[CHATBOT SERVICE] createBot");
|
|
59
|
+
|
|
60
|
+
return await axios({
|
|
61
|
+
url: api_url + '/' + project_id + '/faq_kb/',
|
|
62
|
+
headers: {
|
|
63
|
+
'Content-Type': 'application/json',
|
|
64
|
+
'Authorization': token
|
|
65
|
+
},
|
|
66
|
+
data: chatbot,
|
|
67
|
+
method: 'POST'
|
|
68
|
+
}).then((resbody) => {
|
|
69
|
+
winston.debug("(CHATBOT SERVICE) createBot resbody: ", resbody.data);
|
|
70
|
+
return resbody.data;
|
|
71
|
+
}).catch((err) => {
|
|
72
|
+
winston.error("(CHATBOT SERVICE) CREATE NEW CHATBOT ERROR " + err);
|
|
73
|
+
return err;
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async importFaqs(api_url, id_faq_kb, token, chatbot, project_id) {
|
|
79
|
+
|
|
80
|
+
winston.info("[CHATBOT SERVICE] importFaqs");
|
|
81
|
+
|
|
82
|
+
return await axios({
|
|
83
|
+
url: api_url + '/' + project_id + '/faq_kb/importjson/' + id_faq_kb + "?intentsOnly=true",
|
|
84
|
+
headers: {
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
'Authorization': token
|
|
87
|
+
},
|
|
88
|
+
data: chatbot,
|
|
89
|
+
method: 'POST'
|
|
90
|
+
}).then((resbody) => {
|
|
91
|
+
winston.debug("(CHATBOT SERVICE) importFaqs resbody: ", resbody.data);
|
|
92
|
+
return resbody.data;
|
|
93
|
+
}).catch((err) => {
|
|
94
|
+
winston.error("(CHATBOT SERVICE) IMPORT FAQS ERROR " + err);
|
|
95
|
+
return err;
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = { ChatbotService }
|