@tiledesk/tiledesk-server 2.3.49 → 2.3.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md 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) => {