@tiledesk/tiledesk-server 2.3.50 → 2.3.52

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,13 +1,23 @@
1
1
 
2
2
 
3
- 💥 TILEDESK SERVER v2.3.48 💥
3
+ 💥 TILEDESK SERVER v2.3.51 💥
4
4
  🚀 TAGGED AND PUBLISHED ON NPM 🚀
5
5
  🚀 IN PRODUCTION 🚀
6
- (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.48)
6
+ (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.51)
7
7
 
8
- # Untagged
8
+ # 2.3.51
9
+ - Added message.received as trigger event
10
+ - Added import chatbot
11
+ - Fix lead.fullname.email.update event
12
+
13
+ # 2.3.50
9
14
  - Added new email sending endpoint
10
15
  - Emails endpoint is now usable by agents
16
+ - Added route for tiledesk-apps
17
+ - Added route for tiledesk-whatsapp
18
+ - Added route for tiledesk-kaleyra
19
+ - Updated widget.json file
20
+ - Fixed template for: beenInvitedNewUser.html beenInvitedExistingUser.html
11
21
 
12
22
  # 2.3.49 -> PROD
13
23
  - @tiledesk/tiledesk-tybot-connector": "^0.1.22
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.50",
4
+ "version": "2.3.52",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -14,7 +14,7 @@
14
14
  "enable-ent": "echo //registry.npmjs.org/:_authToken=${NPM_TOKEN} > .npmrc"
15
15
  },
16
16
  "private": false,
17
- "author": "Andrea Leo - Frontiere21 SRL",
17
+ "author": "Andrea Leo - Tiledesk SRL",
18
18
  "license": "AGPL-3.0",
19
19
  "homepage": "https://www.tiledesk.com",
20
20
  "repository": {
@@ -36,9 +36,8 @@
36
36
  "@tiledesk-ent/tiledesk-server-enterprise": "^1.0.0"
37
37
  },
38
38
  "dependencies": {
39
- "@tiledesk/tiledesk-apps": "^1.0.6",
39
+ "@tiledesk/tiledesk-apps": "^1.0.9",
40
40
  "@tiledesk/tiledesk-whatsapp-connector": "^0.1.19",
41
- "@tiledesk/tiledesk-kaleyra-proxy": "^0.1.5",
42
41
  "@tiledesk/tiledesk-chat21-app": "^1.1.7",
43
42
  "@tiledesk/tiledesk-chatbot-util": "^0.8.33",
44
43
  "@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
@@ -121,7 +121,7 @@ router.get('/', function (req, res) {
121
121
  winston.debug('CannedResponse ROUTE - SKIP PAGE ', skip);
122
122
 
123
123
  // var query = { "id_project": req.projectid, "status": {$lt:1000}};
124
- var query = {"id_project": req.projectid, "status": { $lt:1000 }, $or:[ { shared: true }, { createdBy: req.user._id } ] }
124
+ var query = {"id_project": req.projectid, "status": { $lt:1000 }, $or:[ { shared: true }, { shared : { $exists: false }}, { createdBy: req.user._id } ] }
125
125
 
126
126
  if (req.query.full_text) {
127
127
  winston.debug('CannedResponse ROUTE req.query.fulltext', req.query.full_text);
@@ -27,9 +27,6 @@ class PubModulesManager {
27
27
  this.whatsapp = undefined;
28
28
  this.whatsappRoute = undefined;
29
29
 
30
- this.kaleyra = undefined;
31
- this.kaleyraRoute = undefined;
32
-
33
30
  this.activityArchiver = undefined;
34
31
  this.activityRoute = undefined;
35
32
 
@@ -70,10 +67,6 @@ class PubModulesManager {
70
67
  app.use('/modules/whatsapp', this.whatsappRoute);
71
68
  winston.info("ModulesManager whatsappRoute controller loaded");
72
69
  }
73
- if (this.kaleyraRoute) {
74
- app.use('/modules/kaleyra', this.kaleyraRoute);
75
- winston.info("ModulesManager kaleyraRoute controller loaded");
76
- }
77
70
  if (this.tilebotRoute) {
78
71
  app.use('/modules/tilebot', this.tilebotRoute);
79
72
  winston.info("ModulesManager tilebot controller loaded");
@@ -269,22 +262,7 @@ class PubModulesManager {
269
262
  winston.info("PubModulesManager error initializing init apps module", err);
270
263
  }
271
264
  }
272
-
273
- try {
274
- this.kaleyra = require('./kaleyra');
275
- winston.debug("this.kaleyra: " + this.kaleyra);
276
- this.kaleyra.listener.listen(config);
277
-
278
- this.kaleyraRoute = this.kaleyra.kaleyraRoute;
279
-
280
- winston.info("PubModulesManager initialized apps.");
281
- } catch(err) {
282
- if (err.code == 'MODULE_NOT_FOUND') {
283
- winston.info("PubModulesManager init apps module not found");
284
- }else {
285
- winston.info("PubModulesManager error initializing init apps module", err);
286
- }
287
- }
265
+
288
266
 
289
267
  try {
290
268
  this.activityArchiver = require('./activities').activityArchiver;
@@ -198,7 +198,7 @@ devi mandare un messaggio welcome tu altrimenti il bot inserito successivamente
198
198
  "Chat closed",
199
199
  request.id_project,
200
200
  'system',
201
- {subtype:"info/support", "updateconversation" : false, messagelabel: {key: "CHAT_CLOSED"}},
201
+ {subtype:"info/support", "updateconversation" : false, messagelabel: {key: "CHAT_CLOSED"}}, // TODO send request.closed_by <- c'è il campo l'ho verificato
202
202
  undefined,
203
203
  request.language
204
204
  );
@@ -228,7 +228,7 @@ devi mandare un messaggio welcome tu altrimenti il bot inserito successivamente
228
228
  request.request_id,
229
229
  "Chat reopened",
230
230
  request.id_project,
231
- 'system',
231
+ 'system', //changed from false to true 6Aug22 because reopen from dashboard history doesn't update convs in ionic
232
232
  {subtype:"info/support", "updateconversation" : true, messagelabel: {key: "CHAT_REOPENED"}},
233
233
  undefined,
234
234
  request.language
@@ -90,7 +90,12 @@ findUnresponsiveRequests() {
90
90
  winston.verbose("CloseAgentUnresponsiveRequestTask: Request closed with request_id: " + request.request_id);
91
91
  // winston.info("Request closed",updatedStatusRequest);
92
92
  }).catch(function(err) {
93
- winston.error("CloseAgentUnresponsiveRequestTask: Error closing the request with request_id: " + request.request_id, err);
93
+ if (process.env.HIDE_CLOSE_REQUEST_ERRORS == true || process.env.HIDE_CLOSE_REQUEST_ERRORS == "true" ) {
94
+
95
+ } else {
96
+ winston.error("CloseAgentUnresponsiveRequestTask: Error closing the request with request_id: " + request.request_id, err);
97
+ }
98
+
94
99
  })
95
100
 
96
101
  });
@@ -65,6 +65,7 @@ findUnresponsiveRequests() {
65
65
 
66
66
  // db.getCollection('requests').find({"hasBot":true, "status": { "$lt": 1000 }, "createdAt": { "$lte" :new ISODate("2020-11-28T20:15:31Z")} }).count()
67
67
 
68
+
68
69
  var query = {hasBot:true, status: { $lt: 1000 }, createdAt: { $lte :new Date(Date.now() - this.queryAfterTimeout ).toISOString()} };
69
70
 
70
71
  if (this.queryProject) {
@@ -101,7 +102,12 @@ findUnresponsiveRequests() {
101
102
  winston.info("CloseBotUnresponsiveRequestTask: Request closed with request_id: " + request.request_id);
102
103
  // winston.info("Request closed",updatedStatusRequest);
103
104
  }).catch(function(err) {
104
- winston.error("CloseBotUnresponsiveRequestTask: Error closing the request with request_id: " + request.request_id, err);
105
+ if (process.env.HIDE_CLOSE_REQUEST_ERRORS == true || process.env.HIDE_CLOSE_REQUEST_ERRORS == "true" ) {
106
+
107
+ } else {
108
+ winston.error("CloseBotUnresponsiveRequestTask: Error closing the request with request_id: " + request.request_id, err);
109
+ }
110
+
105
111
  })
106
112
 
107
113
  });
@@ -65,6 +65,9 @@ class RulesTrigger {
65
65
  });
66
66
  });
67
67
 
68
+
69
+
70
+ // da aggiungere in dashboard
68
71
  requestEvent.on('request.participants.join', function(data) {
69
72
  let request = data.request;
70
73
  let member = data.member;
@@ -82,10 +85,10 @@ class RulesTrigger {
82
85
  // operatingHoursService.projectIsOpenNow(request.id_project, function (isOpen, err) {
83
86
  that.exec(message, 'message.create.from.requester', success, error);
84
87
  });
85
- // not in use
86
- // messageEvent.on('message.received', function(request) {
87
- // that.exec(request, 'message.received', success, error);
88
- // });
88
+
89
+ messageEvent.on('message.received', function(message) {
90
+ that.exec(message, 'message.received', success, error);
91
+ });
89
92
 
90
93
  // event2Event.on('*', function(event){
91
94
  // winston.verbose('event2Event this.event: ' + this.event);
package/routes/faq_kb.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var express = require('express');
2
2
  var router = express.Router();
3
3
  var Faq_kb = require("../models/faq_kb");
4
- var Faq= require("../models/faq");
4
+ var Faq = require("../models/faq");
5
5
  var Department = require("../models/department");
6
6
  var faqService = require("../services/faqService");
7
7
  const botEvent = require('../event/botEvent');
@@ -14,11 +14,11 @@ var upload = multer()
14
14
 
15
15
 
16
16
  router.post('/', function (req, res) {
17
- winston.info('create BOT ', req.body);
18
- //create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template)
19
- faqService.create(req.body.name, req.body.url, req.projectid, req.user.id, req.body.type, req.body.description, undefined, undefined, req.body.language, req.body.template).then(function(savedFaq_kb) {
20
- res.json(savedFaq_kb);
21
- });
17
+ winston.info('create BOT ', req.body);
18
+ //create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template)
19
+ faqService.create(req.body.name, req.body.url, req.projectid, req.user.id, req.body.type, req.body.description, undefined, undefined, req.body.language, req.body.template).then(function (savedFaq_kb) {
20
+ res.json(savedFaq_kb);
21
+ });
22
22
 
23
23
  });
24
24
 
@@ -27,7 +27,7 @@ router.post('/train', function (req, res) {
27
27
 
28
28
  winston.info('train BOT ', req.body);
29
29
 
30
- Faq_kb.findById(req.body.id_faq_kb).exec(function(err, faq_kb) {
30
+ Faq_kb.findById(req.body.id_faq_kb).exec(function (err, faq_kb) {
31
31
  if (err) {
32
32
  return res.status(500).send({ success: false, msg: 'Error getting object.' });
33
33
  }
@@ -36,59 +36,59 @@ router.post('/train', function (req, res) {
36
36
  }
37
37
  winston.debug('faq_kb ', faq_kb.toJSON());
38
38
 
39
- winston.debug('faq_kb.type :'+ faq_kb.type);
40
- if (faq_kb.type =="internal" && faq_kb.url) {
39
+ winston.debug('faq_kb.type :' + faq_kb.type);
40
+ if (faq_kb.type == "internal" && faq_kb.url) {
41
41
 
42
42
 
43
43
 
44
- var train = {
45
- language:faq_kb.language,
46
- nlu:[]
44
+ var train = {
45
+ language: faq_kb.language,
46
+ nlu: []
47
47
  };
48
- winston.info("train", train);
49
-
50
-
51
- var query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb};
52
-
53
- Faq.find(query)
54
- .limit(10000)
55
- .lean().
56
- exec(async (err, faqs) => {
57
- if (err) {
58
- return res.status(500).send({ success: false, msg: 'Error getting object.' });
59
- }
60
- if (faqs && faqs.length>0) {
61
- winston.info("faqs exact", faqs);
62
-
63
- faqs.forEach(function(f) {
64
- var intent = {
65
- intent:f.intent_display_name,
66
- examples:[]
67
- }
68
- var questions = f.question.split("\n");
69
- winston.info("questions", questions);
70
-
71
- questions.forEach(function(q) {
72
- winston.info("q", q);
73
- intent.examples.push(q);
74
- });
75
- winston.info("intent", intent);
76
- train.nlu.push(intent);
77
- });
78
- winston.info("train", train);
79
-
80
- try {
81
- var trainHttp = await httpUtil.call(faq_kb.url+"/trainandload", undefined, train, "POST");
82
- }catch(e) {
83
- winston.error("error training", e);
48
+ winston.info("train", train);
49
+
50
+
51
+ var query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb };
52
+
53
+ Faq.find(query)
54
+ .limit(10000)
55
+ .lean().
56
+ exec(async (err, faqs) => {
57
+ if (err) {
58
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
84
59
  }
85
-
60
+ if (faqs && faqs.length > 0) {
61
+ winston.info("faqs exact", faqs);
62
+
63
+ faqs.forEach(function (f) {
64
+ var intent = {
65
+ intent: f.intent_display_name,
66
+ examples: []
67
+ }
68
+ var questions = f.question.split("\n");
69
+ winston.info("questions", questions);
70
+
71
+ questions.forEach(function (q) {
72
+ winston.info("q", q);
73
+ intent.examples.push(q);
74
+ });
75
+ winston.info("intent", intent);
76
+ train.nlu.push(intent);
77
+ });
78
+ winston.info("train", train);
79
+
80
+ try {
81
+ var trainHttp = await httpUtil.call(faq_kb.url + "/trainandload", undefined, train, "POST");
82
+ } catch (e) {
83
+ winston.error("error training", e);
84
+ }
85
+
86
86
 
87
- return res.json({train:train, httpResponse:trainHttp});
88
- // return res.json(trainHttp);
89
- }else {
90
- return res.status(400).send({ success: false, msg: 'no faq to train on external bot.' });
91
- }
87
+ return res.json({ train: train, httpResponse: trainHttp });
88
+ // return res.json(trainHttp);
89
+ } else {
90
+ return res.status(400).send({ success: false, msg: 'no faq to train on external bot.' });
91
+ }
92
92
  });
93
93
  } else {
94
94
  winston.debug('external query: ');
@@ -97,28 +97,28 @@ router.post('/train', function (req, res) {
97
97
 
98
98
  });
99
99
 
100
- /*
101
- {
102
- "language":"it",
103
- "nlu":[
104
- {
105
- "intent":"eta",
106
- "examples":[
107
- "quanti anni hai",
108
- "dimmi la tua età",
109
- "quanto sei grande",
110
- "parlami della tua età"
111
- ]
112
- },
113
- {
114
- "intent":"brutteparole",
115
- "examples":[
116
- "non dire parolacce",
117
- "le brutte parole non dovrebbero dirsi"
118
- ]
119
- }
120
- ]
121
- }
100
+ /*
101
+ {
102
+ "language":"it",
103
+ "nlu":[
104
+ {
105
+ "intent":"eta",
106
+ "examples":[
107
+ "quanti anni hai",
108
+ "dimmi la tua età",
109
+ "quanto sei grande",
110
+ "parlami della tua età"
111
+ ]
112
+ },
113
+ {
114
+ "intent":"brutteparole",
115
+ "examples":[
116
+ "non dire parolacce",
117
+ "le brutte parole non dovrebbero dirsi"
118
+ ]
119
+ }
120
+ ]
121
+ }
122
122
  */
123
123
 
124
124
  });
@@ -128,7 +128,7 @@ router.post('/askbot', function (req, res) {
128
128
 
129
129
  winston.debug('ASK BOT ', req.body);
130
130
 
131
- Faq_kb.findById(req.body.id_faq_kb).exec(function(err, faq_kb) {
131
+ Faq_kb.findById(req.body.id_faq_kb).exec(function (err, faq_kb) {
132
132
  if (err) {
133
133
  return res.status(500).send({ success: false, msg: 'Error getting object.' });
134
134
  }
@@ -136,73 +136,73 @@ router.post('/askbot', function (req, res) {
136
136
  return res.status(404).send({ success: false, msg: 'Object not found.' });
137
137
  }
138
138
  winston.debug('faq_kb ', faq_kb.toJSON());
139
- winston.debug('faq_kb.type :'+ faq_kb.type);
140
- if (faq_kb.type =="internal" || faq_kb.type =="tilebot") {
139
+ winston.debug('faq_kb.type :' + faq_kb.type);
140
+ if (faq_kb.type == "internal" || faq_kb.type == "tilebot") {
141
+
141
142
 
142
143
 
143
144
 
144
-
145
145
 
146
- var query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb, "question": req.body.question};
146
+ var query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb, "question": req.body.question };
147
147
 
148
- Faq.find(query)
149
- .lean().
150
- exec(function (err, faqs) {
151
- if (err) {
152
- return res.status(500).send({ success: false, msg: 'Error getting object.' });
153
- }
154
- if (faqs && faqs.length>0) {
155
- winston.debug("faqs exact", faqs);
148
+ Faq.find(query)
149
+ .lean().
150
+ exec(function (err, faqs) {
151
+ if (err) {
152
+ return res.status(500).send({ success: false, msg: 'Error getting object.' });
153
+ }
154
+ if (faqs && faqs.length > 0) {
155
+ winston.debug("faqs exact", faqs);
156
156
 
157
- faqs.forEach(f => {
158
- f.score = 100;
159
- });
160
- var result = {hits:faqs};
157
+ faqs.forEach(f => {
158
+ f.score = 100;
159
+ });
160
+ var result = { hits: faqs };
161
161
 
162
162
 
163
- res.json(result);
164
- }else {
165
- query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb};
163
+ res.json(result);
164
+ } else {
165
+ query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb };
166
166
 
167
- var search_obj = {"$search": req.body.question};
167
+ var search_obj = { "$search": req.body.question };
168
168
 
169
- if (faq_kb.language) {
169
+ if (faq_kb.language) {
170
170
  search_obj["$language"] = faq_kb.language;
171
+ }
172
+ query.$text = search_obj;
173
+ winston.debug("fulltext search query", query);
174
+
175
+
176
+ winston.debug('internal ft query: ' + query);
177
+
178
+ Faq.find(query, { score: { $meta: "textScore" } })
179
+ .sort({ score: { $meta: "textScore" } }) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
180
+ .lean().
181
+ exec(function (err, faqs) {
182
+ if (err) {
183
+ winston.error('Error getting object.', err);
184
+ return res.status(500).send({ success: false, msg: 'Error getting fulltext object.' });
185
+ }
186
+
187
+ winston.debug("faqs", faqs);
188
+
189
+ var result = { hits: faqs };
190
+ res.json(result);
191
+ });
192
+
193
+
171
194
  }
172
- query.$text = search_obj;
173
- winston.debug("fulltext search query", query);
174
-
175
-
176
- winston.debug('internal ft query: '+ query);
177
-
178
- Faq.find(query, {score: { $meta: "textScore" } })
179
- .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
180
- .lean().
181
- exec(function (err, faqs) {
182
- if (err) {
183
- winston.error('Error getting object.', err);
184
- return res.status(500).send({ success: false, msg: 'Error getting fulltext object.' });
185
- }
186
-
187
- winston.debug("faqs", faqs);
188
-
189
- var result = {hits:faqs};
190
- res.json(result);
191
- });
192
195
 
193
-
194
- }
195
196
 
196
-
197
- });
197
+ });
198
+
198
199
 
199
-
200
- }else {
200
+ } else {
201
201
  winston.debug('external query: ');
202
202
  return res.status(400).send({ success: false, msg: 'askbot on external bot.' });
203
203
  }
204
-
205
-
204
+
205
+
206
206
  });
207
207
 
208
208
  });
@@ -214,26 +214,26 @@ router.put('/:faq_kbid', function (req, res) {
214
214
  winston.debug(req.body);
215
215
 
216
216
  var update = {};
217
- if (req.body.name!=undefined) {
217
+ if (req.body.name != undefined) {
218
218
  update.name = req.body.name;
219
219
  }
220
- if (req.body.description!=undefined) {
220
+ if (req.body.description != undefined) {
221
221
  update.description = req.body.description;
222
222
  }
223
- if (req.body.url!=undefined) {
223
+ if (req.body.url != undefined) {
224
224
  update.url = req.body.url;
225
225
  }
226
- if (req.body.webhook_url!=undefined) {
226
+ if (req.body.webhook_url != undefined) {
227
227
  update.webhook_url = req.body.webhook_url;
228
228
  }
229
- if (req.body.webhook_enabled!=undefined) {
229
+ if (req.body.webhook_enabled != undefined) {
230
230
  update.webhook_enabled = req.body.webhook_enabled;
231
231
  }
232
-
233
- if (req.body.type!=undefined) {
232
+
233
+ if (req.body.type != undefined) {
234
234
  update.type = req.body.type;
235
235
  }
236
- if (req.body.trashed!=undefined) {
236
+ if (req.body.trashed != undefined) {
237
237
  update.trashed = req.body.trashed;
238
238
  }
239
239
 
@@ -321,10 +321,10 @@ router.get('/', function (req, res) {
321
321
  */
322
322
  var query = { "id_project": req.projectid, "trashed": { $in: [null, false] } };
323
323
 
324
- if (req.query.all!="true") {
324
+ if (req.query.all != "true") {
325
325
  query.type = { $ne: "identity" }
326
326
  }
327
-
327
+
328
328
  winston.debug("query", query);
329
329
 
330
330
  Faq_kb.find(query, function (err, faq_kb) {
@@ -347,86 +347,134 @@ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) =>
347
347
  let json_string = req.file.buffer.toString('utf-8');
348
348
  winston.debug("json_string: ", json_string);
349
349
 
350
- Faq_kb.findById(id_faq_kb, (err, faq_kb) => {
351
- if (err) {
352
- winston.error("GET FAQ-KB ERROR", err);
353
- return res.status(500).send({ success: false, msg: "Error getting bot." });
354
- }
355
- if (!faq_kb) {
356
- return res.status(404).send({ success: false, msg: 'Bot not found.'});
357
- }
350
+ if (req.query.intentsOnly == "true") {
358
351
 
359
- const json = JSON.parse(json_string);
352
+ winston.info("intents only")
360
353
 
361
- if (json.webhook_enabled) {
362
- faq_kb.webhook_enabled = json.webhook_enabled;
363
- }
364
- if (json.webhook_url) {
365
- faq_kb.webhook_url = json.webhook_url;
366
- }
367
- if (json.language) {
368
- faq_kb.language = json.language;
369
- }
370
- if (json.name) {
371
- faq_kb.name = json.name;
372
- }
373
- if (json.description) {
374
- faq_kb.description = json.description;
375
- }
354
+ const json = JSON.parse(json_string)
355
+ console.log("\n intents --> \n")
356
+ console.log(json)
357
+
358
+ json.intents.forEach((intent) => {
376
359
 
377
- Faq_kb.findByIdAndUpdate(id_faq_kb, faq_kb, { new: true }, (err, updatedFaq_kb) => {
360
+ var new_faq = new Faq({
361
+ id_faq_kb: id_faq_kb,
362
+ id_project: req.projectid,
363
+ createdBy: req.user.id,
364
+ question: intent.question,
365
+ answer: intent.answer,
366
+ reply: intent.reply,
367
+ form: intent.form,
368
+ enabled: intent.enabled,
369
+ webhook_enabled: intent.webhook_enabled,
370
+ language: intent.language,
371
+
372
+ })
373
+
374
+ new_faq.save((err, savedFaq) => {
375
+ if (err) {
376
+ winston.error("GET FAQ-KB ERROR", err);
377
+ if (err.code == 11000) {
378
+ return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
379
+ } else {
380
+ winston.debug('--- > ERROR ', err)
381
+ return res.status(500).send({ success: false, msg: 'Error saving intent.' });
382
+ }
383
+ }
384
+ winston.debug("NEW FAQ CREATED WITH ID: ", savedFaq._id);
385
+ faqBotEvent.emit('faq.create', savedFaq);
386
+ })
387
+
388
+ })
389
+
390
+ return res.status(200).send({ success: true, msg: "Intents imported successfully"})
391
+
392
+ } else {
393
+
394
+ Faq_kb.findById(id_faq_kb, (err, faq_kb) => {
378
395
  if (err) {
379
- return res.status(500).send({ success: false, msg: "Error updating bot." });
396
+ winston.error("GET FAQ-KB ERROR", err);
397
+ return res.status(500).send({ success: false, msg: "Error getting bot." });
380
398
  }
381
-
382
- botEvent.emit('faqbot.update', updatedFaq_kb);
383
-
384
- json.intents.forEach((intent) => {
385
-
386
- var new_faq = new Faq({
387
- id_faq_kb: updatedFaq_kb._id,
388
- id_project: req.projectid,
389
- createdBy: req.user.id,
390
- question: intent.question,
391
- answer: intent.answer,
392
- reply: intent.reply,
393
- form: intent.form,
394
- enabled: intent.enabled,
395
- webhook_enabled: intent.webhook_enabled,
396
- language: intent.language,
397
-
398
- })
399
-
400
- new_faq.save((err, savedFaq) => {
401
- if (err) {
402
- winston.error("GET FAQ-KB ERROR", err);
403
- if (err.code == 11000) {
404
- return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
405
- } else {
406
- winston.debug('--- > ERROR ', err)
407
- return res.status(500).send({ success: false, msg: 'Error saving intent.' });
408
- }
409
- }
410
- winston.debug("NEW FAQ CREATED WITH ID: ", savedFaq._id);
411
- faqBotEvent.emit('faq.create', savedFaq);
399
+ if (!faq_kb) {
400
+ return res.status(404).send({ success: false, msg: 'Bot not found.' });
401
+ }
402
+
403
+ const json = JSON.parse(json_string);
404
+
405
+ if (json.webhook_enabled) {
406
+ faq_kb.webhook_enabled = json.webhook_enabled;
407
+ }
408
+ if (json.webhook_url) {
409
+ faq_kb.webhook_url = json.webhook_url;
410
+ }
411
+ if (json.language) {
412
+ faq_kb.language = json.language;
413
+ }
414
+ if (json.name) {
415
+ faq_kb.name = json.name;
416
+ }
417
+ if (json.description) {
418
+ faq_kb.description = json.description;
419
+ }
420
+
421
+ Faq_kb.findByIdAndUpdate(id_faq_kb, faq_kb, { new: true }, (err, updatedFaq_kb) => {
422
+ if (err) {
423
+ return res.status(500).send({ success: false, msg: "Error updating bot." });
424
+ }
425
+
426
+ botEvent.emit('faqbot.update', updatedFaq_kb);
427
+
428
+ json.intents.forEach((intent) => {
429
+
430
+ var new_faq = new Faq({
431
+ id_faq_kb: updatedFaq_kb._id,
432
+ id_project: req.projectid,
433
+ createdBy: req.user.id,
434
+ question: intent.question,
435
+ answer: intent.answer,
436
+ reply: intent.reply,
437
+ form: intent.form,
438
+ enabled: intent.enabled,
439
+ webhook_enabled: intent.webhook_enabled,
440
+ language: intent.language,
441
+
442
+ })
443
+
444
+ new_faq.save((err, savedFaq) => {
445
+ if (err) {
446
+ winston.error("GET FAQ-KB ERROR", err);
447
+ if (err.code == 11000) {
448
+ return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
449
+ } else {
450
+ winston.debug('--- > ERROR ', err)
451
+ return res.status(500).send({ success: false, msg: 'Error saving intent.' });
452
+ }
453
+ }
454
+ winston.debug("NEW FAQ CREATED WITH ID: ", savedFaq._id);
455
+ faqBotEvent.emit('faq.create', savedFaq);
456
+ })
457
+
412
458
  })
413
-
414
- })
415
459
 
416
- res.send(updatedFaq_kb);
460
+ return res.send(updatedFaq_kb);
461
+
462
+ })
417
463
 
418
464
  })
419
-
420
- })
465
+ }
421
466
 
422
467
  })
423
468
 
424
469
  router.get('/exportjson/:id_faq_kb', (req, res) => {
425
470
 
471
+ winston.info("exporting bot...")
472
+
473
+
426
474
  let id_faq_kb = req.params.id_faq_kb;
427
475
 
428
476
  Faq_kb.findById(id_faq_kb, (err, faq_kb) => {
429
- if (err){
477
+ if (err) {
430
478
  winston.error('GET FAQ-KB ERROR ', err)
431
479
  return res.status(500).send({ success: false, msg: 'Error getting bot.' });
432
480
  } else {
@@ -434,9 +482,9 @@ router.get('/exportjson/:id_faq_kb', (req, res) => {
434
482
 
435
483
 
436
484
  faqService.getAll(id_faq_kb).then((faqs) => {
437
-
438
- const intents = faqs.map(({_id, id_project, topic, status, id_faq_kb, createdBy, intent_id, createdAt, updatedAt, __v, ...keepAttrs}) => keepAttrs)
439
-
485
+
486
+ const intents = faqs.map(({ _id, id_project, topic, status, id_faq_kb, createdBy, intent_id, createdAt, updatedAt, __v, ...keepAttrs }) => keepAttrs)
487
+
440
488
  let json = {
441
489
  webhook_enabled: faq_kb.webhook_enabled,
442
490
  webhook_url: faq_kb.webhook_url,
@@ -446,10 +494,20 @@ router.get('/exportjson/:id_faq_kb', (req, res) => {
446
494
  intents: intents
447
495
  }
448
496
 
449
- let json_string = JSON.stringify(json);
497
+ if (req.query.intentsOnly == 'true') {
498
+ let intents_obj = {
499
+ intents: intents
500
+ }
501
+ let intents_string = JSON.stringify(intents_obj);
502
+ res.set({ "Content-Disposition": "attachment; filename=\"intents.txt\"" });
503
+ return res.send(intents_string);
504
+
505
+ } else {
506
+ let json_string = JSON.stringify(json);
507
+ res.set({ "Content-Disposition": "attachment; filename=\"bot.txt\"" });
508
+ return res.send(json_string);
509
+ }
450
510
 
451
- res.set({"Content-Disposition":"attachment; filename=\"bot.txt\""});
452
- return res.send(json_string);
453
511
 
454
512
  }).catch((err) => {
455
513
  winston.error('GET FAQ ERROR: ', err)
@@ -457,7 +515,7 @@ router.get('/exportjson/:id_faq_kb', (req, res) => {
457
515
  })
458
516
  }
459
517
  })
460
-
518
+
461
519
  })
462
520
 
463
521
 
package/routes/lead.js CHANGED
@@ -88,6 +88,10 @@ router.put('/:leadid', function (req, res) {
88
88
  if (req.body.email!=undefined) {
89
89
  leadEvent.emit('lead.email.update', updatedLead);
90
90
  }
91
+
92
+ if (req.body.email!=undefined || req.body.fullname!=undefined) {
93
+ leadEvent.emit('lead.fullname.email.update', updatedLead);
94
+ }
91
95
 
92
96
  res.json(updatedLead);
93
97
  });
@@ -130,6 +130,7 @@ class LeadService {
130
130
  leadEvent.emit('lead.update', updatedLead);
131
131
  leadEvent.emit('lead.email.update', updatedLead);
132
132
  leadEvent.emit('lead.fullname.update', updatedLead);
133
+ leadEvent.emit('lead.fullname.email.update', updatedLead);
133
134
  return resolve(updatedLead);
134
135
  });
135
136
  });
@@ -63,7 +63,8 @@ class RequestService {
63
63
 
64
64
 
65
65
  sendMessageUpdateLead() {
66
- leadEvent.on('lead.fullname.update', function(lead) {
66
+ leadEvent.on('lead.fullname.email.update', function(lead) {
67
+ winston.debug("lead.fullname.email.update ");
67
68
  // leadEvent.on('lead.update', function(lead) {
68
69
 
69
70
  setImmediate(() => {
@@ -0,0 +1 @@
1
+ {"intents":[{"webhook_enabled":false,"enabled":true,"question":"\\start","answer":"Hello","intent_display_name":"start","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"}]}
@@ -148,6 +148,54 @@ describe('FaqKBRoute', () => {
148
148
  })
149
149
  })
150
150
 
151
+ it('import json (intents only)', (done) => {
152
+
153
+ var email = "test-signup-" + Date.now() + "@email.com";
154
+ var pwd = "pwd";
155
+
156
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
157
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
158
+
159
+ chai.request(server)
160
+ .post('/' + savedProject._id + '/faq_kb')
161
+ .auth(email, pwd)
162
+ .send({ "name": "testbot", type: "internal", language: 'fr' })
163
+ .end((err, res) => {
164
+ console.log("res.body: ", res.body);
165
+ res.should.have.status(200);
166
+ res.body.should.be.a('object');
167
+ expect(res.body.name).to.equal("testbot");
168
+ expect(res.body.language).to.equal("fr");
169
+ let id_faq_kb = res.body._id;
170
+
171
+ chai.request(server)
172
+ .post('/' + savedProject._id + '/faq_kb/importjson/' + id_faq_kb + '?intentsOnly=true')
173
+ .auth(email, pwd)
174
+ .set('Content-Type', 'text/plain')
175
+ .attach('uploadFile', fs.readFileSync(path.resolve(__dirname, './example-json-intents.txt')), 'example-json-intents.txt')
176
+ .end((err, res) => {
177
+ console.log("import (intents only) json res: ", res.body);
178
+ res.should.have.status(200);
179
+ //res.should.be.a('object');
180
+ //expect(res.body.success).to.equal(true);
181
+
182
+ chai.request(server)
183
+ .get('/' + savedProject._id + '/faq?id_faq_kb=' + id_faq_kb)
184
+ .auth(email, pwd)
185
+ .end((err, res) => {
186
+ console.log("faq_list: ", res.body);
187
+ res.should.have.status(200);
188
+ res.body.should.be.an('array').that.is.not.empty;
189
+
190
+ done();
191
+
192
+ })
193
+ })
194
+ })
195
+ })
196
+ })
197
+ })
198
+
151
199
 
152
200
  it('export json', (done) => {
153
201
 
@@ -199,6 +247,56 @@ describe('FaqKBRoute', () => {
199
247
 
200
248
  }).timeout(20000);
201
249
 
250
+ it('export json (intents only)', (done) => {
251
+
252
+
253
+ // this.timeout();
254
+
255
+ var email = "test-signup-" + Date.now() + "@email.com";
256
+ var pwd = "pwd";
257
+
258
+ userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
259
+ projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
260
+
261
+ chai.request(server)
262
+ .post('/' + savedProject._id + '/faq_kb')
263
+ .auth(email, pwd)
264
+ .send({ "name": "testbot", type: "internal", template: "example", language: 'fr' })
265
+ .end((err, res) => {
266
+ //console.log("res", res);
267
+ console.log("res.body", res.body);
268
+ res.should.have.status(200);
269
+ res.body.should.be.a('object');
270
+ expect(res.body.name).to.equal("testbot");
271
+ expect(res.body.language).to.equal("fr");
272
+ let id_faq_kb = res.body._id;
273
+ console.log("res.body._id: ", res.body._id)
274
+
275
+ chai.request(server)
276
+ .get('/' + savedProject._id + '/faq?id_faq_kb=' + id_faq_kb)
277
+ .auth(email, pwd)
278
+ .end((err, res) => {
279
+ console.log("faq_list: ", res.body);
280
+ res.should.have.status(200);
281
+ res.body.should.be.an('array').that.is.not.empty;
282
+
283
+ chai.request(server)
284
+ .get('/' + savedProject._id + '/faq_kb/exportjson/' + id_faq_kb + "?intentsOnly=true")
285
+ .auth(email, pwd)
286
+ .end((err, res) => {
287
+ console.log("export json res: ", res.body);
288
+ res.should.have.status(200);
289
+ //res.body.should.be.a('string');
290
+
291
+ done();
292
+ })
293
+ })
294
+ });
295
+ });
296
+ });
297
+
298
+ }).timeout(20000);
299
+
202
300
 
203
301
  // mocha test/faqkbRoute.js --grep 'train'
204
302
  it('train', (done) => {
@@ -1,6 +0,0 @@
1
- const listener = require('./listener');
2
-
3
- const kaleyra = require('@tiledesk/tiledesk-kaleyra-proxy');
4
- const kaleyraRoute = kaleyra.router;
5
-
6
- module.exports = { listener: listener, kaleyraRoute: kaleyraRoute }
@@ -1,32 +0,0 @@
1
- const kaleyra = require("@tiledesk/tiledesk-kaleyra-proxy");
2
- var winston = require('../../config/winston');
3
- var configGlobal = require('../../config/global');
4
-
5
- const apiUrl = process.env.API_URL || configGlobal.apiUrl;
6
- winston.info("Kaleyra apiUrl: " + apiUrl);
7
-
8
- class Listener {
9
-
10
- listen(config) {
11
- winston.info("Kaleyra Listener listen");
12
- if (config.databaseUri) {
13
- winston.debug("kaleyra config databaseUri: " + config.databaseUri);
14
- }
15
-
16
- kaleyra.startApp({
17
- MONGODB_URL: config.databaseUri,
18
- API_URL: apiUrl,
19
- BASE_URL: apiUrl + "/modules/kaleyra",
20
- APPS_API_URL: apiUrl + "/modules/apps",
21
- KALEYRA_API_URL: process.env.KALEYRA_API_URL,
22
- API_KEY: process.env.API_KEY,
23
- log: process.env.KALEYRA_LOG
24
- }, () => {
25
- winston.info("Tiledesk Kaleyra proxy server succesfully started.");
26
- })
27
- }
28
- }
29
-
30
- var listener = new Listener();
31
-
32
- module.exports = listener;