@tiledesk/tiledesk-server 2.1.4-0.3 → 2.1.4-0.31
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/.circleci/config.yml +44 -0
- package/.github/workflows/docker-community-push-latest.yml +22 -0
- package/.github/workflows/{docker-image-push.yml → docker-image-en-tag-push.yml} +1 -1
- package/.github/workflows/docker-image-tag-community-tag-push.yml +21 -0
- package/.github/workflows/{docker-push-latest.yml → docker-push-en-push-latest.yml} +1 -1
- package/CHANGELOG.md +3 -0
- package/Dockerfile +1 -1
- package/Dockerfile-en +1 -1
- package/app.js +9 -1
- package/channels/chat21/chat21Handler.js +48 -5
- package/channels/chat21/package-lock.json +3013 -0
- package/models/faq_kb.js +5 -0
- package/models/message.js +10 -4
- package/models/messageConstants.js +6 -0
- package/package.json +4 -4
- package/pubmodules/emailNotification/requestNotification.js +96 -31
- package/pubmodules/pubModulesManager.js +66 -13
- package/pubmodules/rules/conciergeBot.js +56 -49
- package/routes/auth.js +4 -3
- package/routes/campaigns.js +117 -25
- package/routes/faq_kb.js +9 -2
- package/routes/messagesRoot.js +73 -16
- package/routes/project_user.js +36 -1
- package/routes/request.js +85 -37
- package/routes/requestUtilRoot.js +30 -0
- package/services/departmentService.js +9 -5
- package/services/emailService.js +41 -7
- package/services/faqBotHandler.js +8 -1
- package/services/messageService.js +57 -9
- package/services/modulesManager.js +86 -23
- package/services/requestService.js +8 -4
- package/test/messageRootRoute.js +188 -0
- package/websocket/webSocketServer.js +5 -4
package/routes/campaigns.js
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
var express = require('express');
|
2
2
|
var router = express.Router();
|
3
|
-
var
|
4
|
-
var
|
3
|
+
var Group = require("../models/group");
|
4
|
+
var User = require("../models/user");
|
5
5
|
var winston = require('../config/winston');
|
6
|
-
var leadService = require("../services/leadService");
|
7
6
|
var requestService = require("../services/requestService");
|
8
7
|
var messageService = require("../services/messageService");
|
9
8
|
var MessageConstants = require("../models/messageConstants");
|
@@ -12,13 +11,6 @@ const uuidv4 = require('uuid/v4');
|
|
12
11
|
|
13
12
|
|
14
13
|
|
15
|
-
// curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@f21.it:123456 -d '{"text":"ciao"}' http://localhost:3000/5f897142c9e7ad9602a744c9/campaigns/
|
16
|
-
// curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@f21.it:123456 -d '{"text":"ciao", "leadid":"213213221"}' http://localhost:3000/5f897142c9e7ad9602a744c9/campaigns/
|
17
|
-
|
18
|
-
|
19
|
-
// curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@frontiere21.it:258456 -d '{"text":"ciao", "leadid":"5f8972c82db41c003473cb03"}' https://tiledesk-server-pre.herokuapp.com/5f86c201189063003453a045/campaigns/
|
20
|
-
// curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@frontiere21.it:258456 -d '{"text":"ciao", "leadid":"5f8972c82db41c003473cb03", "request_id":"group-123456789112233"}' https://tiledesk-server-pre.herokuapp.com/5f86c201189063003453a045/campaigns/
|
21
|
-
|
22
14
|
|
23
15
|
// this endpoint supports support-group- or groups. this create a conversation for the sender (agent console)
|
24
16
|
router.post('/', function (req, res) {
|
@@ -27,43 +19,143 @@ router.post('/', function (req, res) {
|
|
27
19
|
|
28
20
|
winston.debug(req.body);
|
29
21
|
winston.debug("req.user", req.user);
|
30
|
-
var request_id = req.body.request_id || 'support-group-'+uuidv4();
|
31
|
-
|
22
|
+
var request_id = req.body.request_id || 'support-group-' + req.projectid + "-" + uuidv4();
|
23
|
+
|
24
|
+
// TODO cicla su segment
|
25
|
+
|
26
|
+
|
32
27
|
// createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes, subject, preflight, channel) {
|
33
|
-
|
34
|
-
|
28
|
+
|
29
|
+
//TODO USE NEW requestService.create()
|
30
|
+
return requestService.createWithIdAndRequester(request_id, req.projectuser._id, req.body.leadid, req.projectid,
|
31
|
+
req.body.text, req.body.departmentid, req.body.sourcePage,
|
35
32
|
req.body.language, req.body.userAgent, null, req.user._id, req.body.attributes, req.body.subject, true, req.body.channel).then(function (savedRequest) {
|
36
33
|
|
37
34
|
winston.info("savedRequest", savedRequest);
|
38
35
|
|
39
36
|
// create(sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata, language, channel_type) {
|
40
37
|
return messageService.create(req.body.sender || req.user._id, req.body.senderFullname || req.user.fullName, savedRequest.request_id, req.body.text,
|
41
|
-
req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata,
|
38
|
+
req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata, req.body.language, MessageConstants.CHANNEL_TYPE.DIRECT, req.body.channel).then(function (savedMessage) {
|
42
39
|
res.json(savedMessage);
|
43
|
-
|
40
|
+
});
|
44
41
|
|
45
|
-
|
42
|
+
});
|
46
43
|
});
|
47
44
|
|
48
|
-
|
49
|
-
router.post('/direct', function (req, res) {
|
45
|
+
router.post('/direct', async function (req, res) {
|
50
46
|
|
51
47
|
let messageStatus = req.body.status || MessageConstants.CHAT_MESSAGE_STATUS.SENDING;
|
52
48
|
|
53
49
|
winston.debug(req.body);
|
54
50
|
winston.debug("req.user", req.user);
|
51
|
+
|
52
|
+
var recipients = [];
|
53
|
+
|
54
|
+
var recipient = req.body.recipient;
|
55
|
+
if (recipient) {
|
56
|
+
recipients.push(recipient);
|
57
|
+
}
|
58
|
+
|
59
|
+
// TODO cicla su segment
|
60
|
+
var segment_id = req.body.segment_id;
|
61
|
+
if (segment_id) {
|
62
|
+
|
63
|
+
}
|
64
|
+
|
65
|
+
var group_id = req.body.group_id;
|
66
|
+
if (group_id) {
|
67
|
+
var group = await Group.findOne({ _id: group_id, id_project: req.projectid }).exec();
|
68
|
+
winston.info("group", group);
|
69
|
+
|
70
|
+
var recipients = group.members;
|
71
|
+
// winston.info("members", members);
|
72
|
+
|
73
|
+
|
74
|
+
}
|
75
|
+
|
76
|
+
winston.info("recipients", recipients);
|
77
|
+
winston.info("recipients.length: " + recipients.length);
|
78
|
+
|
79
|
+
let message = {
|
80
|
+
sender: req.body.sender || req.user._id,
|
81
|
+
senderFullname: req.body.senderFullname || req.user.fullName,
|
82
|
+
recipient: req.body.recipient,
|
83
|
+
recipientFullname: req.body.recipientFullname,
|
84
|
+
text: req.body.text,
|
85
|
+
id_project: req.projectid, // rendilo opzionale?
|
86
|
+
createdBy: req.user._id,
|
87
|
+
status: messageStatus,
|
88
|
+
attributes: req.body.attributes,
|
89
|
+
type: req.body.type,
|
90
|
+
metadata: req.body.metadata,
|
91
|
+
language: req.body.language,
|
92
|
+
channel_type: MessageConstants.CHANNEL_TYPE.DIRECT,
|
93
|
+
channel: req.body.channel
|
94
|
+
};
|
55
95
|
|
56
96
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
97
|
+
if (recipients.length == 0) {
|
98
|
+
// return res XXX
|
99
|
+
}
|
100
|
+
|
101
|
+
if (recipients.length == 1) {
|
102
|
+
return messageService.save(message).then(function(savedMessage){
|
103
|
+
if (req.body.returnobject) {
|
104
|
+
return res.json(savedMessage);
|
105
|
+
} else {
|
106
|
+
return res.json({ success: true });
|
107
|
+
}
|
108
|
+
|
109
|
+
});
|
110
|
+
}
|
111
|
+
|
112
|
+
|
113
|
+
var promises = [];
|
114
|
+
for (const recipient of recipients) {
|
115
|
+
// recipients.forEach( async (recipient) => {
|
116
|
+
|
117
|
+
// create(sender, senderFullname, recipient, text, id_project, createdBy, status, attributes, type, metadata, language, channel_type) {
|
118
|
+
// var promise = messageService.create(req.body.sender || req.user._id, req.body.senderFullname || req.user.fullName, recipient, req.body.text,
|
119
|
+
// req.projectid, req.user._id, messageStatus, req.body.attributes, req.body.type, req.body.metadata, req.body.language, MessageConstants.CHANNEL_TYPE.DIRECT, req.body.channel);
|
120
|
+
|
121
|
+
winston.info("recipient: " + recipient);
|
122
|
+
|
123
|
+
message.recipient = recipient;
|
124
|
+
|
125
|
+
var user = await User.findOne({_id:recipient}).exec();
|
126
|
+
winston.info("user", user);
|
127
|
+
|
128
|
+
message.recipientFullname = user.fullName;
|
129
|
+
|
130
|
+
var promise = messageService.save(message);
|
131
|
+
promises.push(promise);
|
132
|
+
// .then(function(savedMessage){
|
133
|
+
// result.push(savedMessage);
|
134
|
+
// res.json(savedMessage);
|
135
|
+
}
|
136
|
+
//);
|
137
|
+
|
138
|
+
Promise.all(promises).then(function (data) {
|
139
|
+
if (req.body.returnobject) {
|
140
|
+
return res.json(data);
|
141
|
+
}
|
142
|
+
});
|
143
|
+
|
144
|
+
if (!req.body.returnobject) {
|
145
|
+
return res.json({ success: true });
|
146
|
+
}
|
147
|
+
|
148
|
+
|
149
|
+
|
62
150
|
|
63
|
-
|
64
151
|
});
|
65
152
|
|
66
153
|
|
67
154
|
|
68
155
|
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
|
69
161
|
module.exports = router;
|
package/routes/faq_kb.js
CHANGED
@@ -58,8 +58,15 @@ router.post('/askbot', function (req, res) {
|
|
58
58
|
}else {
|
59
59
|
query = { "id_project": req.projectid, "id_faq_kb": req.body.id_faq_kb};
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
var search_obj = {"$search": req.body.question};
|
62
|
+
|
63
|
+
if (faq_kb.language) {
|
64
|
+
search_obj["$language"] = faq_kb.language;
|
65
|
+
}
|
66
|
+
query.$text = search_obj;
|
67
|
+
winston.info("fulltext search query", query);
|
68
|
+
|
69
|
+
|
63
70
|
winston.debug('internal ft query: '+ query);
|
64
71
|
|
65
72
|
Faq.find(query, {score: { $meta: "textScore" } })
|
package/routes/messagesRoot.js
CHANGED
@@ -1,41 +1,98 @@
|
|
1
1
|
var express = require('express');
|
2
2
|
|
3
3
|
// https://stackoverflow.com/questions/28977253/express-router-undefined-params-with-router-use-when-split-across-files
|
4
|
-
var router = express.Router();
|
4
|
+
var router = express.Router({mergeParams: true});
|
5
5
|
|
6
6
|
var MessageConstants = require("../models/messageConstants");
|
7
|
+
var Message = require("../models/message");
|
7
8
|
var messageService = require("../services/messageService");
|
8
9
|
var winston = require('../config/winston');
|
10
|
+
var fastCsv = require("fast-csv");
|
11
|
+
var roleChecker = require('../middleware/has-role');
|
12
|
+
const { check, validationResult } = require('express-validator');
|
9
13
|
|
10
|
-
// curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@frontiere21.it:258456td -d '{"senderFullname":"Bot","recipient":"USERID", "text":"ciao"}' https://tiledesk-server-pre.herokuapp.com/5f86c201189063003453a045/messages/
|
11
|
-
// curl -v -X POST -H 'Content-Type:application/json' -u andrea.leo@f21.it:123456 -d '{"senderFullname":"Bot","recipient":"USERID", "text":"ciao"}' http://localhost:3000/609e3fd8e049553972114b88/messages/
|
12
14
|
|
13
15
|
router.post('/',
|
16
|
+
[
|
17
|
+
check('recipient').notEmpty(),
|
18
|
+
check('recipientFullname').notEmpty(),
|
19
|
+
check('text').custom((value, { req }) => {
|
20
|
+
winston.debug('validation: '+ value + ' req.body.type ' + req.body.type);
|
21
|
+
if (!value && (!req.body.type || req.body.type === "text") ) {
|
22
|
+
winston.debug('validation1 ');
|
23
|
+
return Promise.reject('Text field is required for messages with type "text"');
|
24
|
+
}
|
25
|
+
winston.debug('validation2 ');
|
26
|
+
return Promise.resolve('validation ok');
|
27
|
+
})
|
28
|
+
],
|
14
29
|
async (req, res) => {
|
15
30
|
|
16
31
|
winston.debug('req.body post message', req.body);
|
17
32
|
winston.debug('req.params: ', req.params);
|
18
33
|
winston.debug('req.params.request_id: ' + req.params.request_id);
|
19
34
|
|
20
|
-
let messageStatus = req.body.status || MessageConstants.CHAT_MESSAGE_STATUS.SENDING;
|
21
35
|
|
22
|
-
|
23
|
-
|
36
|
+
const errors = validationResult(req);
|
37
|
+
if (!errors.isEmpty()) {
|
38
|
+
winston.error("Signup validation error", errors);
|
39
|
+
return res.status(422).json({ errors: errors.array() });
|
40
|
+
}
|
41
|
+
let message = {
|
42
|
+
sender: req.body.sender || req.user._id,
|
43
|
+
senderFullname: req.body.senderFullname || req.user.fullName,
|
44
|
+
recipient: req.body.recipient,
|
45
|
+
recipientFullname: req.body.recipientFullname,
|
46
|
+
text: req.body.text,
|
47
|
+
id_project: req.projectid, // rendilo opzionale?
|
48
|
+
createdBy: req.user._id,
|
49
|
+
status: MessageConstants.CHAT_MESSAGE_STATUS.SENDING,
|
50
|
+
attributes: req.body.attributes,
|
51
|
+
type: req.body.type,
|
52
|
+
metadata: req.body.metadata,
|
53
|
+
language: req.body.language,
|
54
|
+
channel_type: req.body.channel_type || MessageConstants.CHANNEL_TYPE.DIRECT,
|
55
|
+
channel: req.body.channel
|
56
|
+
};
|
57
|
+
return messageService.save(message).then(function(savedMessage){
|
24
58
|
res.json(savedMessage);
|
25
|
-
})
|
59
|
+
}).catch(function(err){
|
60
|
+
winston.error('Error saving message.', err);
|
61
|
+
return res.status(500).send({ success: false, msg: 'Error saving message.', err: err });
|
62
|
+
})
|
26
63
|
|
27
64
|
});
|
28
65
|
|
29
66
|
|
30
|
-
//TODO reenable it with role owner
|
31
|
-
/*
|
32
|
-
router.get('/csv', function(req, res) {
|
33
67
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
68
|
+
router.get('/csv', roleChecker.hasRoleOrTypes('owner'), function(req, res) {
|
69
|
+
|
70
|
+
|
71
|
+
const cursor = Message.find({id_project: req.projectid}).select("-channel -attributes -metadata");
|
72
|
+
|
73
|
+
const transformer = (doc)=> {
|
74
|
+
return {
|
75
|
+
Id: doc._id,
|
76
|
+
Name: doc.fullname,
|
77
|
+
Email: doc.email,
|
78
|
+
Type: doc.registration_type,
|
79
|
+
RegisterOn: doc.registered_on
|
80
|
+
};
|
81
|
+
}
|
82
|
+
|
83
|
+
const filename = 'export.csv';
|
84
|
+
|
85
|
+
res.setHeader('Content-disposition', `attachment; filename=${filename}`);
|
86
|
+
res.writeHead(200, { 'Content-Type': 'text/csv' });
|
87
|
+
|
88
|
+
res.flushHeaders();
|
89
|
+
|
90
|
+
console.log("fastCsv",fastCsv)
|
91
|
+
var csvStream = fastCsv.format({headers: true})//.transform(transformer)
|
92
|
+
// var csvStream = fastCsv.createWriteStream({headers: true}).transform(transformer)
|
93
|
+
cursor.stream().pipe(csvStream).pipe(res);
|
94
|
+
|
38
95
|
});
|
39
|
-
*/
|
40
96
|
|
41
|
-
|
97
|
+
|
98
|
+
module.exports = router;
|
package/routes/project_user.js
CHANGED
@@ -112,7 +112,7 @@ router.post('/invite', [passport.authenticate(['basic', 'jwt'], { session: false
|
|
112
112
|
// if ('5ae6c62c61c7d54bf119ac73' == '5ae6c62c61c7d54bf119ac73') {
|
113
113
|
|
114
114
|
winston.debug('»»»» THE PRJCT-USER ID ', p_user.id_user, ' MATCHES THE FOUND USER-ID', user._id)
|
115
|
-
winston.
|
115
|
+
winston.warn("User " + projectUserId+ " is already a member of the project: " + req.projectid)
|
116
116
|
|
117
117
|
// cannot use continue or break inside a JavaScript Array.prototype.forEach loop. However, there are other options:
|
118
118
|
throw new Error('User is already a member'); // break
|
@@ -359,6 +359,37 @@ router.get('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
359
359
|
});
|
360
360
|
|
361
361
|
|
362
|
+
router.get('/users/search', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], async (req, res, next) => {
|
363
|
+
winston.info("--> users search ");
|
364
|
+
|
365
|
+
if (!req.project) {
|
366
|
+
return res.status(404).send({ success: false, msg: 'Project not found.' });
|
367
|
+
}
|
368
|
+
|
369
|
+
|
370
|
+
let query = {email: req.query.email};
|
371
|
+
|
372
|
+
winston.info('query: ', query);
|
373
|
+
|
374
|
+
let user = await User.findOne(query).exec();
|
375
|
+
winston.info('user: ', user);
|
376
|
+
|
377
|
+
if (!user) {
|
378
|
+
return res.status(404).send({ success: false, msg: 'Object not found.' });
|
379
|
+
}
|
380
|
+
|
381
|
+
|
382
|
+
let project_user = await Project_user.findOne({id_user: user._id, id_project: req.projectid}).exec();
|
383
|
+
winston.info('project_user: ', project_user);
|
384
|
+
|
385
|
+
if (!project_user) {
|
386
|
+
return res.status(403).json({msg: "Unauthorized. This is not a your teammate." });
|
387
|
+
}
|
388
|
+
|
389
|
+
|
390
|
+
return res.json({_id: user._id});
|
391
|
+
|
392
|
+
});
|
362
393
|
|
363
394
|
/**
|
364
395
|
* GET PROJECT-USER BY PROJECT ID AND CURRENT USER ID
|
@@ -368,6 +399,10 @@ router.get('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
368
399
|
router.get('/users/:user_id', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['subscription'])], function (req, res, next) {
|
369
400
|
winston.debug("--> users USER ID ", req.params.user_id);
|
370
401
|
|
402
|
+
if (!req.project) {
|
403
|
+
return res.status(404).send({ success: false, msg: 'Project not found.' });
|
404
|
+
}
|
405
|
+
|
371
406
|
var isObjectId = mongoose.Types.ObjectId.isValid(req.params.user_id);
|
372
407
|
winston.debug("isObjectId:"+ isObjectId);
|
373
408
|
|
package/routes/request.js
CHANGED
@@ -541,6 +541,37 @@ router.delete('/:requestid', function (req, res) {
|
|
541
541
|
|
542
542
|
|
543
543
|
|
544
|
+
|
545
|
+
router.delete('/id/:id', function (req, res) {
|
546
|
+
|
547
|
+
var projectuser = req.projectuser;
|
548
|
+
|
549
|
+
|
550
|
+
if (projectuser.role != "owner" ) {
|
551
|
+
return res.status(403).send({ success: false, msg: 'Unauthorized.' });
|
552
|
+
}
|
553
|
+
|
554
|
+
Request.remove({ _id: req.params.id }, function (err, request) {
|
555
|
+
if (err) {
|
556
|
+
winston.error('--- > ERROR ', err);
|
557
|
+
return res.status(500).send({ success: false, msg: 'Error deleting object.' });
|
558
|
+
}
|
559
|
+
|
560
|
+
if (!request) {
|
561
|
+
return res.status(404).send({ success: false, msg: 'Object not found.' });
|
562
|
+
}
|
563
|
+
|
564
|
+
winston.verbose('Request deleted with id: '+ req.params.id );
|
565
|
+
|
566
|
+
requestEvent.emit('request.delete', request);
|
567
|
+
|
568
|
+
res.json(request);
|
569
|
+
|
570
|
+
});
|
571
|
+
});
|
572
|
+
|
573
|
+
|
574
|
+
|
544
575
|
router.get('/', function (req, res, next) {
|
545
576
|
|
546
577
|
winston.debug("req projectid", req.projectid);
|
@@ -957,51 +988,68 @@ router.get('/csv', function (req, res, next) {
|
|
957
988
|
}
|
958
989
|
|
959
990
|
|
960
|
-
|
961
|
-
|
962
|
-
var channel_name = "";
|
963
|
-
if (element.channel && element.channel.name) {
|
964
|
-
channel_name = element.channel.name;
|
965
|
-
}
|
966
|
-
delete element.channel;
|
967
|
-
element.channel_name = channel_name;
|
968
|
-
|
969
|
-
var department_name = "";
|
970
|
-
if (element.department && element.department.name) {
|
971
|
-
department_name = element.department.name;
|
972
|
-
}
|
973
|
-
delete element.department;
|
974
|
-
element.department_name = department_name;
|
975
|
-
|
976
|
-
var lead_fullname = "";
|
977
|
-
if (element.lead && element.lead.fullname) {
|
978
|
-
lead_fullname = element.lead.fullname
|
979
|
-
}
|
980
|
-
element.lead_fullname = lead_fullname;
|
981
|
-
|
982
|
-
|
983
|
-
var lead_email = "";
|
984
|
-
if (element.lead && element.lead.email) {
|
985
|
-
lead_email = element.lead.email
|
986
|
-
}
|
987
|
-
|
988
|
-
element.lead_email = lead_email;
|
991
|
+
requests.forEach(function(element) {
|
989
992
|
|
990
|
-
|
993
|
+
var channel_name = "";
|
994
|
+
if (element.channel && element.channel.name) {
|
995
|
+
channel_name = element.channel.name;
|
996
|
+
}
|
997
|
+
delete element.channel;
|
998
|
+
element.channel_name = channel_name;
|
991
999
|
|
992
|
-
|
1000
|
+
var department_name = "";
|
1001
|
+
if (element.department && element.department.name) {
|
1002
|
+
department_name = element.department.name;
|
1003
|
+
}
|
1004
|
+
delete element.department;
|
1005
|
+
element.department_name = department_name;
|
993
1006
|
|
994
|
-
|
1007
|
+
var lead_fullname = "";
|
1008
|
+
if (element.lead && element.lead.fullname) {
|
1009
|
+
lead_fullname = element.lead.fullname
|
1010
|
+
}
|
1011
|
+
element.lead_fullname = lead_fullname;
|
995
1012
|
|
996
|
-
delete element.tags;
|
997
1013
|
|
998
|
-
|
1014
|
+
var lead_email = "";
|
1015
|
+
if (element.lead && element.lead.email) {
|
1016
|
+
lead_email = element.lead.email
|
1017
|
+
}
|
1018
|
+
|
1019
|
+
element.lead_email = lead_email;
|
999
1020
|
|
1000
|
-
|
1021
|
+
var tags = [];
|
1022
|
+
var tagsString = "";
|
1023
|
+
if (element.tags && element.tags.length>0) {
|
1001
1024
|
|
1025
|
+
element.tags.forEach(function(tag) {
|
1026
|
+
// tags = tags + tag.tag + ", ";
|
1027
|
+
tags.push(tag.tag);
|
1028
|
+
});
|
1029
|
+
}
|
1030
|
+
tagsString = tags.join(", ")
|
1002
1031
|
|
1003
|
-
|
1004
|
-
|
1032
|
+
winston.debug('tagsString ' +tagsString)
|
1033
|
+
|
1034
|
+
element.tags = tagsString;
|
1035
|
+
|
1036
|
+
delete element.lead;
|
1037
|
+
|
1038
|
+
delete element.attributes;
|
1039
|
+
|
1040
|
+
delete element.notes;
|
1041
|
+
|
1042
|
+
// delete element.tags;
|
1043
|
+
|
1044
|
+
delete element.channelOutbound;
|
1045
|
+
|
1046
|
+
delete element.location;
|
1047
|
+
|
1048
|
+
delete element.snapshot;
|
1049
|
+
|
1050
|
+
|
1051
|
+
// TODO print also lead. use a library to flattize
|
1052
|
+
});
|
1005
1053
|
|
1006
1054
|
winston.debug('REQUEST ROUTE - REQUEST AS CSV', requests);
|
1007
1055
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
var express = require('express');
|
2
|
+
|
3
|
+
var router = express.Router();
|
4
|
+
|
5
|
+
var Request = require("../models/request");
|
6
|
+
var winston = require('../config/winston');
|
7
|
+
|
8
|
+
// https://tiledesk-server-pre.herokuapp.com/requests_util/lookup/id_project/support-group-60ffe291f725db00347661ef-b4cb6875785c4a23b27244fe498eecf4
|
9
|
+
router.get('/lookup/id_project/:request_id', function(req, res) {
|
10
|
+
winston.info("lookup: "+req.params.request_id);
|
11
|
+
|
12
|
+
return Request.findOne({request_id: req.params.request_id}).select("id_project").exec(function(err, request) {
|
13
|
+
if (err) {
|
14
|
+
return res.status(500).send({success: false, msg: 'Error creating message', err:err });
|
15
|
+
}
|
16
|
+
if (!request) {
|
17
|
+
return res.status(404).send({success: false, msg: "Request with " + req.params.request_id + " not found" });
|
18
|
+
}
|
19
|
+
winston.info("request",request);
|
20
|
+
res.json({id_project: request.id_project});
|
21
|
+
});
|
22
|
+
|
23
|
+
});
|
24
|
+
|
25
|
+
|
26
|
+
module.exports = router;
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
@@ -77,11 +77,11 @@ roundRobin(operatorSelectedEvent) {
|
|
77
77
|
|
78
78
|
// db.getCollection('requests').find({id_project: "5c12662488379d0015753c49", participants: { $exists: true, $ne: [] }}).sort({_id:-1}).limit(1)
|
79
79
|
|
80
|
-
// https://stackoverflow.com/questions/14789684/find-mongodb-records-where-array-field-is-not-empty
|
80
|
+
// https://stackoverflow.com/questions/14789684/find-mongodb-records-where-array-field-is-not-empty
|
81
81
|
let query = {id_project: operatorSelectedEvent.id_project,
|
82
82
|
hasBot:false, preflight:false, status: { $gt: 100 },
|
83
83
|
participants: { $exists: true, $ne: [] }};
|
84
|
-
|
84
|
+
|
85
85
|
winston.debug('query', query);
|
86
86
|
|
87
87
|
// let lastRequests = await
|
@@ -96,6 +96,7 @@ roundRobin(operatorSelectedEvent) {
|
|
96
96
|
winston.debug('lastRequests',lastRequests);
|
97
97
|
|
98
98
|
if (lastRequests.length==0) {
|
99
|
+
winston.debug('roundRobin lastRequest not found. fall back to random info',operatorSelectedEvent);
|
99
100
|
winston.verbose('roundRobin lastRequest not found. fall back to random');
|
100
101
|
//first request use default random algoritm
|
101
102
|
// return 0;
|
@@ -123,7 +124,7 @@ roundRobin(operatorSelectedEvent) {
|
|
123
124
|
if (operatorSelectedEvent.available_agents && operatorSelectedEvent.available_agents.length==0) {
|
124
125
|
winston.debug('operatorSelectedEvent.available_agents empty ', operatorSelectedEvent.available_agents);
|
125
126
|
return resolve(operatorSelectedEvent);
|
126
|
-
}
|
127
|
+
}
|
127
128
|
|
128
129
|
// https://stackoverflow.com/questions/15997879/get-the-index-of-the-object-inside-an-array-matching-a-condition
|
129
130
|
let lastOperatorIndex = operatorSelectedEvent.available_agents.findIndex(projectUser => projectUser.id_user.toString() === lastOperatorId);
|
@@ -135,6 +136,9 @@ roundRobin(operatorSelectedEvent) {
|
|
135
136
|
|
136
137
|
winston.debug('lastOperatorIndex: ' + lastOperatorIndex);
|
137
138
|
|
139
|
+
winston.debug('operatorSelectedEvent.available_agents: ', operatorSelectedEvent.available_agents);
|
140
|
+
|
141
|
+
|
138
142
|
let nextOperator = that.nextOperator(operatorSelectedEvent.available_agents, lastOperatorIndex);
|
139
143
|
|
140
144
|
|
@@ -210,8 +214,8 @@ getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
|
|
210
214
|
}
|
211
215
|
// console.log("department", department);
|
212
216
|
if (!department) {
|
213
|
-
winston.error("Department not found for query ", query);
|
214
|
-
return reject({ success: false, msg: 'Department not found
|
217
|
+
winston.error("Department not found for projectid: "+ projectid +" for query: ", query, context);
|
218
|
+
return reject({ success: false, msg: 'Department not found for projectid: '+ projectid +' for query: ' + JSON.stringify(query) });
|
215
219
|
}
|
216
220
|
// console.log('OPERATORS - »»» DETECTED ROUTING ', department.routing)
|
217
221
|
// console.log('OPERATORS - »»» DEPARTMENT - ID BOT ', department.id_bot)
|