@tiledesk/tiledesk-server 2.10.32 → 2.10.34
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/CHANGELOG.md +16 -0
- package/app.js +1 -1
- package/jobs.js +3 -0
- package/jobsManager.js +8 -0
- package/models/analytics.js +29 -0
- package/package.json +5 -4
- package/pubmodules/analytics/analytics.js +84 -0
- package/pubmodules/sms/listener.js +0 -1
- package/pubmodules/voice-twilio/listener.js +0 -1
- package/routes/kb.js +17 -38
- package/routes/lead.js +71 -0
- package/routes/request.js +146 -1
- package/services/Scheduler.js +12 -0
- package/services/requestService.js +3 -3
- package/test/leadRoute.js +156 -0
- package/test/requestRoute.js +366 -146
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,22 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.10.34
|
9
|
+
- added add tags endpoint
|
10
|
+
- added tags analytics endpoint
|
11
|
+
- added tiledesk-multi-worker 0.1.5
|
12
|
+
- updated tybot-connector to 0.2.134
|
13
|
+
- updated vxml-connector to 0.1.67
|
14
|
+
- updated voice-twilio-connector to 0.1.12
|
15
|
+
- updated sms-connector to 0.1.11
|
16
|
+
- fix kb source with citations issue (from dashboard)
|
17
|
+
|
18
|
+
# 2.10.33
|
19
|
+
- Bug fix: conflicts between faqs and urls with same source of different namespaces
|
20
|
+
|
21
|
+
# 2.10.32
|
22
|
+
- Externalized PINECONE_TYPE variable for kb engine
|
23
|
+
|
8
24
|
# 2.10.31
|
9
25
|
- updated twilio-voice-connector to 0.1.11
|
10
26
|
|
package/app.js
CHANGED
@@ -553,7 +553,7 @@ app.use('/:projectid/departments', department);
|
|
553
553
|
channelManager.useUnderProjects(app);
|
554
554
|
|
555
555
|
app.use('/:projectid/groups', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], group);
|
556
|
-
app.use('/:projectid/tags', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.
|
556
|
+
app.use('/:projectid/tags', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRoleOrTypes('agent', ['bot','subscription'])], tag);
|
557
557
|
app.use('/:projectid/subscriptions', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], resthook);
|
558
558
|
|
559
559
|
//deprecated
|
package/jobs.js
CHANGED
@@ -112,6 +112,9 @@ async function main()
|
|
112
112
|
let scheduler = require('./pubmodules/scheduler');
|
113
113
|
jobsManager.listenScheduler(scheduler);
|
114
114
|
|
115
|
+
let multiWorkerQueue = require('@tiledesk/tiledesk-multi-worker');
|
116
|
+
jobsManager.listenMultiWorker(multiWorkerQueue);
|
117
|
+
|
115
118
|
|
116
119
|
winston.info("Jobs started");
|
117
120
|
|
package/jobsManager.js
CHANGED
@@ -87,6 +87,14 @@ class JobsManager {
|
|
87
87
|
// this.whatsappQueue.listen(); // oppure codice
|
88
88
|
}
|
89
89
|
|
90
|
+
listenMultiWorker(multiWorkerQueue) {
|
91
|
+
console.log("JobsManager multiWorkerQueue started");
|
92
|
+
console.log("multiWorkerQueue is: ", multiWorkerQueue)
|
93
|
+
if (this.jobWorkerEnabled == true) {
|
94
|
+
return winston.info("JobsManager jobWorkerEnabled is enabled. Skipping listener for MultiWorker Queue");
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
90
98
|
// listenTrainingQueue(trainingQueue) {
|
91
99
|
// console.log("JobsManager listenTrainingQueue started");
|
92
100
|
// console.log("trainingQueue is: ", trainingQueue)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
var mongoose = require('mongoose');
|
2
|
+
var Schema = mongoose.Schema;
|
3
|
+
|
4
|
+
var AnalyticsSchema = new Schema({
|
5
|
+
id_project: {
|
6
|
+
type: String,
|
7
|
+
required: true,
|
8
|
+
},
|
9
|
+
type: {
|
10
|
+
type: String,
|
11
|
+
required: true
|
12
|
+
},
|
13
|
+
date: {
|
14
|
+
type: String,
|
15
|
+
required: true
|
16
|
+
//default: () => new Date().setHours(0, 0, 0, 0)
|
17
|
+
},
|
18
|
+
keys: {
|
19
|
+
type: Object,
|
20
|
+
required: true
|
21
|
+
}
|
22
|
+
}, {
|
23
|
+
timestamps: true
|
24
|
+
})
|
25
|
+
|
26
|
+
|
27
|
+
const Analytics = mongoose.model('Analytics', AnalyticsSchema)
|
28
|
+
module.exports = Analytics
|
29
|
+
|
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.10.
|
4
|
+
"version": "2.10.34",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -51,9 +51,10 @@
|
|
51
51
|
"@tiledesk/tiledesk-tybot-connector": "^0.2.134",
|
52
52
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.75",
|
53
53
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.10",
|
54
|
-
"@tiledesk/tiledesk-sms-connector": "^0.1.
|
55
|
-
"@tiledesk/tiledesk-vxml-connector": "^0.1.
|
56
|
-
"@tiledesk/tiledesk-voice-twilio-connector": "^0.1.
|
54
|
+
"@tiledesk/tiledesk-sms-connector": "^0.1.11",
|
55
|
+
"@tiledesk/tiledesk-vxml-connector": "^0.1.67",
|
56
|
+
"@tiledesk/tiledesk-voice-twilio-connector": "^0.1.12",
|
57
|
+
"@tiledesk/tiledesk-multi-worker": "^0.1.5",
|
57
58
|
"amqplib": "^0.5.5",
|
58
59
|
"app-root-path": "^3.0.0",
|
59
60
|
"bcrypt-nodejs": "0.0.3",
|
@@ -9,6 +9,7 @@ var RoleConstants = require("../../models/roleConstants");
|
|
9
9
|
|
10
10
|
var mongoose = require('mongoose');
|
11
11
|
var winston = require('../../config/winston');
|
12
|
+
var Analytics = require('../../models/analytics');
|
12
13
|
var ObjectId = require('mongodb').ObjectId;
|
13
14
|
|
14
15
|
|
@@ -1742,5 +1743,88 @@ router.get('/messages/count', function(req, res) {
|
|
1742
1743
|
|
1743
1744
|
});
|
1744
1745
|
|
1746
|
+
router.get('/tags/:type', async (req, res) => {
|
1747
|
+
|
1748
|
+
let id_project = req.projectid;
|
1749
|
+
let type = req.params.type;
|
1750
|
+
let startDate = req.query.start_date;
|
1751
|
+
let endDate = req.query.end_date;
|
1752
|
+
|
1753
|
+
if (!type) {
|
1754
|
+
return res.status(400).send({ success: false, error: "Missing parameter 'type'" });
|
1755
|
+
}
|
1756
|
+
|
1757
|
+
if (!startDate) {
|
1758
|
+
startDate = new Date();
|
1759
|
+
startDate.setDate(startDate.getDate() - 6);
|
1760
|
+
} else {
|
1761
|
+
startDate = new Date(startDate)
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
if (!endDate) {
|
1765
|
+
endDate = new Date();
|
1766
|
+
} else {
|
1767
|
+
endDate = new Date(endDate);
|
1768
|
+
}
|
1769
|
+
|
1770
|
+
startDate = startDate.setHours(0, 0, 0, 0);
|
1771
|
+
endDate = endDate.setHours(0, 0, 0, 0);
|
1772
|
+
|
1773
|
+
if (startDate > endDate) {
|
1774
|
+
return res.status(400).send({ success: false, error: "Invalid dates: start_date can't be greater of end_date"})
|
1775
|
+
}
|
1776
|
+
|
1777
|
+
let query = {
|
1778
|
+
id_project: id_project,
|
1779
|
+
type: type,
|
1780
|
+
date: { $gte: startDate, $lte: endDate }
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
console.log("analytics tags query: ", query)
|
1784
|
+
|
1785
|
+
let result = await Analytics.find(query).catch((err) => {
|
1786
|
+
winston.error("Error finding Analytics: ", err);
|
1787
|
+
return res.status(500).send({ success: false, error: "Unable to find analytics" })
|
1788
|
+
})
|
1789
|
+
|
1790
|
+
let parsedDates = result
|
1791
|
+
.sort((a, b) => parseInt(a.date) - parseInt(b.date))
|
1792
|
+
.map(r => {
|
1793
|
+
let date = new Date(parseInt(r.date));
|
1794
|
+
let day = String(date.getDate()).padStart(2, '0'); // Day with two digit
|
1795
|
+
let month = String(date.getMonth() + 1).padStart(2, '0'); // Month with two digit
|
1796
|
+
let year = date.getFullYear(); // Complete year
|
1797
|
+
|
1798
|
+
return {
|
1799
|
+
formatted: `${day}/${month}/${year}`,
|
1800
|
+
original: r
|
1801
|
+
};
|
1802
|
+
});
|
1803
|
+
|
1804
|
+
// Extract and sort all unique dates
|
1805
|
+
let dates = [...new Set(parsedDates.map(d => d.formatted))].sort();
|
1806
|
+
|
1807
|
+
// Extract all unique keys
|
1808
|
+
let allKeys = [...new Set(result.flatMap(r => Object.keys(r.keys)))];
|
1809
|
+
|
1810
|
+
// Pre-build a map to optimize data access
|
1811
|
+
let dataMap = parsedDates.reduce((acc, { formatted, original }) => {
|
1812
|
+
acc[formatted] = original.keys;
|
1813
|
+
return acc;
|
1814
|
+
}, {});
|
1815
|
+
|
1816
|
+
// Build the data series
|
1817
|
+
let series = allKeys.map(key => {
|
1818
|
+
let values = dates.map(date => dataMap[date]?.[key] || 0); // Default a 0 se il tag non è presente
|
1819
|
+
return { name: key, values };
|
1820
|
+
});
|
1821
|
+
|
1822
|
+
// Assembly final result
|
1823
|
+
let data = { dates, series };
|
1824
|
+
console.log(data);
|
1825
|
+
|
1826
|
+
return res.status(200).send(data);
|
1827
|
+
|
1828
|
+
})
|
1745
1829
|
|
1746
1830
|
module.exports = router;
|
package/routes/kb.js
CHANGED
@@ -298,41 +298,20 @@ router.post('/qa', async (req, res) => {
|
|
298
298
|
winston.debug("qa resp: ", resp.data);
|
299
299
|
let answer = resp.data;
|
300
300
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
KB.findById(id, (err, resource) => {
|
308
|
-
|
309
|
-
if (publicKey === true) {
|
310
|
-
let multiplier = MODELS_MULTIPLIER[data.model];
|
311
|
-
if (!multiplier) {
|
312
|
-
multiplier = 1;
|
313
|
-
winston.info("No multiplier found for AI model")
|
314
|
-
}
|
315
|
-
obj.multiplier = multiplier;
|
316
|
-
obj.tokens = answer.prompt_token_size;
|
317
|
-
|
318
|
-
let incremented_key = quoteManager.incrementTokenCount(req.project, obj);
|
319
|
-
winston.verbose("incremented_key: ", incremented_key);
|
320
|
-
}
|
321
|
-
|
322
|
-
if (err) {
|
323
|
-
winston.error("Unable to find resource with id " + id + " in namespace " + answer.namespace + ". The standard answer is returned.")
|
324
|
-
return res.status(200).send(resp.data);
|
325
|
-
}
|
326
|
-
|
327
|
-
if (!resource) {
|
328
|
-
winston.error("Resource with id " + id + " not found in namespace " + answer.namespace + ". The standard answer is returned.")
|
329
|
-
return res.status(200).send(resp.data);
|
301
|
+
if (publicKey === true) {
|
302
|
+
let multiplier = MODELS_MULTIPLIER[data.model];
|
303
|
+
if (!multiplier) {
|
304
|
+
multiplier = 1;
|
305
|
+
winston.info("No multiplier found for AI model")
|
330
306
|
}
|
307
|
+
obj.multiplier = multiplier;
|
308
|
+
obj.tokens = answer.prompt_token_size;
|
331
309
|
|
332
|
-
|
333
|
-
|
334
|
-
}
|
335
|
-
|
310
|
+
let incremented_key = quoteManager.incrementTokenCount(req.project, obj);
|
311
|
+
winston.verbose("incremented_key: ", incremented_key);
|
312
|
+
}
|
313
|
+
|
314
|
+
return res.status(200).send(answer);
|
336
315
|
|
337
316
|
}).catch((err) => {
|
338
317
|
winston.error("qa err: ", err);
|
@@ -998,7 +977,7 @@ router.post('/', async (req, res) => {
|
|
998
977
|
let resources = [];
|
999
978
|
|
1000
979
|
resources.push(json);
|
1001
|
-
if (
|
980
|
+
if (process.env.NODE_ENV !== 'test') {
|
1002
981
|
scheduleScrape(resources);
|
1003
982
|
}
|
1004
983
|
|
@@ -1104,7 +1083,7 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
1104
1083
|
let operations = kbs.map(doc => {
|
1105
1084
|
return {
|
1106
1085
|
updateOne: {
|
1107
|
-
filter: { id_project: doc.id_project, type: 'url', source: doc.source },
|
1086
|
+
filter: { id_project: doc.id_project, type: 'url', source: doc.source, namespace: namespace_id },
|
1108
1087
|
update: doc,
|
1109
1088
|
upsert: true,
|
1110
1089
|
returnOriginal: false
|
@@ -1123,7 +1102,7 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
|
1123
1102
|
});
|
1124
1103
|
winston.verbose("resources to be sent to worker: ", resources);
|
1125
1104
|
|
1126
|
-
if (
|
1105
|
+
if (process.env.NODE_ENV !== 'test') {
|
1127
1106
|
scheduleScrape(resources);
|
1128
1107
|
}
|
1129
1108
|
res.status(200).send(result);
|
@@ -1214,7 +1193,7 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
|
|
1214
1193
|
let operations = kbs.map(doc => {
|
1215
1194
|
return {
|
1216
1195
|
updateOne: {
|
1217
|
-
filter: { id_project: doc.id_project, type: 'faq', source: doc.source },
|
1196
|
+
filter: { id_project: doc.id_project, type: 'faq', source: doc.source, namespace: namespace_id },
|
1218
1197
|
update: doc,
|
1219
1198
|
upsert: true,
|
1220
1199
|
returnOriginal: false
|
@@ -1232,7 +1211,7 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
|
|
1232
1211
|
return { id: _id, webhooh: webhook, engine: engine, ...rest };
|
1233
1212
|
})
|
1234
1213
|
winston.verbose("resources to be sent to worker: ", resources);
|
1235
|
-
if (
|
1214
|
+
if (process.env.NODE_ENV !== 'test') {
|
1236
1215
|
scheduleScrape(resources);
|
1237
1216
|
}
|
1238
1217
|
res.status(200).send(result);
|
package/routes/lead.js
CHANGED
@@ -100,6 +100,58 @@ router.put('/:leadid', function (req, res) {
|
|
100
100
|
});
|
101
101
|
|
102
102
|
|
103
|
+
router.put('/:leadid/tag', async (req, res) => {
|
104
|
+
|
105
|
+
let lead_id = req.params.leadid;
|
106
|
+
let tags_list = req.body;
|
107
|
+
winston.debug("(Lead) /tag tags_list: ", tags_list)
|
108
|
+
|
109
|
+
if (tags_list.length == 0) {
|
110
|
+
winston.warn("(Lead) /tag no tag specified")
|
111
|
+
return res.status(400).send({ success: false, message: "No tag specified" })
|
112
|
+
}
|
113
|
+
|
114
|
+
let lead = await Lead.findById(lead_id).catch((err) => {
|
115
|
+
winston.error("(Lead) /tag error getting lead ", err);
|
116
|
+
return res.status(500).send({ success: false, error: "Error getting lead with id " + lead_id});
|
117
|
+
})
|
118
|
+
|
119
|
+
if (!lead) {
|
120
|
+
winston.warn("(Lead) /tag lead not found with lead_id " + lead_id);
|
121
|
+
return res.status(404).send({ success: false, error: "Lead not found with id " + lead_id });
|
122
|
+
}
|
123
|
+
|
124
|
+
let current_tags = lead.tags;
|
125
|
+
tags_list.forEach(t => {
|
126
|
+
// Check if tag already exists in the lead. If true, skip the adding.
|
127
|
+
if (!current_tags.includes(t)) {
|
128
|
+
current_tags.push(t)
|
129
|
+
}
|
130
|
+
})
|
131
|
+
|
132
|
+
let update = {
|
133
|
+
tags: current_tags
|
134
|
+
}
|
135
|
+
|
136
|
+
Lead.findByIdAndUpdate(lead_id, update, { new: true }, (err, updatedLead) => {
|
137
|
+
if (err) {
|
138
|
+
winston.error("(Lead) /tag error finding and update lead ", err);
|
139
|
+
return res.status(500).send({ success: false, error: "Error updating lead with id " + lead_id })
|
140
|
+
}
|
141
|
+
|
142
|
+
if (!updatedLead) {
|
143
|
+
winston.warn("(Lead) /tag The lead was deleted while adding tags for lead " + lead_id);
|
144
|
+
return res.status(404).send({ success: false, error: "The lead was deleted while adding tags for lead " + lead_id })
|
145
|
+
}
|
146
|
+
|
147
|
+
winston.debug("(Lead) /tag Lead updated successfully ", updatedLead);
|
148
|
+
|
149
|
+
leadEvent.emit('lead.update', updatedLead);
|
150
|
+
res.status(200).send(updatedLead)
|
151
|
+
|
152
|
+
})
|
153
|
+
})
|
154
|
+
|
103
155
|
|
104
156
|
router.patch('/:leadid/attributes', function (req, res) {
|
105
157
|
var data = req.body;
|
@@ -274,6 +326,25 @@ router.patch('/:leadid/properties', function (req, res) {
|
|
274
326
|
// res.json(updatedLead);
|
275
327
|
// });
|
276
328
|
// });
|
329
|
+
router.delete('/:leadid/tag/:tag', async (req, res) => {
|
330
|
+
|
331
|
+
let lead_id = req.params.leadid;
|
332
|
+
let tag = req.params.tag;
|
333
|
+
|
334
|
+
Lead.findByIdAndUpdate(lead_id, { $pull: { tags: tag }}, { new: true}).then((updatedLead) => {
|
335
|
+
if (!updatedLead) {
|
336
|
+
winston.warn("(Lead) /removetag lead not found with id " + lead_id);
|
337
|
+
return res.status(404).send({ success: false, error: "Lead not found with id " + lead_id })
|
338
|
+
}
|
339
|
+
|
340
|
+
winston.debug("(Lead) /removetag updatedLead: ", updatedLead)
|
341
|
+
res.status(200).send(updatedLead)
|
342
|
+
}).catch((err) => {
|
343
|
+
winston.error("(Lead) /removetag error updating lead: ", err);
|
344
|
+
res.status(500).send({ success: false, error: err });
|
345
|
+
})
|
346
|
+
})
|
347
|
+
|
277
348
|
|
278
349
|
router.delete('/:leadid', function (req, res) {
|
279
350
|
winston.debug(req.body);
|
package/routes/request.js
CHANGED
@@ -23,7 +23,7 @@ var cacheEnabler = require("../services/cacheEnabler");
|
|
23
23
|
var Project_user = require("../models/project_user");
|
24
24
|
var Lead = require("../models/lead");
|
25
25
|
var UIDGenerator = require("../utils/UIDGenerator");
|
26
|
-
|
26
|
+
let JobManager = require("@tiledesk/tiledesk-multi-worker");
|
27
27
|
|
28
28
|
csv = require('csv-express');
|
29
29
|
csv.separator = ';';
|
@@ -31,9 +31,28 @@ csv.separator = ';';
|
|
31
31
|
const { check, validationResult } = require('express-validator');
|
32
32
|
const RoleConstants = require('../models/roleConstants');
|
33
33
|
const eventService = require('../pubmodules/events/eventService');
|
34
|
+
const { Scheduler } = require('../services/Scheduler');
|
35
|
+
//const JobManager = require('../utils/jobs-worker-queue-manager-v2/JobManagerV2');
|
34
36
|
|
35
37
|
// var messageService = require('../services/messageService');
|
36
38
|
|
39
|
+
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
40
|
+
|
41
|
+
let jobManager = new JobManager(AMQP_MANAGER_URL, {
|
42
|
+
debug: false,
|
43
|
+
queueName: "conversation-tags_queue",
|
44
|
+
exchange: "tiledesk-multi",
|
45
|
+
topic: "conversation-tags",
|
46
|
+
})
|
47
|
+
|
48
|
+
jobManager.connectAndStartPublisher((status, error) => {
|
49
|
+
if (error) {
|
50
|
+
winston.error("connectAndStartPublisher error: ", error);
|
51
|
+
} else {
|
52
|
+
winston.info("KbRoute - ConnectPublisher done with status: ", status);
|
53
|
+
}
|
54
|
+
})
|
55
|
+
|
37
56
|
|
38
57
|
|
39
58
|
router.post('/simple', [check('first_text').notEmpty()], async (req, res) => {
|
@@ -848,6 +867,76 @@ router.put('/:requestid/followers', function (req, res) {
|
|
848
867
|
|
849
868
|
});
|
850
869
|
|
870
|
+
|
871
|
+
router.put('/:requestid/tag', async (req, res) => {
|
872
|
+
|
873
|
+
let id_project = req.projectid;
|
874
|
+
let request_id = req.params.requestid;
|
875
|
+
let tags_list = req.body;
|
876
|
+
winston.debug("(Request) /tag tags_list: ", tags_list)
|
877
|
+
|
878
|
+
if (tags_list.length == 0) {
|
879
|
+
winston.warn("(Request) /tag no tag specified")
|
880
|
+
return res.status(400).send({ success: false, message: "No tag specified" })
|
881
|
+
}
|
882
|
+
|
883
|
+
let request = await Request.findOne({ id_project: id_project, request_id: request_id }).catch((err) => {
|
884
|
+
winston.error("(Request) /tag error getting request ", err);
|
885
|
+
return res.status(500).send({ success: false, error: "Error getting request with request id " + request_id});
|
886
|
+
})
|
887
|
+
|
888
|
+
if (!request) {
|
889
|
+
winston.warn("(Request) /tag request not found with request_id " + request_id);
|
890
|
+
return res.status(404).send({ success: false, error: "Request not found with request id " + request_id});
|
891
|
+
}
|
892
|
+
|
893
|
+
let current_tags = request.tags;
|
894
|
+
let adding_tags = [];
|
895
|
+
|
896
|
+
tags_list.forEach(t => {
|
897
|
+
// Check if tag already exists in the conversation. If true, skip the adding.
|
898
|
+
if(!current_tags.some(tag => tag.tag === t.tag)) {
|
899
|
+
current_tags.push(t);
|
900
|
+
adding_tags.push(t);
|
901
|
+
}
|
902
|
+
})
|
903
|
+
|
904
|
+
let update = {
|
905
|
+
tags: current_tags
|
906
|
+
}
|
907
|
+
|
908
|
+
Request.findOneAndUpdate({ id_project: id_project, request_id: request_id }, update, { new: true }).then( async (updatedRequest) => {
|
909
|
+
|
910
|
+
if (!updatedRequest) {
|
911
|
+
winston.warn("(Request) /tag The request was deleted while adding tags for request " + request_id);
|
912
|
+
return res.status(404).send({ success: false, error: "The request was deleted while adding tags for request " + request_id })
|
913
|
+
}
|
914
|
+
|
915
|
+
winston.debug("(Request) /tag Request updated successfully ", updatedRequest);
|
916
|
+
|
917
|
+
const populatedRequest =
|
918
|
+
await updatedRequest
|
919
|
+
.populate('lead')
|
920
|
+
.populate('department')
|
921
|
+
.populate('participatingBots')
|
922
|
+
.populate('participatingAgents')
|
923
|
+
.populate({ path: 'requester', populate: { path: 'id_user' } })
|
924
|
+
.execPopulate();
|
925
|
+
|
926
|
+
requestEvent.emit("request.update", populatedRequest)
|
927
|
+
res.status(200).send(updatedRequest)
|
928
|
+
|
929
|
+
if (process.env.NODE_ENV !== 'test') {
|
930
|
+
scheduleTags(id_project, adding_tags);
|
931
|
+
}
|
932
|
+
|
933
|
+
}).catch((err) => {
|
934
|
+
winston.error("(Request) /tag error finding and update request ", err);
|
935
|
+
return res.status(500).send({ success: false, error: "Error updating request with id " + request_id })
|
936
|
+
})
|
937
|
+
|
938
|
+
})
|
939
|
+
|
851
940
|
router.delete('/:requestid/followers/:followerid', function (req, res) {
|
852
941
|
winston.debug(req.body);
|
853
942
|
|
@@ -864,7 +953,40 @@ router.delete('/:requestid/followers/:followerid', function (req, res) {
|
|
864
953
|
|
865
954
|
|
866
955
|
|
956
|
+
router.delete('/:requestid/tag/:tag_id', async (req, res) => {
|
957
|
+
|
958
|
+
let id_project = req.projectid;
|
959
|
+
let request_id = req.params.requestid;
|
960
|
+
let tag_id = req.params.tag_id;
|
961
|
+
|
962
|
+
|
867
963
|
|
964
|
+
Request.findOneAndUpdate({ id_project: id_project, request_id: request_id }, { $pull: { tags: { _id: tag_id } } }, { new: true }).then( async (updatedRequest) => {
|
965
|
+
|
966
|
+
if (!updatedRequest) {
|
967
|
+
winston.warn("(Request) /removetag request not found with id: " + request_id)
|
968
|
+
return res.status(404).send({ success: false, error: "Request not found with id " + request_id})
|
969
|
+
}
|
970
|
+
|
971
|
+
winston.debug("(Request) /removetag updatedRequest: ", updatedRequest)
|
972
|
+
|
973
|
+
const populatedRequest =
|
974
|
+
await updatedRequest
|
975
|
+
.populate('lead')
|
976
|
+
.populate('department')
|
977
|
+
.populate('participatingBots')
|
978
|
+
.populate('participatingAgents')
|
979
|
+
.populate({ path: 'requester', populate: { path: 'id_user' } })
|
980
|
+
.execPopulate();
|
981
|
+
|
982
|
+
requestEvent.emit("request.update", populatedRequest)
|
983
|
+
res.status(200).send(updatedRequest);
|
984
|
+
|
985
|
+
}).catch((err) => {
|
986
|
+
winston.error("(Request) /removetag error updating request: ", err)
|
987
|
+
res.status(500).send({ success: false, error: err })
|
988
|
+
})
|
989
|
+
})
|
868
990
|
|
869
991
|
|
870
992
|
// TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
|
@@ -2166,4 +2288,27 @@ router.get('/:requestid/chatbot/parameters', async (req, res) => {
|
|
2166
2288
|
|
2167
2289
|
})
|
2168
2290
|
|
2291
|
+
|
2292
|
+
async function scheduleTags(id_project, tags) {
|
2293
|
+
|
2294
|
+
let scheduler = new Scheduler({ jobManager: jobManager })
|
2295
|
+
tags.forEach(t => {
|
2296
|
+
let payload = {
|
2297
|
+
id_project: id_project,
|
2298
|
+
tag: t.tag,
|
2299
|
+
type: "conversation-tag",
|
2300
|
+
date: new Date()
|
2301
|
+
}
|
2302
|
+
console.log("payload: ", payload);
|
2303
|
+
scheduler.tagSchedule(payload, async (err, result) => {
|
2304
|
+
if (err) {
|
2305
|
+
winston.error("Scheduling error: ", err);
|
2306
|
+
} else {
|
2307
|
+
winston.info("Scheduling result: ", result);
|
2308
|
+
}
|
2309
|
+
})
|
2310
|
+
})
|
2311
|
+
}
|
2312
|
+
|
2313
|
+
|
2169
2314
|
module.exports = router;
|
package/services/Scheduler.js
CHANGED
@@ -28,6 +28,18 @@ class Scheduler {
|
|
28
28
|
}
|
29
29
|
});
|
30
30
|
}
|
31
|
+
|
32
|
+
tagSchedule(data, callback) {
|
33
|
+
|
34
|
+
winston.debug("(tagScheduler) data: ", data);
|
35
|
+
this.jobManager.publish(data, (err, ok) => {
|
36
|
+
let response_data = { success: true, message: "Scheduled" };
|
37
|
+
if (callback) {
|
38
|
+
callback(err, response_data);
|
39
|
+
}
|
40
|
+
})
|
41
|
+
}
|
42
|
+
|
31
43
|
}
|
32
44
|
|
33
45
|
module.exports = { Scheduler };
|
@@ -20,8 +20,8 @@ var configGlobal = require('../config/global');
|
|
20
20
|
const projectService = require('./projectService');
|
21
21
|
const axios = require("axios").default;
|
22
22
|
|
23
|
-
|
24
|
-
const
|
23
|
+
let port = process.env.PORT || '3000';
|
24
|
+
const TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT || "http://localhost:" + port+ "/modules/tilebot/ext/";
|
25
25
|
|
26
26
|
let tdCache = new TdCache({
|
27
27
|
host: process.env.CACHE_REDIS_HOST,
|
@@ -2812,7 +2812,7 @@ class RequestService {
|
|
2812
2812
|
|
2813
2813
|
return new Promise( async (resolve, reject) => {
|
2814
2814
|
await axios({
|
2815
|
-
url:
|
2815
|
+
url: TILEBOT_ENDPOINT + 'reserved/parameters/requests/' + request_id,
|
2816
2816
|
headers: {
|
2817
2817
|
'Content-Type': 'application/json'
|
2818
2818
|
},
|