@tiledesk/tiledesk-server 2.3.35 → 2.3.37

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,7 +19,7 @@ var exchange = 'amq.topic';
19
19
  function start() {
20
20
  amqp.connect(url, function(err, conn) {
21
21
  if (err) {
22
- winston.error("[AMQP]", err.message);
22
+ winston.error("[AMQP]", err);
23
23
  return setTimeout(start, 1000);
24
24
  }
25
25
  conn.on("error", function(err) {
@@ -117,10 +117,30 @@ function startWorker() {
117
117
  winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_create");
118
118
  winston.info("Data queue", oka)
119
119
  });
120
- ch.bindQueue(_ok.queue, exchange, "request_update", {}, function(err3, oka) {
121
- winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update");
120
+ ch.bindQueue(_ok.queue, exchange, "request_update_preflight", {}, function(err3, oka) {
121
+ winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update_preflight");
122
122
  winston.info("Data queue", oka)
123
123
  });
124
+ ch.bindQueue(_ok.queue, exchange, "request_participants_update", {}, function(err3, oka) {
125
+ winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_participants_update");
126
+ winston.info("Data queue", oka)
127
+ });
128
+
129
+ ch.bindQueue(_ok.queue, exchange, "request_update", {}, function(err3, oka) {
130
+ winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update");
131
+ winston.info("Data queue", oka)
132
+ });
133
+
134
+ ch.bindQueue(_ok.queue, exchange, "request_close", {}, function(err3, oka) {
135
+ winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_close");
136
+ winston.info("Data queue", oka)
137
+ });
138
+
139
+ ch.bindQueue(_ok.queue, exchange, "request_close_extended", {}, function(err3, oka) {
140
+ winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_close_extended");
141
+ winston.info("Data queue", oka)
142
+ });
143
+
124
144
  ch.bindQueue(_ok.queue, exchange, "message_create", {}, function(err3, oka) {
125
145
  winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: message_create");
126
146
  winston.info("Data queue", oka)
@@ -158,22 +178,47 @@ function work(msg, cb) {
158
178
  winston.debug("Got msg:"+ message_string + " topic:" + topic);
159
179
 
160
180
  if (topic === 'request_create') {
161
- winston.info("here topic:" + topic);
181
+ winston.debug("reconnect here topic:" + topic);
162
182
  // requestEvent.emit('request.create.queue', msg.content);
163
183
  requestEvent.emit('request.create.queue', JSON.parse(message_string));
164
184
  }
165
185
  if (topic === 'request_update') {
166
- winston.info("here topic:" + topic);
186
+ winston.debug("reconnect here topic:" + topic);
167
187
  // requestEvent.emit('request.update.queue', msg.content);
168
188
  requestEvent.emit('request.update.queue', JSON.parse(message_string));
169
189
  }
190
+
191
+ if (topic === 'request_update_preflight') {
192
+ winston.debug("reconnect here topic:" + topic);
193
+ // requestEvent.emit('request.update.queue', msg.content);
194
+ requestEvent.emit('request.update.preflight.queue', JSON.parse(message_string));
195
+ }
196
+
197
+ if (topic === 'request_participants_update') {
198
+ winston.debug("reconnect here topic:" + topic);
199
+ // requestEvent.emit('request.update.queue', msg.content);
200
+ requestEvent.emit('request.participants.update.queue', JSON.parse(message_string));
201
+ }
202
+
203
+ if (topic === 'request_close') {
204
+ winston.debug("reconnect here topic:" + topic);
205
+ // requestEvent.emit('request.update.queue', msg.content);
206
+ requestEvent.emit('request.close.queue', JSON.parse(message_string));
207
+ }
208
+
209
+ if (topic === 'request_close_extended') {
210
+ winston.debug("reconnect here topic:" + topic);
211
+ // requestEvent.emit('request.update.queue', msg.content);
212
+ requestEvent.emit('request.close.extended.queue', JSON.parse(message_string));
213
+ }
214
+
170
215
  if (topic === 'message_create') {
171
- winston.debug("here topic:" + topic);
216
+ winston.debug("reconnect here topic:" + topic);
172
217
  // requestEvent.emit('request.create.queue', msg.content);
173
218
  messageEvent.emit('message.create.queue', JSON.parse(message_string));
174
219
  }
175
220
  if (topic === 'project_user_update') {
176
- winston.debug("here topic:" + topic);
221
+ winston.debug("reconnect here topic:" + topic);
177
222
  // requestEvent.emit('request.create.queue', msg.content);
178
223
  authEvent.emit('project_user.update.queue', JSON.parse(message_string));
179
224
  }
@@ -204,19 +249,51 @@ function listen() {
204
249
 
205
250
  requestEvent.on('request.create', function(request) {
206
251
  setImmediate(() => {
207
- winston.info("reconnect request.create")
252
+ winston.debug("reconnect request.create")
208
253
  publish(exchange, "request_create", Buffer.from(JSON.stringify(request)));
209
254
  });
210
255
  });
211
256
 
212
257
  requestEvent.on('request.update', function(request) {
213
258
  setImmediate(() => {
214
- winston.info("reconnect request.update")
259
+ winston.debug("reconnect request.update")
215
260
  publish(exchange, "request_update", Buffer.from(JSON.stringify(request)));
216
261
  });
217
262
  });
218
263
 
219
264
 
265
+
266
+
267
+ requestEvent.on('request.participants.update', function(request) {
268
+ setImmediate(() => {
269
+ publish(exchange, "request_participants_update", Buffer.from(JSON.stringify(request)));
270
+ winston.debug("reconnect participants.update published")
271
+ });
272
+ });
273
+
274
+ requestEvent.on('request.update.preflight', function(request) {
275
+ setImmediate(() => {
276
+ // winston.info("reconnect request.update.preflight")
277
+ publish(exchange, "request_update_preflight", Buffer.from(JSON.stringify(request)));
278
+ winston.debug("reconnect request.update.preflight published")
279
+ });
280
+ });
281
+
282
+
283
+ requestEvent.on('request.close', function(request) {
284
+ setImmediate(() => {
285
+ publish(exchange, "request_close", Buffer.from(JSON.stringify(request)));
286
+ });
287
+ });
288
+
289
+ requestEvent.on('request.close.extended', function(request) {
290
+ setImmediate(() => {
291
+ publish(exchange, "request_close_extended", Buffer.from(JSON.stringify(request)));
292
+ });
293
+ });
294
+
295
+
296
+
220
297
  messageEvent.on('message.create', function(message) {
221
298
  setImmediate(() => {
222
299
  publish(exchange, "message_create", Buffer.from(JSON.stringify(message)));
@@ -226,10 +303,17 @@ function listen() {
226
303
  authEvent.on('project_user.update',function(data) {
227
304
  setImmediate(() => {
228
305
  let user = undefined;
229
- if (data.req && data.req.user) { //i think is null from chat21webhook
230
- user = data.req.user;
306
+ let body = undefined;
307
+ if (data.req ) {
308
+ if (data.req.user) { //i think is null from chat21webhook
309
+ user = data.req.user;
310
+ }
311
+ if (data.req.body) {
312
+ body = data.req.body;
313
+ }
231
314
  }
232
- var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user}}; //remove request
315
+ var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user, body: body}}; //remove request
316
+ winston.debug("dat",dat);
233
317
  publish(exchange, "project_user_update", Buffer.from(JSON.stringify(dat)));
234
318
  });
235
319
  });
@@ -19,7 +19,7 @@ var exchange = 'ws';
19
19
  function start() {
20
20
  amqp.connect(url, function(err, conn) {
21
21
  if (err) {
22
- winston.error("[AMQP Fanout]", err.message);
22
+ winston.error("[AMQP Fanout]", err);
23
23
  return setTimeout(start, 1000);
24
24
  }
25
25
  conn.on("error", function(err) {
@@ -115,7 +115,7 @@ function startWorker() {
115
115
  //MOD4
116
116
  ch.bindQueue(_ok.queue, exchange, '', {}, function(err3, oka) {
117
117
  winston.info("Queue Fanout bind: "+_ok.queue+ " err: "+err3);
118
- winston.info("Data Queue", oka)
118
+ winston.info("Data Queue Fanout", oka)
119
119
  });
120
120
 
121
121
  // ch.bindQueue(_ok.queue, exchange, "request_create", {}, function(err3, oka) {
@@ -163,20 +163,20 @@ function work(msg, cb) {
163
163
  winston.debug("Got Fanout msg:"+ message_string + " topic:" + topic);
164
164
 
165
165
  if (topic === 'request_create') {
166
- winston.debug("here topic:" + topic);
167
- winston.info("reconnect request.update")
166
+ winston.debug("reconnectfanout here topic:" + topic);
167
+ winston.debug("reconnect request.update")
168
168
  requestEvent.emit('request.create.queue.pubsub', JSON.parse(message_string));
169
169
  }
170
170
  if (topic === 'request_update') {
171
- winston.debug("here topic:" + topic);
171
+ winston.debug("reconnectfanout here topic:" + topic);
172
172
  requestEvent.emit('request.update.queue.pubsub', JSON.parse(message_string));
173
173
  }
174
174
  if (topic === 'message_create') {
175
- winston.debug("here topic:" + topic);
175
+ winston.debug("reconnectfanout here topic:" + topic);
176
176
  messageEvent.emit('message.create.queue.pubsub', JSON.parse(message_string));
177
177
  }
178
178
  if (topic === 'project_user_update') {
179
- winston.debug("here topic:" + topic);
179
+ winston.debug("reconnectfanout here topic:" + topic);
180
180
  authEvent.emit('project_user.update.queue.pubsub', JSON.parse(message_string));
181
181
  }
182
182
  cb(true);
@@ -227,12 +227,18 @@ function listen() {
227
227
 
228
228
  authEvent.on('project_user.update',function(data) {
229
229
  setImmediate(() => {
230
-
231
230
  let user = undefined;
232
- if (data.req && data.req.user) { //i think is null from chat21webhook
233
- user = data.req.user;
234
- }
235
- var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user}}; //remove request
231
+ let body = undefined;
232
+ if (data.req ) {
233
+ if (data.req.user) { //i think is null from chat21webhook
234
+ user = data.req.user;
235
+ }
236
+ if (data.req.body) {
237
+ body = data.req.body;
238
+ }
239
+ }
240
+ var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user, body: body}}; //remove request
241
+ winston.debug("dat",dat);
236
242
 
237
243
  publish(exchange, "project_user_update", Buffer.from(JSON.stringify(dat)));
238
244
  });
@@ -53,6 +53,8 @@ class RulesTrigger {
53
53
 
54
54
  requestEvent.on('request.support_group.created', function(request) {
55
55
 
56
+ // performance console log
57
+ // console.log("************* request.support_group.created: "+new Date().toISOString());
56
58
 
57
59
  // requestEvent.on('request.create', function(request) {
58
60
  var requestJson = request.toJSON();
@@ -174,6 +176,9 @@ class RulesTrigger {
174
176
  // attributes
175
177
  // );
176
178
 
179
+ // performance console log
180
+ // console.log("************* send message trigger: "+new Date().toISOString(), text);
181
+
177
182
  // send(sender, senderFullname, recipient, text, id_project, createdBy, attributes, type, metadata, language) {
178
183
  sendMessageUtil.send(
179
184
  sender,
@@ -864,7 +869,8 @@ class RulesTrigger {
864
869
 
865
870
  return requestService.create(new_request).then(function (savedRequest) {
866
871
 
867
-
872
+ // performance console log
873
+ // console.log("************* request created trigger: "+new Date().toISOString());
868
874
 
869
875
  if (attributes) {
870
876
  attributes.sendnotification = false; // sembra nn funzionae
package/routes/faq.js CHANGED
@@ -116,6 +116,7 @@ router.post('/', function (req, res) {
116
116
  question: req.body.question,
117
117
  answer: req.body.answer,
118
118
  reply: req.body.reply,
119
+ form: req.body.form,
119
120
  enabled: true,
120
121
  id_project: req.projectid,
121
122
  topic: req.body.topic,
@@ -188,7 +189,10 @@ router.put('/:faqid', function (req, res) {
188
189
  update.enabled = req.body.enabled;
189
190
  }
190
191
  if (req.body.reply!=undefined) {
191
- updated.reply = req.body.enabled;
192
+ update.reply = req.body.enabled;
193
+ }
194
+ if (req.body.form!=undefined) {
195
+ update.form = req.body.form;
192
196
  }
193
197
 
194
198
 
package/routes/faq_kb.js CHANGED
@@ -5,16 +5,20 @@ 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');
8
+ const faqBotEvent = require('../event/faqBotEvent');
8
9
  var winston = require('../config/winston');
9
10
  var httpUtil = require("../utils/httpUtil");
11
+ const { forEach } = require('lodash');
12
+ var multer = require('multer')
13
+ var upload = multer()
14
+
10
15
 
11
16
  router.post('/', function (req, res) {
12
- winston.info('create BOT ', req.body);
13
- // create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template)
17
+ winston.info('create BOT ', req.body);
18
+ //create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template)
14
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) {
15
- res.json(savedFaq_kb);
16
- });
17
-
20
+ res.json(savedFaq_kb);
21
+ });
18
22
 
19
23
  });
20
24
 
@@ -335,4 +339,126 @@ router.get('/', function (req, res) {
335
339
 
336
340
  });
337
341
 
342
+ router.post('/importjson/:id_faq_kb', upload.single('uploadFile'), (req, res) => {
343
+
344
+ let id_faq_kb = req.params.id_faq_kb;
345
+ winston.debug('id_faq_kb: ', id_faq_kb);
346
+
347
+ let json_string = req.file.buffer.toString('utf-8');
348
+ winston.debug("json_string: ", json_string);
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
+ }
358
+
359
+ const json = JSON.parse(json_string);
360
+
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
+ }
376
+
377
+ Faq_kb.findByIdAndUpdate(id_faq_kb, faq_kb, { new: true }, (err, updatedFaq_kb) => {
378
+ if (err) {
379
+ return res.status(500).send({ success: false, msg: "Error updating bot." });
380
+ }
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);
412
+ })
413
+
414
+ })
415
+
416
+ res.send(updatedFaq_kb);
417
+
418
+ })
419
+
420
+ })
421
+
422
+ })
423
+
424
+ router.get('/exportjson/:id_faq_kb', (req, res) => {
425
+
426
+ let id_faq_kb = req.params.id_faq_kb;
427
+
428
+ Faq_kb.findById(id_faq_kb, (err, faq_kb) => {
429
+ if (err){
430
+ winston.error('GET FAQ-KB ERROR ', err)
431
+ return res.status(500).send({ success: false, msg: 'Error getting bot.' });
432
+ } else {
433
+ winston.debug('FAQ-KB: ', faq_kb)
434
+
435
+
436
+ 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
+
440
+ let json = {
441
+ webhook_enabled: faq_kb.webhook_enabled,
442
+ webhook_url: faq_kb.webhook_url,
443
+ language: faq_kb.language,
444
+ name: faq_kb.name,
445
+ description: faq_kb.description,
446
+ intents: intents
447
+ }
448
+
449
+ let json_string = JSON.stringify(json);
450
+
451
+ res.set({"Content-Disposition":"attachment; filename=\"bot.txt\""});
452
+ return res.send(json_string);
453
+
454
+ }).catch((err) => {
455
+ winston.error('GET FAQ ERROR: ', err)
456
+ return res.status(500).send({ success: false, msg: 'Error getting faqs.' });
457
+ })
458
+ }
459
+ })
460
+
461
+ })
462
+
463
+
338
464
  module.exports = router;
@@ -3,6 +3,7 @@ var router = express.Router();
3
3
 
4
4
  var User = require("../models/user");
5
5
  var winston = require('../config/winston');
6
+ var mongoose = require('mongoose');
6
7
 
7
8
 
8
9
 
@@ -13,13 +14,20 @@ router.get('/:userid', function (req, res) {
13
14
  winston.debug("users");
14
15
  var userid = req.params.userid;
15
16
 
17
+ var isObjectId = mongoose.Types.ObjectId.isValid(userid);
18
+ winston.debug("isObjectId:"+ isObjectId);
19
+
20
+ if (!isObjectId) {
21
+ return res.status(404).send({ success: false, msg: 'User id not found' });
22
+ }
23
+
16
24
  User.findById(userid, 'firstname lastname _id', function (err, user) {
17
25
  if (err) {
18
26
  winston.error('Error getting object.',err);
19
27
  return res.status(500).send({ success: false, msg: 'Error getting object.' });
20
28
  }
21
29
  if (!user) {
22
- winston.warn("Object not found with id " +req.user.id);
30
+ winston.warn("Object not found with id " +userid);
23
31
  return res.status(404).send({ success: false, msg: 'Object not found.' });
24
32
  }
25
33
  winston.debug("GET USER BY ID RES JSON", user);
@@ -98,7 +98,11 @@ class EmailService {
98
98
  this.host = process.env.EMAIL_HOST || config.host;
99
99
  winston.info('EmailService host: ' + this.host);
100
100
 
101
- this.secure = process.env.EMAIL_SECURE || false;
101
+ this.secure = false;
102
+ if (process.env.EMAIL_SECURE == "true" || process.env.EMAIL_SECURE ==true) {
103
+ this.secure = true;
104
+ }
105
+ // this.secure = process.env.EMAIL_SECURE || false;
102
106
  winston.info('EmailService secure: ' + this.secure);
103
107
 
104
108
  this.user = process.env.EMAIL_USERNAME || config.username;
@@ -108,7 +112,11 @@ class EmailService {
108
112
  winston.info('EmailService port: ' + this.port);
109
113
 
110
114
 
111
- this.markdown = process.env.EMAIL_MARKDOWN || true;
115
+ this.markdown = true;
116
+ if (process.env.EMAIL_MARKDOWN =="false" || process.env.EMAIL_MARKDOWN ==false) {
117
+ this.markdown = false;
118
+ }
119
+ // this.markdown = process.env.EMAIL_MARKDOWN || true;
112
120
  winston.info('EmailService markdown: '+ this.markdown);
113
121
 
114
122
  this.headers = {
@@ -252,6 +260,8 @@ class EmailService {
252
260
  };
253
261
 
254
262
  winston.debug('mailOptions', mailOptions);
263
+ winston.debug(' mail.config', mail.config);
264
+
255
265
  if (!mail.to) {
256
266
  return winston.warn("EmailService send method. to field is not defined", mailOptions);
257
267
  }
@@ -1683,6 +1693,6 @@ async sendRequestTranscript(to, messages, request, project) {
1683
1693
 
1684
1694
  var emailService = new EmailService();
1685
1695
 
1686
- // emailService.sendTest("asd.");
1696
+ // emailService.sendTest("abc@abc.it");
1687
1697
 
1688
1698
  module.exports = emailService;
@@ -151,6 +151,21 @@ class FaqService {
151
151
  });
152
152
  }
153
153
 
154
+ getAll(faq_kb_id) {
155
+
156
+ winston.debug("(Service) GET ALL FAQ OF THE BOT ID (req.query): ", faq_kb_id);
157
+
158
+ return new Promise((resolve, reject) => {
159
+
160
+ Faq.find({ id_faq_kb: faq_kb_id}, (err, faqs) => {
161
+ if (err) {
162
+ reject(err);
163
+ }
164
+ resolve(faqs);
165
+ }).lean().exec()
166
+ })
167
+ }
168
+
154
169
 
155
170
  }
156
171
 
@@ -50,10 +50,10 @@ class GeoService {
50
50
 
51
51
 
52
52
  var requestCreateKey = 'request.create';
53
- // if (requestEvent.queueEnabled) {
54
- // requestCreateKey = 'request.create.queue';
55
- // }
56
- // winston.debug('GeoService requestCreateKey: ' + requestCreateKey);
53
+ if (requestEvent.queueEnabled) {
54
+ requestCreateKey = 'request.create.queue';
55
+ }
56
+ winston.debug('GeoService requestCreateKey: ' + requestCreateKey);
57
57
 
58
58
 
59
59
  requestEvent.on(requestCreateKey, function(request) {
@@ -66,7 +66,7 @@ class GeoService {
66
66
  winston.debug("ip" + ip);
67
67
  if (ip) {
68
68
  var geo = geoip.lookup(ip);
69
- winston.verbose("Geo result", geo);
69
+ winston.debug("Geo result", geo);
70
70
 
71
71
  // var update = {};
72
72
  if (geo) {
@@ -822,6 +822,7 @@ class RequestService {
822
822
 
823
823
 
824
824
  return new Promise(function (resolve, reject) {
825
+ winston.debug("changeFirstTextAndPreflightByRequestId", request_id);
825
826
  // winston.debug("request_id", request_id);
826
827
  // winston.debug("newstatus", newstatus);
827
828
 
@@ -0,0 +1 @@
1
+ {"webhook_enabled":false,"language":"en","name":"examplebot","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"}]}