@tiledesk/tiledesk-server 2.3.17 → 2.3.19
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/channels/chat21/chat21Handler.js +18 -3
- package/channels/chat21/package-lock.json +663 -706
- package/channels/chat21/package.json +2 -2
- package/models/project_user.js +4 -0
- package/models/request.js +12 -1
- package/package.json +3 -5
- package/pubmodules/activities/activityArchiver.js +1 -1
- package/pubmodules/activities/routes/activity.js +1 -1
- package/pubmodules/canned/cannedResponse.js +4 -0
- package/pubmodules/canned/cannedResponseRoute.js +11 -5
- package/pubmodules/emailNotification/requestNotification.js +25 -2
- package/pubmodules/events/eventRoute.js +37 -7
- package/pubmodules/pubModulesManager.js +57 -5
- package/pubmodules/queue/index.js +4 -0
- package/pubmodules/queue/reconnect.js +247 -0
- package/pubmodules/queue/reconnectFanout.js +250 -0
- package/pubmodules/routing-queue/index.js +3 -0
- package/pubmodules/routing-queue/listener.js +328 -0
- package/pubmodules/trigger/start.js +5 -1
- package/routes/auth.js +7 -2
- package/routes/project_user.js +9 -0
- package/routes/request.js +18 -0
- package/services/geoService.js +30 -4
- package/services/modulesManager.js +34 -33
- package/template/email/pooledRequest.html +1 -1
- package/test/cannedRoute.js +166 -0
- package/websocket/webSocketServer.js +23 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiledesk/tiledesk-chat21-app",
|
|
3
3
|
"description": "The Tiledesk Chat21 module",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.7",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Andrea Leo - Frontiere21 SRL",
|
|
7
7
|
"license": "AGPL-3.0",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"url": "https://github.com/Tiledesk/tiledesk-server"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@chat21/chat21-node-sdk": "^1.1.
|
|
14
|
+
"@chat21/chat21-node-sdk": "^1.1.7",
|
|
15
15
|
"winston": "^3.3.3",
|
|
16
16
|
"firebase-admin": "^9.5.0"
|
|
17
17
|
},
|
package/models/project_user.js
CHANGED
|
@@ -37,6 +37,9 @@ var TagSchema = require("../models/tag");
|
|
|
37
37
|
index: true
|
|
38
38
|
// required: true
|
|
39
39
|
},
|
|
40
|
+
profileStatus: {
|
|
41
|
+
type: String,
|
|
42
|
+
},
|
|
40
43
|
presence: PresenceSchema,
|
|
41
44
|
attributes: {
|
|
42
45
|
type: Object,
|
|
@@ -108,5 +111,6 @@ Project_userSchema.virtual('isAuthenticated').get(function () {
|
|
|
108
111
|
// Project_user.find({ id_project: projectid, id_user: { $in : group[0].members}, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.AGENT]} })
|
|
109
112
|
Project_userSchema.index({ id_project: 1, id_user:1, role: 1 });
|
|
110
113
|
|
|
114
|
+
|
|
111
115
|
module.exports = mongoose.model('project_user', Project_userSchema);;
|
|
112
116
|
|
package/models/request.js
CHANGED
|
@@ -273,7 +273,16 @@ var RequestSchema = new Schema({
|
|
|
273
273
|
required: true,
|
|
274
274
|
index: true
|
|
275
275
|
},
|
|
276
|
-
|
|
276
|
+
smartAssignment: {
|
|
277
|
+
type: Boolean,
|
|
278
|
+
default: true,
|
|
279
|
+
index: true
|
|
280
|
+
},
|
|
281
|
+
workingStatus: { //new, pending
|
|
282
|
+
type: String,
|
|
283
|
+
required: false,
|
|
284
|
+
index: true
|
|
285
|
+
},
|
|
277
286
|
createdBy: {
|
|
278
287
|
type: String,
|
|
279
288
|
required: true
|
|
@@ -465,6 +474,8 @@ RequestSchema.index({ id_project: 1, createdAt: 1, preflight: 1});
|
|
|
465
474
|
RequestSchema.index({ hasBot: 1, status: 1, createdAt: 1});
|
|
466
475
|
|
|
467
476
|
|
|
477
|
+
|
|
478
|
+
|
|
468
479
|
// cannot index parallel arrays [agents] [participants] {"driv
|
|
469
480
|
// RequestSchema.index({ id_project: 1, status: 1, preflight:1, participants:1, "agents.id_user":1, updatedAt: -1 }); //NN LO APPLICA
|
|
470
481
|
|
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.
|
|
4
|
+
"version": "2.3.19",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "node ./bin/www",
|
|
7
7
|
"pretest": "mongodb-runner start",
|
|
@@ -33,18 +33,16 @@
|
|
|
33
33
|
"@tiledesk-ent/tiledesk-server-dialogflow": "^1.1.6",
|
|
34
34
|
"@tiledesk-ent/tiledesk-server-jwthistory": "^1.1.9",
|
|
35
35
|
"@tiledesk-ent/tiledesk-server-payments": "^1.1.6",
|
|
36
|
-
"@tiledesk-ent/tiledesk-server-queue": "^1.1.11",
|
|
37
36
|
"@tiledesk-ent/tiledesk-server-request-history": "^1.1.5",
|
|
38
|
-
"@tiledesk-ent/tiledesk-server-routing-queue": "^1.1.11",
|
|
39
37
|
"@tiledesk-ent/tiledesk-server-visitorcounter": "^1.1.1",
|
|
40
38
|
"@tiledesk-ent/tiledesk-server-enterprise": "^1.0.0"
|
|
41
39
|
},
|
|
42
40
|
"dependencies": {
|
|
43
|
-
"@tiledesk/tiledesk-chat21-app": "^1.1.
|
|
41
|
+
"@tiledesk/tiledesk-chat21-app": "^1.1.7",
|
|
44
42
|
"@tiledesk/tiledesk-chatbot-util": "^0.8.33",
|
|
45
43
|
"@tiledesk/tiledesk-json-rules-engine": "^4.0.3",
|
|
46
44
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
|
47
|
-
"@tiledesk/tiledesk-tybot-connector": "^0.1.
|
|
45
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.1.5",
|
|
48
46
|
"app-root-path": "^3.0.0",
|
|
49
47
|
"bcrypt-nodejs": "0.0.3",
|
|
50
48
|
"body-parser": "^1.20.0",
|
|
@@ -275,7 +275,7 @@ class ActivityArchiver {
|
|
|
275
275
|
setImmediate(() => {
|
|
276
276
|
|
|
277
277
|
try {
|
|
278
|
-
winston.
|
|
278
|
+
winston.debug('ActivityArchiver close');
|
|
279
279
|
|
|
280
280
|
var activity = new Activity({actor: {type:"user", id: request.closed_by},
|
|
281
281
|
verb: "REQUEST_CLOSE", actionObj: request,
|
|
@@ -154,7 +154,7 @@ router.get('/', function (req, res) {
|
|
|
154
154
|
return (err);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
return Activity.
|
|
157
|
+
return Activity.countDocuments(query, function (err, totalRowCount) {
|
|
158
158
|
if (err) {
|
|
159
159
|
winston.error('Activity ROUTE - REQUEST FIND ERR ', err)
|
|
160
160
|
return (err);
|
|
@@ -12,12 +12,18 @@ router.post('/', function (req, res) {
|
|
|
12
12
|
|
|
13
13
|
var newCannedResponse = new CannedResponse({
|
|
14
14
|
title: req.body.title,
|
|
15
|
-
text: req.body.text,
|
|
15
|
+
text: req.body.text,
|
|
16
16
|
id_project: req.projectid,
|
|
17
17
|
createdBy: req.user.id,
|
|
18
18
|
updatedBy: req.user.id
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
if (req.projectuser.role == 'owner' || req.projectuser.role == 'admin') {
|
|
22
|
+
newCannedResponse.shared = true;
|
|
23
|
+
} else {
|
|
24
|
+
newCannedResponse.shared = false;
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
newCannedResponse.save(function (err, savedCannedResponse) {
|
|
22
28
|
if (err) {
|
|
23
29
|
winston.error('--- > ERROR ', err)
|
|
@@ -104,7 +110,7 @@ router.get('/:cannedResponseid', function (req, res) {
|
|
|
104
110
|
});
|
|
105
111
|
|
|
106
112
|
router.get('/', function (req, res) {
|
|
107
|
-
var limit =
|
|
113
|
+
var limit = 1000; // Number of CannedResponses per page
|
|
108
114
|
var page = 0;
|
|
109
115
|
|
|
110
116
|
if (req.query.page) {
|
|
@@ -114,15 +120,15 @@ router.get('/', function (req, res) {
|
|
|
114
120
|
var skip = page * limit;
|
|
115
121
|
winston.debug('CannedResponse ROUTE - SKIP PAGE ', skip);
|
|
116
122
|
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
// var query = { "id_project": req.projectid, "status": {$lt:1000}};
|
|
124
|
+
console.log("canned_req.user: ", req.user);
|
|
125
|
+
var query = {"id_project": req.projectid, "status": { $lt:1000 }, $or:[ { shared: true }, { createdBy: req.user._id } ] }
|
|
119
126
|
|
|
120
127
|
if (req.query.full_text) {
|
|
121
128
|
winston.debug('CannedResponse ROUTE req.query.fulltext', req.query.full_text);
|
|
122
129
|
query.$text = { "$search": req.query.full_text };
|
|
123
130
|
}
|
|
124
131
|
|
|
125
|
-
|
|
126
132
|
var direction = -1; //-1 descending , 1 ascending
|
|
127
133
|
if (req.query.direction) {
|
|
128
134
|
direction = req.query.direction;
|
|
@@ -31,11 +31,25 @@ winston.debug('********* RequestNotification apiUrl: ' + apiUrl);
|
|
|
31
31
|
|
|
32
32
|
class RequestNotification {
|
|
33
33
|
|
|
34
|
+
constructor() {
|
|
35
|
+
this.enabled = true;
|
|
36
|
+
if (process.env.EMAIL_NOTIFICATION_ENABLED=="false" || process.env.EMAIL_NOTIFICATION_ENABLED==false) {
|
|
37
|
+
this.enabled = false;
|
|
38
|
+
}
|
|
39
|
+
winston.debug("RequestNotification this.enabled: "+ this.enabled);
|
|
40
|
+
}
|
|
34
41
|
|
|
35
42
|
listen() {
|
|
36
|
-
var that = this;
|
|
43
|
+
var that = this;
|
|
37
44
|
|
|
38
45
|
|
|
46
|
+
|
|
47
|
+
if (this.enabled==true) {
|
|
48
|
+
winston.info("RequestNotification listener started");
|
|
49
|
+
} else {
|
|
50
|
+
return winston.info("RequestNotification listener disabled");
|
|
51
|
+
}
|
|
52
|
+
|
|
39
53
|
|
|
40
54
|
var messageCreateKey = 'message.create';
|
|
41
55
|
if (messageEvent.queueEnabled) {
|
|
@@ -813,7 +827,12 @@ sendAgentEmail(projectid, savedRequest) {
|
|
|
813
827
|
// send email
|
|
814
828
|
try {
|
|
815
829
|
|
|
816
|
-
|
|
830
|
+
// console.log("sendAgentEmail")
|
|
831
|
+
if (savedRequest.preflight === true) { //only for channel email and form preflight is false otherwise request.participants.update is used i think?
|
|
832
|
+
winston.debug("preflight request sendAgentEmail disabled")
|
|
833
|
+
return 0;
|
|
834
|
+
}
|
|
835
|
+
|
|
817
836
|
Project.findOne({_id: projectid, status: 100}).select("+settings").exec( async function(err, project){
|
|
818
837
|
if (err) {
|
|
819
838
|
return winston.error(err);
|
|
@@ -834,6 +853,8 @@ sendAgentEmail(projectid, savedRequest) {
|
|
|
834
853
|
// TODO fare il controllo anche sul dipartimento con modalità assigned o pooled
|
|
835
854
|
if (savedRequest.status==RequestConstants.UNASSIGNED) { //POOLED
|
|
836
855
|
|
|
856
|
+
winston.debug("savedRequest.status==RequestConstants.UNASSIGNED");
|
|
857
|
+
|
|
837
858
|
if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.pooled == false ) {
|
|
838
859
|
return winston.info("RequestNotification email notification for the project with id : " + projectid + " for the pooled conversation is disabled");
|
|
839
860
|
}
|
|
@@ -906,6 +927,8 @@ sendAgentEmail(projectid, savedRequest) {
|
|
|
906
927
|
// TODO fare il controllo anche sul dipartimento con modalità assigned o pooled
|
|
907
928
|
else if (savedRequest.status==RequestConstants.ASSIGNED) { //ASSIGNED
|
|
908
929
|
|
|
930
|
+
winston.debug("savedRequest.status==RequestConstants.ASSIGNED");
|
|
931
|
+
|
|
909
932
|
if (project.settings && project.settings.email && project.settings.email.notification && project.settings.email.notification.conversation && project.settings.email.notification.conversation.assigned == false ) {
|
|
910
933
|
return winston.verbose("RequestNotification email notification for the project with id : " + projectid + " for the assigned conversation is disabled");
|
|
911
934
|
}
|
|
@@ -2,7 +2,6 @@ var express = require('express');
|
|
|
2
2
|
var router = express.Router({mergeParams: true});
|
|
3
3
|
var Event = require("./event");
|
|
4
4
|
var winston = require('../../config/winston');
|
|
5
|
-
const eventEvent = require('./eventEvent');
|
|
6
5
|
var validtoken = require('../../middleware/valid-token');
|
|
7
6
|
const eventService = require('./eventService');
|
|
8
7
|
const { check, validationResult } = require('express-validator');
|
|
@@ -10,6 +9,9 @@ var passport = require('passport');
|
|
|
10
9
|
require('../../middleware/passport')(passport);
|
|
11
10
|
var roleChecker = require('../../middleware/has-role');
|
|
12
11
|
|
|
12
|
+
const messageEvent = require('../../event/messageEvent');
|
|
13
|
+
|
|
14
|
+
|
|
13
15
|
router.post('/', [
|
|
14
16
|
passport.authenticate(['basic', 'jwt'],
|
|
15
17
|
{ session: false }),
|
|
@@ -37,13 +39,41 @@ router.post('/', [
|
|
|
37
39
|
pu = req.projectuser.id
|
|
38
40
|
}
|
|
39
41
|
|
|
42
|
+
console.log("************* emit event"+new Date().toISOString());
|
|
43
|
+
|
|
44
|
+
// // message.senderFullname, message.recipient,
|
|
45
|
+
// // message.recipient_fullname, message.text, message.sender, attributes, message.type, message.metadata, timestamp, message.group
|
|
46
|
+
// var recipient = req.body.attributes.request_id;
|
|
47
|
+
// console.log("recipient",recipient);
|
|
48
|
+
// var sender = req.user.id;
|
|
49
|
+
// console.log("sender",sender);
|
|
50
|
+
|
|
51
|
+
// messageEvent.emit("message.test",
|
|
52
|
+
// {
|
|
53
|
+
// recipient: recipient,
|
|
54
|
+
// recipient_fullname: "pluto",
|
|
55
|
+
// // sender:"bb0d809b-b093-419b-8b48-11a192cc3619",
|
|
56
|
+
// sender: sender,
|
|
57
|
+
// senderFullname: "Tiledesk",
|
|
58
|
+
// text:"welcome",
|
|
59
|
+
// group: {
|
|
60
|
+
// members: {
|
|
61
|
+
// // "bb0d809b-b093-419b-8b48-11a192cc3619": 1,
|
|
62
|
+
// sender: 1
|
|
63
|
+
|
|
64
|
+
// }
|
|
65
|
+
// }
|
|
66
|
+
// }
|
|
67
|
+
// );
|
|
68
|
+
|
|
40
69
|
// emit(name, attributes, id_project, project_user, createdBy, status, user) {
|
|
41
70
|
eventService.emit(req.body.name, req.body.attributes, req.projectid, pu, req.user.id, undefined, req.user).then(function(event) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
71
|
+
|
|
72
|
+
res.json(event);
|
|
73
|
+
}).catch(function(err) {
|
|
74
|
+
winston.error('Error saving the event '+ JSON.stringify(event), err)
|
|
75
|
+
return res.status(500).send({success: false, msg: 'Error saving the event '+ JSON.stringify(event)});
|
|
76
|
+
});
|
|
47
77
|
|
|
48
78
|
// var newEvent = new Event({
|
|
49
79
|
// name: req.body.name,
|
|
@@ -137,7 +167,7 @@ router.get('/', [passport.authenticate(['basic', 'jwt'],
|
|
|
137
167
|
}
|
|
138
168
|
|
|
139
169
|
// collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead
|
|
140
|
-
return Event.
|
|
170
|
+
return Event.countDocuments(query, function (err, totalRowCount) {
|
|
141
171
|
|
|
142
172
|
var objectToReturn = {
|
|
143
173
|
perPage: limit,
|
|
@@ -33,6 +33,12 @@ class PubModulesManager {
|
|
|
33
33
|
|
|
34
34
|
this.tilebot = undefined;
|
|
35
35
|
this.tilebotRoute = undefined;
|
|
36
|
+
|
|
37
|
+
this.queue = undefined;
|
|
38
|
+
|
|
39
|
+
this.jobsManager = undefined;
|
|
40
|
+
|
|
41
|
+
this.routingQueue = undefined;
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
|
|
@@ -88,6 +94,8 @@ class PubModulesManager {
|
|
|
88
94
|
init(config) {
|
|
89
95
|
winston.debug("PubModulesManager init");
|
|
90
96
|
|
|
97
|
+
// this.jobsManager = config.jobsManager;
|
|
98
|
+
|
|
91
99
|
try {
|
|
92
100
|
this.appRules = require('./rules/appRules');
|
|
93
101
|
// this.appRules.start();
|
|
@@ -128,7 +136,6 @@ class PubModulesManager {
|
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
|
|
131
|
-
|
|
132
139
|
try {
|
|
133
140
|
this.emailNotification = require('./emailNotification');
|
|
134
141
|
winston.debug("this.emailNotification:"+ this.emailNotification);
|
|
@@ -203,7 +210,6 @@ class PubModulesManager {
|
|
|
203
210
|
|
|
204
211
|
|
|
205
212
|
|
|
206
|
-
|
|
207
213
|
try {
|
|
208
214
|
this.activityArchiver = require('./activities').activityArchiver;
|
|
209
215
|
// this.activityArchiver.listen();
|
|
@@ -282,6 +288,39 @@ class PubModulesManager {
|
|
|
282
288
|
}
|
|
283
289
|
|
|
284
290
|
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
this.queue = require('./queue');
|
|
295
|
+
winston.debug("this.queue:"+ this.queue);
|
|
296
|
+
|
|
297
|
+
winston.info("PubModulesManager initialized queue.");
|
|
298
|
+
} catch(err) {
|
|
299
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
|
300
|
+
winston.info("PubModulesManager init queue module not found");
|
|
301
|
+
}else {
|
|
302
|
+
winston.info("PubModulesManager error initializing init queue module", err);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
this.routingQueue = require('./routing-queue').listener;
|
|
311
|
+
// this.routingQueue.listen();
|
|
312
|
+
winston.debug("this.routingQueue:"+ this.routingQueue);
|
|
313
|
+
|
|
314
|
+
winston.info("PubModulesManager routing queue initialized");
|
|
315
|
+
} catch(err) {
|
|
316
|
+
if (err.code == 'MODULE_NOT_FOUND') {
|
|
317
|
+
winston.info("PubModulesManager init routing queue module not found");
|
|
318
|
+
}else {
|
|
319
|
+
winston.error("PubModulesManager error initializing init routing queue module", err);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
285
324
|
}
|
|
286
325
|
|
|
287
326
|
start() {
|
|
@@ -316,9 +355,11 @@ class PubModulesManager {
|
|
|
316
355
|
|
|
317
356
|
}
|
|
318
357
|
|
|
358
|
+
// job_here
|
|
319
359
|
if (this.emailNotification) {
|
|
320
360
|
try {
|
|
321
361
|
this.emailNotification.requestNotification.listen();
|
|
362
|
+
// this.jobsManager.listenEmailNotification(this.emailNotification);
|
|
322
363
|
winston.info("PubModulesManager emailNotification started.");
|
|
323
364
|
} catch(err) {
|
|
324
365
|
winston.info("PubModulesManager error starting requestNotification module", err);
|
|
@@ -334,13 +375,24 @@ class PubModulesManager {
|
|
|
334
375
|
}
|
|
335
376
|
}
|
|
336
377
|
|
|
337
|
-
|
|
378
|
+
// job_here
|
|
338
379
|
if (this.activityArchiver) {
|
|
339
380
|
try {
|
|
340
381
|
this.activityArchiver.listen();
|
|
341
|
-
|
|
382
|
+
// this.jobsManager.listenActivityArchiver(this.activityArchiver);
|
|
383
|
+
winston.info("PubModulesManager activityArchiver started");
|
|
384
|
+
} catch(err) {
|
|
385
|
+
winston.info("PubModulesManager error starting activityArchiver module", err);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
if (this.routingQueue) {
|
|
391
|
+
try {
|
|
392
|
+
this.routingQueue.listen();
|
|
393
|
+
winston.info("PubModulesManager routingQueue started");
|
|
342
394
|
} catch(err) {
|
|
343
|
-
winston.info("
|
|
395
|
+
winston.info("PubModulesManager error starting routingQueue module", err);
|
|
344
396
|
}
|
|
345
397
|
}
|
|
346
398
|
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
var amqp = require('amqplib/callback_api');
|
|
2
|
+
var winston = require('../../config/winston');
|
|
3
|
+
const requestEvent = require('../../event/requestEvent');
|
|
4
|
+
const messageEvent = require('../../event/messageEvent');
|
|
5
|
+
const authEvent = require('../../event/authEvent');
|
|
6
|
+
// https://elements.heroku.com/addons/cloudamqp
|
|
7
|
+
// https://gist.github.com/carlhoerberg/006b01ac17a0a94859ba#file-reconnect-js
|
|
8
|
+
// http://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
|
|
9
|
+
|
|
10
|
+
// if the connection is closed or fails to be established at all, we will reconnect
|
|
11
|
+
var amqpConn = null;
|
|
12
|
+
|
|
13
|
+
var url = process.env.CLOUDAMQP_URL + "?heartbeat=60" || "amqp://localhost";
|
|
14
|
+
// attento devi aggiornare configMap di PRE E PROD
|
|
15
|
+
// var url = process.env.AMQP_URL + "?heartbeat=60" || "amqp://localhost?heartbeat=60";
|
|
16
|
+
|
|
17
|
+
var exchange = 'amq.topic';
|
|
18
|
+
|
|
19
|
+
function start() {
|
|
20
|
+
amqp.connect(url, function(err, conn) {
|
|
21
|
+
if (err) {
|
|
22
|
+
winston.error("[AMQP]", err.message);
|
|
23
|
+
return setTimeout(start, 1000);
|
|
24
|
+
}
|
|
25
|
+
conn.on("error", function(err) {
|
|
26
|
+
if (err.message !== "Connection closing") {
|
|
27
|
+
winston.error("[AMQP] conn error", err);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
conn.on("close", function() {
|
|
31
|
+
winston.error("[AMQP] reconnecting");
|
|
32
|
+
return setTimeout(start, 1000);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
winston.info("[AMQP] connected");
|
|
36
|
+
amqpConn = conn;
|
|
37
|
+
|
|
38
|
+
whenConnected();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function whenConnected() {
|
|
43
|
+
startPublisher();
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
let jobWorkerEnabled = false;
|
|
47
|
+
if (process.env.JOB_WORKER_ENABLED=="true" || process.env.JOB_WORKER_ENABLED == true) {
|
|
48
|
+
jobWorkerEnabled = true;
|
|
49
|
+
}
|
|
50
|
+
winston.info("JobsManager jobWorkerEnabled: "+ jobWorkerEnabled);
|
|
51
|
+
|
|
52
|
+
if (jobWorkerEnabled == false) {
|
|
53
|
+
winston.info("Queue Reconnect start worker");
|
|
54
|
+
startWorker();
|
|
55
|
+
} else {
|
|
56
|
+
winston.info("Queue Reconnect without worker because external worker is enabled");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var pubChannel = null;
|
|
62
|
+
var offlinePubQueue = [];
|
|
63
|
+
function startPublisher() {
|
|
64
|
+
amqpConn.createConfirmChannel(function(err, ch) {
|
|
65
|
+
if (closeOnErr(err)) return;
|
|
66
|
+
ch.on("error", function(err) {
|
|
67
|
+
winston.error("[AMQP] channel error", err);
|
|
68
|
+
});
|
|
69
|
+
ch.on("close", function() {
|
|
70
|
+
winston.info("[AMQP] channel closed");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
pubChannel = ch;
|
|
74
|
+
while (true) {
|
|
75
|
+
var m = offlinePubQueue.shift();
|
|
76
|
+
if (!m) break;
|
|
77
|
+
publish(m[0], m[1], m[2]);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// method to publish a message, will queue messages internally if the connection is down and resend later
|
|
83
|
+
function publish(exchange, routingKey, content) {
|
|
84
|
+
try {
|
|
85
|
+
pubChannel.publish(exchange, routingKey, content, { persistent: true },
|
|
86
|
+
function(err, ok) {
|
|
87
|
+
if (err) {
|
|
88
|
+
winston.error("[AMQP] publish", err);
|
|
89
|
+
offlinePubQueue.push([exchange, routingKey, content]);
|
|
90
|
+
pubChannel.connection.close();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
} catch (e) {
|
|
94
|
+
winston.error("[AMQP] publish", e);
|
|
95
|
+
offlinePubQueue.push([exchange, routingKey, content]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// A worker that acks messages only if processed succesfully
|
|
100
|
+
// var channel;
|
|
101
|
+
function startWorker() {
|
|
102
|
+
amqpConn.createChannel(function(err, ch) {
|
|
103
|
+
if (closeOnErr(err)) return;
|
|
104
|
+
ch.on("error", function(err) {
|
|
105
|
+
winston.error("[AMQP] channel error", err);
|
|
106
|
+
});
|
|
107
|
+
ch.on("close", function() {
|
|
108
|
+
winston.info("[AMQP] channel closed");
|
|
109
|
+
});
|
|
110
|
+
ch.prefetch(10);//leggila da env
|
|
111
|
+
ch.assertExchange(exchange, 'topic', {
|
|
112
|
+
durable: true
|
|
113
|
+
});
|
|
114
|
+
ch.assertQueue("jobs", { durable: true }, function(err, _ok) {
|
|
115
|
+
if (closeOnErr(err)) return;
|
|
116
|
+
ch.bindQueue(_ok.queue, exchange, "request_create", {}, function(err3, oka) {
|
|
117
|
+
winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_create");
|
|
118
|
+
winston.info("Data queue", oka)
|
|
119
|
+
});
|
|
120
|
+
ch.bindQueue(_ok.queue, exchange, "request_update", {}, function(err3, oka) {
|
|
121
|
+
winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: request_update");
|
|
122
|
+
winston.info("Data queue", oka)
|
|
123
|
+
});
|
|
124
|
+
ch.bindQueue(_ok.queue, exchange, "message_create", {}, function(err3, oka) {
|
|
125
|
+
winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: message_create");
|
|
126
|
+
winston.info("Data queue", oka)
|
|
127
|
+
});
|
|
128
|
+
ch.bindQueue(_ok.queue, exchange, "project_user_update", {}, function(err3, oka) {
|
|
129
|
+
winston.info("Queue bind: "+_ok.queue+ " err: "+err3+ " key: project_user_update");
|
|
130
|
+
winston.info("Data queue", oka)
|
|
131
|
+
});
|
|
132
|
+
ch.consume("jobs", processMsg, { noAck: false });
|
|
133
|
+
winston.info("Worker is started");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
function processMsg(msg) {
|
|
138
|
+
work(msg, function(ok) {
|
|
139
|
+
try {
|
|
140
|
+
if (ok)
|
|
141
|
+
ch.ack(msg);
|
|
142
|
+
else
|
|
143
|
+
ch.reject(msg, true);
|
|
144
|
+
} catch (e) {
|
|
145
|
+
closeOnErr(e);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function work(msg, cb) {
|
|
153
|
+
const message_string = msg.content.toString();
|
|
154
|
+
const topic = msg.fields.routingKey //.replace(/[.]/g, '/');
|
|
155
|
+
|
|
156
|
+
winston.debug("Got msg topic:" + topic);
|
|
157
|
+
|
|
158
|
+
winston.debug("Got msg:"+ message_string + " topic:" + topic);
|
|
159
|
+
|
|
160
|
+
if (topic === 'request_create') {
|
|
161
|
+
winston.info("here topic:" + topic);
|
|
162
|
+
// requestEvent.emit('request.create.queue', msg.content);
|
|
163
|
+
requestEvent.emit('request.create.queue', JSON.parse(message_string));
|
|
164
|
+
}
|
|
165
|
+
if (topic === 'request_update') {
|
|
166
|
+
winston.info("here topic:" + topic);
|
|
167
|
+
// requestEvent.emit('request.update.queue', msg.content);
|
|
168
|
+
requestEvent.emit('request.update.queue', JSON.parse(message_string));
|
|
169
|
+
}
|
|
170
|
+
if (topic === 'message_create') {
|
|
171
|
+
winston.debug("here topic:" + topic);
|
|
172
|
+
// requestEvent.emit('request.create.queue', msg.content);
|
|
173
|
+
messageEvent.emit('message.create.queue', JSON.parse(message_string));
|
|
174
|
+
}
|
|
175
|
+
if (topic === 'project_user_update') {
|
|
176
|
+
winston.debug("here topic:" + topic);
|
|
177
|
+
// requestEvent.emit('request.create.queue', msg.content);
|
|
178
|
+
authEvent.emit('project_user.update.queue', JSON.parse(message_string));
|
|
179
|
+
}
|
|
180
|
+
cb(true);
|
|
181
|
+
// WebSocket.cb(true);
|
|
182
|
+
// requestEvent.on(msg.KEYYYYYYY+'.ws', msg.content);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
function closeOnErr(err) {
|
|
187
|
+
if (!err) return false;
|
|
188
|
+
winston.error("[AMQP] error", err);
|
|
189
|
+
amqpConn.close();
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// setInterval(function() {
|
|
194
|
+
// var d = new Date();
|
|
195
|
+
// publish(exchange, "request_create", Buffer.from("work work work: "+d));
|
|
196
|
+
// publish(exchange, "request_update", Buffer.from("work2 work work: "+d));
|
|
197
|
+
// }, 1000);
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
function listen() {
|
|
201
|
+
|
|
202
|
+
// http://www.squaremobius.net/amqp.node/channel_api.html
|
|
203
|
+
// https://docs.parseplatform.org/parse-server/guide/#scalability
|
|
204
|
+
|
|
205
|
+
requestEvent.on('request.create', function(request) {
|
|
206
|
+
setImmediate(() => {
|
|
207
|
+
winston.info("reconnect request.create")
|
|
208
|
+
publish(exchange, "request_create", Buffer.from(JSON.stringify(request)));
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
requestEvent.on('request.update', function(request) {
|
|
213
|
+
setImmediate(() => {
|
|
214
|
+
winston.info("reconnect request.update")
|
|
215
|
+
publish(exchange, "request_update", Buffer.from(JSON.stringify(request)));
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
messageEvent.on('message.create', function(message) {
|
|
221
|
+
setImmediate(() => {
|
|
222
|
+
publish(exchange, "message_create", Buffer.from(JSON.stringify(message)));
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
authEvent.on('project_user.update',function(data) {
|
|
227
|
+
setImmediate(() => {
|
|
228
|
+
let user = undefined;
|
|
229
|
+
if (data.req && data.req.user) { //i think is null from chat21webhook
|
|
230
|
+
user = data.req.user;
|
|
231
|
+
}
|
|
232
|
+
var dat = {updatedProject_userPopulated: data.updatedProject_userPopulated, req: {user: user}}; //remove request
|
|
233
|
+
publish(exchange, "project_user_update", Buffer.from(JSON.stringify(dat)));
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (process.env.QUEUE_ENABLED === "true") {
|
|
240
|
+
requestEvent.queueEnabled = true;
|
|
241
|
+
messageEvent.queueEnabled = true;
|
|
242
|
+
authEvent.queueEnabled = true;
|
|
243
|
+
listen();
|
|
244
|
+
start();
|
|
245
|
+
winston.info("Queue enabled. endpint: " + url );
|
|
246
|
+
}
|
|
247
|
+
|