@tiledesk/tiledesk-server 2.4.38 → 2.4.40

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -5,12 +5,20 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.4.39
9
+ - Queued botSubscriptionNotifier
10
+ - added lead.create to the queue????? testare di nuovo
11
+ - @tiledesk/tiledesk-tybot-connector: 0.1.89
12
+ - jobsManager.listen(); //listen after pubmodules to enabled queued *.queueEnabled events
13
+
14
+ # 2.4.38
15
+ - str fix
8
16
 
9
17
  # 2.4.37
10
18
  - added replyto to email endpoint
11
19
  - tiledesk/tiledesk-tybot-connector: 0.1.88
12
20
  - added lead.create to the queue
13
- - added subscriptionNotifiedQueued for the most common events (request.create, request.update, request.close, lead.create, project_user.update)
21
+ - added subscriptionNotifiedQueued for the most common events (message.create, request.create, request.update, request.close, lead.create, project_user.update)
14
22
 
15
23
 
16
24
  # 2.4.36
@@ -19,7 +27,7 @@
19
27
  # 2.4.35
20
28
  - tiledesk/tiledesk-tybot-connector: 0.1.87
21
29
 
22
- # 2.4.34
30
+ # 2.4.34 -> ERRORE PAGAMENTO
23
31
  - tiledesk/tiledesk-tybot-connector:0.1.83
24
32
  - stateless as default for Google Strategy
25
33
  - added redis session for google auth. To enable it put ENABLE_REDIS_SESSION to true otherwise standard passport session is used
package/app.js CHANGED
@@ -135,6 +135,7 @@ var RouterLogger = require('./models/routerLogger');
135
135
  var cacheEnabler = require("./services/cacheEnabler");
136
136
  const session = require('express-session');
137
137
  const RedisStore = require("connect-redis").default
138
+ const botEvent = require('./event/botEvent');
138
139
 
139
140
  require('./services/mongoose-cache-fn')(mongoose);
140
141
 
@@ -146,7 +147,9 @@ var subscriptionNotifierQueued = require('./services/subscriptionNotifierQueued'
146
147
 
147
148
 
148
149
  var botSubscriptionNotifier = require('./services/BotSubscriptionNotifier');
149
- botSubscriptionNotifier.start();
150
+ botSubscriptionNotifier.start(); //queued but disabled
151
+
152
+ botEvent.listen(); //queued but disabled
150
153
 
151
154
  var trainingService = require('./services/trainingService');
152
155
  trainingService.start();
@@ -164,10 +167,7 @@ if (process.env.JOB_WORKER_ENABLED=="true" || process.env.JOB_WORKER_ENABLED ==
164
167
  }
165
168
  winston.info("JobsManager jobWorkerEnabled: "+ jobWorkerEnabled);
166
169
 
167
- let jobsManager = new JobsManager(jobWorkerEnabled, geoService, subscriptionNotifierQueued);
168
- jobsManager.listen();
169
-
170
-
170
+ let jobsManager = new JobsManager(jobWorkerEnabled, geoService, botEvent, subscriptionNotifierQueued, botSubscriptionNotifier);
171
171
 
172
172
  var faqBotHandler = require('./services/faqBotHandler');
173
173
  faqBotHandler.listen();
@@ -175,6 +175,8 @@ faqBotHandler.listen();
175
175
  var pubModulesManager = require('./pubmodules/pubModulesManager');
176
176
  pubModulesManager.init({express:express, mongoose:mongoose, passport:passport, databaseUri:databaseUri, routes:{}, jobsManager:jobsManager});
177
177
 
178
+ jobsManager.listen(); //listen after pubmodules to enabled queued *.queueEnabled events
179
+
178
180
  var channelManager = require('./channels/channelManager');
179
181
  channelManager.listen();
180
182
 
@@ -85,6 +85,8 @@ class Chat21Handler {
85
85
 
86
86
 
87
87
 
88
+ // chat21Handler on worker is loaded with stadard events like request.create and NOT request.create.queue because it is used internally by the worker when the request is closed by ChatUnhandledRequestScheduler
89
+
88
90
  // su projectUser create e update
89
91
  authEvent.on('user.signup', function(userData) {
90
92
  var firstName = userData.savedUser.firstname;
@@ -258,7 +260,7 @@ class Chat21Handler {
258
260
  });
259
261
  });
260
262
 
261
-
263
+ // chat21Handler on worker is loaded with stadard events like request.create and NOT request.create.queue because it is used internally by the worker when the request is closed by ChatUnhandledRequestScheduler
262
264
  messageEvent.on('message.sending', function(message) {
263
265
 
264
266
  // setImmediate(() => {
@@ -358,7 +360,7 @@ class Chat21Handler {
358
360
  return chat21.messages.sendToGroup(message.senderFullname, message.recipient,
359
361
  recipient_fullname, message.text, message.sender, attributes, message.type, message.metadata, timestamp)
360
362
  .then(function(data){
361
- winston.verbose("Chat21Sender sendToGroup sent: "+ JSON.stringify(data));
363
+ winston.verbose("Chat21Sender sendToGroup sent: "+ JSON.stringify(data) + " for text message " + message.text);
362
364
 
363
365
 
364
366
  // chat21.conversations.stopTyping(message.recipient,message.sender);
@@ -520,6 +522,8 @@ class Chat21Handler {
520
522
  // });
521
523
  // });
522
524
 
525
+
526
+ // chat21Handler on worker is loaded with stadard events like request.create and NOT request.create.queue because it is used internally by the worker when the request is closed by ChatUnhandledRequestScheduler
523
527
  requestEvent.on('request.create', function(request) {
524
528
 
525
529
  winston.debug("chat21Handler requestEvent request.create called" , request);
@@ -632,9 +636,10 @@ class Chat21Handler {
632
636
  });
633
637
 
634
638
 
635
-
636
- requestEvent.on('request.close', function(request) {
639
+ // chat21Handler on worker is loaded with stadard events like request.create and NOT request.create.queue because it is used internally by the worker when the request is closed by ChatUnhandledRequestScheduler
637
640
 
641
+ requestEvent.on('request.close', function(request) { //request.close event here noqueued
642
+ winston.debug("request.close event here 8")
638
643
  winston.debug("chat21Handler requestEvent request.close called" , request);
639
644
 
640
645
  setImmediate(() => {
package/event/botEvent.js CHANGED
@@ -14,6 +14,102 @@ class BotEvent extends EventEmitter {
14
14
  this.queueEnabled = false;
15
15
  this.setMaxListeners(11);
16
16
  }
17
+
18
+
19
+ listen() {
20
+ //TODO modify to async
21
+ //messageEvent.on('message.received', function(message) {
22
+
23
+
24
+ var messageCreateKey = 'message.create';
25
+ if (messageEvent.queueEnabled) {
26
+ messageCreateKey = 'message.create.queue';
27
+ }
28
+
29
+ winston.info("Listening " + messageCreateKey + " event for Chatbot messages");
30
+
31
+ messageEvent.on(messageCreateKey, function(message) {
32
+
33
+ winston.debug("message", message);
34
+
35
+ // TODO usa meglio se attributes.reply_always=true
36
+ if (message.sender === "system" && message.text && message.text!="\\start") {
37
+ winston.debug("it s a message sent from system, exit");
38
+ return null;
39
+ }
40
+
41
+ if (message.text && ( message.text.indexOf("\\agent") > -1 || message.text.indexOf("\\close") > -1)) { //not reply to a message containing \\agent
42
+ return 0;
43
+ }
44
+
45
+ // if (message.text.startsWith("\\")) { //not reply to a message containing \
46
+ // return null;
47
+ // }
48
+
49
+ var botId = getBotId(message);
50
+
51
+ winston.debug("botId: " + botId);
52
+
53
+ if (!botId) {
54
+ return null;
55
+ }else {
56
+ //loop fix for messages sent from external bot
57
+ // botprefix
58
+ if (message.sender === 'bot_'+botId || message.sender === botId) {
59
+ winston.debug("it s a message sent from bot, exit");
60
+ return null;
61
+ }else {
62
+ messageEvent.emit('message.received.for.bot', message); //UNUSED
63
+ }
64
+
65
+ }
66
+
67
+ // qui potresti leggere anche +secret ed evitare prossima query in botNotification
68
+ let qbot = Faq_kb.findById(botId); //TODO add cache_bot_here
69
+ //TODO unselect secret. secret is unselectable by default in the model
70
+
71
+ if (cacheEnabler.faq_kb) {
72
+ winston.debug('message.id_project+":faq_kbs:id:"+botId: '+ message.id_project+":faq_kbs:id:"+botId);
73
+ qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId)
74
+ winston.debug('faq_kb cache enabled');
75
+ }
76
+
77
+ qbot.exec(function(err, bot) {
78
+
79
+
80
+
81
+ if (err) {
82
+ winston.error('Error getting object.', err);
83
+ return 0;
84
+ }
85
+ if (!bot) {
86
+ winston.warn('Bot not found with id '+botId);
87
+ }
88
+
89
+ winston.debug("bot debug", bot);
90
+
91
+ if (bot) {
92
+ if (bot.type==="internal") {
93
+ botEvent.emit('bot.message.received.notify.internal', message);
94
+
95
+ }else { //external
96
+ if (bot.url) {
97
+ var botNotification = {bot: bot, message: message};
98
+ botEvent.emit('bot.message.received.notify.external', botNotification);
99
+ }else {
100
+ winston.warn("bot url is not defined", bot);
101
+ }
102
+ }
103
+ }
104
+
105
+ });
106
+
107
+
108
+
109
+ });
110
+
111
+ }
112
+
17
113
  }
18
114
 
19
115
  const botEvent = new BotEvent();
@@ -79,87 +175,6 @@ function getBotId(message) {
79
175
 
80
176
  }
81
177
 
82
- //TODO modify to async
83
- //messageEvent.on('message.received', function(message) {
84
- messageEvent.on('message.create', function(message) {
85
-
86
- winston.debug("message", message);
87
-
88
- // TODO usa meglio se attributes.reply_always=true
89
- if (message.sender === "system" && message.text && message.text!="\\start") {
90
- winston.debug("it s a message sent from system, exit");
91
- return null;
92
- }
93
-
94
- if (message.text && ( message.text.indexOf("\\agent") > -1 || message.text.indexOf("\\close") > -1)) { //not reply to a message containing \\agent
95
- return 0;
96
- }
97
-
98
- // if (message.text.startsWith("\\")) { //not reply to a message containing \
99
- // return null;
100
- // }
101
-
102
- var botId = getBotId(message);
103
-
104
- winston.debug("botId: " + botId);
105
-
106
- if (!botId) {
107
- return null;
108
- }else {
109
- //loop fix for messages sent from external bot
110
- // botprefix
111
- if (message.sender === 'bot_'+botId || message.sender === botId) {
112
- winston.debug("it s a message sent from bot, exit");
113
- return null;
114
- }else {
115
- messageEvent.emit('message.received.for.bot', message);
116
- }
117
-
118
- }
119
-
120
-
121
- let qbot = Faq_kb.findById(botId); //TODO add cache_bot_here
122
- //TODO unselect secret. secret is unselectable by default in the model
123
-
124
- if (cacheEnabler.faq_kb) {
125
- winston.debug('message.id_project+":faq_kbs:id:"+botId: '+ message.id_project+":faq_kbs:id:"+botId);
126
- qbot.cache(cacheUtil.defaultTTL, message.id_project+":faq_kbs:id:"+botId)
127
- winston.debug('faq_kb cache enabled');
128
- }
129
-
130
- qbot.exec(function(err, bot) {
131
-
132
-
133
-
134
- if (err) {
135
- winston.error('Error getting object.', err);
136
- return 0;
137
- }
138
- if (!bot) {
139
- winston.warn('Bot not found with id '+botId);
140
- }
141
-
142
- winston.debug("bot", bot);
143
-
144
- if (bot) {
145
- if (bot.type==="internal") {
146
- botEvent.emit('bot.message.received.notify.internal', message);
147
-
148
- }else { //external
149
- if (bot.url) {
150
- var botNotification = {bot: bot, message: message};
151
- botEvent.emit('bot.message.received.notify.external', botNotification);
152
- }else {
153
- winston.warn("bot url is not defined", bot);
154
- }
155
- }
156
- }
157
-
158
- });
159
-
160
-
161
-
162
- });
163
178
 
164
179
 
165
180
  module.exports = botEvent;
@@ -1,10 +1,14 @@
1
1
  const EventEmitter = require('events');
2
2
 
3
- class LeadEvent extends EventEmitter {}
3
+ class LeadEvent extends EventEmitter {
4
+ constructor() {
5
+ super();
6
+ this.queueEnabled = false;
7
+ this.setMaxListeners(11);
8
+ }
9
+ }
4
10
 
5
11
  const leadEvent = new LeadEvent();
6
12
 
7
13
 
8
-
9
-
10
14
  module.exports = leadEvent;
package/jobs.js CHANGED
@@ -23,6 +23,10 @@ let JobsManager = require('./jobsManager');
23
23
  let geoService = require('./services/geoService');
24
24
  // let subscriptionNotifier = require('./services/subscriptionNotifier');
25
25
  var subscriptionNotifierQueued = require('./services/subscriptionNotifierQueued');
26
+ var botSubscriptionNotifier = require('./services/BotSubscriptionNotifier');
27
+
28
+ const botEvent = require('./event/botEvent');
29
+ var channelManager = require('./channels/channelManager');
26
30
 
27
31
  require('./services/mongoose-cache-fn')(mongoose);
28
32
 
@@ -55,12 +59,28 @@ winston.info("Mongoose connection done on host: "+mongoose.connection.host + " o
55
59
  async function main()
56
60
  {
57
61
 
58
- //************* LOAD QUEUE ************ //
59
- require('./pubmodules/queue');
60
-
62
+ ////************* LOAD QUEUE ************ //
63
+ require('./pubmodules/cache').cachegoose(mongoose);
64
+
65
+
66
+ ////************* LOAD CONCIERGE BOT ************ //
67
+ require('./pubmodules/rules/appRules').start();
68
+
69
+
70
+ // require('./pubmodules/trigger/rulesTrigger').listen(); request.close trigger event is not triggered by anyone now?
71
+
72
+
73
+ //************* LOAD QUEUE ************ //
74
+ require('./pubmodules/queue');
61
75
  // require('@tiledesk-ent/tiledesk-server-queue');
62
76
 
63
- let jobsManager = new JobsManager(undefined, geoService, subscriptionNotifierQueued);
77
+ //************* LOAD CHAT21 ************ //
78
+ channelManager.listen(); // chat21Handler is loaded with stadard events like request.create and NOT request.create.queue because it is used internally by the worker when the request is closed by ChatUnhandledRequestScheduler
79
+
80
+
81
+
82
+
83
+ let jobsManager = new JobsManager(undefined, geoService, botEvent, subscriptionNotifierQueued, botSubscriptionNotifier);
64
84
 
65
85
  jobsManager.listen();
66
86
 
@@ -72,6 +92,17 @@ async function main()
72
92
  let activityArchiver = require('./pubmodules/activities').activityArchiver;
73
93
  jobsManager.listenActivityArchiver(activityArchiver);
74
94
 
95
+
96
+ // let routingQueue = require('./pubmodules/routing-queue').listener; //ci sono altri eventi che nn gestisco in queue request.participants.join etc
97
+ // winston.info("routingQueue1");
98
+ // jobsManager.listenRoutingQueue(routingQueue);
99
+
100
+
101
+
102
+ let scheduler = require('./pubmodules/scheduler');
103
+ jobsManager.listenScheduler(scheduler);
104
+
105
+
75
106
  winston.info("Jobs started");
76
107
 
77
108
  await new Promise(function () {});
package/jobsManager.js CHANGED
@@ -2,15 +2,16 @@
2
2
  var winston = require('./config/winston');
3
3
 
4
4
  class JobsManager {
5
- constructor(jobWorkerEnabled, geoService, subscriptionNotifierQueued) {
5
+ constructor(jobWorkerEnabled, geoService, botEvent, subscriptionNotifierQueued, botSubscriptionNotifier) {
6
6
  this.geoService = geoService;
7
+ this.botEvent = botEvent;
7
8
  // this.subscriptionNotifier = subscriptionNotifier;
8
9
  this.subscriptionNotifierQueued = subscriptionNotifierQueued;
10
+ this.botSubscriptionNotifier = botSubscriptionNotifier;
9
11
 
10
12
  this.emailNotificatio = undefined;
11
13
  this.activityArchiver = undefined;
12
-
13
-
14
+
14
15
  this.jobWorkerEnabled = jobWorkerEnabled;
15
16
  // this.jobWorkerEnabled = false;
16
17
  // if (process.env.JOB_WORKER_ENABLED=="true" || process.env.JOB_WORKER_ENABLED == true) {
@@ -26,8 +27,13 @@ class JobsManager {
26
27
  return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listeners");
27
28
  }
28
29
  this.geoService.listen();
30
+
31
+ // this.botEvent.listen(); // disabled
32
+
29
33
  // this.subscriptionNotifier.start();
30
34
  this.subscriptionNotifierQueued.start();
35
+
36
+ // this.botSubscriptionNotifier.start(); // disabled
31
37
  }
32
38
 
33
39
  listenEmailNotification(emailNotification) {
@@ -39,7 +45,23 @@ class JobsManager {
39
45
  this.emailNotification.requestNotification.listen();
40
46
  }
41
47
 
48
+ // listenRoutingQueue(routingQueue) {
49
+ // winston.info("JobsManager routingQueue started");
50
+ // if ( this.jobWorkerEnabled == true) {
51
+ // return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for routingQueue");
52
+ // }
53
+ // this.routingQueue = routingQueue;
54
+ // this.routingQueue.listen();
55
+ // }
42
56
 
57
+ listenScheduler(scheduler) {
58
+ winston.info("JobsManager scheduler started");
59
+ if ( this.jobWorkerEnabled == true) {
60
+ return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for scheduler");
61
+ }
62
+ this.scheduler = scheduler;
63
+ this.scheduler.taskRunner.start();
64
+ }
43
65
 
44
66
  listenActivityArchiver(activityArchiver) {
45
67
  winston.info("JobsManager listenActivityArchiver started");
package/models/user.js CHANGED
@@ -15,7 +15,7 @@ var UserSchema = new Schema({
15
15
  type: String,
16
16
  required: true,
17
17
  // https://stackoverflow.com/questions/12096262/how-to-protect-the-password-field-in-mongoose-mongodb-so-it-wont-return-in-a-qu
18
- select: false
18
+ select: false
19
19
  },
20
20
  firstname: {
21
21
  type: String,
@@ -31,10 +31,10 @@ var UserSchema = new Schema({
31
31
  },
32
32
  resetpswrequestid: {
33
33
  type: String,
34
- select: false
34
+ select: false
35
35
  },
36
36
  signedInAt: {
37
- type:Date
37
+ type: Date
38
38
  },
39
39
 
40
40
  // db.users.find({authUrl: {$exists : false }}).forEach(function(mydoc) {
@@ -43,7 +43,7 @@ var UserSchema = new Schema({
43
43
 
44
44
  authUrl: {
45
45
  type: String,
46
- index:true
46
+ index: true
47
47
  },
48
48
  attributes: {
49
49
  type: Object,
@@ -54,10 +54,18 @@ var UserSchema = new Schema({
54
54
  default: 100,
55
55
  index: true,
56
56
  // select: false
57
- },
57
+ },
58
58
  description: {
59
59
  type: String,
60
60
  },
61
+ public_email: {
62
+ type: String,
63
+ required: false
64
+ },
65
+ public_website: {
66
+ type: String,
67
+ required: false
68
+ }
61
69
  // authType: { // update db old data
62
70
  // type: String,
63
71
  // index:true,
@@ -68,9 +76,9 @@ var UserSchema = new Schema({
68
76
  // ref: 'auth',
69
77
  // //required: true
70
78
  // },
71
- },{
72
- timestamps: true
73
- }
79
+ }, {
80
+ timestamps: true
81
+ }
74
82
  );
75
83
 
76
84
  // UserSchema.set('toJSON', {
@@ -111,8 +119,8 @@ UserSchema.methods.comparePassword = function (passw, cb) {
111
119
 
112
120
  UserSchema.virtual('fullName').get(function () {
113
121
  return (this.firstname || '') + ' ' + (this.lastname || '');
114
- });
115
-
122
+ });
123
+
116
124
 
117
125
  //UserSchema.index({ email: 1, authType: 1 }, { unique: true });
118
126
 
@@ -126,6 +134,6 @@ var UserModel = mongoose.model('user', UserSchema);
126
134
  if (process.env.MONGOOSE_SYNCINDEX) {
127
135
  UserModel.syncIndexes();
128
136
  winston.info("UserModel syncIndexes")
129
- }
137
+ }
130
138
 
131
139
  module.exports = UserModel;
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.4.38",
4
+ "version": "2.4.40",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -44,7 +44,7 @@
44
44
  "@tiledesk/tiledesk-kaleyra-proxy": "^0.1.7",
45
45
  "@tiledesk/tiledesk-messenger-connector": "0.1.9",
46
46
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
47
- "@tiledesk/tiledesk-tybot-connector": "^0.1.87",
47
+ "@tiledesk/tiledesk-tybot-connector": "^0.1.89",
48
48
  "@tiledesk/tiledesk-whatsapp-connector": "^0.1.50",
49
49
  "amqplib": "^0.5.5",
50
50
  "app-root-path": "^3.0.0",
@@ -42,6 +42,7 @@ class ActivityArchiver {
42
42
  activityEvent.on('lead.download.csv', this.save);
43
43
  */
44
44
 
45
+ // works only if worker is disabled
45
46
  var authProjectUserInvitePendingKey = 'project_user.invite.pending'; //Don't work if job_worker enabled because queue.worker is disabled
46
47
  // if (authEvent.queueEnabled) { //queue not supported.
47
48
  // authProjectUserInvitePendingKey = 'project_user.invite.pending.queue';
@@ -63,6 +64,10 @@ class ActivityArchiver {
63
64
 
64
65
  });
65
66
 
67
+
68
+
69
+
70
+ // works only if worker is disabled
66
71
  var authProjectUserInviteKey = 'project_user.invite'; //Don't work if job_worker enabled because queue.worker is disabled
67
72
  // if (authEvent.queueEnabled) { //queue not supported
68
73
  // authProjectUserInviteKey = 'project_user.invite.queue';
@@ -84,6 +89,9 @@ class ActivityArchiver {
84
89
 
85
90
  });
86
91
  });
92
+
93
+
94
+
87
95
 
88
96
  // verified with queue
89
97
  var authProjectUserUpdateKey = 'project_user.update';
@@ -125,7 +133,7 @@ class ActivityArchiver {
125
133
 
126
134
  });
127
135
 
128
-
136
+ // works only if worker is disabled
129
137
  var authProjectUserDeleteKey = 'project_user.delete'; //Don't work if job_worker enabled because queue.worker is disabled
130
138
  // if (authEvent.queueEnabled) { //queue not supported
131
139
  // authProjectUserDeleteKey = 'project_user.delete.queue';
@@ -147,8 +155,10 @@ class ActivityArchiver {
147
155
 
148
156
  });
149
157
  });
150
-
151
158
 
159
+
160
+
161
+ // disabled why? performance?
152
162
  // var authUserSignineKey = 'user.signin';
153
163
  // // if (authEvent.queueEnabled) { //queue not supported
154
164
  // // authUserSignineKey = 'user.signin.queue';
@@ -83,14 +83,14 @@ listen() {
83
83
 
84
84
  //messages sent from admins or agents to requester
85
85
  if (message.sender != message.request.lead.lead_id) {
86
- winston.verbose("sending sendToUserEmailChannelEmail for EMAIL or FORM channel");
86
+ winston.debug("sending sendToUserEmailChannelEmail for EMAIL or FORM channel");
87
87
 
88
88
  //send email notification to requester (send also to followers)
89
89
  return that.sendToUserEmailChannelEmail(message.id_project, message);
90
90
  } else { //messages sent from requester to agents or admins
91
91
 
92
92
  if (message.text != message.request.first_text) {
93
- winston.verbose("sending sendToAgentEmailChannelEmail for EMAIL or FORM channel");
93
+ winston.debug("sending sendToAgentEmailChannelEmail for EMAIL or FORM channel");
94
94
 
95
95
  //send email notification to admins and agents(send also to followers)
96
96
  return that.sendToAgentEmailChannelEmail(message.id_project, message);
@@ -140,7 +140,7 @@ listen() {
140
140
 
141
141
  /*
142
142
  if (request && (request.channel.name===ChannelConstants.EMAIL || request.channel.name===ChannelConstants.FORM )) {
143
- winston.verbose("sending sendEmailChannelTakingNotification for EMAIL or FORM channel");
143
+ winston.debug("sending sendEmailChannelTakingNotification for EMAIL or FORM channel");
144
144
  that.sendEmailChannelTakingNotification(request.id_project, request)
145
145
  }
146
146
  */
@@ -190,7 +190,7 @@ listen() {
190
190
  if (requestEvent.queueEnabled) {
191
191
  requestCloseExtendedKey = 'request.close.extended.queue';
192
192
  }
193
- winston.debug('RequestNotification requestCloseExtendedKey: ' + requestCloseExtendedKey);
193
+ winston.debug('RequestNotification requestCloseExtendedKey: ' + requestCloseExtendedKey); //request.close event here queued under job
194
194
  requestEvent.on(requestCloseExtendedKey, function(data) {
195
195
  winston.debug('requestEvent.on(requestCloseExtendedKey ' + requestCloseExtendedKey);
196
196
  setImmediate(() => {
@@ -563,7 +563,7 @@ sendToAgentEmailChannelEmail(projectid, message) {
563
563
  if (!user) {
564
564
  winston.warn("User not found", userid);
565
565
  } else {
566
- winston.verbose("Sending sendNewPooledMessageNotification to user with email: "+ user.email);
566
+ winston.debug("Sending sendNewPooledMessageNotification to user with email: "+ user.email);
567
567
  if (user.emailverified) {
568
568
  emailService.sendNewPooledMessageEmailNotification(user.email, savedRequest, project, message);
569
569
  }else {
@@ -997,7 +997,7 @@ sendAgentEmail(projectid, savedRequest) {
997
997
  if (!user) {
998
998
  winston.warn("User not found", savedRequest.participants[0]);
999
999
  } else {
1000
- winston.verbose("Sending sendNewAssignedRequestNotification to user with email", user.email);
1000
+ winston.debug("Sending sendNewAssignedRequestNotification to user with email", user.email);
1001
1001
  // if (user.emailverified) { enable it? send anyway to improve engagment for new account
1002
1002
 
1003
1003
 
@@ -493,7 +493,8 @@ class PubModulesManager {
493
493
 
494
494
  if (this.scheduler) {
495
495
  try {
496
- this.scheduler.taskRunner.start();
496
+ // this.scheduler.taskRunner.start();
497
+ this.jobsManager.listenScheduler(this.scheduler);
497
498
  winston.info("PubModulesManager scheduler started.");
498
499
  } catch(err) {
499
500
  winston.info("PubModulesManager error starting scheduler module", err);
@@ -515,6 +516,7 @@ class PubModulesManager {
515
516
  if (this.routingQueue) {
516
517
  try {
517
518
  this.routingQueue.listen();
519
+ // this.jobsManager.listenRoutingQueue(this.routingQueue);
518
520
  winston.info("PubModulesManager routingQueue started");
519
521
  } catch(err) {
520
522
  winston.info("PubModulesManager error starting routingQueue module", err);
@@ -17,7 +17,9 @@ var url = process.env.CLOUDAMQP_URL + "?heartbeat=60" || "amqp://localhost";
17
17
  // attento devi aggiornare configMap di PRE E PROD
18
18
  // var url = process.env.AMQP_URL + "?heartbeat=60" || "amqp://localhost?heartbeat=60";
19
19
 
20
+ // var durable = true;
20
21
  var durable = false;
22
+
21
23
  // if (process.env.ENABLE_DURABLE_QUEUE == false || process.env.ENABLE_DURABLE_QUEUE == "false") {
22
24
  // durable = false;
23
25
  // }
@@ -67,10 +69,10 @@ function whenConnected() {
67
69
  winston.info("JobsManager jobWorkerEnabled: "+ jobWorkerEnabled);
68
70
 
69
71
  if (jobWorkerEnabled == false) {
70
- winston.info("Queue Reconnect start worker");
72
+ winston.info("Queue Reconnect starts queue worker (queue observer)");
71
73
  startWorker();
72
74
  } else {
73
- winston.info("Queue Reconnect without worker because external worker is enabled");
75
+ winston.info("Queue Reconnect without queue worker (queue observer) because external worker is enabled");
74
76
  }
75
77
 
76
78
  }
@@ -328,9 +330,10 @@ function listen() {
328
330
  });
329
331
  });
330
332
 
331
-
333
+ // winston.debug("sub to reconnect request.close");
332
334
  requestEvent.on('request.close', function(request) {
333
335
  setImmediate(() => {
336
+ winston.debug("reconnect request.close");
334
337
  publish(exchange, "request_close", Buffer.from(JSON.stringify(request)));
335
338
  });
336
339
  });
@@ -395,6 +398,6 @@ if (process.env.QUEUE_ENABLED === "true") {
395
398
  leadEvent.queueEnabled = true;
396
399
  listen();
397
400
  start();
398
- winston.info("Queue enabled. endpint: " + url );
401
+ winston.info("Queue enabled. endpoint: " + url );
399
402
  }
400
403
 
package/routes/faq.js CHANGED
@@ -10,6 +10,7 @@ const faqEvent = require('../event/faqBotEvent')
10
10
 
11
11
  var parsecsv = require("fast-csv");
12
12
  const botEvent = require('../event/botEvent');
13
+ const uuidv4 = require('uuid/v4');
13
14
  csv = require('csv-express');
14
15
  csv.separator = ';';
15
16
 
@@ -21,21 +22,22 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
21
22
  winston.debug(' -> FILE ', req.file);
22
23
 
23
24
  var id_faq_kb = req.body.id_faq_kb;
24
- winston.debug('id_faq_kb: '+id_faq_kb);
25
+ winston.debug('id_faq_kb: ' + id_faq_kb);
25
26
 
26
27
  var delimiter = req.body.delimiter || ";";
27
- winston.debug('delimiter: '+delimiter);
28
+ winston.debug('delimiter: ' + delimiter);
28
29
 
29
30
  var csv = req.file.buffer.toString('utf8');
31
+ console.log("--> csv: ", csv)
30
32
  // winston.debug(' -> CSV STRING ', csv);
31
33
 
32
34
  // res.json({ success: true, msg: 'Importing CSV...' });
33
35
 
34
36
  // PARSE CSV
35
-
36
37
 
37
38
 
38
- Faq_kb.findById(id_faq_kb).exec(function(err, faq_kb) {
39
+
40
+ Faq_kb.findById(id_faq_kb).exec(function (err, faq_kb) {
39
41
  if (err) {
40
42
  return res.status(500).send({ success: false, msg: 'Error getting object.' });
41
43
  }
@@ -44,18 +46,45 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
44
46
  }
45
47
  winston.debug('faq_kb ', faq_kb.toJSON());
46
48
 
47
- // getFaqKbKeyById(req.body.id_faq_kb, function (remote_faqkb_key) {
49
+ // getFaqKbKeyById(req.body.id_faq_kb, function (remote_faqkb_key) {
48
50
 
49
51
  parsecsv.parseString(csv, { headers: false, delimiter: delimiter })
50
52
  .on("data", function (data) {
51
53
  winston.debug('PARSED CSV ', data);
52
54
 
55
+ console.log('--> PARSED CSV ', data);
56
+
53
57
  var question = data[0]
54
- var answer = data[1]
58
+ //var answer = data[1]
55
59
  var intent_id = data[2];
56
60
  var intent_display_name = data[3];
57
61
  var webhook_enabled = data[4];
58
62
 
63
+
64
+ var actions = [
65
+ {
66
+ _tdActionType: "reply",
67
+ _tdActionId: uuidv4(),
68
+ text: data[1],
69
+ attributes: {
70
+ commands: [
71
+ {
72
+ type: "wait",
73
+ time: 500
74
+ },
75
+ {
76
+ type: "message",
77
+ message: {
78
+ type: "text",
79
+ text: data[1]
80
+ }
81
+ }
82
+ ]
83
+ }
84
+
85
+ }
86
+ ]
87
+
59
88
  var webhook_enabled_boolean = false;
60
89
  if (webhook_enabled) {
61
90
  webhook_enabled_boolean = (webhook_enabled == 'true');
@@ -67,8 +96,9 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
67
96
  var newFaq = new Faq({
68
97
  id_faq_kb: id_faq_kb,
69
98
  question: question,
70
- answer: answer,
71
- intent_id:intent_id,
99
+ //answer: answer,
100
+ actions: actions,
101
+ intent_id: intent_id,
72
102
  intent_display_name: intent_display_name,
73
103
  webhook_enabled: webhook_enabled_boolean,
74
104
  language: faq_kb.language,
@@ -77,6 +107,8 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
77
107
  updatedBy: req.user.id
78
108
  });
79
109
 
110
+ console.log("--> newFaq: ", JSON.stringify(newFaq, null, 2));
111
+
80
112
  newFaq.save(function (err, savedFaq) {
81
113
  if (err) {
82
114
  winston.error('--- > ERROR uploadcsv', err)
@@ -85,7 +117,7 @@ router.post('/uploadcsv', upload.single('uploadFile'), function (req, res, next)
85
117
  } else {
86
118
  faqBotEvent.emit('faq.create', savedFaq);
87
119
  }
88
-
120
+
89
121
  });
90
122
  })
91
123
  .on("end", function () {
@@ -105,7 +137,7 @@ router.post('/', function (req, res) {
105
137
 
106
138
  winston.debug(req.body);
107
139
 
108
- Faq_kb.findById(req.body.id_faq_kb).exec(function(err, faq_kb) {
140
+ Faq_kb.findById(req.body.id_faq_kb).exec(function (err, faq_kb) {
109
141
  if (err) {
110
142
  return res.status(500).send({ success: false, msg: 'Error getting object.' });
111
143
  }
@@ -148,7 +180,7 @@ router.post('/', function (req, res) {
148
180
  } else {
149
181
  winston.debug('--- > ERROR ', err)
150
182
  return res.status(500).send({ success: false, msg: 'Error saving object.' });
151
- }
183
+ }
152
184
  }
153
185
  winston.debug('1. ID OF THE NEW FAQ CREATED ', savedFaq._id)
154
186
  winston.debug('1. QUESTION OF THE NEW FAQ CREATED ', savedFaq.question)
@@ -160,7 +192,7 @@ router.post('/', function (req, res) {
160
192
 
161
193
  res.json(savedFaq);
162
194
 
163
-
195
+
164
196
  });
165
197
  });
166
198
  });
@@ -187,7 +219,7 @@ router.patch('/:faqid/attributes', function (req, res) {
187
219
 
188
220
  winston.debug("updatedFaq attributes", updatedFaq.attributes);
189
221
 
190
- Object.keys(data).forEach(function(key) {
222
+ Object.keys(data).forEach(function (key) {
191
223
  var val = data[key];
192
224
  winston.debug("data attributes" + key + " " + val);
193
225
  updatedFaq.attributes[key] = val;
@@ -221,38 +253,38 @@ router.put('/:faqid', function (req, res) {
221
253
  winston.debug('UPDATE FAQ ', req.body);
222
254
 
223
255
  var update = {};
224
-
225
- if (req.body.intent!=undefined) {
256
+
257
+ if (req.body.intent != undefined) {
226
258
  update.intent = req.body.intent;
227
259
  }
228
- if (req.body.question!=undefined) {
260
+ if (req.body.question != undefined) {
229
261
  update.question = req.body.question;
230
262
  }
231
- if (req.body.answer!=undefined) {
263
+ if (req.body.answer != undefined) {
232
264
  update.answer = req.body.answer;
233
265
  }
234
- if (req.body.topic!=undefined) {
266
+ if (req.body.topic != undefined) {
235
267
  update.topic = req.body.topic;
236
268
  }
237
- if (req.body.status!=undefined) {
269
+ if (req.body.status != undefined) {
238
270
  update.status = req.body.status;
239
271
  }
240
- if (req.body.language!=undefined) {
272
+ if (req.body.language != undefined) {
241
273
  update.language = req.body.language;
242
274
  }
243
- if (req.body.intent_display_name!=undefined) {
275
+ if (req.body.intent_display_name != undefined) {
244
276
  update.intent_display_name = req.body.intent_display_name;
245
277
  }
246
- if (req.body.webhook_enabled!=undefined) {
278
+ if (req.body.webhook_enabled != undefined) {
247
279
  update.webhook_enabled = req.body.webhook_enabled;
248
280
  }
249
- if (req.body.enabled!=undefined) {
281
+ if (req.body.enabled != undefined) {
250
282
  update.enabled = req.body.enabled;
251
283
  }
252
- if (req.body.reply!=undefined) {
284
+ if (req.body.reply != undefined) {
253
285
  update.reply = req.body.reply;
254
286
  }
255
- if (req.body.form!=undefined) {
287
+ if (req.body.form != undefined) {
256
288
  update.form = req.body.form;
257
289
  }
258
290
  if (req.body.actions != undefined) {
@@ -266,7 +298,7 @@ router.put('/:faqid', function (req, res) {
266
298
  if (err) {
267
299
  if (err.code == 11000) {
268
300
  return res.status(409).send({ success: false, msg: 'Duplicate intent_display_name.' });
269
- }else {
301
+ } else {
270
302
  return res.status(500).send({ success: false, msg: 'Error updating object.' });
271
303
  }
272
304
  }
@@ -315,16 +347,18 @@ router.get('/csv', function (req, res) {
315
347
 
316
348
  winston.debug('EXPORT FAQS TO CSV QUERY', query);
317
349
 
318
- Faq.find(query, 'question answer intent_id intent_display_name webhook_enabled -_id').lean().exec(function (err, faqs) {
350
+ Faq.find(query, 'question answer intent_id intent_display_name webhook_enabled -_id').lean().exec(function (err, faqs) {
319
351
  if (err) {
320
352
  winston.debug('EXPORT FAQS TO CSV ERR', err)
321
353
  return (err)
322
354
  };
323
355
  var csv = [];
324
- faqs.forEach(function(element) {
325
- var row = {question: element.question, answer: element.answer,
356
+ faqs.forEach(function (element) {
357
+ var row = {
358
+ question: element.question, answer: element.answer,
326
359
  intent_id: element.intent_id, intent_display_name: element.intent_display_name,
327
- webhook_enabled: element.webhook_enabled || false }
360
+ webhook_enabled: element.webhook_enabled || false
361
+ }
328
362
  csv.push(row);
329
363
  });
330
364
  winston.debug('EXPORT FAQ TO CSV FAQS', csv)
@@ -363,9 +397,9 @@ router.get('/', function (req, res, next) {
363
397
 
364
398
  var limit = 3000; // Number of request per page
365
399
 
366
- if (req.query.limit) {
400
+ if (req.query.limit) {
367
401
  limit = parseInt(req.query.limit);
368
- winston.debug('faq ROUTE - limit: '+limit);
402
+ winston.debug('faq ROUTE - limit: ' + limit);
369
403
  }
370
404
 
371
405
  var page = 0;
@@ -388,15 +422,15 @@ router.get('/', function (req, res, next) {
388
422
  }
389
423
 
390
424
  if (req.query.intent_display_name) {
391
- query.intent_display_name=req.query.intent_display_name
425
+ query.intent_display_name = req.query.intent_display_name
392
426
  }
393
-
427
+
394
428
 
395
429
  winston.debug("GET FAQ query", query);
396
430
 
397
431
  // query.$text = {"$search": "question"};
398
432
 
399
- // TODO ORDER BY SCORE
433
+ // TODO ORDER BY SCORE
400
434
  // return Faq.find(query, {score: { $meta: "textScore" } })
401
435
  // .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
402
436
 
@@ -404,11 +438,11 @@ router.get('/', function (req, res, next) {
404
438
  // return Faq.search('a closer', (err, result) => {
405
439
  // console.log("result: ", result);
406
440
  // })
407
-
441
+
408
442
  return Faq.find(query).
409
- skip(skip).limit(limit).
410
- populate({path:'faq_kb'})//, match: { trashed: { $in: [null, false] } }}).
411
- .exec(function (err, faq) {
443
+ skip(skip).limit(limit).
444
+ populate({ path: 'faq_kb' })//, match: { trashed: { $in: [null, false] } }}).
445
+ .exec(function (err, faq) {
412
446
  winston.debug("GET FAQ ", faq);
413
447
 
414
448
  if (err) {
@@ -420,7 +454,7 @@ router.get('/', function (req, res, next) {
420
454
 
421
455
  });
422
456
 
423
-
457
+
424
458
  });
425
459
 
426
460
 
@@ -21,7 +21,7 @@ router.get('/:userid', function (req, res) {
21
21
  return res.status(404).send({ success: false, msg: 'User id not found' });
22
22
  }
23
23
 
24
- User.findById(userid, 'firstname lastname _id', function (err, user) {
24
+ User.findById(userid, 'firstname lastname _id public_website public_email description', function (err, user) {
25
25
  if (err) {
26
26
  winston.error('Error getting object.',err);
27
27
  return res.status(500).send({ success: false, msg: 'Error getting object.' });
package/routes/users.js CHANGED
@@ -7,23 +7,36 @@ var winston = require('../config/winston');
7
7
  const authEvent = require('../event/authEvent');
8
8
  const uuidv4 = require('uuid/v4');
9
9
 
10
-
11
-
12
-
13
-
14
10
  router.put('/', function (req, res) {
15
11
 
16
12
  winston.debug('UPDATE USER - REQ BODY ', req.body);
17
13
 
18
14
  var update = {};
19
-
20
- update.firstname = req.body.firstname;
21
- update.lastname = req.body.lastname;
22
- update.attributes = req.body.attributes;
23
- update.description = req.body.description;
24
-
25
-
26
15
 
16
+ // update.firstname = req.body.firstname;
17
+ // update.lastname = req.body.lastname;
18
+ // update.attributes = req.body.attributes;
19
+ // update.description = req.body.description;
20
+
21
+ if (req.body.firstname != undefined) {
22
+ update.firstname = req.body.firstname;
23
+ }
24
+ if (req.body.lastname != undefined) {
25
+ update.lastname = req.body.lastname;
26
+ }
27
+ if (req.body.attributes != undefined) {
28
+ update.attributes = req.body.attributes;
29
+ }
30
+ if (req.body.description != undefined) {
31
+ update.description = req.body.description;
32
+ }
33
+ if (req.body.public_email != undefined) {
34
+ update.public_email = req.body.public_email;
35
+ }
36
+ if (req.body.public_website != undefined) {
37
+ update.public_website = req.body.public_website;
38
+ }
39
+
27
40
  User.findByIdAndUpdate(req.user.id, update, { new: true, upsert: true }, function (err, updatedUser) {
28
41
  if (err) {
29
42
  winston.error("Error putting user",err);
@@ -19,7 +19,7 @@ class BotSubscriptionNotifier {
19
19
 
20
20
  notify(bot,botWithSecret, payload) {
21
21
 
22
- winston.verbose("BotSubscriptionNotifier bot", bot.toObject());
22
+ winston.debug("BotSubscriptionNotifier bot", bot.toObject());
23
23
  winston.debug("BotSubscriptionNotifier payload", payload );
24
24
 
25
25
  var url = bot.url;
@@ -27,11 +27,13 @@ class SubscriptionNotifierQueued {
27
27
  if (messageEvent.queueEnabled) {
28
28
  messageCreateKey = 'message.create.queue';
29
29
  }
30
+ winston.debug('SubscriptionNotifierQueued messageCreateKey: ' + messageCreateKey);
31
+
30
32
  messageEvent.on(messageCreateKey, function(message) { //queued tested
31
33
  setImmediate(() => {
32
- winston.debug('SubscriptionNotifier message.create');
34
+ winston.debug('SubscriptionNotifierQueued message.create');
33
35
  subscriptionNotifier.subscribe('message.create', message);
34
- winston.debug('SubscriptionNotifier message.create sent');
36
+ winston.debug('SubscriptionNotifierQueued message.create sent');
35
37
  });
36
38
  });
37
39
 
@@ -643,7 +643,7 @@ class WebSocketServer {
643
643
  if (messageEvent.queueEnabled) {
644
644
  messageCreateKey = 'message.create.queue.pubsub';
645
645
  }
646
- winston.debug('messageCreateKey: ' + messageCreateKey);
646
+ winston.debug('WS messageCreateKey: ' + messageCreateKey);
647
647
 
648
648
  messageEvent.on(messageCreateKey, function (message) {
649
649
  setImmediate(async () => {