@tiledesk/tiledesk-server 2.3.63 → 2.3.65
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +19 -2
- package/app.js +1 -1
- package/package.json +2 -2
- package/routes/faq_kb.js +108 -41
- package/services/emailService.js +26 -14
- package/test/example.json +1 -0
- package/test/faqkbRoute.js +45 -1
package/CHANGELOG.md
CHANGED
@@ -1,12 +1,29 @@
|
|
1
1
|
|
2
2
|
|
3
|
-
💥 TILEDESK SERVER v2.3.
|
3
|
+
💥 TILEDESK SERVER v2.3.65 💥
|
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.65)
|
7
|
+
|
8
|
+
# 2.3.65
|
9
|
+
- Updated tiledesk-tybot-connector 0.1.38
|
10
|
+
- chatbot and subscription can use send email endpoint
|
11
|
+
- Added EMAIL_CC_ENABLED env variable to disable CCs email inboud notification
|
12
|
+
|
13
|
+
# 2.3.64
|
14
|
+
- log fix
|
15
|
+
- Tybot updated to 0.1.37
|
7
16
|
|
8
17
|
# 2.3.63
|
9
18
|
- Tybot updated to 0.1.36
|
19
|
+
- ChangeLog degli ultimi due commit:
|
20
|
+
- added trainingService.js file
|
21
|
+
- added certified, mainCategory and intentsEngine fields for faq_kb model
|
22
|
+
- deleted new_bot_name for forked chatbot
|
23
|
+
- updated faq and faq_kb tests
|
24
|
+
- edit trainingService.js
|
25
|
+
- add test for bot with intentsEngine (training)
|
26
|
+
|
10
27
|
|
11
28
|
# 2.3.62
|
12
29
|
- if (request.markModified) fix webhook in queue
|
package/app.js
CHANGED
@@ -489,7 +489,7 @@ app.use('/:projectid/labels', [fetchLabels],labels);
|
|
489
489
|
|
490
490
|
app.use('/:projectid/campaigns',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], campaigns);
|
491
491
|
|
492
|
-
app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.
|
492
|
+
app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], email);
|
493
493
|
|
494
494
|
|
495
495
|
|
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.65",
|
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.38",
|
46
46
|
"@tiledesk/tiledesk-dialogflow-connector": "^1.7.4",
|
47
47
|
"app-root-path": "^3.0.0",
|
48
48
|
"bcrypt-nodejs": "0.0.3",
|
package/routes/faq_kb.js
CHANGED
@@ -402,7 +402,7 @@ router.post('/fork/:id_faq_kb', async (req, res) => {
|
|
402
402
|
router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) => {
|
403
403
|
|
404
404
|
let id_faq_kb = req.params.id_faq_kb;
|
405
|
-
winston.
|
405
|
+
winston.info('import on id_faq_kb: ', id_faq_kb);
|
406
406
|
|
407
407
|
let json_string;
|
408
408
|
let json;
|
@@ -413,8 +413,6 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) =>
|
|
413
413
|
json = req.body;
|
414
414
|
}
|
415
415
|
|
416
|
-
winston.info("json_string: " + json_string);
|
417
|
-
|
418
416
|
if (req.query.intentsOnly == "true") {
|
419
417
|
|
420
418
|
winston.info("intents only")
|
@@ -473,44 +471,15 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) =>
|
|
473
471
|
|
474
472
|
} else {
|
475
473
|
|
476
|
-
|
477
|
-
|
478
|
-
winston.
|
479
|
-
|
480
|
-
}
|
481
|
-
if (!faq_kb) {
|
482
|
-
return res.status(404).send({ success: false, msg: 'Bot not found.' });
|
483
|
-
}
|
484
|
-
|
485
|
-
const json = JSON.parse(json_string);
|
486
|
-
|
487
|
-
if (json.webhook_enabled) {
|
488
|
-
faq_kb.webhook_enabled = json.webhook_enabled;
|
489
|
-
}
|
490
|
-
if (json.webhook_url) {
|
491
|
-
faq_kb.webhook_url = json.webhook_url;
|
492
|
-
}
|
493
|
-
if (json.language) {
|
494
|
-
faq_kb.language = json.language;
|
495
|
-
}
|
496
|
-
if (json.name) {
|
497
|
-
faq_kb.name = json.name;
|
498
|
-
}
|
499
|
-
if (json.description) {
|
500
|
-
faq_kb.description = json.description;
|
501
|
-
}
|
502
|
-
|
503
|
-
Faq_kb.findByIdAndUpdate(id_faq_kb, faq_kb, { new: true }, (err, updatedFaq_kb) => {
|
504
|
-
if (err) {
|
505
|
-
return res.status(500).send({ success: false, msg: "Error updating bot." });
|
506
|
-
}
|
507
|
-
|
508
|
-
botEvent.emit('faqbot.update', updatedFaq_kb);
|
474
|
+
if (req.query.create == 'true') {
|
475
|
+
faqService.create(json.name, undefined, req.projectid, req.user.id, "tilebot", json.description, json.webhook_url, json.webhook_enabled, json.language, undefined, undefined, undefined).then((savedFaq_kb) => {
|
476
|
+
winston.debug("saved (and imported) faq kb: ", savedFaq_kb);
|
477
|
+
botEvent.emit('faqbot.create', savedFaq_kb);
|
509
478
|
|
510
479
|
json.intents.forEach((intent) => {
|
511
|
-
|
480
|
+
|
512
481
|
let new_faq = {
|
513
|
-
id_faq_kb:
|
482
|
+
id_faq_kb: savedFaq_kb._id,
|
514
483
|
id_project: req.projectid,
|
515
484
|
createdBy: req.user.id,
|
516
485
|
intent_display_name: intent.intent_display_name,
|
@@ -523,7 +492,7 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) =>
|
|
523
492
|
language: intent.language
|
524
493
|
}
|
525
494
|
|
526
|
-
//
|
495
|
+
// TO DELETE: no used when req.query.create = 'true'
|
527
496
|
if (req.query.overwrite == "true") {
|
528
497
|
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) => {
|
529
498
|
if (err) {
|
@@ -559,12 +528,110 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) =>
|
|
559
528
|
}
|
560
529
|
|
561
530
|
})
|
531
|
+
return res.status(200).send(savedFaq_kb);
|
562
532
|
|
563
|
-
|
533
|
+
}).catch((err) => {
|
534
|
+
console.error("error saving faq_kb: ", err);
|
535
|
+
return res.status(500).send(err);
|
536
|
+
})
|
564
537
|
|
538
|
+
} else {
|
539
|
+
|
540
|
+
Faq_kb.findById(id_faq_kb, (err, faq_kb) => {
|
541
|
+
if (err) {
|
542
|
+
winston.error("GET FAQ-KB ERROR", err);
|
543
|
+
return res.status(500).send({ success: false, msg: "Error getting bot." });
|
544
|
+
}
|
545
|
+
if (!faq_kb) {
|
546
|
+
return res.status(404).send({ success: false, msg: 'Bot not found.' });
|
547
|
+
}
|
548
|
+
|
549
|
+
// should be wrong
|
550
|
+
//const json = JSON.parse(json_string);
|
551
|
+
|
552
|
+
if (json.webhook_enabled) {
|
553
|
+
faq_kb.webhook_enabled = json.webhook_enabled;
|
554
|
+
}
|
555
|
+
if (json.webhook_url) {
|
556
|
+
faq_kb.webhook_url = json.webhook_url;
|
557
|
+
}
|
558
|
+
if (json.language) {
|
559
|
+
faq_kb.language = json.language;
|
560
|
+
}
|
561
|
+
if (json.name) {
|
562
|
+
faq_kb.name = json.name;
|
563
|
+
}
|
564
|
+
if (json.description) {
|
565
|
+
faq_kb.description = json.description;
|
566
|
+
}
|
567
|
+
|
568
|
+
Faq_kb.findByIdAndUpdate(id_faq_kb, faq_kb, { new: true }, (err, updatedFaq_kb) => {
|
569
|
+
if (err) {
|
570
|
+
return res.status(500).send({ success: false, msg: "Error updating bot." });
|
571
|
+
}
|
572
|
+
|
573
|
+
botEvent.emit('faqbot.update', updatedFaq_kb);
|
574
|
+
|
575
|
+
json.intents.forEach((intent) => {
|
576
|
+
|
577
|
+
let new_faq = {
|
578
|
+
id_faq_kb: updatedFaq_kb._id,
|
579
|
+
id_project: req.projectid,
|
580
|
+
createdBy: req.user.id,
|
581
|
+
intent_display_name: intent.intent_display_name,
|
582
|
+
question: intent.question,
|
583
|
+
answer: intent.answer,
|
584
|
+
reply: intent.reply,
|
585
|
+
form: intent.form,
|
586
|
+
enabled: intent.enabled,
|
587
|
+
webhook_enabled: intent.webhook_enabled,
|
588
|
+
language: intent.language
|
589
|
+
}
|
590
|
+
|
591
|
+
// overwrite duplicated intents
|
592
|
+
if (req.query.overwrite == "true") {
|
593
|
+
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) => {
|
594
|
+
if (err) {
|
595
|
+
winston.error("findOneAndUpdate (upsert) FAQ ERROR ", err);
|
596
|
+
} else {
|
597
|
+
|
598
|
+
if (savingResult.lastErrorObject.updatedExisting == true) {
|
599
|
+
winston.info("updated existing intent")
|
600
|
+
faqBotEvent.emit('faq.update', savingResult.value);
|
601
|
+
} else {
|
602
|
+
winston.info("new intent crated")
|
603
|
+
faqBotEvent.emit('faq.create', savingResult.value);
|
604
|
+
}
|
605
|
+
|
606
|
+
}
|
607
|
+
|
608
|
+
})
|
609
|
+
|
610
|
+
// don't overwrite duplicated intents
|
611
|
+
} else {
|
612
|
+
Faq.create(new_faq, (err, savedFaq) => {
|
613
|
+
if (err) {
|
614
|
+
winston.debug("create new FAQ ERROR ", err);
|
615
|
+
if (err.code == 11000) {
|
616
|
+
winston.error("Duplicate intent_display_name.");
|
617
|
+
winston.info("Skip duplicated intent_display_name");
|
618
|
+
} else {
|
619
|
+
winston.info("new intent crated")
|
620
|
+
faqBotEvent.emit('faq.create', savedFaq);
|
621
|
+
}
|
622
|
+
}
|
623
|
+
})
|
624
|
+
}
|
625
|
+
|
626
|
+
})
|
627
|
+
|
628
|
+
return res.send(updatedFaq_kb);
|
629
|
+
|
630
|
+
})
|
631
|
+
|
565
632
|
})
|
633
|
+
}
|
566
634
|
|
567
|
-
})
|
568
635
|
}
|
569
636
|
|
570
637
|
})
|
package/services/emailService.js
CHANGED
@@ -124,6 +124,13 @@ class EmailService {
|
|
124
124
|
}
|
125
125
|
winston.info('EmailService headers: ' + JSON.stringify(this.headers));
|
126
126
|
|
127
|
+
this.ccEnabled = false
|
128
|
+
|
129
|
+
if (process.env.EMAIL_CC_ENABLED ==="true" || process.env.EMAIL_CC_ENABLED === true ) {
|
130
|
+
this.ccEnabled = true;
|
131
|
+
}
|
132
|
+
winston.info('EmailService ccEnabled: ' + ccEnabled);
|
133
|
+
|
127
134
|
}
|
128
135
|
|
129
136
|
readTemplate(templateName, settings) {
|
@@ -1124,14 +1131,17 @@ class EmailService {
|
|
1124
1131
|
references = message.request.attributes.email_references;
|
1125
1132
|
}
|
1126
1133
|
|
1127
|
-
if (
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
+
if (this.ccEnabled==true) {
|
1135
|
+
if (message.request.attributes.email_cc) {
|
1136
|
+
cc = message.request.attributes.email_cc;
|
1137
|
+
}
|
1138
|
+
winston.debug("email message.request.attributes.email_ccStr: "+ message.request.attributes.email_ccStr);
|
1139
|
+
if (message.request.attributes.email_ccStr!=undefined) {
|
1140
|
+
ccString = message.request.attributes.email_ccStr;
|
1141
|
+
winston.debug("email set ccString");
|
1142
|
+
}
|
1134
1143
|
}
|
1144
|
+
|
1135
1145
|
}
|
1136
1146
|
winston.verbose("email inReplyTo: "+ inReplyTo);
|
1137
1147
|
winston.verbose("email references: "+ references);
|
@@ -1293,13 +1303,15 @@ class EmailService {
|
|
1293
1303
|
references = message.request.attributes.email_references;
|
1294
1304
|
}
|
1295
1305
|
|
1296
|
-
if (
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1306
|
+
if (this.ccEnabled==true) {
|
1307
|
+
if (message.request.attributes.email_cc) {
|
1308
|
+
cc = message.request.attributes.email_cc;
|
1309
|
+
}
|
1310
|
+
winston.debug("email message.request.attributes.email_ccStr: "+ message.request.attributes.email_ccStr);
|
1311
|
+
if (message.request.attributes.email_ccStr!=undefined) {
|
1312
|
+
ccString = message.request.attributes.email_ccStr;
|
1313
|
+
winston.debug("email set ccString");
|
1314
|
+
}
|
1303
1315
|
}
|
1304
1316
|
}
|
1305
1317
|
winston.verbose("email inReplyTo: "+ inReplyTo);
|
@@ -0,0 +1 @@
|
|
1
|
+
{"webhook_enabled":false,"language":"en","name":"examplebot","intents":[{"webhook_enabled":false,"enabled":true,"question":"\\start","answer":"Hi","intent_display_name":"start","language":"en"},{"webhook_enabled":false,"enabled":true,"question":"question1","answer":"question1","intent_display_name":"question1","language":"en"},{"webhook_enabled":false,"enabled":true,"question":"defaultFallback","answer":"I can not provide an adequate answer. Write a new question or talk to a human agent.\n* Back to start tdAction:start\n* See the docs https://docs.tiledesk.com/\n* 👨🏻🦰 I want an agent","intent_display_name":"defaultFallback","language":"en"}]}
|
package/test/faqkbRoute.js
CHANGED
@@ -232,6 +232,50 @@ describe('FaqKBRoute', () => {
|
|
232
232
|
})
|
233
233
|
})
|
234
234
|
|
235
|
+
it('create bot and import json', (done) => {
|
236
|
+
|
237
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
238
|
+
var pwd = "pwd";
|
239
|
+
|
240
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
241
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
242
|
+
|
243
|
+
chai.request(server)
|
244
|
+
.post('/' + savedProject._id + '/faq_kb/importjson/' + null + "?create=true")
|
245
|
+
.auth(email, pwd)
|
246
|
+
.set('Content-Type', 'text/plain')
|
247
|
+
.attach('uploadFile', fs.readFileSync(path.resolve(__dirname, './example.json')), 'example.json')
|
248
|
+
.end((err, res) => {
|
249
|
+
if (log) {
|
250
|
+
console.log("import json res: ", res.body);
|
251
|
+
}
|
252
|
+
res.should.have.status(200);
|
253
|
+
res.should.be.a('object');
|
254
|
+
expect(res.body.name).to.equal("examplebot");
|
255
|
+
expect(res.body.language).to.equal("en");
|
256
|
+
|
257
|
+
let id_faq_kb = res.body._id;
|
258
|
+
|
259
|
+
chai.request(server)
|
260
|
+
.get('/' + savedProject._id + '/faq?id_faq_kb=' + id_faq_kb)
|
261
|
+
.auth(email, pwd)
|
262
|
+
.end((err, res) => {
|
263
|
+
if (log) {
|
264
|
+
console.log("faq_list: ", res.body);
|
265
|
+
}
|
266
|
+
res.should.have.status(200);
|
267
|
+
res.body.should.be.an('array').that.is.not.empty;
|
268
|
+
|
269
|
+
done();
|
270
|
+
|
271
|
+
})
|
272
|
+
})
|
273
|
+
|
274
|
+
})
|
275
|
+
})
|
276
|
+
|
277
|
+
})
|
278
|
+
|
235
279
|
|
236
280
|
it('import json (overwrite true)', (done) => {
|
237
281
|
|
@@ -259,7 +303,7 @@ describe('FaqKBRoute', () => {
|
|
259
303
|
.post('/' + savedProject._id + '/faq_kb/importjson/' + id_faq_kb + "?overwrite=true")
|
260
304
|
.auth(email, pwd)
|
261
305
|
.set('Content-Type', 'text/plain')
|
262
|
-
.attach('uploadFile', fs.readFileSync(path.resolve(__dirname, './example
|
306
|
+
.attach('uploadFile', fs.readFileSync(path.resolve(__dirname, './example.json')), 'example.json')
|
263
307
|
.end((err, res) => {
|
264
308
|
if (log) {
|
265
309
|
console.log("import json res: ", res.body);
|