@tiledesk/tiledesk-server 2.4.46 → 2.4.48
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/app.js +3 -0
- package/jobs.js +3 -3
- package/jobsManager.js +8 -8
- package/models/openai_kbs.js +23 -0
- package/package.json +1 -1
- package/pubmodules/pubModulesManager.js +14 -2
- package/pubmodules/routing-queue/index.js +3 -1
- package/pubmodules/routing-queue/listener.js +1 -96
- package/pubmodules/routing-queue/listenerQueued.js +194 -0
- package/routes/email.js +21 -19
- package/routes/faq.js +3 -1
- package/routes/openai_kbs.js +57 -0
- package/services/faqService.js +138 -115
- package/test/faqRoute.js +1 -1
- package/test/faqkbRoute.js +42 -0
- package/test/openaiKbsRoute.js +75 -0
package/app.js
CHANGED
|
@@ -112,6 +112,7 @@ var jwtroute = require('./routes/jwt');
|
|
|
112
112
|
var key = require('./routes/key');
|
|
113
113
|
var widgets = require('./routes/widget');
|
|
114
114
|
var widgetsLoader = require('./routes/widgetLoader');
|
|
115
|
+
var openai_kbs = require('./routes/openai_kbs');
|
|
115
116
|
|
|
116
117
|
// var admin = require('./routes/admin');
|
|
117
118
|
var faqpub = require('./routes/faqpub');
|
|
@@ -549,6 +550,8 @@ app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session:
|
|
|
549
550
|
|
|
550
551
|
app.use('/:projectid/properties',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], property);
|
|
551
552
|
|
|
553
|
+
app.use('/:projectid/openai_kbs', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent')], openai_kbs);
|
|
554
|
+
|
|
552
555
|
|
|
553
556
|
|
|
554
557
|
if (pubModulesManager) {
|
package/jobs.js
CHANGED
|
@@ -93,9 +93,9 @@ async function main()
|
|
|
93
93
|
jobsManager.listenActivityArchiver(activityArchiver);
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
let routingQueueQueued = require('./pubmodules/routing-queue').listenerQueued;
|
|
97
|
+
winston.debug("routingQueueQueued");
|
|
98
|
+
jobsManager.listenRoutingQueue(routingQueueQueued);
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
|
package/jobsManager.js
CHANGED
|
@@ -45,14 +45,14 @@ class JobsManager {
|
|
|
45
45
|
this.emailNotification.requestNotification.listen();
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
listenRoutingQueue(routingQueue) {
|
|
49
|
+
winston.info("JobsManager routingQueue started");
|
|
50
|
+
if ( this.jobWorkerEnabled == true) {
|
|
51
|
+
return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for routingQueue");
|
|
52
|
+
}
|
|
53
|
+
this.routingQueue = routingQueue;
|
|
54
|
+
this.routingQueue.listen();
|
|
55
|
+
}
|
|
56
56
|
|
|
57
57
|
listenScheduler(scheduler) {
|
|
58
58
|
winston.info("JobsManager scheduler started");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var mongoose = require('mongoose');
|
|
2
|
+
var Schema = mongoose.Schema;
|
|
3
|
+
var winston = require('../config/winston');
|
|
4
|
+
|
|
5
|
+
var OpenaiKbsSchema = new Schema({
|
|
6
|
+
name: {
|
|
7
|
+
type: String,
|
|
8
|
+
required: true
|
|
9
|
+
},
|
|
10
|
+
url: {
|
|
11
|
+
type: String,
|
|
12
|
+
required: true
|
|
13
|
+
},
|
|
14
|
+
id_project: {
|
|
15
|
+
type: String,
|
|
16
|
+
required: true,
|
|
17
|
+
index: true
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
module.exports = mongoose.model('OpenaiKbs', OpenaiKbsSchema);
|
package/package.json
CHANGED
|
@@ -51,6 +51,7 @@ class PubModulesManager {
|
|
|
51
51
|
this.jobsManager = undefined;
|
|
52
52
|
|
|
53
53
|
this.routingQueue = undefined;
|
|
54
|
+
this.routingQueueQueued = undefined;
|
|
54
55
|
|
|
55
56
|
this.cache = undefined;
|
|
56
57
|
|
|
@@ -407,8 +408,11 @@ class PubModulesManager {
|
|
|
407
408
|
|
|
408
409
|
try {
|
|
409
410
|
this.routingQueue = require('./routing-queue').listener;
|
|
411
|
+
this.routingQueueQueued = require('./routing-queue').listenerQueued;
|
|
412
|
+
|
|
410
413
|
// this.routingQueue.listen();
|
|
411
414
|
winston.debug("this.routingQueue:"+ this.routingQueue);
|
|
415
|
+
winston.debug("this.routingQueueQueued:"+ this.routingQueueQueued);
|
|
412
416
|
|
|
413
417
|
winston.info("PubModulesManager routing queue initialized");
|
|
414
418
|
} catch(err) {
|
|
@@ -515,13 +519,21 @@ class PubModulesManager {
|
|
|
515
519
|
|
|
516
520
|
if (this.routingQueue) {
|
|
517
521
|
try {
|
|
518
|
-
this.routingQueue.listen();
|
|
519
|
-
// this.jobsManager.listenRoutingQueue(this.routingQueue);
|
|
522
|
+
this.routingQueue.listen();
|
|
520
523
|
winston.info("PubModulesManager routingQueue started");
|
|
521
524
|
} catch(err) {
|
|
522
525
|
winston.info("PubModulesManager error starting routingQueue module", err);
|
|
523
526
|
}
|
|
524
527
|
}
|
|
528
|
+
if (this.routingQueueQueued) {
|
|
529
|
+
try {
|
|
530
|
+
// this.routingQueueQueued.listen();
|
|
531
|
+
this.jobsManager.listenRoutingQueue(this.routingQueueQueued);
|
|
532
|
+
winston.info("PubModulesManager routingQueue queued started");
|
|
533
|
+
} catch(err) {
|
|
534
|
+
winston.info("PubModulesManager error starting routingQueue queued module", err);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
525
537
|
|
|
526
538
|
// if (this.dialogFlow) {
|
|
527
539
|
// try {
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
const projectEvent = require('../../event/projectEvent');
|
|
2
1
|
const departmentEvent = require('../../event/departmentEvent');
|
|
3
|
-
const authEvent = require('../../event/authEvent');
|
|
4
|
-
const requestEvent = require('../../event/requestEvent');
|
|
5
2
|
var Request = require('../../models/request');
|
|
6
|
-
var Project = require('../../models/project');
|
|
7
|
-
var Project_user = require('../../models/project_user');
|
|
8
3
|
var winston = require('../../config/winston');
|
|
9
4
|
|
|
10
|
-
var ProjectUserUtil = require("../../utils/project_userUtil");
|
|
11
5
|
|
|
12
6
|
// var request = require('retry-request', {
|
|
13
7
|
// request: require('request')
|
|
@@ -55,42 +49,6 @@ class Listener {
|
|
|
55
49
|
// };
|
|
56
50
|
}
|
|
57
51
|
|
|
58
|
-
// db.getCollection('project_users').find({"number_assigned_requests" : {"$lt":0}}).count()
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
updateProjectUser(id_user, id_project, operation) {
|
|
62
|
-
winston.debug("updateProjectUser start");
|
|
63
|
-
return Project_user
|
|
64
|
-
.findOneAndUpdate({id_user: id_user, id_project: id_project}, {$inc : {'number_assigned_requests' : operation}}, {new: true, upsert:false}, function(err, updatedPU) {
|
|
65
|
-
if (err) {
|
|
66
|
-
return winston.error(err);
|
|
67
|
-
}
|
|
68
|
-
winston.debug("number_assigned_requests +1 :" + updatedPU.id);
|
|
69
|
-
|
|
70
|
-
updatedPU.populate({path:'id_user', select:{'firstname':1, 'lastname':1}},function (err, updatedProject_userPopulated){
|
|
71
|
-
|
|
72
|
-
var pu = updatedProject_userPopulated.toJSON();
|
|
73
|
-
|
|
74
|
-
return Project.findById(id_project).exec(function(err, project) {
|
|
75
|
-
pu.isBusy = ProjectUserUtil.isBusy(updatedProject_userPopulated, project.settings && project.settings.max_agent_assigned_chat);
|
|
76
|
-
winston.debug("pu.isBusy: "+ pu.isBusy);
|
|
77
|
-
authEvent.emit('project_user.update', {updatedProject_userPopulated:pu, req: undefined, skipArchive: true});
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
updateParticipatingProjectUsers(request, operation) {
|
|
86
|
-
winston.debug("request.participatingAgents", request.participatingAgents);
|
|
87
|
-
if (request.participatingAgents.length>0) {
|
|
88
|
-
request.participatingAgents.forEach(user => {
|
|
89
|
-
winston.debug("request.participatingAgents user",user); //it is a user and not a project_user
|
|
90
|
-
this.updateProjectUser(user.id, request.id_project, operation);
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
52
|
|
|
95
53
|
listen() {
|
|
96
54
|
|
|
@@ -101,57 +59,6 @@ class Listener {
|
|
|
101
59
|
}
|
|
102
60
|
|
|
103
61
|
var that = this;
|
|
104
|
-
|
|
105
|
-
// TODO fai versione che passa anche project
|
|
106
|
-
requestEvent.on('request.create', async (request) => {
|
|
107
|
-
setImmediate(() => {
|
|
108
|
-
this.updateParticipatingProjectUsers(request, +1);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
// TODO usa versione complete con project per evitare query??
|
|
113
|
-
requestEvent.on('request.close', async (request) => {
|
|
114
|
-
setImmediate(() => {
|
|
115
|
-
this.updateParticipatingProjectUsers(request, -1);
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
requestEvent.on('request.participants.join', async (data) => {
|
|
121
|
-
var request = data.request;
|
|
122
|
-
var member = data.member;
|
|
123
|
-
setImmediate(() => {
|
|
124
|
-
this.updateProjectUser(member, request.id_project, 1);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
requestEvent.on('request.participants.leave', async (data) => {
|
|
129
|
-
var request = data.request;
|
|
130
|
-
var member = data.member;
|
|
131
|
-
setImmediate(() => {
|
|
132
|
-
this.updateProjectUser(member, request.id_project, -1);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
requestEvent.on('request.participants.update', async (data) => {
|
|
137
|
-
var request = data.request;
|
|
138
|
-
var removedParticipants = data.removedParticipants;
|
|
139
|
-
var addedParticipants = data.addedParticipants;
|
|
140
|
-
|
|
141
|
-
setImmediate(() => {
|
|
142
|
-
|
|
143
|
-
addedParticipants.forEach(participant => {
|
|
144
|
-
winston.debug('addedParticipants participant', participant);
|
|
145
|
-
this.updateProjectUser(participant, request.id_project, 1);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
removedParticipants.forEach(participant => {
|
|
149
|
-
winston.debug('removedParticipants participant', participant);
|
|
150
|
-
this.updateProjectUser(participant, request.id_project, -1);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
62
|
|
|
156
63
|
departmentEvent.on('operator.select.base2', async (res) => {
|
|
157
64
|
// departmentEvent.prependListener('operator.select', async (data) => {
|
|
@@ -170,9 +77,7 @@ class Listener {
|
|
|
170
77
|
|
|
171
78
|
}
|
|
172
79
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
80
|
+
|
|
176
81
|
|
|
177
82
|
|
|
178
83
|
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
const authEvent = require('../../event/authEvent');
|
|
2
|
+
const requestEvent = require('../../event/requestEvent');
|
|
3
|
+
var Project = require('../../models/project');
|
|
4
|
+
var Project_user = require('../../models/project_user');
|
|
5
|
+
var winston = require('../../config/winston');
|
|
6
|
+
|
|
7
|
+
var ProjectUserUtil = require("../../utils/project_userUtil");
|
|
8
|
+
|
|
9
|
+
// var request = require('retry-request', {
|
|
10
|
+
// request: require('request')
|
|
11
|
+
// });
|
|
12
|
+
|
|
13
|
+
// TODO riabilitare questo
|
|
14
|
+
|
|
15
|
+
// const ROUTE_QUEUE_ENDPOINT = process.env.ROUTE_QUEUE_ENDPOINT;
|
|
16
|
+
// winston.debug("ROUTE_QUEUE_ENDPOINT: " + ROUTE_QUEUE_ENDPOINT);
|
|
17
|
+
|
|
18
|
+
// if (ROUTE_QUEUE_ENDPOINT) {
|
|
19
|
+
// winston.info("Route queue endpoint: " + ROUTE_QUEUE_ENDPOINT);
|
|
20
|
+
// } else {
|
|
21
|
+
// winston.info("Route queue endpoint not configured");
|
|
22
|
+
// }
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// TODO web socket is not supported with queue
|
|
28
|
+
class Listener {
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
constructor() {
|
|
32
|
+
this.enabled = true;
|
|
33
|
+
if (process.env.ROUTE_QUEUE_ENABLED=="false" || process.env.ROUTE_QUEUE_ENABLED==false) {
|
|
34
|
+
this.enabled = false;
|
|
35
|
+
}
|
|
36
|
+
winston.debug("Listener this.enabled: "+ this.enabled);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
// db.getCollection('project_users').find({"number_assigned_requests" : {"$lt":0}}).count()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
updateProjectUser(id_user, id_project, operation) {
|
|
44
|
+
winston.debug("Route queue updateProjectUser start");
|
|
45
|
+
return Project_user
|
|
46
|
+
.findOneAndUpdate({id_user: id_user, id_project: id_project}, {$inc : {'number_assigned_requests' : operation}}, {new: true, upsert:false}, function(err, updatedPU) {
|
|
47
|
+
if (err) {
|
|
48
|
+
return winston.error(err);
|
|
49
|
+
}
|
|
50
|
+
winston.debug("Route queue number_assigned_requests +1 :" + updatedPU.id);
|
|
51
|
+
|
|
52
|
+
updatedPU.populate({path:'id_user', select:{'firstname':1, 'lastname':1}},function (err, updatedProject_userPopulated){
|
|
53
|
+
|
|
54
|
+
var pu = updatedProject_userPopulated.toJSON();
|
|
55
|
+
|
|
56
|
+
return Project.findById(id_project).exec(function(err, project) {
|
|
57
|
+
pu.isBusy = ProjectUserUtil.isBusy(updatedProject_userPopulated, project.settings && project.settings.max_agent_assigned_chat);
|
|
58
|
+
winston.debug("Route queue pu.isBusy: "+ pu.isBusy);
|
|
59
|
+
|
|
60
|
+
authEvent.emit('project_user.update', {updatedProject_userPopulated:pu, req: undefined, skipArchive: true}); //if queued with jobs -> websocket notification on project_user.update doesn't work??? forse si in quanto viene convertito in .pub.queue e poi rifunziiona
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
// project_user.update triggers activityArchiver(tested), cache invalidation(tested), subscriptionNotifierQueued and websocket(tested works from queue i trigger ws)
|
|
64
|
+
if (requestEvent.queueEnabled) { //force to .queue to be catched into the queue (activity archiver, subscriptionNotifierQueued )
|
|
65
|
+
authEvent.emit('project_user.update.queue', {updatedProject_userPopulated:pu, req: undefined, skipArchive: true});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
updateParticipatingProjectUsers(request, operation) {
|
|
76
|
+
winston.debug("Route queue request.participatingAgents", request.participatingAgents);
|
|
77
|
+
if (request.participatingAgents.length>0) {
|
|
78
|
+
request.participatingAgents.forEach(user => {
|
|
79
|
+
winston.debug("request.participatingAgents user",user); //it is a user and not a project_user
|
|
80
|
+
this.updateProjectUser(user.id, request.id_project, operation);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
listen() {
|
|
86
|
+
|
|
87
|
+
if (this.enabled==true) {
|
|
88
|
+
winston.info("Route queue with queue Listener listen");
|
|
89
|
+
} else {
|
|
90
|
+
return winston.info("Route queue with queue Listener disabled");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
var that = this;
|
|
94
|
+
|
|
95
|
+
// TODO fai versione che passa anche project
|
|
96
|
+
var requestCreateKey = 'request.create';
|
|
97
|
+
if (requestEvent.queueEnabled) {
|
|
98
|
+
requestCreateKey = 'request.create.queue';
|
|
99
|
+
}
|
|
100
|
+
winston.debug('Route queue requestCreateKey: ' + requestCreateKey);
|
|
101
|
+
|
|
102
|
+
requestEvent.on(requestCreateKey, async (request) => {
|
|
103
|
+
setImmediate(() => {
|
|
104
|
+
winston.debug('Route queue requestCreate');
|
|
105
|
+
this.updateParticipatingProjectUsers(request, +1);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// TODO usa versione complete con project per evitare query??
|
|
110
|
+
var requestCloseKey = 'request.close'; //request.close event here queued under job
|
|
111
|
+
if (requestEvent.queueEnabled) {
|
|
112
|
+
requestCloseKey = 'request.close.queue';
|
|
113
|
+
}
|
|
114
|
+
winston.debug('Route queue requestCloseKey: ' + requestCloseKey);
|
|
115
|
+
|
|
116
|
+
requestEvent.on(requestCloseKey, async (request) => { //request.close event here noqueued
|
|
117
|
+
winston.debug("request.close event here 4")
|
|
118
|
+
setImmediate(() => {
|
|
119
|
+
winston.debug('Route queue requestClose');
|
|
120
|
+
this.updateParticipatingProjectUsers(request, -1);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
var requestParticipantsJoinKey = 'request.participants.join';
|
|
126
|
+
if (requestEvent.queueEnabled) {
|
|
127
|
+
requestParticipantsJoinKey = 'request.participants.join.queue';
|
|
128
|
+
}
|
|
129
|
+
winston.debug('Route queue requestParticipantsJoinKey: ' + requestParticipantsJoinKey);
|
|
130
|
+
|
|
131
|
+
requestEvent.on(requestParticipantsJoinKey, async (data) => {
|
|
132
|
+
winston.debug('Route queue ParticipantsJoin');
|
|
133
|
+
|
|
134
|
+
var request = data.request;
|
|
135
|
+
var member = data.member;
|
|
136
|
+
setImmediate(() => {
|
|
137
|
+
this.updateProjectUser(member, request.id_project, 1);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
var requestParticipantsLeaveKey = 'request.participants.leave';
|
|
142
|
+
if (requestEvent.queueEnabled) {
|
|
143
|
+
requestParticipantsLeaveKey = 'request.participants.leave.queue';
|
|
144
|
+
}
|
|
145
|
+
winston.debug('Route queue requestParticipantsLeaveKey: ' + requestParticipantsLeaveKey);
|
|
146
|
+
|
|
147
|
+
requestEvent.on(requestParticipantsLeaveKey, async (data) => {
|
|
148
|
+
winston.debug('Route queue ParticipantsLeave');
|
|
149
|
+
|
|
150
|
+
var request = data.request;
|
|
151
|
+
var member = data.member;
|
|
152
|
+
setImmediate(() => {
|
|
153
|
+
this.updateProjectUser(member, request.id_project, -1);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
var requestParticipantsUpdateKey = 'request.participants.update';
|
|
158
|
+
if (requestEvent.queueEnabled) {
|
|
159
|
+
requestParticipantsUpdateKey = 'request.participants.update.queue';
|
|
160
|
+
}
|
|
161
|
+
winston.debug('Route queue requestParticipantsUpdateKey: ' + requestParticipantsUpdateKey);
|
|
162
|
+
|
|
163
|
+
requestEvent.on(requestParticipantsUpdateKey, async (data) => {
|
|
164
|
+
winston.debug('Route queue Participants Update');
|
|
165
|
+
|
|
166
|
+
var request = data.request;
|
|
167
|
+
var removedParticipants = data.removedParticipants;
|
|
168
|
+
var addedParticipants = data.addedParticipants;
|
|
169
|
+
|
|
170
|
+
setImmediate(() => {
|
|
171
|
+
|
|
172
|
+
addedParticipants.forEach(participant => {
|
|
173
|
+
winston.debug('addedParticipants participant', participant);
|
|
174
|
+
this.updateProjectUser(participant, request.id_project, 1);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
removedParticipants.forEach(participant => {
|
|
178
|
+
winston.debug('removedParticipants participant', participant);
|
|
179
|
+
this.updateProjectUser(participant, request.id_project, -1);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
var listener = new Listener();
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
module.exports = listener;
|
package/routes/email.js
CHANGED
|
@@ -303,33 +303,35 @@ if (process.env.ENABLE_TEST_EMAIL_ENDPOINT==true || process.env.ENABLE_TEST_EMAI
|
|
|
303
303
|
|
|
304
304
|
|
|
305
305
|
//TODO add cc
|
|
306
|
-
router.post('/send',
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
306
|
+
// router.post('/send',
|
|
307
|
+
// async (req, res) => {
|
|
308
|
+
// let to = req.body.to;
|
|
309
|
+
// winston.debug("to: " + to);
|
|
310
310
|
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
// let text = req.body.text;
|
|
312
|
+
// winston.debug("text: " + text);
|
|
313
313
|
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
// let request_id = req.body.request_id;
|
|
315
|
+
// winston.debug("request_id: " + request_id);
|
|
316
316
|
|
|
317
|
-
|
|
318
|
-
|
|
317
|
+
// let subject = req.body.subject;
|
|
318
|
+
// winston.debug("subject: " + subject);
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
// winston.debug("req.project", req.project);
|
|
321
321
|
|
|
322
|
-
|
|
323
|
-
|
|
322
|
+
// let newto = await recipientEmailUtil.process(to, req.projectid);
|
|
323
|
+
// winston.debug("newto: " + newto);
|
|
324
324
|
|
|
325
|
-
|
|
326
|
-
|
|
325
|
+
// let replyto = req.body.replyto;
|
|
326
|
+
// winston.debug("replyto: " + replyto);
|
|
327
327
|
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
// winston.info("Sending an email with text : " + text + " to " + to);
|
|
329
|
+
|
|
330
|
+
// //sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage, payload)
|
|
331
|
+
// emailService.sendEmailDirect(newto, text, req.project, request_id, subject, undefined, undefined, undefined, replyto);
|
|
330
332
|
|
|
331
|
-
|
|
333
|
+
// res.json({"queued": true});
|
|
332
334
|
|
|
333
|
-
});
|
|
335
|
+
// });
|
|
334
336
|
|
|
335
337
|
module.exports = router;
|
package/routes/faq.js
CHANGED
|
@@ -168,10 +168,12 @@ router.post('/', function (req, res) {
|
|
|
168
168
|
if (req.body.actions) {
|
|
169
169
|
newFaq.actions = req.body.actions
|
|
170
170
|
}
|
|
171
|
-
|
|
172
171
|
if (req.body.attributes) {
|
|
173
172
|
newFaq.attributes = req.body.attributes
|
|
174
173
|
}
|
|
174
|
+
if (req.body.intent_id) {
|
|
175
|
+
newFaq.intent_id = req.body.intent_id;
|
|
176
|
+
}
|
|
175
177
|
|
|
176
178
|
newFaq.save(function (err, savedFaq) {
|
|
177
179
|
if (err) {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var express = require('express');
|
|
2
|
+
var OpenaiKbs = require('../models/openai_kbs');
|
|
3
|
+
var router = express.Router();
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
router.get('/', async (req, res) => {
|
|
7
|
+
|
|
8
|
+
let project_id = req.projectid;
|
|
9
|
+
|
|
10
|
+
OpenaiKbs.find({ id_project: project_id }, (err, kbs) => {
|
|
11
|
+
if (err) {
|
|
12
|
+
console.error("find all kbs error: ", err);
|
|
13
|
+
return res.status(500).send({ success: false, error: err });
|
|
14
|
+
} else {
|
|
15
|
+
return res.status(200).send(kbs);
|
|
16
|
+
}
|
|
17
|
+
})
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
router.post('/', async (req, res) => {
|
|
21
|
+
|
|
22
|
+
let body = req.body;
|
|
23
|
+
|
|
24
|
+
let new_kbs = new OpenaiKbs({
|
|
25
|
+
name: body.name,
|
|
26
|
+
url: body.url,
|
|
27
|
+
id_project: req.projectid
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
new_kbs.save(function (err, savedKbs) {
|
|
31
|
+
if (err) {
|
|
32
|
+
console.error("save new kbs error: ", err);
|
|
33
|
+
return res.status(500).send({ success: false, error: err});
|
|
34
|
+
} else {
|
|
35
|
+
return res.status(200).send(savedKbs);
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
router.put('/', async (req, res) => {
|
|
41
|
+
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
router.delete('/:kbs_id', async (req, res) => {
|
|
45
|
+
let kbs_id = req.params.kbs_id;
|
|
46
|
+
|
|
47
|
+
OpenaiKbs.findOneAndDelete( { _id: kbs_id }, (err, kbDeleted) => {
|
|
48
|
+
if (err) {
|
|
49
|
+
console.error("find one and delete kbs error: ", err);
|
|
50
|
+
return res.status(500).send({ success: false, error: err});
|
|
51
|
+
} else {
|
|
52
|
+
return res.status(200).send({ success: true, message: 'Knowledge Base deleted successfully', openai_kb: kbDeleted });
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
module.exports = router;
|
package/services/faqService.js
CHANGED
|
@@ -12,53 +12,53 @@ class FaqService {
|
|
|
12
12
|
var that = this;
|
|
13
13
|
return new Promise(function (resolve, reject) {
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
15
|
+
//winston.debug('FAQ-KB POST REQUEST BODY ', req.body);
|
|
16
|
+
var newFaq_kb = new Faq_kb({
|
|
17
|
+
name: name,
|
|
18
|
+
description: description,
|
|
19
|
+
url: url,
|
|
20
|
+
id_project: projectid,
|
|
21
|
+
webhook_url: webhook_url,
|
|
22
|
+
webhook_enabled: webhook_enabled,
|
|
23
|
+
type: type,
|
|
24
|
+
language: language,
|
|
25
|
+
public: false,
|
|
26
|
+
certified: false,
|
|
27
|
+
mainCategory: mainCategory,
|
|
28
|
+
intentsEngine: intentsEngine,
|
|
29
|
+
trashed: false,
|
|
30
|
+
createdBy: user_id,
|
|
31
|
+
updatedBy: user_id,
|
|
32
|
+
attributes: attributes
|
|
33
|
+
});
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
|
|
36
|
+
newFaq_kb.save(function (err, savedFaq_kb) {
|
|
37
|
+
if (err) {
|
|
38
|
+
winston.error('--- > ERROR ', err)
|
|
39
|
+
return reject('Error saving object.');
|
|
40
|
+
}
|
|
41
|
+
winston.debug('-> -> SAVED FAQFAQ KB ', savedFaq_kb.toObject())
|
|
42
|
+
|
|
43
|
+
botEvent.emit('faqbot.create', savedFaq_kb);
|
|
44
|
+
|
|
45
|
+
winston.debug('type ' + type)
|
|
46
|
+
|
|
47
|
+
if (type === "internal" || type === "tilebot") {
|
|
48
|
+
|
|
49
|
+
if (!template) {
|
|
50
|
+
template = "empty";
|
|
40
51
|
}
|
|
41
|
-
winston.debug('
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (type==="internal" || type==="tilebot") {
|
|
48
|
-
|
|
49
|
-
if (!template) {
|
|
50
|
-
template = "empty";
|
|
51
|
-
}
|
|
52
|
-
winston.debug('template '+ template);
|
|
53
|
-
that.createGreetingsAndOperationalsFaqs(savedFaq_kb._id, savedFaq_kb.createdBy, savedFaq_kb.id_project, template);
|
|
54
|
-
} else {
|
|
55
|
-
winston.debug('external bot: ', savedFaq_kb);
|
|
56
|
-
}
|
|
52
|
+
winston.debug('template ' + template);
|
|
53
|
+
that.createGreetingsAndOperationalsFaqs(savedFaq_kb._id, savedFaq_kb.createdBy, savedFaq_kb.id_project, template);
|
|
54
|
+
} else {
|
|
55
|
+
winston.debug('external bot: ', savedFaq_kb);
|
|
56
|
+
}
|
|
57
57
|
|
|
58
|
-
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
|
|
60
|
+
return resolve(savedFaq_kb);
|
|
61
|
+
});
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -69,98 +69,119 @@ class FaqService {
|
|
|
69
69
|
// aggiungi esempio tdAction con intent_id
|
|
70
70
|
|
|
71
71
|
// TODO non scatta i trigger sui rest hook. fare?
|
|
72
|
-
winston.debug('template: '+ template);
|
|
72
|
+
winston.debug('template: ' + template);
|
|
73
73
|
|
|
74
74
|
var faqsArray;
|
|
75
75
|
|
|
76
|
-
if (template==="example") {
|
|
76
|
+
if (template === "example") {
|
|
77
77
|
|
|
78
78
|
faqsArray = [
|
|
79
79
|
{ 'question': 'Hi', 'answer': 'Hi', 'topic': 'greetings' },
|
|
80
80
|
{ 'question': 'Hello', 'answer': 'Hello', 'topic': 'greetings' },
|
|
81
|
-
{ 'question': 'Who are you?', 'answer': 'Hi, I\'m a bot 🤖. You can find more about me [here](https://tiledesk.com/chatbot-for-customer-service).\ntdImage:https://console.tiledesk.com/assets/images/tily-welcomebot.gif\n* See the website https://tiledesk.com/\n* Back to start tdAction:start', 'topic': 'greetings' },
|
|
82
|
-
{ 'question': '👨🏻🦰 I want an agent', 'answer': 'We are looking for an operator.. '+ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
|
|
83
|
-
{ 'question': 'Close\nResolved', 'answer': ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE, 'topic': 'internal' },
|
|
84
|
-
{ 'question': '\\start', 'answer': 'Hello 👋. I\'m a bot 🤖.\n\nChoose one of the options below or write a message to reach our staff.\n* Who are you?\n* Where are you?\n* What can you do?\n* 👨🏻🦰 I want an agent', 'intent_display_name': 'start', 'topic': 'internal' },
|
|
81
|
+
{ 'question': 'Who are you?', 'answer': 'Hi, I\'m a bot 🤖. You can find more about me [here](https://tiledesk.com/chatbot-for-customer-service).\ntdImage:https://console.tiledesk.com/assets/images/tily-welcomebot.gif\n* See the website https://tiledesk.com/\n* Back to start tdAction:start', 'topic': 'greetings' },
|
|
82
|
+
{ 'question': '👨🏻🦰 I want an agent', 'answer': 'We are looking for an operator.. ' + ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
|
|
83
|
+
{ 'question': 'Close\nResolved', 'answer': ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE, 'topic': 'internal' },
|
|
84
|
+
{ 'question': '\\start', 'answer': 'Hello 👋. I\'m a bot 🤖.\n\nChoose one of the options below or write a message to reach our staff.\n* Who are you?\n* Where are you?\n* What can you do?\n* 👨🏻🦰 I want an agent', 'intent_display_name': 'start', 'topic': 'internal' },
|
|
85
85
|
{ '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', 'topic': 'internal' }, //TODO se metto spazio n * nn va
|
|
86
|
-
{ 'question': 'What can you do?', 'answer': 'Using natural language processing, I\'m able to find the best answer for your users. I also support images, videos etc.. Let\'s try:\n* Sample Image\n* Sample Video\n* Sample Action tdAction:action1\n* Sample Frame\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
87
|
-
{ 'question': 'Sample Image', 'answer': 'tdImage:https://tiledesk.com/wp-content/uploads/2022/07/tiledesk_v2.png\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
88
|
-
{ 'question': 'Sample Frame', 'answer': 'tdFrame:https://www.emanueleferonato.com/wp-content/uploads/2019/02/runner/\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
89
|
-
{ 'question': 'Sample Video', 'answer': 'tdVideo:https://www.youtube.com/embed/EngW7tLk6R8\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
90
|
-
{ 'question': 'Where are you?', 'answer': 'We are here ❤️\ntdFrame:https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6087916.923447935!2d8.234804542117423!3d41.836572992140624!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12d4fe82448dd203%3A0xe22cf55c24635e6f!2sItaly!5e0!3m2!1sen!2sit!4v1613657475377!5m2!1sen!2sit\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
91
|
-
|
|
86
|
+
{ 'question': 'What can you do?', 'answer': 'Using natural language processing, I\'m able to find the best answer for your users. I also support images, videos etc.. Let\'s try:\n* Sample Image\n* Sample Video\n* Sample Action tdAction:action1\n* Sample Frame\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
87
|
+
{ 'question': 'Sample Image', 'answer': 'tdImage:https://tiledesk.com/wp-content/uploads/2022/07/tiledesk_v2.png\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
88
|
+
{ 'question': 'Sample Frame', 'answer': 'tdFrame:https://www.emanueleferonato.com/wp-content/uploads/2019/02/runner/\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
89
|
+
{ 'question': 'Sample Video', 'answer': 'tdVideo:https://www.youtube.com/embed/EngW7tLk6R8\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
90
|
+
{ 'question': 'Where are you?', 'answer': 'We are here ❤️\ntdFrame:https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6087916.923447935!2d8.234804542117423!3d41.836572992140624!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12d4fe82448dd203%3A0xe22cf55c24635e6f!2sItaly!5e0!3m2!1sen!2sit!4v1613657475377!5m2!1sen!2sit\n* Back to start tdAction:start', 'topic': 'sample' },
|
|
91
|
+
|
|
92
92
|
// { 'question': 'Sample Webhook', 'answer': 'tdWebhook:https://tiledesk-bot-webhook.tiledesk.repl.co', 'topic': 'sample' },
|
|
93
|
-
{ 'question': 'Sample Action', 'answer': 'Hello 👋 Would you like to take a closer look at our offer?\n* Yes, please tdAction:yes_action\n* No tdAction:no_action','intent_display_name': 'action1', 'topic': 'sample' },
|
|
94
|
-
{ 'question': 'Yes Action', 'answer': 'Great! Take a look here:\n* Tiledesk Pricing https://tiledesk.com/pricing-cloud/',
|
|
95
|
-
{ 'question': 'No Action', 'answer': 'All right! If you need anything, let us know.',
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
{ 'question': 'Sample Action', 'answer': 'Hello 👋 Would you like to take a closer look at our offer?\n* Yes, please tdAction:yes_action\n* No tdAction:no_action', 'intent_display_name': 'action1', 'topic': 'sample' },
|
|
94
|
+
{ 'question': 'Yes Action', 'answer': 'Great! Take a look here:\n* Tiledesk Pricing https://tiledesk.com/pricing-cloud/', 'intent_display_name': 'yes_action', 'topic': 'sample' },
|
|
95
|
+
{ 'question': 'No Action', 'answer': 'All right! If you need anything, let us know.', 'intent_display_name': 'no_action', 'topic': 'sample' },
|
|
96
|
+
|
|
97
|
+
|
|
98
98
|
// action button nn si può fare perche gli id cambiano
|
|
99
99
|
]
|
|
100
100
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
if (template==="blank") {
|
|
103
|
+
if (template === "blank") {
|
|
104
104
|
|
|
105
105
|
// faqsArray = [
|
|
106
106
|
// { 'question': '\\start', 'answer': 'Hello', 'intent_display_name': 'start', 'topic': 'internal' },
|
|
107
107
|
// { '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', 'topic': 'internal' }, //TODO se metto spazio n * nn va
|
|
108
108
|
// ]
|
|
109
|
-
faqsArray = [
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
109
|
+
faqsArray = [{
|
|
110
|
+
"webhook_enabled": false,
|
|
111
|
+
"enabled": true,
|
|
112
|
+
"actions": [{
|
|
113
|
+
"_tdActionType": "reply",
|
|
114
|
+
"text": "I didn't understand. Can you rephrase your question?",
|
|
115
|
+
"attributes": {
|
|
116
|
+
"commands": [{
|
|
117
|
+
"type": "message",
|
|
118
|
+
"message": {
|
|
119
|
+
"type": "text",
|
|
120
|
+
"text": "I didn't understand. Can you rephrase your question?"
|
|
121
|
+
}
|
|
122
|
+
}]
|
|
123
|
+
}
|
|
124
|
+
}],
|
|
125
|
+
"intent_display_name": "defaultFallback",
|
|
126
|
+
"attributes": {
|
|
127
|
+
"position": {
|
|
128
|
+
"x": 714,
|
|
129
|
+
"y": 528
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}, {
|
|
133
|
+
"webhook_enabled": false,
|
|
134
|
+
"enabled": true,
|
|
135
|
+
"actions": [{
|
|
136
|
+
"_tdActionType": "intent",
|
|
137
|
+
"intentName": "#9d0b96b9-e036-4c2d-8504-1181b5c4be75"
|
|
138
|
+
}],
|
|
139
|
+
"question": "\\start",
|
|
140
|
+
"intent_display_name": "start",
|
|
141
|
+
"attributes": {
|
|
142
|
+
"position": {
|
|
143
|
+
"x": 172,
|
|
144
|
+
"y": 384
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}, {
|
|
148
|
+
"webhook_enabled": false,
|
|
149
|
+
"enabled": true,
|
|
150
|
+
"actions": [{
|
|
151
|
+
"_tdActionType": "reply",
|
|
152
|
+
"attributes": {
|
|
153
|
+
"disableInputMessage": false,
|
|
154
|
+
"commands": [{
|
|
155
|
+
"type": "wait",
|
|
156
|
+
"time": 500
|
|
157
|
+
}, {
|
|
158
|
+
"type": "message",
|
|
159
|
+
"message": {
|
|
160
|
+
"type": "text",
|
|
161
|
+
"text": "Hi, how can I help you?"
|
|
162
|
+
}
|
|
163
|
+
}]
|
|
164
|
+
},
|
|
165
|
+
"text": "Hi, how can I help you?\r\n"
|
|
166
|
+
}],
|
|
167
|
+
"intent_display_name": "welcome",
|
|
168
|
+
"intent_id": "9d0b96b9-e036-4c2d-8504-1181b5c4be75",
|
|
169
|
+
"attributes": {
|
|
170
|
+
"position": {
|
|
171
|
+
"x": 714,
|
|
172
|
+
"y": 113
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}]
|
|
155
176
|
|
|
156
177
|
}
|
|
157
178
|
|
|
158
179
|
|
|
159
|
-
if (template==="handoff") {
|
|
180
|
+
if (template === "handoff") {
|
|
160
181
|
|
|
161
|
-
faqsArray = [
|
|
162
|
-
{ 'question': '\\start', 'answer': 'Hello', 'intent_display_name': 'start', 'topic': 'internal' },
|
|
163
|
-
{ 'question': '👨🏻🦰 I want an agent', 'answer': 'We are looking for an operator.. '+ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
|
|
182
|
+
faqsArray = [
|
|
183
|
+
{ 'question': '\\start', 'answer': 'Hello', 'intent_display_name': 'start', 'topic': 'internal' },
|
|
184
|
+
{ 'question': '👨🏻🦰 I want an agent', 'answer': 'We are looking for an operator.. ' + ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
|
|
164
185
|
{ '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', 'topic': 'internal' }, //TODO se metto spazio n * nn va
|
|
165
186
|
]
|
|
166
187
|
|
|
@@ -169,18 +190,20 @@ class FaqService {
|
|
|
169
190
|
if (template === "empty") {
|
|
170
191
|
faqsArray = [];
|
|
171
192
|
}
|
|
172
|
-
|
|
173
|
-
|
|
193
|
+
|
|
194
|
+
|
|
174
195
|
faqsArray.forEach(faq => {
|
|
175
196
|
|
|
176
197
|
var newFaq = new Faq({
|
|
177
198
|
id_faq_kb: faq_kb_id,
|
|
199
|
+
intent_id: faq.intent_id,
|
|
178
200
|
question: faq.question,
|
|
179
201
|
answer: faq.answer,
|
|
180
202
|
actions: faq.actions,
|
|
181
203
|
reply: faq.reply,
|
|
182
204
|
intent_display_name: faq.intent_display_name,
|
|
183
205
|
language: "en",
|
|
206
|
+
attributes: faq.attributes,
|
|
184
207
|
id_project: projectid,
|
|
185
208
|
topic: faq.topic,
|
|
186
209
|
createdBy: created_by,
|
|
@@ -207,8 +230,8 @@ class FaqService {
|
|
|
207
230
|
winston.debug("(Service) GET ALL FAQ OF THE BOT ID (req.query): ", faq_kb_id);
|
|
208
231
|
|
|
209
232
|
return new Promise((resolve, reject) => {
|
|
210
|
-
|
|
211
|
-
Faq.find({ id_faq_kb: faq_kb_id}, (err, faqs) => {
|
|
233
|
+
|
|
234
|
+
Faq.find({ id_faq_kb: faq_kb_id }, (err, faqs) => {
|
|
212
235
|
if (err) {
|
|
213
236
|
reject(err);
|
|
214
237
|
}
|
package/test/faqRoute.js
CHANGED
|
@@ -53,7 +53,7 @@ describe('FaqKBRoute', () => {
|
|
|
53
53
|
chai.request(server)
|
|
54
54
|
.post('/' + savedProject._id + '/faq')
|
|
55
55
|
.auth(email, pwd)
|
|
56
|
-
.send({ id_faq_kb: id_faq_kb, question: "question1", answer: "answer1", attributes: { attr1: { one: "one", two: "two"}, attr2: {three: "three"}} })
|
|
56
|
+
.send({ id_faq_kb: id_faq_kb, question: "question1", answer: "answer1", attributes: { attr1: { one: "one", two: "two"}, attr2: {three: "three"}}, intent_id: 'custom-intent-id' }) // if intent_id is null the value will be the default one
|
|
57
57
|
.end((err, res) => {
|
|
58
58
|
//console.log("res", res);
|
|
59
59
|
console.log("res.body", res.body);
|
package/test/faqkbRoute.js
CHANGED
|
@@ -111,6 +111,48 @@ describe('FaqKBRoute', () => {
|
|
|
111
111
|
|
|
112
112
|
|
|
113
113
|
|
|
114
|
+
});
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('create with template blank', (done) => {
|
|
120
|
+
|
|
121
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
|
122
|
+
var pwd = "pwd";
|
|
123
|
+
|
|
124
|
+
userService.signup(email, pwd, "Test Firstname", "Test Lastname").then((savedUser) => {
|
|
125
|
+
projectService.create("test-faqkb-create", savedUser._id).then((savedProject) => {
|
|
126
|
+
|
|
127
|
+
chai.request(server)
|
|
128
|
+
.post('/' + savedProject._id + '/faq_kb')
|
|
129
|
+
.auth(email, pwd)
|
|
130
|
+
.send({ "name": "testbot", type: "internal", template: "blank" })
|
|
131
|
+
.end((err, res) => {
|
|
132
|
+
if (log) {
|
|
133
|
+
}
|
|
134
|
+
console.log("res.body", res.body);
|
|
135
|
+
res.should.have.status(200);
|
|
136
|
+
res.body.should.be.a('object');
|
|
137
|
+
expect(res.body.name).to.equal("testbot");
|
|
138
|
+
var id_faq_kb = res.body._id;
|
|
139
|
+
|
|
140
|
+
chai.request(server)
|
|
141
|
+
.get('/' + savedProject._id + '/faq?id_faq_kb=' + id_faq_kb)
|
|
142
|
+
.auth(email, pwd)
|
|
143
|
+
.end((err, res) => {
|
|
144
|
+
if (log) {
|
|
145
|
+
}
|
|
146
|
+
console.log("faq_list: ", JSON.stringify(res.body, null, 2));
|
|
147
|
+
res.should.have.status(200);
|
|
148
|
+
res.body.should.be.an('array').that.is.not.empty;
|
|
149
|
+
|
|
150
|
+
done();
|
|
151
|
+
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
114
156
|
});
|
|
115
157
|
})
|
|
116
158
|
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
//During the test the env variable is set to test
|
|
2
|
+
process.env.NODE_ENV = 'test';
|
|
3
|
+
|
|
4
|
+
let log = false;
|
|
5
|
+
|
|
6
|
+
//Require the dev-dependencies
|
|
7
|
+
let chai = require('chai');
|
|
8
|
+
let chaiHttp = require('chai-http');
|
|
9
|
+
let server = require('../app');
|
|
10
|
+
let should = chai.should();
|
|
11
|
+
var fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
14
|
+
// chai.config.includeStack = true;
|
|
15
|
+
|
|
16
|
+
var expect = chai.expect;
|
|
17
|
+
var assert = chai.assert;
|
|
18
|
+
|
|
19
|
+
chai.use(chaiHttp);
|
|
20
|
+
|
|
21
|
+
describe('FaqKBRoute', () => {
|
|
22
|
+
|
|
23
|
+
describe('/create', () => {
|
|
24
|
+
|
|
25
|
+
it('home', (done) => {
|
|
26
|
+
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('create', (done) => {
|
|
30
|
+
|
|
31
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
|
32
|
+
var pwd = "pwd";
|
|
33
|
+
|
|
34
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
|
35
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
|
36
|
+
chai.request(server)
|
|
37
|
+
.post('/' + savedProject._id + '/faq_kb')
|
|
38
|
+
.auth(email, pwd)
|
|
39
|
+
.send({ "name": "testbot", type: "external", language: 'fr' })
|
|
40
|
+
.end((err, res) => {
|
|
41
|
+
if (log) {
|
|
42
|
+
console.log("res.body", res.body);
|
|
43
|
+
}
|
|
44
|
+
res.should.have.status(200);
|
|
45
|
+
res.body.should.be.a('object');
|
|
46
|
+
expect(res.body.name).to.equal("testbot");
|
|
47
|
+
expect(res.body.language).to.equal("fr");
|
|
48
|
+
|
|
49
|
+
chai.request(server)
|
|
50
|
+
.get('/' + savedProject._id + '/faq_kb/' + res.body._id)
|
|
51
|
+
.auth(email, pwd)
|
|
52
|
+
.end((err, res) => {
|
|
53
|
+
if (log) {
|
|
54
|
+
console.log("res.body", res.body);
|
|
55
|
+
}
|
|
56
|
+
res.should.have.status(200);
|
|
57
|
+
|
|
58
|
+
done();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
}).timeout(20000);
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
|