@tiledesk/tiledesk-server 2.2.24 → 2.2.26

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,6 +5,7 @@ var Schema = mongoose.Schema;
5
5
  var winston = require('../config/winston');
6
6
  var RoleConstants = require('./roleConstants');
7
7
  var PresenceSchema = require('./presence');
8
+ var TagSchema = require("../models/tag");
8
9
 
9
10
 
10
11
 
@@ -58,6 +59,7 @@ var PresenceSchema = require('./presence');
58
59
  settings: {
59
60
  type: Object,
60
61
  },
62
+ tags: [TagSchema],
61
63
  createdBy: {
62
64
  type: String,
63
65
  required: true
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.2.24",
4
+ "version": "2.2.26",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -109,7 +109,7 @@
109
109
  "chai-string": "^1.5.0",
110
110
  "loadtest": "^5.1.2",
111
111
  "mocha": "^8.4.0",
112
- "mongodb-runner": "4.8.1",
112
+ "mongodb-runner": "4.8.3",
113
113
  "nodemon": "^2.0.12",
114
114
  "sinon": "^9.2.4",
115
115
  "sinon-mongoose": "^2.3.0"
@@ -48,9 +48,15 @@ scheduleUnresponsiveRequests() {
48
48
  // }
49
49
 
50
50
  //https://crontab.guru/examples.html
51
- var s= schedule.scheduleJob(this.cronExp, function(fireDate){
52
- winston.debug('CloseBotUnresponsiveRequestTask scheduleUnresponsiveRequests job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date());
53
- that.findUnresponsiveRequests();
51
+ var s= schedule.scheduleJob(this.cronExp, function(fireDate){ //TODO aggiungi un bias random
52
+
53
+ let timeInMs = Math.random() * (1000); // avoid cluster concurrent jobs in multiple nodes between 0 and 1sec
54
+ winston.info('timeInMs => '+ timeInMs);
55
+
56
+ setTimeout(function () {
57
+ winston.debug('CloseBotUnresponsiveRequestTask scheduleUnresponsiveRequests job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date());
58
+ that.findUnresponsiveRequests();
59
+ },timeInMs );
54
60
  });
55
61
  }
56
62
 
@@ -65,6 +71,8 @@ findUnresponsiveRequests() {
65
71
  query.id_project = JSON.parse(this.queryProject);
66
72
  }
67
73
 
74
+
75
+
68
76
  winston.debug("CloseBotUnresponsiveRequestTask query",query);
69
77
 
70
78
  Request.find(query)
@@ -84,6 +92,7 @@ findUnresponsiveRequests() {
84
92
  winston.debug("CloseBotUnresponsiveRequestTask: found unresponsive requests ", requests);
85
93
 
86
94
  requests.forEach(request => {
95
+
87
96
  winston.debug("********unresponsive request ", request);
88
97
 
89
98
  return requestService.closeRequestByRequestId(request.request_id, request.id_project, false, false).then(function(updatedStatusRequest) {
package/routes/faq_kb.js CHANGED
@@ -10,9 +10,8 @@ var httpUtil = require("../utils/httpUtil");
10
10
 
11
11
  router.post('/', function (req, res) {
12
12
  winston.info('create BOT ', req.body);
13
- // create(name, url, projectid, user_id, type, description) {
14
- faqService.create(req.body.name, req.body.url, req.projectid, req.user.id, req.body.type, req.body.description, undefined, undefined,
15
- req.body.language).then(function(savedFaq_kb) {
13
+ // create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template)
14
+ 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) {
16
15
  res.json(savedFaq_kb);
17
16
  });
18
17
 
@@ -196,7 +196,8 @@ router.post('/', [passport.authenticate(['basic', 'jwt'], { session: false }), v
196
196
  // role: RoleConstants.USER,
197
197
  // - Create project_user endpoint by agent (Ticketing) now is with Guest Role
198
198
  role: RoleConstants.GUEST,
199
- user_available: false,
199
+ user_available: false,
200
+ tags: req.body.tags,
200
201
  createdBy: req.user.id,
201
202
  updatedBy: req.user.id
202
203
  });
@@ -234,6 +235,10 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
234
235
  if (req.body["settings.email.notification.conversation.pooled"]!=undefined) {
235
236
  update["settings.email.notification.conversation.pooled"] = req.body["settings.email.notification.conversation.pooled"];
236
237
  }
238
+ if (req.body.tags!=undefined) {
239
+ update.tags = req.body.tags;
240
+ }
241
+
237
242
 
238
243
 
239
244
  Project_user.findByIdAndUpdate(req.projectuser.id, update, { new: true, upsert: true }, function (err, updatedProject_user) {
@@ -289,7 +294,9 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
289
294
  update["settings.email.notification.conversation.pooled"] = req.body["settings.email.notification.conversation.pooled"];
290
295
  }
291
296
 
292
-
297
+ if (req.body.tags!=undefined) {
298
+ update.tags = req.body.tags;
299
+ }
293
300
 
294
301
  winston.debug("project_userid update", update);
295
302
 
package/routes/widget.js CHANGED
@@ -116,7 +116,7 @@ router.get('/', function(req, res, next) {
116
116
 
117
117
  // TOOD add labels
118
118
  Promise.all([
119
- Project.findOne({_id: req.projectid, status: 100}).select('-settings') //--profile todo trialExpired attento user_available cambia spesso quindi magari leggerlo dal db ogni volta
119
+ Project.findOne({_id: req.projectid, status: 100}).select('-settings')
120
120
  //@DISABLED_CACHE .cache(cacheUtil.queryTTL, "projects:query:id:status:100:"+req.projectid+":select:-settings")
121
121
  ,
122
122
  availableUsers()
@@ -283,6 +283,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
283
283
  return resolve ({
284
284
  department: department, available_agents: _available_agents, agents: project_users,
285
285
  id_bot:department.id_bot, project: project,
286
+ context: context,
286
287
  // botprefix
287
288
  operators: [{ id_user: 'bot_' + department.id_bot }]
288
289
  });
@@ -386,7 +387,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
386
387
  selectedoperator = that.getRandomAvailableOperator(_available_agents);
387
388
  }
388
389
 
389
- let objectToReturn = { available_agents: _available_agents, agents: project_users, operators: selectedoperator, department: department, group: group, id_project: projectid, project: project };
390
+ let objectToReturn = { available_agents: _available_agents, agents: project_users, operators: selectedoperator, department: department, group: group, id_project: projectid, project: project, context: context };
390
391
 
391
392
  that.roundRobin(objectToReturn).then(function(objectToReturnRoundRobin){
392
393
 
@@ -409,7 +410,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
409
410
 
410
411
  } else {
411
412
  // here subscription notifier??
412
- var objectToReturn = { available_agents: [], agents: [], operators: [] };
413
+ var objectToReturn = { available_agents: [], agents: [], operators: [], context: context };
413
414
  return resolve(objectToReturn);
414
415
  }
415
416
 
@@ -447,7 +448,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
447
448
  selectedoperator = that.getRandomAvailableOperator(_available_agents);
448
449
  }
449
450
 
450
- let objectToReturn = { available_agents: _available_agents, agents: project_users, operators: selectedoperator, department: department, id_project: projectid, project: project };
451
+ let objectToReturn = { available_agents: _available_agents, agents: project_users, operators: selectedoperator, department: department, id_project: projectid, project: project, context: context };
451
452
 
452
453
  that.roundRobin(objectToReturn).then(function(objectToReturnRoundRobin) {
453
454
  winston.debug("context2",context);
@@ -474,7 +475,7 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
474
475
 
475
476
  } else {
476
477
  // here subscription notifier??
477
- let objectToReturn = { available_agents: [], agents: [], operators: [] };
478
+ let objectToReturn = { available_agents: [], agents: [], operators: [], context: context };
478
479
  return resolve(objectToReturn);
479
480
  }
480
481
 
@@ -98,13 +98,13 @@ 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; //gestire bene il parsing da stringa per kube
101
+ this.secure = process.env.EMAIL_SECURE || false;
102
102
  winston.info('EmailService secure: ' + this.secure);
103
103
 
104
104
  this.user = process.env.EMAIL_USERNAME || config.username;
105
105
  winston.info('EmailService username: ' + this.user);
106
106
 
107
- this.port = process.env.EMAIL_PORT; //default is 587
107
+ this.port = process.env.EMAIL_PORT;
108
108
  winston.info('EmailService port: ' + this.port);
109
109
 
110
110
 
@@ -8,7 +8,7 @@ const ActionsConstants = require('../models/actionsConstants');
8
8
  class FaqService {
9
9
 
10
10
 
11
- create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language) {
11
+ create(name, url, projectid, user_id, type, description, webhook_url, webhook_enabled, language, template) {
12
12
  var that = this;
13
13
  return new Promise(function (resolve, reject) {
14
14
 
@@ -37,8 +37,15 @@ class FaqService {
37
37
 
38
38
  botEvent.emit('faqbot.create', savedFaq_kb);
39
39
 
40
+ winston.debug('type '+ type)
41
+
40
42
  if (type==="internal") {
41
- that.createGreetingsAndOperationalsFaqs(savedFaq_kb._id, savedFaq_kb.createdBy, savedFaq_kb.id_project);
43
+
44
+ if (!template) {
45
+ template = "example";
46
+ }
47
+ winston.debug('template '+ template);
48
+ that.createGreetingsAndOperationalsFaqs(savedFaq_kb._id, savedFaq_kb.createdBy, savedFaq_kb.id_project, template);
42
49
  } else {
43
50
  winston.debug('external bot: ', savedFaq_kb);
44
51
  }
@@ -50,33 +57,63 @@ class FaqService {
50
57
  });
51
58
  }
52
59
 
53
- createGreetingsAndOperationalsFaqs(faq_kb_id, created_by, projectid, remote_faqkb_key) {
60
+ createGreetingsAndOperationalsFaqs(faq_kb_id, created_by, projectid, template) {
54
61
  var that = this;
55
62
  return new Promise(function (resolve, reject) {
56
63
 
57
64
  // aggiungi esempio tdAction con intent_id
58
- var faqsArray = [
59
- { 'question': 'Hi', 'answer': 'Hi', 'topic': 'greetings' },
60
- { 'question': 'Hello', 'answer': 'Hello', 'topic': 'greetings' },
61
- { 'question': 'Who are you?', 'answer': 'Hi, I\'m a bot 🤖. You can find more about me [here](https://tiledesk.com/chatbot-for-customer-service).\ntdImage:https://console.tiledesk.com/assets/images/tily-welcomebot.gif\n* See the website https://tiledesk.com/\n* Back to start tdAction:start', 'topic': 'greetings' },
62
- { 'question': '👨🏻‍🦰 I want an agent', 'answer': 'We are looking for an operator.. '+ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
63
- { 'question': 'Close\nResolved', 'answer': ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE, 'topic': 'internal' },
64
- { 'question': '\\start', 'answer': 'Hello 👋. I\'m a bot 🤖.\n\nChoose one of the options below or write a message to reach our staff.\n* Who are you?\n* Where are you?\n* What can you do?\n* 👨🏻‍🦰 I want an agent', 'intent_display_name': 'start', 'topic': 'internal' },
65
- { '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', 'topic': 'internal' }, //TODO se metto spazio n * nn va
66
- { 'question': 'What can you do?', 'answer': 'Using natural language processing, I\'m able to find the best answer for your users. I also support images, videos etc.. Let\'s try:\n* Sample Image\n* Sample Video\n* Sample Action tdAction:action1\n* Sample Frame\n* Back to start tdAction:start', 'topic': 'sample' },
67
- { 'question': 'Sample Image', 'answer': 'tdImage:https://tiledesk.com/tiledesk-logo-x1.png\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
68
- { 'question': 'Sample Frame', 'answer': 'tdFrame:https://www.emanueleferonato.com/wp-content/uploads/2019/02/runner/\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
69
- { 'question': 'Sample Video', 'answer': 'tdVideo:https://www.youtube.com/embed/EngW7tLk6R8\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
70
- { 'question': 'Where are you?', 'answer': 'We are here ❤️\ntdFrame:https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6087916.923447935!2d8.234804542117423!3d41.836572992140624!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12d4fe82448dd203%3A0xe22cf55c24635e6f!2sItaly!5e0!3m2!1sen!2sit!4v1613657475377!5m2!1sen!2sit\n* Back to start tdAction:start', 'topic': 'sample' },
71
-
72
- // { 'question': 'Sample Webhook', 'answer': 'tdWebhook:https://tiledesk-bot-webhook.tiledesk.repl.co', 'topic': 'sample' },
73
- { 'question': 'Sample Action', 'answer': 'Hello 👋 Would you like to take a closer look at our offer?\n* Yes, please tdAction:yes_action\n* No tdAction:no_action','intent_display_name': 'action1', 'topic': 'sample' },
74
- { 'question': 'Yes Action', 'answer': 'Great! Take a look here:\n* Tiledesk Pricing https://tiledesk.com/pricing-cloud/', 'intent_display_name': 'yes_action','topic': 'sample' },
75
- { 'question': 'No Action', 'answer': 'All right! If you need anything, let us know.', 'intent_display_name': 'no_action','topic': 'sample' },
76
-
77
-
78
- // action button nn si può fare perche gli id cambiano
79
- ]
65
+
66
+ winston.debug('template: '+ template);
67
+
68
+ var faqsArray;
69
+
70
+ if (template==="example") {
71
+
72
+ faqsArray = [
73
+ { 'question': 'Hi', 'answer': 'Hi', 'topic': 'greetings' },
74
+ { 'question': 'Hello', 'answer': 'Hello', 'topic': 'greetings' },
75
+ { 'question': 'Who are you?', 'answer': 'Hi, I\'m a bot 🤖. You can find more about me [here](https://tiledesk.com/chatbot-for-customer-service).\ntdImage:https://console.tiledesk.com/assets/images/tily-welcomebot.gif\n* See the website https://tiledesk.com/\n* Back to start tdAction:start', 'topic': 'greetings' },
76
+ { 'question': '👨🏻‍🦰 I want an agent', 'answer': 'We are looking for an operator.. '+ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
77
+ { 'question': 'Close\nResolved', 'answer': ActionsConstants.CHAT_ACTION_MESSAGE.CLOSE, 'topic': 'internal' },
78
+ { 'question': '\\start', 'answer': 'Hello 👋. I\'m a bot 🤖.\n\nChoose one of the options below or write a message to reach our staff.\n* Who are you?\n* Where are you?\n* What can you do?\n* 👨🏻‍🦰 I want an agent', 'intent_display_name': 'start', 'topic': 'internal' },
79
+ { 'question': 'defaultFallback', 'answer': 'I can not provide an adequate answer. Write a new question or talk to a human agent.\n* Back to start tdAction:start\n* See the docs https://docs.tiledesk.com/\n* 👨🏻‍🦰 I want an agent', 'intent_display_name': 'defaultFallback', 'topic': 'internal' }, //TODO se metto spazio n * nn va
80
+ { 'question': 'What can you do?', 'answer': 'Using natural language processing, I\'m able to find the best answer for your users. I also support images, videos etc.. Let\'s try:\n* Sample Image\n* Sample Video\n* Sample Action tdAction:action1\n* Sample Frame\n* Back to start tdAction:start', 'topic': 'sample' },
81
+ { 'question': 'Sample Image', 'answer': 'tdImage:https://tiledesk.com/tiledesk-logo-x1.png\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
82
+ { 'question': 'Sample Frame', 'answer': 'tdFrame:https://www.emanueleferonato.com/wp-content/uploads/2019/02/runner/\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
83
+ { 'question': 'Sample Video', 'answer': 'tdVideo:https://www.youtube.com/embed/EngW7tLk6R8\n* What can you do?\n* Back to start tdAction:start', 'topic': 'sample' },
84
+ { 'question': 'Where are you?', 'answer': 'We are here ❤️\ntdFrame:https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d6087916.923447935!2d8.234804542117423!3d41.836572992140624!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12d4fe82448dd203%3A0xe22cf55c24635e6f!2sItaly!5e0!3m2!1sen!2sit!4v1613657475377!5m2!1sen!2sit\n* Back to start tdAction:start', 'topic': 'sample' },
85
+
86
+ // { 'question': 'Sample Webhook', 'answer': 'tdWebhook:https://tiledesk-bot-webhook.tiledesk.repl.co', 'topic': 'sample' },
87
+ { 'question': 'Sample Action', 'answer': 'Hello 👋 Would you like to take a closer look at our offer?\n* Yes, please tdAction:yes_action\n* No tdAction:no_action','intent_display_name': 'action1', 'topic': 'sample' },
88
+ { 'question': 'Yes Action', 'answer': 'Great! Take a look here:\n* Tiledesk Pricing https://tiledesk.com/pricing-cloud/', 'intent_display_name': 'yes_action','topic': 'sample' },
89
+ { 'question': 'No Action', 'answer': 'All right! If you need anything, let us know.', 'intent_display_name': 'no_action','topic': 'sample' },
90
+
91
+
92
+ // action button nn si può fare perche gli id cambiano
93
+ ]
94
+
95
+ }
96
+
97
+ if (template==="blank") {
98
+
99
+ faqsArray = [
100
+ { 'question': '\\start', 'answer': 'Hello', 'intent_display_name': 'start', 'topic': 'internal' },
101
+ { 'question': 'defaultFallback', 'answer': 'I can not provide an adequate answer. Write a new question or talk to a human agent.\n* Back to start tdAction:start\n* See the docs https://docs.tiledesk.com/\n* 👨🏻‍🦰 I want an agent', 'intent_display_name': 'defaultFallback', 'topic': 'internal' }, //TODO se metto spazio n * nn va
102
+ ]
103
+
104
+ }
105
+
106
+
107
+ if (template==="handoff") {
108
+
109
+ faqsArray = [
110
+ { 'question': '\\start', 'answer': 'Hello', 'intent_display_name': 'start', 'topic': 'internal' },
111
+ { 'question': '👨🏻‍🦰 I want an agent', 'answer': 'We are looking for an operator.. '+ActionsConstants.CHAT_ACTION_MESSAGE.AGENT, 'intent_display_name': 'agent_handoff', 'topic': 'internal' },
112
+ { 'question': 'defaultFallback', 'answer': 'I can not provide an adequate answer. Write a new question or talk to a human agent.\n* Back to start tdAction:start\n* See the docs https://docs.tiledesk.com/\n* 👨🏻‍🦰 I want an agent', 'intent_display_name': 'defaultFallback', 'topic': 'internal' }, //TODO se metto spazio n * nn va
113
+ ]
114
+
115
+ }
116
+
80
117
 
81
118
  faqsArray.forEach(faq => {
82
119
 
@@ -101,10 +138,6 @@ class FaqService {
101
138
  winston.debug('FAQ SERVICE (save new faq) - QUESTION OF THE NEW GREETINGS FAQ CREATED ', savedFaq.question)
102
139
  winston.debug('FAQ SERVICE (save new faq) - ANSWER OF THE NEW GREETINGS FAQ CREATED ', savedFaq.answer)
103
140
  winston.debug('FAQ SERVICE (save new faq) - ID FAQKB GET IN THE OBJECT OF NEW FAQ CREATED ', savedFaq.id_faq_kb)
104
- // res.json({ 'Greetings Faqs': savedFaq });
105
- // return resolve(savedFaq);
106
-
107
- // that.createRemoteFaq(remote_faqkb_key, savedFaq);
108
141
 
109
142
  })
110
143
  });