@tiledesk/tiledesk-server 2.3.49 → 2.3.51

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,10 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.48)
7
7
 
8
+ # Untagged
9
+ - Added new email sending endpoint
10
+ - Emails endpoint is now usable by agents
11
+
8
12
  # 2.3.49 -> PROD
9
13
  - @tiledesk/tiledesk-tybot-connector": "^0.1.22
10
14
 
package/app.js CHANGED
@@ -481,7 +481,8 @@ app.use('/:projectid/labels', [fetchLabels],labels);
481
481
 
482
482
  app.use('/:projectid/campaigns',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], campaigns);
483
483
 
484
- app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('owner')], email);
484
+ app.use('/:projectid/emails',[passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], email);
485
+
485
486
 
486
487
 
487
488
 
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.49",
4
+ "version": "2.3.51",
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,6 +36,8 @@
36
36
  "@tiledesk-ent/tiledesk-server-enterprise": "^1.0.0"
37
37
  },
38
38
  "dependencies": {
39
+ "@tiledesk/tiledesk-apps": "^1.0.6",
40
+ "@tiledesk/tiledesk-whatsapp-connector": "^0.1.19",
39
41
  "@tiledesk/tiledesk-chat21-app": "^1.1.7",
40
42
  "@tiledesk/tiledesk-chatbot-util": "^0.8.33",
41
43
  "@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
@@ -0,0 +1,8 @@
1
+ const listener = require("./listener");
2
+
3
+ const apps = require("@tiledesk/tiledesk-apps");
4
+ const appsRoute = apps.router;
5
+
6
+
7
+ module.exports = { listener: listener, appsRoute: appsRoute }
8
+
@@ -0,0 +1,27 @@
1
+ const apps = require("@tiledesk/tiledesk-apps");
2
+ var winston = require('../../config/winston');
3
+
4
+ class Listener {
5
+
6
+ listen(config) {
7
+
8
+ winston.info("Apps Listener listen");
9
+
10
+ if (config.databaseUri) {
11
+ winston.debug("apps config databaseUri: " + config.databaseUri);
12
+ }
13
+
14
+ apps.startApp({
15
+ ACCESS_TOKEN_SECRET: process.env.APPS_ACCESS_TOKEN_SECRET || 'nodeauthsecret',
16
+ MONGODB_URI: process.env.APPS_MONGODB_URI || config.databaseUri,
17
+ }, () => {
18
+ winston.info("Tiledesk Apps proxy server succesfully started.")
19
+ })
20
+
21
+ }
22
+
23
+ }
24
+
25
+ var listener = new Listener();
26
+
27
+ module.exports = listener;
@@ -21,6 +21,12 @@ class PubModulesManager {
21
21
  this.rasa = undefined;
22
22
  this.rasaRoute = undefined;
23
23
 
24
+ this.apps = undefined;
25
+ this.appsRoute = undefined;
26
+
27
+ this.whatsapp = undefined;
28
+ this.whatsappRoute = undefined;
29
+
24
30
  this.activityArchiver = undefined;
25
31
  this.activityRoute = undefined;
26
32
 
@@ -53,6 +59,14 @@ class PubModulesManager {
53
59
  app.use('/modules/rasa', this.rasaRoute);
54
60
  winston.info("ModulesManager rasaRoute controller loaded");
55
61
  }
62
+ if (this.appsRoute) {
63
+ app.use('/modules/apps', this.appsRoute);
64
+ winston.info("ModulesManager appsRoute controller loaded");
65
+ }
66
+ if (this.whatsappRoute) {
67
+ app.use('/modules/whatsapp', this.whatsappRoute);
68
+ winston.info("ModulesManager whatsappRoute controller loaded");
69
+ }
56
70
  if (this.tilebotRoute) {
57
71
  app.use('/modules/tilebot', this.tilebotRoute);
58
72
  winston.info("ModulesManager tilebot controller loaded");
@@ -217,7 +231,38 @@ class PubModulesManager {
217
231
  }
218
232
  }
219
233
 
234
+ try {
235
+ this.apps = require('./apps');
236
+ winston.debug("this.apps: " + this.apps);
237
+ this.apps.listener.listen(config);
238
+
239
+ this.appsRoute = this.apps.appsRoute;
220
240
 
241
+ winston.info("PubModulesManager initialized apps.");
242
+ } catch(err) {
243
+ if (err.code == 'MODULE_NOT_FOUND') {
244
+ winston.info("PubModulesManager init apps module not found");
245
+ }else {
246
+ winston.info("PubModulesManager error initializing init apps module", err);
247
+ }
248
+ }
249
+
250
+ try {
251
+ this.whatsapp = require('./whatsapp');
252
+ winston.debug("this.whatsapp: " + this.whatsapp);
253
+ this.whatsapp.listener.listen(config);
254
+
255
+ this.whatsappRoute = this.whatsapp.whatsappRoute;
256
+
257
+ winston.info("PubModulesManager initialized apps.");
258
+ } catch(err) {
259
+ if (err.code == 'MODULE_NOT_FOUND') {
260
+ winston.info("PubModulesManager init apps module not found");
261
+ }else {
262
+ winston.info("PubModulesManager error initializing init apps module", err);
263
+ }
264
+ }
265
+
221
266
 
222
267
  try {
223
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
@@ -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);
@@ -0,0 +1,7 @@
1
+ const listener = require("./listener");
2
+
3
+ const whatsapp = require("@tiledesk/tiledesk-whatsapp-connector");
4
+ const whatsappRoute = whatsapp.router;
5
+
6
+
7
+ module.exports = { listener: listener, whatsappRoute: whatsappRoute }
@@ -0,0 +1,32 @@
1
+ const whatsapp = require("@tiledesk/tiledesk-whatsapp-connector");
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('Whatsapp apiUrl: ' + apiUrl);
7
+
8
+ class Listener {
9
+
10
+ listen(config) {
11
+ winston.info("WhatsApp Listener listen");
12
+ if (config.databaseUri) {
13
+ winston.debug("whatsapp config databaseUri: " + config.databaseUri);
14
+ }
15
+
16
+ whatsapp.startApp({
17
+ MONGODB_URL: config.databaseUri,
18
+ API_URL: apiUrl,
19
+ GRAPH_URL: process.env.META_GRAPH_URL || config.graphUrl,
20
+ BASE_URL: apiUrl + "/modules/whatsapp",
21
+ APPS_API_URL: apiUrl + "/modules/apps",
22
+ log: process.env.WHATSAPP_LOG
23
+ }, () => {
24
+ winston.info("Tiledesk WhatsApp Connector proxy server succesfully started.");
25
+ })
26
+
27
+ }
28
+ }
29
+
30
+ var listener = new Listener();
31
+
32
+ module.exports = listener;
package/routes/email.js CHANGED
@@ -17,10 +17,10 @@ router.get('/templates/:templateid',
17
17
  router.post('/test/send',
18
18
  async (req, res) => {
19
19
  let to = req.body.to;
20
- winston.info("to",to);
20
+ winston.debug("to",to);
21
21
 
22
22
  let configEmail = req.body.config;
23
- winston.info("configEmail", configEmail);
23
+ winston.debug("configEmail", configEmail);
24
24
 
25
25
  emailService.sendTest(to, configEmail, function(err,obj) {
26
26
  // winston.info("sendTest rest", err, obj);
@@ -29,4 +29,28 @@ router.post('/test/send',
29
29
 
30
30
  });
31
31
 
32
+
33
+ router.post('/send',
34
+ async (req, res) => {
35
+ let to = req.body.to;
36
+ winston.info("to: " + to);
37
+
38
+ let text = req.body.text;
39
+ winston.info("text: " + text);
40
+
41
+ let request_id = req.body.request_id;
42
+ winston.info("request_id: " + request_id);
43
+
44
+ let subject = req.body.subject;
45
+ winston.info("subject: " + subject);
46
+
47
+ winston.info("req.project", req.project);
48
+
49
+ //sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage)
50
+ emailService.sendEmailDirect(to, text, req.project, request_id, subject, undefined, undefined);
51
+
52
+ res.json({"queued": true});
53
+
54
+ });
55
+
32
56
  module.exports = router;
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
  });
@@ -1030,7 +1030,7 @@ class EmailService {
1030
1030
 
1031
1031
  }
1032
1032
 
1033
-
1033
+
1034
1034
 
1035
1035
  async sendEmailChannelNotification(to, message, project, tokenQueryString, sourcePage) {
1036
1036
 
@@ -1360,10 +1360,6 @@ class EmailService {
1360
1360
  }
1361
1361
 
1362
1362
 
1363
-
1364
-
1365
-
1366
-
1367
1363
  /*
1368
1364
  sendEmailChannelTakingNotification(to, request, project, tokenQueryString) {
1369
1365
 
@@ -1411,6 +1407,102 @@ class EmailService {
1411
1407
  }
1412
1408
  */
1413
1409
 
1410
+
1411
+
1412
+
1413
+
1414
+
1415
+
1416
+ async sendEmailDirect(to, text, project, request_id, subject, tokenQueryString, sourcePage) {
1417
+
1418
+ var that = this;
1419
+
1420
+
1421
+ if (project.toJSON) {
1422
+ project = project.toJSON();
1423
+ }
1424
+
1425
+ var html = await this.readTemplate('emailDirect.html', project.settings);
1426
+
1427
+ var envTemplate = process.env.EMAIL_DIRECT_HTML_TEMPLATE;
1428
+ winston.debug("envTemplate: " + envTemplate);
1429
+
1430
+ if (envTemplate) {
1431
+ html = envTemplate;
1432
+ }
1433
+
1434
+ winston.debug("html: " + html);
1435
+
1436
+ var template = handlebars.compile(html);
1437
+
1438
+ var baseScope = JSON.parse(JSON.stringify(that));
1439
+ delete baseScope.pass;
1440
+
1441
+
1442
+ let msgText = text;
1443
+ msgText = encode(msgText);
1444
+ if (this.markdown) {
1445
+ msgText = marked(msgText);
1446
+ }
1447
+
1448
+ winston.debug("msgText: " + msgText);
1449
+ winston.debug("baseScope: " + JSON.stringify(baseScope));
1450
+
1451
+
1452
+ var replacements = {
1453
+ project: project,
1454
+ seamlessPage: sourcePage,
1455
+ msgText: msgText,
1456
+ tokenQueryString: tokenQueryString,
1457
+ baseScope: baseScope
1458
+ };
1459
+
1460
+ var html = template(replacements);
1461
+ winston.debug("html: " + html);
1462
+
1463
+
1464
+ let replyTo;
1465
+ if (this.replyEnabled) {
1466
+ replyTo = request_id + this.inboundDomainDomainWithAt;
1467
+ }
1468
+
1469
+ let from;
1470
+ let configEmail;
1471
+ if (project && project.settings && project.settings.email) {
1472
+ if (project.settings.email.config) {
1473
+ configEmail = project.settings.email.config;
1474
+ winston.verbose("custom email configEmail setting found: ", configEmail);
1475
+ }
1476
+ if (project.settings.email.from) {
1477
+ from = project.settings.email.from;
1478
+ winston.verbose("custom from email setting found: "+ from);
1479
+ }
1480
+ }
1481
+
1482
+
1483
+ // if (message.request && message.request.lead && message.request.lead.email) {
1484
+ // winston.info("message.request.lead.email: " + message.request.lead.email);
1485
+ // replyTo = replyTo + ", "+ message.request.lead.email;
1486
+ // }
1487
+
1488
+ // if (!subject) {
1489
+ // subject = "Tiledesk"
1490
+ // }
1491
+
1492
+ that.send({
1493
+ from:from,
1494
+ to:to,
1495
+ replyTo: replyTo,
1496
+ subject:subject,
1497
+ text:html,
1498
+ html:html,
1499
+ config:configEmail,
1500
+ });
1501
+
1502
+ }
1503
+
1504
+
1505
+
1414
1506
  // ok
1415
1507
  async sendPasswordResetRequestEmail(to, resetPswRequestId, userFirstname, userLastname) {
1416
1508
 
@@ -1693,6 +1785,5 @@ async sendRequestTranscript(to, messages, request, project) {
1693
1785
 
1694
1786
  var emailService = new EmailService();
1695
1787
 
1696
- // emailService.sendTest("abc@abc.it");
1697
1788
 
1698
1789
  module.exports = emailService;
@@ -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(() => {
@@ -94,7 +94,7 @@
94
94
  {{currentUserFirstname}} {{currentUserLastname}} has invited you to the TileDesk project <strong> {{projectName}}</strong>
95
95
  </h2>
96
96
 
97
- <br> <br<strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">Hi {{invitedUserFirstname}} {{invitedUserLastname}},</strong>
97
+ <br> <br><strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">Hi {{invitedUserFirstname}} {{invitedUserLastname}},</strong>
98
98
 
99
99
  <br> <br>
100
100
  I invited you to take on the role of {{invitedUserRole}} of the TileDesk <strong> {{projectName}}</strong> project
@@ -95,7 +95,7 @@
95
95
  {{currentUserFirstname}} {{currentUserLastname}} has invited you to the Tiledesk project <strong> {{projectName}}</strong>
96
96
  </h2>
97
97
 
98
- <br> <br<strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{to}},</strong>
98
+ <br> <br><strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{to}},</strong>
99
99
 
100
100
  <br> <br>
101
101
  I invited you to take on the role of {{invitedUserRole}} of the Tiledesk <strong> {{projectName}}</strong> project
@@ -0,0 +1,121 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html lang="en" xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
3
+
4
+ <head>
5
+ <meta name="viewport" content="width=device-width" />
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
+ <title>New Ticket from TileDesk</title>
8
+
9
+ <style type="text/css">
10
+ img {
11
+ max-width: 100%;
12
+ margin-left:16px;
13
+ margin-bottom:16px;
14
+ text-align:center !important;
15
+ }
16
+ body {
17
+ -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em;
18
+ }
19
+ body {
20
+ background-color: #f6f6f6;
21
+ }
22
+
23
+ @media only screen and (max-width: 640px) {
24
+ body {
25
+ padding: 0 !important;
26
+ }
27
+ h1 {
28
+ font-weight: 800 !important; margin: 20px 0 5px !important;
29
+ text-align:center !important;
30
+ }
31
+ h2 {
32
+ font-weight: 800 !important; margin: 20px 0 5px !important;
33
+ }
34
+ h3 {
35
+ font-weight: 800 !important; margin: 20px 0 5px !important;
36
+ }
37
+ h4 {
38
+ font-weight: 800 !important; margin: 20px 0 5px !important;
39
+ }
40
+ h1 {
41
+ font-size: 22px !important;
42
+ }
43
+ h2 {
44
+ font-size: 18px !important;
45
+ }
46
+ h3 {
47
+ font-size: 16px !important;
48
+ }
49
+ .container {
50
+ padding: 0 !important; width: 100% !important;
51
+ }
52
+ .content {
53
+ padding: 0 !important;
54
+ }
55
+ .content-wrap {
56
+ padding: 10px !important;
57
+ }
58
+ .invoice {
59
+ width: 100% !important;
60
+ }
61
+ }
62
+ </style>
63
+ </head>
64
+
65
+ <body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
66
+
67
+ {{#if baseScope.replyEnabled}}
68
+ <div>\# Please type your reply above this line \#</div>
69
+ {{/if}}
70
+
71
+ <table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff">
72
+
73
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
74
+ <td class="alert alert-warning" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; margin: 0;" align="center" valign="top">
75
+
76
+ <div style="text-align:center">
77
+ <a href="http://www.tiledesk.com" style="color:#2daae1;font-weight:bold;text-decoration:none;word-break:break-word" target="_blank">
78
+ <!-- <img src="https://tiledesk.com/wp-content/uploads/2022/07/tiledesk_v2.png" style="width:20%;outline:none;text-decoration:none;border:none;min-height:36px" class="CToWUd"> -->
79
+ <img src="https://tiledesk.com/wp-content/uploads/2022/09/tiledeesk_log_email.png" style="max-width:200px;outline:none;text-decoration:none;border:none;height:auto;margin-left:0px;" class="CToWUd">
80
+ </a>
81
+ </div>
82
+ </td>
83
+ </tr>
84
+
85
+
86
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
87
+ <td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
88
+ <table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
89
+
90
+
91
+
92
+
93
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
94
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
95
+ <div style="white-space: pre-wrap;">{{{msgText}}}</div>
96
+ </td>
97
+ </tr>
98
+
99
+
100
+
101
+
102
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
103
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
104
+ </td>
105
+ </tr>
106
+ </table>
107
+ </td>
108
+ </tr>
109
+ </table>
110
+ <div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
111
+ <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
112
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
113
+ <td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top">
114
+ <span><a href="http://www.tiledesk.com" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;" > Tiledesk.com </a></span>
115
+ <!-- <br><span><a href="%unsubscribe_url%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">Unsubscribe</a></span> -->
116
+ </td>
117
+ </tr>
118
+ </table>
119
+
120
+ </body>
121
+ </html>
@@ -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) => {