@tiledesk/tiledesk-server 2.5.2 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +9 -0
- package/README.md +1 -1
- package/app.js +7 -1
- package/deploy.sh +1 -1
- package/event/botEvent.js +24 -3
- package/jobs.js +9 -1
- package/jobsManager.js +13 -1
- package/package.json +7 -5
- package/pubmodules/queue/reconnect.js +47 -0
- package/pubmodules/trigger/default.js +2 -2
- package/pubmodules/trigger/rulesTrigger.js +14 -2
- package/routes/kb.js +307 -62
- package/routes/project_user.js +10 -1
- package/services/QuoteManager.js +26 -20
- package/services/Scheduler.js +33 -0
- package/services/openaiService.js +12 -11
- package/services/requestService.js +96 -92
- package/services/updateLeadQueued.js +149 -0
- package/test/TooManykbUrlsList.txt +304 -0
- package/test/kbRoute.js +331 -20
- package/test/kbUrlsList.txt +4 -0
- package/utils/jobs-worker-queue-manager/JobManagerV2.js +146 -0
- package/utils/jobs-worker-queue-manager/queueManagerClassV2.js +355 -0
package/routes/kb.js
CHANGED
@@ -2,8 +2,26 @@ var express = require('express');
|
|
2
2
|
var { KB } = require('../models/kb_setting');
|
3
3
|
var router = express.Router();
|
4
4
|
var winston = require('../config/winston');
|
5
|
+
var multer = require('multer')
|
6
|
+
var upload = multer()
|
5
7
|
const openaiService = require('../services/openaiService');
|
8
|
+
const JobManager = require('../utils/jobs-worker-queue-manager/JobManagerV2');
|
9
|
+
const { Scheduler } = require('../services/Scheduler');
|
6
10
|
|
11
|
+
const Sitemapper = require('sitemapper');
|
12
|
+
|
13
|
+
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
14
|
+
const JOB_TOPIC_EXCHANGE = process.env.JOB_TOPIC_EXCHANGE_TRAIN || 'tiledesk-trainer';
|
15
|
+
|
16
|
+
let jobManager = new JobManager(AMQP_MANAGER_URL, {
|
17
|
+
debug: false,
|
18
|
+
topic: JOB_TOPIC_EXCHANGE,
|
19
|
+
exchange: JOB_TOPIC_EXCHANGE
|
20
|
+
})
|
21
|
+
|
22
|
+
jobManager.connectAndStartPublisher(() => {
|
23
|
+
winston.info("ConnectPublisher done");
|
24
|
+
})
|
7
25
|
|
8
26
|
router.get('/', async (req, res) => {
|
9
27
|
|
@@ -27,7 +45,7 @@ router.get('/', async (req, res) => {
|
|
27
45
|
limit = parseInt(req.query.limit);
|
28
46
|
winston.debug("Get kb limit: " + limit)
|
29
47
|
}
|
30
|
-
|
48
|
+
|
31
49
|
if (req.query.page) {
|
32
50
|
page = parseInt(req.query.page);
|
33
51
|
winston.debug("Get kb page: " + page)
|
@@ -55,54 +73,54 @@ router.get('/', async (req, res) => {
|
|
55
73
|
let sortQuery = {};
|
56
74
|
sortQuery[sortField] = direction;
|
57
75
|
winston.debug("Get kb sortQuery: " + sortQuery);
|
58
|
-
|
76
|
+
|
59
77
|
KB.countDocuments(query, (err, kbs_count) => {
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
KB.find(query)
|
66
|
-
.skip(skip)
|
67
|
-
.limit(limit)
|
68
|
-
.sort(sortQuery)
|
69
|
-
.exec((err, kbs) => {
|
70
|
-
if (err) {
|
71
|
-
winston.error("Find all kbs error: ", err);
|
72
|
-
return res.status(500).send({ success: false, error: err });
|
73
|
-
}
|
74
|
-
|
75
|
-
winston.debug("KBs found: ", kbs);
|
76
|
-
|
77
|
-
let response = {
|
78
|
-
count: kbs_count,
|
79
|
-
query: {},
|
80
|
-
kbs: kbs
|
81
|
-
}
|
82
|
-
if (status) {
|
83
|
-
response.query.status = status;
|
84
|
-
}
|
85
|
-
if (limit) {
|
86
|
-
response.query.limit = limit;
|
87
|
-
}
|
88
|
-
if (status) {
|
89
|
-
response.query.page = page;
|
90
|
-
}
|
91
|
-
if (sortField) {
|
92
|
-
response.query.sortField = sortField;
|
93
|
-
}
|
94
|
-
if (direction) {
|
95
|
-
response.query.direction = direction;
|
96
|
-
}
|
97
|
-
if (text) {
|
98
|
-
response.query.search = text;
|
99
|
-
}
|
100
|
-
|
101
|
-
|
102
|
-
return res.status(200).send(response);
|
103
|
-
})
|
78
|
+
if (err) {
|
79
|
+
winston.error("Find all kbs error: ", err);
|
80
|
+
}
|
81
|
+
winston.debug("KBs count: ", kbs_count);
|
104
82
|
|
105
|
-
|
83
|
+
KB.find(query)
|
84
|
+
.skip(skip)
|
85
|
+
.limit(limit)
|
86
|
+
.sort(sortQuery)
|
87
|
+
.exec((err, kbs) => {
|
88
|
+
if (err) {
|
89
|
+
winston.error("Find all kbs error: ", err);
|
90
|
+
return res.status(500).send({ success: false, error: err });
|
91
|
+
}
|
92
|
+
|
93
|
+
winston.debug("KBs found: ", kbs);
|
94
|
+
|
95
|
+
let response = {
|
96
|
+
count: kbs_count,
|
97
|
+
query: {},
|
98
|
+
kbs: kbs
|
99
|
+
}
|
100
|
+
if (status) {
|
101
|
+
response.query.status = status;
|
102
|
+
}
|
103
|
+
if (limit) {
|
104
|
+
response.query.limit = limit;
|
105
|
+
}
|
106
|
+
if (status) {
|
107
|
+
response.query.page = page;
|
108
|
+
}
|
109
|
+
if (sortField) {
|
110
|
+
response.query.sortField = sortField;
|
111
|
+
}
|
112
|
+
if (direction) {
|
113
|
+
response.query.direction = direction;
|
114
|
+
}
|
115
|
+
if (text) {
|
116
|
+
response.query.search = text;
|
117
|
+
}
|
118
|
+
|
119
|
+
|
120
|
+
return res.status(200).send(response);
|
121
|
+
})
|
122
|
+
|
123
|
+
})
|
106
124
|
|
107
125
|
|
108
126
|
})
|
@@ -127,6 +145,31 @@ router.post('/', async (req, res) => {
|
|
127
145
|
let project_id = req.projectid;
|
128
146
|
let body = req.body;
|
129
147
|
|
148
|
+
// add or override namespace value if it is passed for security reason
|
149
|
+
body.namespace = project_id;
|
150
|
+
|
151
|
+
// if (req.body.namespace) {
|
152
|
+
// if (req.body.namespace != req.projectid) {
|
153
|
+
// return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project."})
|
154
|
+
// }
|
155
|
+
// }
|
156
|
+
|
157
|
+
let quoteManager = req.app.get('quote_manager');
|
158
|
+
let limits = await quoteManager.getPlanLimits(req.project);
|
159
|
+
let kbs_limit = limits.kbs;
|
160
|
+
winston.verbose("Limit of kbs for current plan: " + kbs_limit);
|
161
|
+
|
162
|
+
let kbs_count = await KB.countDocuments({ id_project: project_id }).exec();
|
163
|
+
winston.verbose("Kbs count: " + kbs_count);
|
164
|
+
|
165
|
+
if (kbs_count >= kbs_limit) {
|
166
|
+
return res.status(403).send({ success: false, error: "Maximum number of resources reached for the current plan", plan_limit: kbs_limit })
|
167
|
+
}
|
168
|
+
|
169
|
+
let total_count = kbs_count + 1;
|
170
|
+
if (total_count > kbs_limit) {
|
171
|
+
return res.status(403).send({ success: false, error: "Cannot exceed the number of resources in the current plan", plan_limit: kbs_limit })
|
172
|
+
}
|
130
173
|
let new_kb = {
|
131
174
|
id_project: project_id,
|
132
175
|
name: body.name,
|
@@ -141,7 +184,6 @@ router.post('/', async (req, res) => {
|
|
141
184
|
}
|
142
185
|
winston.debug("adding kb: ", new_kb);
|
143
186
|
|
144
|
-
|
145
187
|
KB.findOneAndUpdate({ id_project: project_id, type: 'url', source: new_kb.source }, new_kb, { upsert: true, new: true, rawResult: true }, async (err, raw) => {
|
146
188
|
if (err) {
|
147
189
|
winston.error("findOneAndUpdate with upsert error: ", err);
|
@@ -163,17 +205,118 @@ router.post('/', async (req, res) => {
|
|
163
205
|
json.content = raw.value.content;
|
164
206
|
}
|
165
207
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
208
|
+
let resources = [];
|
209
|
+
|
210
|
+
resources.push(json);
|
211
|
+
scheduleScrape(resources);
|
212
|
+
|
213
|
+
// startScrape(json).then((response) => {
|
214
|
+
// winston.verbose("startScrape response: ", response);
|
215
|
+
// }).catch((err) => {
|
216
|
+
// winston.error("startScrape err: ", err);
|
217
|
+
// })
|
218
|
+
|
219
|
+
}
|
220
|
+
})
|
221
|
+
|
222
|
+
})
|
223
|
+
|
224
|
+
|
225
|
+
router.post('/multi', upload.single('uploadFile'), async (req, res) => {
|
226
|
+
|
227
|
+
let list;
|
228
|
+
if (req.file) {
|
229
|
+
file_string = req.file.buffer.toString('utf-8');
|
230
|
+
list = file_string.trim().split('\n');
|
231
|
+
} else {
|
232
|
+
list = req.body.list;
|
233
|
+
}
|
234
|
+
|
235
|
+
let project_id = req.projectid;
|
236
|
+
|
237
|
+
let quoteManager = req.app.get('quote_manager');
|
238
|
+
let limits = await quoteManager.getPlanLimits(req.project);
|
239
|
+
let kbs_limit = limits.kbs;
|
240
|
+
winston.verbose("Limit of kbs for current plan: " + kbs_limit);
|
241
|
+
|
242
|
+
let kbs_count = await KB.countDocuments({ id_project: project_id }).exec();
|
243
|
+
winston.verbose("Kbs count: " + kbs_count);
|
244
|
+
|
245
|
+
if (kbs_count >= kbs_limit) {
|
246
|
+
return res.status(403).send({ success: false, error: "Maximum number of resources reached for the current plan", plan_limit: kbs_limit })
|
247
|
+
}
|
248
|
+
|
249
|
+
let total_count = kbs_count + list.length;
|
250
|
+
if (total_count > kbs_limit) {
|
251
|
+
return res.status(403).send({ success: false, error: "Cannot exceed the number of resources in the current plan", plan_limit: kbs_limit })
|
252
|
+
}
|
253
|
+
|
254
|
+
if (list.length > 300) {
|
255
|
+
winston.error("Too many urls. Can't index more than 300 urls at a time.");
|
256
|
+
return res.status(403).send({ success: false, error: "Too many urls. Can't index more than 300 urls at a time."})
|
257
|
+
}
|
171
258
|
|
259
|
+
let kbs = [];
|
260
|
+
list.forEach(url => {
|
261
|
+
kbs.push({
|
262
|
+
id_project: project_id,
|
263
|
+
name: url,
|
264
|
+
source: url,
|
265
|
+
type: 'url',
|
266
|
+
content: "",
|
267
|
+
namespace: project_id,
|
268
|
+
status: -1
|
269
|
+
})
|
270
|
+
})
|
271
|
+
|
272
|
+
let operations = kbs.map(doc => {
|
273
|
+
return {
|
274
|
+
updateOne: {
|
275
|
+
filter: { id_project: doc.id_project, type: 'url', source: doc.source },
|
276
|
+
update: doc,
|
277
|
+
upsert: true,
|
278
|
+
returnOriginal: false
|
279
|
+
}
|
172
280
|
}
|
173
281
|
})
|
174
282
|
|
283
|
+
saveBulk(operations, kbs, project_id).then((result) => {
|
284
|
+
|
285
|
+
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
286
|
+
resources = resources.map(({ _id, ...rest }) => {
|
287
|
+
return { id: _id, ...rest };
|
288
|
+
});
|
289
|
+
winston.verbose("resources to be sent to worker: ", resources)
|
290
|
+
scheduleScrape(resources);
|
291
|
+
res.status(200).send(result);
|
292
|
+
|
293
|
+
}).catch((err) => {
|
294
|
+
winston.error("Unable to save kbs in bulk ", err)
|
295
|
+
res.status(500).send(err);
|
296
|
+
})
|
297
|
+
|
298
|
+
})
|
299
|
+
|
300
|
+
router.post('/sitemap', async (req, res) => {
|
301
|
+
|
302
|
+
let sitemap_url = req.body.sitemap;
|
303
|
+
|
304
|
+
const sitemap = new Sitemapper({
|
305
|
+
url: sitemap_url,
|
306
|
+
timeout: 15000
|
307
|
+
});
|
308
|
+
|
309
|
+
sitemap.fetch().then((data) => {
|
310
|
+
winston.debug("data: ", data);
|
311
|
+
res.status(200).send(data);
|
312
|
+
}).catch((err) => {
|
313
|
+
console.error("err ", err)
|
314
|
+
res.status(500).send({ success: false, error: err });
|
315
|
+
})
|
316
|
+
|
175
317
|
})
|
176
318
|
|
319
|
+
|
177
320
|
router.put('/:kb_id', async (req, res) => {
|
178
321
|
|
179
322
|
let kb_id = req.params.kb_id;
|
@@ -230,10 +373,14 @@ router.post('/scrape/single', async (req, res) => {
|
|
230
373
|
id: kb._id,
|
231
374
|
type: kb.type,
|
232
375
|
source: kb.source,
|
233
|
-
content:
|
376
|
+
content: "",
|
234
377
|
namespace: kb.namespace
|
235
378
|
}
|
236
379
|
|
380
|
+
if (kb.content) {
|
381
|
+
json.content = kb.content;
|
382
|
+
}
|
383
|
+
|
237
384
|
startScrape(json).then((response) => {
|
238
385
|
winston.verbose("startScrape response: ", response);
|
239
386
|
res.status(200).send(response);
|
@@ -256,24 +403,27 @@ router.post('/scrape/status', async (req, res) => {
|
|
256
403
|
|
257
404
|
if (req.query &&
|
258
405
|
req.query.returnObject &&
|
259
|
-
(req.query.returnObject === true || req.query.returnObject === true)) {
|
406
|
+
(req.query.returnObject === true || req.query.returnObject === 'true')) {
|
260
407
|
returnObject = true;
|
261
408
|
}
|
262
409
|
|
263
|
-
openaiService.scrapeStatus(data).then((response) => {
|
410
|
+
openaiService.scrapeStatus(data).then( async (response) => {
|
264
411
|
|
265
412
|
winston.debug("scrapeStatus response.data: ", response.data);
|
266
413
|
|
267
414
|
let update = {};
|
268
415
|
|
269
416
|
if (response.data.status_code) {
|
270
|
-
update.status = response.data.status_code;
|
417
|
+
// update.status = response.data.status_code;
|
418
|
+
update.status = await statusConverter(response.data.status_code)
|
419
|
+
|
271
420
|
}
|
272
421
|
|
273
422
|
KB.findByIdAndUpdate(data.id, update, { new: true }, (err, savedKb) => {
|
274
423
|
|
275
424
|
if (err) {
|
276
425
|
winston.verbose("Status was successfully recovered, but the update on the db failed");
|
426
|
+
winston.error("find kb by id and updated error: ", err);
|
277
427
|
|
278
428
|
if (returnObject) {
|
279
429
|
return res.status(206).send({ warning: "Unable to udpate content on db", message: "The original reply was forwarded", data: response.data });
|
@@ -298,8 +448,14 @@ router.post('/scrape/status', async (req, res) => {
|
|
298
448
|
|
299
449
|
router.post('/qa', async (req, res) => {
|
300
450
|
let data = req.body;
|
451
|
+
// add or override namespace value if it is passed for security reason
|
452
|
+
data.namespace = req.projectid;
|
301
453
|
winston.debug("/qa data: ", data);
|
302
454
|
|
455
|
+
// if (req.body.namespace != req.projectid) {
|
456
|
+
// return res.status(403).send({ success: false, error: "Not allowed. The namespace does not belong to the current project."})
|
457
|
+
// }
|
458
|
+
|
303
459
|
if (!data.gptkey) {
|
304
460
|
let gptkey = process.env.GPTKEY;
|
305
461
|
if (!gptkey) {
|
@@ -310,11 +466,38 @@ router.post('/qa', async (req, res) => {
|
|
310
466
|
|
311
467
|
openaiService.askNamespace(data).then((resp) => {
|
312
468
|
winston.debug("qa resp: ", resp.data);
|
313
|
-
|
469
|
+
let answer = resp.data;
|
470
|
+
|
471
|
+
let id = answer.id;
|
472
|
+
let index = id.indexOf("#");
|
473
|
+
if (index != -1) {
|
474
|
+
id = id.substring(index + 1);
|
475
|
+
}
|
476
|
+
|
477
|
+
KB.findById(id, (err, resource) => {
|
478
|
+
|
479
|
+
if (err) {
|
480
|
+
winston.error("Unable to find resource with id " + id + " in namespace " + answer.namespace + ". The standard answer is returned.")
|
481
|
+
return res.status(200).send(resp.data);
|
482
|
+
}
|
483
|
+
|
484
|
+
answer.source = resource.name;
|
485
|
+
return res.status(200).send(answer);
|
486
|
+
})
|
487
|
+
|
488
|
+
|
314
489
|
}).catch((err) => {
|
315
490
|
winston.error("qa err: ", err);
|
316
|
-
|
317
|
-
|
491
|
+
console.log(err.response)
|
492
|
+
if (err.response
|
493
|
+
&& err.response.status) {
|
494
|
+
let status = err.response.status;
|
495
|
+
res.status(status).send({ success: false, statusText: err.response.statusText, error: err.response.data.detail });
|
496
|
+
}
|
497
|
+
else {
|
498
|
+
res.status(500).send({ success: false, error: err });
|
499
|
+
}
|
500
|
+
|
318
501
|
})
|
319
502
|
})
|
320
503
|
|
@@ -375,7 +558,7 @@ router.delete('/:kb_id', async (req, res) => {
|
|
375
558
|
})
|
376
559
|
|
377
560
|
} else {
|
378
|
-
winston.
|
561
|
+
winston.verbose("resp.data: ", resp.data);
|
379
562
|
|
380
563
|
KB.findOneAndDelete({ _id: kb_id, status: { $in: [-1, 3, 4] } }, (err, deletedKb) => {
|
381
564
|
if (err) {
|
@@ -398,6 +581,51 @@ router.delete('/:kb_id', async (req, res) => {
|
|
398
581
|
|
399
582
|
})
|
400
583
|
|
584
|
+
async function saveBulk(operations, kbs, project_id) {
|
585
|
+
|
586
|
+
return new Promise((resolve, reject) => {
|
587
|
+
KB.bulkWrite(operations, { ordered: false }).then((result) => {
|
588
|
+
winston.verbose("bulkWrite operations result: ", result);
|
589
|
+
|
590
|
+
KB.find({ id_project: project_id, source: { $in: kbs.map(kb => kb.source) } }).lean().then((documents) => {
|
591
|
+
winston.debug("documents: ", documents);
|
592
|
+
resolve(documents)
|
593
|
+
}).catch((err) => {
|
594
|
+
winston.error("Error finding documents ", err)
|
595
|
+
reject(err);
|
596
|
+
})
|
597
|
+
|
598
|
+
}).catch((err) => {
|
599
|
+
reject(err);
|
600
|
+
})
|
601
|
+
})
|
602
|
+
|
603
|
+
}
|
604
|
+
|
605
|
+
async function statusConverter(status) {
|
606
|
+
return new Promise((resolve) => {
|
607
|
+
|
608
|
+
let td_status;
|
609
|
+
switch(status) {
|
610
|
+
case 0:
|
611
|
+
td_status = -1;
|
612
|
+
break;
|
613
|
+
case 2:
|
614
|
+
td_status = 200;
|
615
|
+
break;
|
616
|
+
case 3:
|
617
|
+
td_status = 300;
|
618
|
+
break;
|
619
|
+
case 4:
|
620
|
+
td_status = 400;
|
621
|
+
break;
|
622
|
+
default:
|
623
|
+
td_status = -1
|
624
|
+
}
|
625
|
+
resolve(td_status);
|
626
|
+
})
|
627
|
+
}
|
628
|
+
|
401
629
|
async function updateStatus(id, status) {
|
402
630
|
return new Promise((resolve) => {
|
403
631
|
|
@@ -412,6 +640,23 @@ async function updateStatus(id, status) {
|
|
412
640
|
})
|
413
641
|
}
|
414
642
|
|
643
|
+
async function scheduleScrape(resources) {
|
644
|
+
|
645
|
+
let data = {
|
646
|
+
resources: resources
|
647
|
+
}
|
648
|
+
winston.info("Schedule job with following data: ", data);
|
649
|
+
let scheduler = new Scheduler({ jobManager: jobManager });
|
650
|
+
scheduler.trainSchedule(data, (err, result) => {
|
651
|
+
if (err) {
|
652
|
+
winston.error("Scheduling error: ", err);
|
653
|
+
}
|
654
|
+
winston.info("Scheduling result: ", result);
|
655
|
+
});
|
656
|
+
|
657
|
+
return true;
|
658
|
+
}
|
659
|
+
|
415
660
|
async function startScrape(data) {
|
416
661
|
|
417
662
|
if (!data.gptkey) {
|
@@ -425,7 +670,7 @@ async function startScrape(data) {
|
|
425
670
|
return new Promise((resolve, reject) => {
|
426
671
|
openaiService.singleScrape(data).then(async (resp) => {
|
427
672
|
winston.debug("singleScrape resp: ", resp.data);
|
428
|
-
let status_updated = await updateStatus(data.id,
|
673
|
+
let status_updated = await updateStatus(data.id, 100);
|
429
674
|
winston.verbose("status of kb " + data.id + " updated: " + status_updated);
|
430
675
|
resolve(resp.data);
|
431
676
|
}).catch((err) => {
|
package/routes/project_user.js
CHANGED
@@ -195,7 +195,7 @@ router.post('/', [passport.authenticate(['basic', 'jwt'], { session: false }), v
|
|
195
195
|
uuid_user: uuidv4(),
|
196
196
|
// role: RoleConstants.USER,
|
197
197
|
// - Create project_user endpoint by agent (Ticketing) now is with Guest Role
|
198
|
-
role: RoleConstants.GUEST,
|
198
|
+
role: RoleConstants.GUEST,
|
199
199
|
user_available: false,
|
200
200
|
tags: req.body.tags,
|
201
201
|
createdBy: req.user.id,
|
@@ -228,6 +228,11 @@ router.put('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
|
|
228
228
|
if (req.body.max_assigned_chat!=undefined) {
|
229
229
|
update.max_assigned_chat = req.body.max_assigned_chat;
|
230
230
|
}
|
231
|
+
|
232
|
+
if (req.body.number_assigned_requests!=undefined) {
|
233
|
+
update.number_assigned_requests = req.body.number_assigned_requests;
|
234
|
+
}
|
235
|
+
|
231
236
|
if (req.body.attributes!=undefined) {
|
232
237
|
update.attributes = req.body.attributes;
|
233
238
|
}
|
@@ -287,6 +292,10 @@ router.put('/:project_userid', [passport.authenticate(['basic', 'jwt'], { sessio
|
|
287
292
|
update.max_assigned_chat = req.body.max_assigned_chat;
|
288
293
|
}
|
289
294
|
|
295
|
+
if (req.body.number_assigned_requests!=undefined) {
|
296
|
+
update.number_assigned_requests = req.body.number_assigned_requests;
|
297
|
+
}
|
298
|
+
|
290
299
|
if (req.body.attributes!=undefined) {
|
291
300
|
update.attributes = req.body.attributes;
|
292
301
|
}
|
package/services/QuoteManager.js
CHANGED
@@ -5,11 +5,11 @@ const messageEvent = require('../event/messageEvent');
|
|
5
5
|
const emailEvent = require('../event/emailEvent');
|
6
6
|
|
7
7
|
const PLANS_LIST = {
|
8
|
-
FREE_TRIAL: { requests: 3000, messages: 0, tokens: 250000, email: 200 }, // same as PREMIUM
|
9
|
-
SANDBOX: { requests: 200, messages: 0, tokens: 10000, email: 200 },
|
10
|
-
BASIC: { requests: 800, messages: 0, tokens: 50000, email: 200 },
|
11
|
-
PREMIUM: { requests: 3000, messages: 0, tokens: 250000, email: 200 },
|
12
|
-
CUSTOM: { requests: 3000, messages: 0, tokens: 250000, email: 200 }
|
8
|
+
FREE_TRIAL: { requests: 3000, messages: 0, tokens: 250000, email: 200, kbs: 50 }, // same as PREMIUM
|
9
|
+
SANDBOX: { requests: 200, messages: 0, tokens: 10000, email: 200, kbs: 50 },
|
10
|
+
BASIC: { requests: 800, messages: 0, tokens: 50000, email: 200, kbs: 150},
|
11
|
+
PREMIUM: { requests: 3000, messages: 0, tokens: 250000, email: 200, kbs: 300},
|
12
|
+
CUSTOM: { requests: 3000, messages: 0, tokens: 250000, email: 200, kbs: 300}
|
13
13
|
}
|
14
14
|
|
15
15
|
const typesList = ['requests', 'messages', 'email', 'tokens']
|
@@ -58,7 +58,7 @@ class QuoteManager {
|
|
58
58
|
|
59
59
|
this.project = project;
|
60
60
|
let key = await this.generateKey(email, 'email');
|
61
|
-
winston.
|
61
|
+
winston.verbose("[QuoteManager] incrementEmailCount key: " + key);
|
62
62
|
|
63
63
|
await this.tdCache.incr(key)
|
64
64
|
return key;
|
@@ -68,7 +68,7 @@ class QuoteManager {
|
|
68
68
|
|
69
69
|
this.project = project;
|
70
70
|
let key = await this.generateKey(data, 'tokens');
|
71
|
-
winston.
|
71
|
+
winston.verbose("[QuoteManager] incrementTokenCount key: " + key);
|
72
72
|
|
73
73
|
if (quotes_enabled === false) {
|
74
74
|
winston.debug("QUOTES DISABLED - incrementTokenCount")
|
@@ -83,8 +83,8 @@ class QuoteManager {
|
|
83
83
|
|
84
84
|
async generateKey(object, type) {
|
85
85
|
|
86
|
-
winston.
|
87
|
-
winston.
|
86
|
+
winston.debug("generateKey object ", object)
|
87
|
+
winston.debug("generateKey type " + type)
|
88
88
|
let subscriptionDate;
|
89
89
|
if (this.project.profile.subStart) {
|
90
90
|
subscriptionDate = this.project.profile.subStart;
|
@@ -92,7 +92,7 @@ class QuoteManager {
|
|
92
92
|
subscriptionDate = this.project.createdAt;
|
93
93
|
}
|
94
94
|
let objectDate = object.createdAt;
|
95
|
-
winston.
|
95
|
+
winston.debug("objectDate " + objectDate);
|
96
96
|
|
97
97
|
// converts date in timestamps and transform from ms to s
|
98
98
|
const objectDateTimestamp = ceil(objectDate.getTime() / 1000);
|
@@ -114,7 +114,7 @@ class QuoteManager {
|
|
114
114
|
|
115
115
|
this.project = project;
|
116
116
|
let key = await this.generateKey(object, type);
|
117
|
-
winston.
|
117
|
+
winston.verbose("[QuoteManager] getCurrentQuote key: " + key);
|
118
118
|
|
119
119
|
let quote = await this.tdCache.get(key);
|
120
120
|
return Number(quote);
|
@@ -147,17 +147,17 @@ class QuoteManager {
|
|
147
147
|
*/
|
148
148
|
async checkQuote(project, object, type) {
|
149
149
|
|
150
|
-
winston.
|
150
|
+
winston.verbose("checkQuote type " + type);
|
151
151
|
if (quotes_enabled === false) {
|
152
|
-
winston.
|
152
|
+
winston.verbose("QUOTES DISABLED - checkQuote for type " + type);
|
153
153
|
return true;
|
154
154
|
}
|
155
155
|
|
156
156
|
this.project = project;
|
157
157
|
let limits = await this.getPlanLimits();
|
158
|
-
winston.
|
158
|
+
winston.verbose("limits for current plan: ", limits)
|
159
159
|
let quote = await this.getCurrentQuote(project, object, type);
|
160
|
-
winston.
|
160
|
+
winston.verbose("getCurrentQuote resp: ", quote)
|
161
161
|
|
162
162
|
if (quote == null) {
|
163
163
|
return true;
|
@@ -171,7 +171,11 @@ class QuoteManager {
|
|
171
171
|
}
|
172
172
|
|
173
173
|
|
174
|
-
async getPlanLimits() {
|
174
|
+
async getPlanLimits(project) {
|
175
|
+
|
176
|
+
if (project) {
|
177
|
+
this.project = project
|
178
|
+
};
|
175
179
|
|
176
180
|
let limits;
|
177
181
|
if (this.project.profile.type === 'payment') {
|
@@ -222,6 +226,8 @@ class QuoteManager {
|
|
222
226
|
}
|
223
227
|
}
|
224
228
|
|
229
|
+
winston.info("QUOTES ENABLED ? ", quotes_enabled);
|
230
|
+
|
225
231
|
// TODO - Try to generalize to avoid repetition
|
226
232
|
let incrementEventHandler = (object) => { }
|
227
233
|
let checkEventHandler = (object) => { }
|
@@ -244,7 +250,7 @@ class QuoteManager {
|
|
244
250
|
let result = await this.incrementRequestsCount(payload.project, payload.request);
|
245
251
|
return result;
|
246
252
|
} else {
|
247
|
-
winston.
|
253
|
+
winston.verbose("QUOTES DISABLED - request.create.quote event")
|
248
254
|
}
|
249
255
|
})
|
250
256
|
// REQUESTS EVENTS - END
|
@@ -267,7 +273,7 @@ class QuoteManager {
|
|
267
273
|
let result = await this.incrementMessagesCount(payload.project, payload.message);
|
268
274
|
return result;
|
269
275
|
} else {
|
270
|
-
winston.
|
276
|
+
winston.verbose("QUOTES DISABLED - message.create.quote event")
|
271
277
|
}
|
272
278
|
})
|
273
279
|
// MESSAGES EVENTS - END
|
@@ -286,11 +292,11 @@ class QuoteManager {
|
|
286
292
|
|
287
293
|
emailEvent.on('email.send.quote', async (payload) => {
|
288
294
|
if (quotes_enabled === true) {
|
289
|
-
winston.
|
295
|
+
winston.verbose("email.send event catched");
|
290
296
|
let result = await this.incrementEmailCount(payload.project, payload.email);
|
291
297
|
return result;
|
292
298
|
} else {
|
293
|
-
winston.
|
299
|
+
winston.verbose("QUOTES DISABLED - email.send event")
|
294
300
|
}
|
295
301
|
})
|
296
302
|
// EMAIL EVENTS - END
|
@@ -0,0 +1,33 @@
|
|
1
|
+
let JobManager = require("jobs-worker-queued");
|
2
|
+
let winston = require('../config/winston');
|
3
|
+
|
4
|
+
let jobManager;
|
5
|
+
|
6
|
+
class Scheduler {
|
7
|
+
|
8
|
+
constructor(config) {
|
9
|
+
|
10
|
+
if (!config) {
|
11
|
+
throw new Error('(Scheduler) config is mandatory');
|
12
|
+
}
|
13
|
+
|
14
|
+
if (!config.jobManager) {
|
15
|
+
throw new Error('(Scheduler) config.jobManager is mandatory');
|
16
|
+
}
|
17
|
+
|
18
|
+
this.jobManager = config.jobManager;
|
19
|
+
}
|
20
|
+
|
21
|
+
trainSchedule(data, callback) {
|
22
|
+
|
23
|
+
winston.debug("(trainScheduler) data: ", data);
|
24
|
+
this.jobManager.publish(data, (err, ok) => {
|
25
|
+
let response_data = { success: true, message: "Scheduled" };
|
26
|
+
if (callback) {
|
27
|
+
callback(err, response_data);
|
28
|
+
}
|
29
|
+
});
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
module.exports = { Scheduler };
|