@tiledesk/tiledesk-server 2.10.65 → 2.10.67
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 +9 -0
- package/app.js +4 -1
- package/models/chatbotTypes.js +6 -0
- package/models/faq_kb.js +7 -0
- package/models/webhook.js +46 -0
- package/package.json +2 -2
- package/pubmodules/trigger/start.js +2 -1
- package/routes/copilot.js +80 -0
- package/routes/faq_kb.js +3 -2
- package/routes/webhook.js +85 -0
- package/routes/webhooks.js +156 -0
- package/services/QuoteManager.js +40 -17
- package/services/faqService.js +170 -66
- package/services/webhookService.js +72 -0
- package/test/faqService.js +8 -5
- package/test/kbRoute.js +92 -113
- package/test/quoteManager.js +4 -2
- package/test/requestService.js +4 -3
- package/test/userRequestRoute.js +2 -1
- package/test/webhookRoute.js +376 -0
- package/test-int/bot.js +6 -5
- package/utils/httpUtil.js +51 -19
package/CHANGELOG.md
CHANGED
@@ -5,6 +5,15 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.10.67
|
9
|
+
- Added route for webhooks
|
10
|
+
- Added endpoint to run webhook
|
11
|
+
- Added chatbot subtypes
|
12
|
+
- Updated tybot-connector to 0.4.0
|
13
|
+
|
14
|
+
# 2.10.66
|
15
|
+
- Updated QuoteService with new plans
|
16
|
+
|
8
17
|
# 2.10.65
|
9
18
|
- fix issue con /rating called by chatbot
|
10
19
|
|
package/app.js
CHANGED
@@ -144,6 +144,8 @@ var email = require('./routes/email');
|
|
144
144
|
var property = require('./routes/property');
|
145
145
|
var segment = require('./routes/segment');
|
146
146
|
var webhook = require('./routes/webhook');
|
147
|
+
var webhooks = require('./routes/webhooks');
|
148
|
+
var copilot = require('./routes/copilot');
|
147
149
|
|
148
150
|
var bootDataLoader = require('./services/bootDataLoader');
|
149
151
|
var settingDataLoader = require('./services/settingDataLoader');
|
@@ -612,7 +614,8 @@ app.use('/:projectid/kb', [passport.authenticate(['basic', 'jwt'], { session: fa
|
|
612
614
|
|
613
615
|
app.use('/:projectid/logs', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], logs);
|
614
616
|
|
615
|
-
|
617
|
+
app.use('/:projectid/webhooks', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('admin')], webhooks);
|
618
|
+
app.use('/:projectid/copilot', [passport.authenticate(['basic', 'jwt'], { session: false }), validtoken, roleChecker.hasRole('agent')], copilot);
|
616
619
|
|
617
620
|
|
618
621
|
if (pubModulesManager) {
|
package/models/faq_kb.js
CHANGED
@@ -43,6 +43,13 @@ var Faq_kbSchema = new Schema({
|
|
43
43
|
default: 'internal',
|
44
44
|
index: true
|
45
45
|
},
|
46
|
+
subtype: {
|
47
|
+
type: String,
|
48
|
+
default: function() {
|
49
|
+
return this.type === 'tilebot' ? 'chatbot' : undefined;
|
50
|
+
},
|
51
|
+
index: true
|
52
|
+
},
|
46
53
|
// external: {
|
47
54
|
// type: Boolean,
|
48
55
|
// default: false
|
@@ -0,0 +1,46 @@
|
|
1
|
+
const mongoose = require('mongoose');
|
2
|
+
const { customAlphabet } = require('nanoid');
|
3
|
+
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 32);
|
4
|
+
|
5
|
+
const WebhookSchema = mongoose.Schema({
|
6
|
+
webhook_id: {
|
7
|
+
type: String,
|
8
|
+
default: () => nanoid(),
|
9
|
+
unique: true,
|
10
|
+
required: true
|
11
|
+
},
|
12
|
+
id_project: {
|
13
|
+
type: String,
|
14
|
+
required: true
|
15
|
+
},
|
16
|
+
chatbot_id: {
|
17
|
+
type: String,
|
18
|
+
required: true
|
19
|
+
},
|
20
|
+
block_id: {
|
21
|
+
type: String,
|
22
|
+
required: true,
|
23
|
+
},
|
24
|
+
async: {
|
25
|
+
type: Boolean,
|
26
|
+
required: true,
|
27
|
+
default: true
|
28
|
+
},
|
29
|
+
copilot: {
|
30
|
+
type: Boolean,
|
31
|
+
required: false
|
32
|
+
}
|
33
|
+
}, {
|
34
|
+
timestamps: true
|
35
|
+
})
|
36
|
+
|
37
|
+
WebhookSchema.index({ id_project: 1, chatbot_id: 1}, { unique: true })
|
38
|
+
|
39
|
+
const Webhook = mongoose.model("Webhook", WebhookSchema);
|
40
|
+
|
41
|
+
if (process.env.MONGOOSE_SYNCINDEX) {
|
42
|
+
Webhook.syncIndexes();
|
43
|
+
winston.verbose("Webhook syncIndexes");
|
44
|
+
}
|
45
|
+
|
46
|
+
module.exports = { Webhook };
|
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.67",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -47,7 +47,7 @@
|
|
47
47
|
"@tiledesk/tiledesk-messenger-connector": "^0.1.23",
|
48
48
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
49
49
|
"@tiledesk/tiledesk-telegram-connector": "^0.1.14",
|
50
|
-
"@tiledesk/tiledesk-tybot-connector": "^0.
|
50
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.4.0",
|
51
51
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.81",
|
52
52
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.11",
|
53
53
|
"@tiledesk/tiledesk-sms-connector": "^0.1.11",
|
@@ -5,6 +5,7 @@ var projectEvent = require('../../event/projectEvent');
|
|
5
5
|
var winston = require('../../config/winston');
|
6
6
|
|
7
7
|
var rulesTrigger = require('./rulesTrigger');
|
8
|
+
const chatbotTypeConstants = require('../../models/chatbotTypes');
|
8
9
|
|
9
10
|
|
10
11
|
function saveTrigger(trigger) {
|
@@ -20,7 +21,7 @@ projectEvent.on('project.create', async (project) => {
|
|
20
21
|
|
21
22
|
|
22
23
|
|
23
|
-
var botIdentity = await faqService.create("Bot", undefined, project._id, "system", "identity", "An identity bot");
|
24
|
+
var botIdentity = await faqService.create("Bot", undefined, project._id, "system", "identity", chatbotTypeConstants.CHATBOT, "An identity bot");
|
24
25
|
var botIdentityId = "bot_"+botIdentity.id;
|
25
26
|
winston.debug("botIdentityId:"+botIdentityId);
|
26
27
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
let express = require('express');
|
2
|
+
let router = express.Router();
|
3
|
+
let winston = require('../config/winston');
|
4
|
+
const { Webhook } = require('../models/webhook');
|
5
|
+
const webhookService = require('../services/webhookService');
|
6
|
+
|
7
|
+
router.get('/', async (req, res) => {
|
8
|
+
|
9
|
+
let id_project = req.projectid;
|
10
|
+
let payload = req.body;
|
11
|
+
let params = req.query;
|
12
|
+
let request_id = req.query.request_id;
|
13
|
+
if (!request_id) {
|
14
|
+
return res.status(400).send({ success: false, error: "Missing query params request_id" })
|
15
|
+
}
|
16
|
+
payload.request_id = request_id;
|
17
|
+
payload.webhook_query_params = params;
|
18
|
+
|
19
|
+
let webhooks = await Webhook.find({ id_project: id_project, copilot: true }).catch((err) => {
|
20
|
+
winston.error("Error finding copilot webhooks: ", err);
|
21
|
+
return res.status(500).send({ success: false, error: err });
|
22
|
+
})
|
23
|
+
|
24
|
+
let promises = webhooks.map((w) =>
|
25
|
+
webhookService.run(w, payload)
|
26
|
+
.then((response) => {
|
27
|
+
return response;
|
28
|
+
}).catch((err) => {
|
29
|
+
winston.error("Error running webhook: ", err);
|
30
|
+
return;
|
31
|
+
})
|
32
|
+
)
|
33
|
+
|
34
|
+
Promise.all(promises).then((result) => {
|
35
|
+
return res.status(200).send(result);
|
36
|
+
}).catch((err) => {
|
37
|
+
// Should never executed - check it
|
38
|
+
return res.status(500).send({ success: false, error: err });
|
39
|
+
})
|
40
|
+
|
41
|
+
})
|
42
|
+
|
43
|
+
router.post('/', async (req, res) => {
|
44
|
+
|
45
|
+
let id_project = req.projectid;
|
46
|
+
let payload = req.body;
|
47
|
+
let params = req.query;
|
48
|
+
let request_id = req.query.request_id;
|
49
|
+
if (!request_id) {
|
50
|
+
return res.status(400).send({ success: false, error: "Missing query params request_id" })
|
51
|
+
}
|
52
|
+
payload.request_id = request_id;
|
53
|
+
payload.webhook_query_params = params;
|
54
|
+
|
55
|
+
let webhooks = await Webhook.find({ id_project: id_project, copilot: true }).catch((err) => {
|
56
|
+
winston.error("Error finding copilot webhooks: ", err);
|
57
|
+
return res.status(500).send({ success: false, error: err });
|
58
|
+
})
|
59
|
+
|
60
|
+
let promises = webhooks.map((w) =>
|
61
|
+
webhookService.run(w, payload)
|
62
|
+
.then((response) => {
|
63
|
+
return response;
|
64
|
+
}).catch((err) => {
|
65
|
+
winston.error("Error running webhook: ", err);
|
66
|
+
return;
|
67
|
+
})
|
68
|
+
)
|
69
|
+
|
70
|
+
Promise.all(promises).then((result) => {
|
71
|
+
return res.status(200).send(result);
|
72
|
+
}).catch((err) => {
|
73
|
+
// Should never executed - check it
|
74
|
+
return res.status(500).send({ success: false, error: err });
|
75
|
+
})
|
76
|
+
|
77
|
+
})
|
78
|
+
|
79
|
+
|
80
|
+
module.exports = router;
|
package/routes/faq_kb.js
CHANGED
@@ -18,6 +18,7 @@ const trainingService = require('../services/trainingService');
|
|
18
18
|
var roleChecker = require('../middleware/has-role');
|
19
19
|
const roleConstants = require('../models/roleConstants');
|
20
20
|
const errorCodes = require('../errorCodes');
|
21
|
+
const chatbotTypeConstants = require('../models/chatbotTypes');
|
21
22
|
|
22
23
|
let chatbot_templates_api_url = process.env.CHATBOT_TEMPLATES_API_URL
|
23
24
|
|
@@ -50,7 +51,7 @@ router.post('/', roleChecker.hasRole('admin'), async function (req, res) {
|
|
50
51
|
//return res.status(403).send({ success: false, error: "Maximum number of chatbots reached for the current plan", plan_limit: chatbots_limit })
|
51
52
|
}
|
52
53
|
|
53
|
-
faqService.create(req.body.name, req.body.url, req.projectid, req.user.id, req.body.type, req.body.description, req.body.webhook_url, req.body.webhook_enabled, req.body.language, req.body.template, req.body.mainCategory, req.body.intentsEngine, req.body.attributes).then(function (savedFaq_kb) {
|
54
|
+
faqService.create(req.body.name, req.body.url, req.projectid, req.user.id, req.body.type, req.body.subtype, req.body.description, req.body.webhook_url, req.body.webhook_enabled, req.body.language, req.body.template, req.body.mainCategory, req.body.intentsEngine, req.body.attributes).then(function (savedFaq_kb) {
|
54
55
|
res.json(savedFaq_kb);
|
55
56
|
});
|
56
57
|
|
@@ -683,7 +684,7 @@ router.post('/importjson/:id_faq_kb', roleChecker.hasRole('admin'), upload.singl
|
|
683
684
|
// **** CREATE TRUE option ****
|
684
685
|
// ****************************
|
685
686
|
if (req.query.create === 'true') {
|
686
|
-
let savedChatbot = await faqService.create(json.name, undefined, req.projectid, req.user.id, "tilebot", json.description, json.webhook_url, json.webhook_enabled, json.language, undefined, undefined, undefined, json.attributes)
|
687
|
+
let savedChatbot = await faqService.create(json.name, undefined, req.projectid, req.user.id, "tilebot", json.subtype, json.description, json.webhook_url, json.webhook_enabled, json.language, undefined, undefined, undefined, json.attributes)
|
687
688
|
.catch((err) => {
|
688
689
|
winston.error("Error creating new chatbot")
|
689
690
|
return res.status(400).send({ succes: false, message: "Error creatings new chatbot", error: err })
|
package/routes/webhook.js
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
var express = require('express');
|
2
2
|
var router = express.Router();
|
3
|
+
const uuidv4 = require('uuid/v4');
|
3
4
|
var { KB, Namespace } = require('../models/kb_setting');
|
4
5
|
var winston = require('../config/winston');
|
5
6
|
const JobManager = require('../utils/jobs-worker-queue-manager/JobManagerV2');
|
6
7
|
const { Scheduler } = require('../services/Scheduler');
|
7
8
|
const { AiReindexService } = require('../services/aiReindexService');
|
9
|
+
const { Webhook } = require('../models/webhook');
|
10
|
+
const httpUtil = require('../utils/httpUtil');
|
11
|
+
var jwt = require('jsonwebtoken');
|
12
|
+
const Faq_kb = require('../models/faq_kb');
|
13
|
+
const webhookService = require('../services/webhookService');
|
14
|
+
|
15
|
+
const port = process.env.PORT || '3000';
|
16
|
+
let TILEBOT_ENDPOINT = "http://localhost:" + port + "/modules/tilebot/";;
|
17
|
+
if (process.env.TILEBOT_ENDPOINT) {
|
18
|
+
TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT + "/"
|
19
|
+
}
|
20
|
+
winston.debug("TILEBOT_ENDPOINT: " + TILEBOT_ENDPOINT);
|
8
21
|
|
9
22
|
const KB_WEBHOOK_TOKEN = process.env.KB_WEBHOOK_TOKEN || 'kbcustomtoken';
|
10
23
|
const AMQP_MANAGER_URL = process.env.AMQP_MANAGER_URL;
|
@@ -167,6 +180,63 @@ router.post('/kb/status', async (req, res) => {
|
|
167
180
|
|
168
181
|
})
|
169
182
|
|
183
|
+
router.all('/:webhook_id', async (req, res) => {
|
184
|
+
|
185
|
+
let webhook_id = req.params.webhook_id;
|
186
|
+
let payload = req.body;
|
187
|
+
payload.webhook_http_method = req.method;
|
188
|
+
let params = req.query;
|
189
|
+
if (params) {
|
190
|
+
payload.webhook_query_params = params;
|
191
|
+
}
|
192
|
+
|
193
|
+
let webhook = await Webhook.findOne({ webhook_id: webhook_id }).catch((err) => {
|
194
|
+
winston.error("Error finding webhook: ", err);
|
195
|
+
return res.status(500).send({ success: false, error: err });
|
196
|
+
})
|
197
|
+
|
198
|
+
if (!webhook) {
|
199
|
+
winston.warn("Webhook not found with id " + webhook_id);
|
200
|
+
return res.status(404).send({ success: false, error: "Webhook not found with id " + webhook_id });
|
201
|
+
}
|
202
|
+
|
203
|
+
webhookService.run(webhook, payload).then((response) => {
|
204
|
+
return res.status(200).send(response);
|
205
|
+
}).catch((err) => {
|
206
|
+
let status = err.status || 500;
|
207
|
+
return res.status(status).send(err.data);
|
208
|
+
})
|
209
|
+
|
210
|
+
// let chatbot = await Faq_kb.findById(webhook.chatbot_id).select("+secret").catch((err) => {
|
211
|
+
// winston.error("Error finding chatbot ", err);
|
212
|
+
// return res.status(500).send({ success: false, error: "Error finding chatbot with id " + webhook.chatbot_id})
|
213
|
+
// })
|
214
|
+
|
215
|
+
// if (!chatbot) {
|
216
|
+
// winston.verbose("Chatbot not found with id " + webhook.chatbot_id);
|
217
|
+
// return res.status(404).send({ success: false, error: "Chatbot not found with id " + webhook.chatbot_id })
|
218
|
+
// }
|
219
|
+
|
220
|
+
// let token = await generateChatbotToken(chatbot);
|
221
|
+
|
222
|
+
// let url = TILEBOT_ENDPOINT + 'block/' + webhook.id_project + "/" + webhook.chatbot_id + "/" + webhook.block_id;
|
223
|
+
// winston.info("Webhook chatbot URL: ", url);
|
224
|
+
|
225
|
+
// payload.async = webhook.async;
|
226
|
+
// payload.token = token;
|
227
|
+
|
228
|
+
// if (process.env.NODE_ENV === 'test') {
|
229
|
+
// return res.status(200).send({ success: true, message: "Webhook disabled in test mode"})
|
230
|
+
// }
|
231
|
+
|
232
|
+
// let response = await httpUtil.post(url, payload).catch((err) => {
|
233
|
+
// winston.error("Error calling webhook on post: ", err);
|
234
|
+
// return res.status(500).send({ success: false, error: err });
|
235
|
+
// })
|
236
|
+
|
237
|
+
// res.status(200).send(response.data);
|
238
|
+
})
|
239
|
+
|
170
240
|
async function scheduleScrape(resources) {
|
171
241
|
|
172
242
|
let scheduler = new Scheduler({ jobManager: jobManager });
|
@@ -185,4 +255,19 @@ async function scheduleScrape(resources) {
|
|
185
255
|
return true;
|
186
256
|
}
|
187
257
|
|
258
|
+
async function generateChatbotToken(chatbot) {
|
259
|
+
let signOptions = {
|
260
|
+
issuer: 'https://tiledesk.com',
|
261
|
+
subject: 'bot',
|
262
|
+
audience: 'https://tiledesk.com/bots/' + chatbot._id,
|
263
|
+
jwtid: uuidv4()
|
264
|
+
};
|
265
|
+
|
266
|
+
let botPayload = chatbot.toObject();
|
267
|
+
let botSecret = botPayload.secret;
|
268
|
+
|
269
|
+
var bot_token = jwt.sign(botPayload, botSecret, signOptions);
|
270
|
+
return bot_token;
|
271
|
+
}
|
272
|
+
|
188
273
|
module.exports = router;
|
@@ -0,0 +1,156 @@
|
|
1
|
+
var express = require('express');
|
2
|
+
var router = express.Router();
|
3
|
+
var winston = require('../config/winston');
|
4
|
+
const { Webhook } = require('../models/webhook');
|
5
|
+
const httpUtil = require('../utils/httpUtil');
|
6
|
+
const { customAlphabet } = require('nanoid');
|
7
|
+
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 32);
|
8
|
+
|
9
|
+
// const port = process.env.PORT || '3000';
|
10
|
+
// let TILEBOT_ENDPOINT = "http://localhost:" + port + "/modules/tilebot/ext/";;
|
11
|
+
// if (process.env.TILEBOT_ENDPOINT) {
|
12
|
+
// TILEBOT_ENDPOINT = process.env.TILEBOT_ENDPOINT + "/ext/"
|
13
|
+
// }
|
14
|
+
// winston.debug("TILEBOT_ENDPOINT: " + TILEBOT_ENDPOINT);
|
15
|
+
|
16
|
+
|
17
|
+
router.get('/:chatbot_id/', async (req, res) => {
|
18
|
+
|
19
|
+
let id_project = req.projectid;
|
20
|
+
let chatbot_id = req.params.chatbot_id;
|
21
|
+
|
22
|
+
let webhook = await Webhook.findOne({ id_project: id_project, chatbot_id: chatbot_id }).catch((err) => {
|
23
|
+
winston.error("Error finding webhook: ", err);
|
24
|
+
return res.status(500).send({ success: false, error: "Error findin webhook with for chatbot " + chatbot_id });
|
25
|
+
})
|
26
|
+
|
27
|
+
if (!webhook) {
|
28
|
+
winston.verbose("Webhook not found for chatbot " + chatbot_id);
|
29
|
+
return res.status(404).send({ success: false, error: "Webhook not found for chatbot " + chatbot_id });
|
30
|
+
}
|
31
|
+
|
32
|
+
res.status(200).send(webhook);
|
33
|
+
|
34
|
+
})
|
35
|
+
|
36
|
+
|
37
|
+
router.post('/', async (req, res) => {
|
38
|
+
|
39
|
+
let id_project = req.projectid;
|
40
|
+
|
41
|
+
let webhook = new Webhook({
|
42
|
+
id_project: id_project,
|
43
|
+
chatbot_id: req.body.chatbot_id || req.body.id_faq_kb,
|
44
|
+
block_id: req.body.block_id,
|
45
|
+
async: req.body.async
|
46
|
+
})
|
47
|
+
|
48
|
+
webhook.save((err, savedWebhook) => {
|
49
|
+
if (err) {
|
50
|
+
if (err.code === 11000) {
|
51
|
+
winston.verbose("Webhook already exists for chatbot " + chatbot_id);
|
52
|
+
return res.status(403).send({ success: false, message: "Webhook already exists for chatbot " + chatbot_id });
|
53
|
+
}
|
54
|
+
winston.error("Error saving new webhook ", err);
|
55
|
+
return res.status(500).send({ success: false, error: err });
|
56
|
+
}
|
57
|
+
|
58
|
+
res.status(200).send(savedWebhook);
|
59
|
+
})
|
60
|
+
|
61
|
+
})
|
62
|
+
|
63
|
+
// router.post('/webhook_id', async (req, res) => {
|
64
|
+
|
65
|
+
// let id_project = req.projectid;
|
66
|
+
// let webhook_id = req.params.webhook_id;
|
67
|
+
// let payload = req.body;
|
68
|
+
|
69
|
+
// let webhook = await Webhook.findOne({ id_project: id_project, webhook_id: webhook_id }).catch((err) => {
|
70
|
+
// winston.error("Error finding webhook: ", err);
|
71
|
+
// return res.status(500).send({ success: false, error: err });
|
72
|
+
// })
|
73
|
+
|
74
|
+
// if (!webhook) {
|
75
|
+
// winston.warn("Webhook not found with id " + webhook_id);
|
76
|
+
// return res.status(404).send({ success: false, error: "Webhook not found with id " + webhook_id });
|
77
|
+
// }
|
78
|
+
|
79
|
+
// let url = TILEBOT_ENDPOINT + 'block/' + id_project + "/" + webhook.chatbot_id + "/" + webhook.block_id;
|
80
|
+
|
81
|
+
// payload.async = webhook.async;
|
82
|
+
|
83
|
+
// let response = httpUtil.post(url, payload).catch((err) => {
|
84
|
+
// winston.error("Error calling webhook on post: ", err);
|
85
|
+
// return res.status(500).send({ success: false, error: err });
|
86
|
+
// })
|
87
|
+
|
88
|
+
// res.status(200).send(response);
|
89
|
+
|
90
|
+
// })
|
91
|
+
|
92
|
+
router.put("/:chatbot_id/regenerate", async (req, res) => {
|
93
|
+
|
94
|
+
let id_project = req.projectid;
|
95
|
+
let chatbot_id = req.params.chatbot_id;
|
96
|
+
|
97
|
+
let update = {
|
98
|
+
webhook_id: nanoid()
|
99
|
+
}
|
100
|
+
|
101
|
+
let updatedWebhook = await Webhook.findOneAndUpdate({ id_project: id_project, chatbot_id: chatbot_id }, update, { new: true }).catch((err) => {
|
102
|
+
winston.error("Error updating webhook ", err);
|
103
|
+
return res.status(500).send({ success: false, error: "Error updating webhook for chatbot " + chatbot_id });
|
104
|
+
})
|
105
|
+
|
106
|
+
if (!updatedWebhook) {
|
107
|
+
winston.verbose("Webhook not found for chatbot " + chatbot_id);
|
108
|
+
return res.status(404).send({ success: false, error: "Webhook not found for chatbot " + chatbot_id });
|
109
|
+
}
|
110
|
+
|
111
|
+
res.status(200).send(updatedWebhook);
|
112
|
+
})
|
113
|
+
|
114
|
+
router.put("/:chatbot_id", async (req, res) => {
|
115
|
+
|
116
|
+
let id_project = req.projectid;
|
117
|
+
let chatbot_id = req.params.chatbot_id;
|
118
|
+
|
119
|
+
let update = {};
|
120
|
+
|
121
|
+
if (req.body.hasOwnProperty("async")) {
|
122
|
+
update.async = req.body.async;
|
123
|
+
}
|
124
|
+
|
125
|
+
if (req.body.hasOwnProperty("copilot")) {
|
126
|
+
update.copilot = req.body.copilot;
|
127
|
+
}
|
128
|
+
|
129
|
+
let updatedWebhook = await Webhook.findOneAndUpdate({ id_project: id_project, chatbot_id: chatbot_id }, update, { new: true }).catch((err) => {
|
130
|
+
winston.error("Error updating webhook ", err);
|
131
|
+
return res.status(500).send({ success: false, error: "Error updating webhook for chatbot " + chatbot_id });
|
132
|
+
})
|
133
|
+
|
134
|
+
if (!updatedWebhook) {
|
135
|
+
winston.verbose("Webhook not found for chatbot " + chatbot_id);
|
136
|
+
return res.status(404).send({ success: false, error: "Webhook not found for chatbot " + chatbot_id });
|
137
|
+
}
|
138
|
+
|
139
|
+
res.status(200).send(updatedWebhook);
|
140
|
+
})
|
141
|
+
|
142
|
+
router.delete("/:chatbot_id", async (req, res) => {
|
143
|
+
|
144
|
+
let id_project = req.projectid;
|
145
|
+
let chatbot_id = req.params.chatbot_id;
|
146
|
+
|
147
|
+
await Webhook.deleteOne({ id_project: id_project, chatbot_id: chatbot_id }).catch((err) => {
|
148
|
+
winston.error("Error deleting webhook ", err);
|
149
|
+
return res.status(500).send({ success: false, error: "Error deleting webhook for chatbot " + chatbot_id });
|
150
|
+
})
|
151
|
+
|
152
|
+
res.status(200).send({ success: true, message: "Webhook for chatbot " + chatbot_id + " deleted successfully" });
|
153
|
+
})
|
154
|
+
|
155
|
+
|
156
|
+
module.exports = router;
|
package/services/QuoteManager.js
CHANGED
@@ -14,16 +14,23 @@ const emailEvent = require('../event/emailEvent');
|
|
14
14
|
// CUSTOM: { requests: 3000, messages: 0, tokens: 5000000, email: 200, chatbots: 20, kbs: 500}
|
15
15
|
// }
|
16
16
|
|
17
|
-
|
18
17
|
const PLANS_LIST = {
|
19
|
-
FREE_TRIAL: { requests: 200, messages: 0, tokens: 100000, voice_duration: 0, email: 200, chatbots: 20, namespace: 3, kbs: 50 }, // same as PREMIUM
|
20
|
-
SANDBOX: { requests: 200, messages: 0, tokens: 100000, voice_duration: 0,
|
21
|
-
BASIC: { requests: 800, messages: 0, tokens: 2000000, voice_duration: 0,
|
22
|
-
PREMIUM: { requests: 3000, messages: 0, tokens: 5000000, voice_duration: 0,
|
23
|
-
TEAM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 0,
|
24
|
-
CUSTOM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 120000, email: 200, chatbots: 50, namespace: 10, kbs: 1000 },
|
18
|
+
//FREE_TRIAL: { requests: 200, messages: 0, tokens: 100000, voice_duration: 0, email: 200, chatbots: 20, namespace: 3, kbs: 50 }, // same as PREMIUM
|
19
|
+
SANDBOX: { requests: 200, messages: 0, tokens: 100000, voice_duration: 0, email: 200, chatbots: 2, namespace: 1, kbs: 50 },
|
20
|
+
BASIC: { requests: 800, messages: 0, tokens: 2000000, voice_duration: 0, email: 200, chatbots: 5, namespace: 1, kbs: 150 },
|
21
|
+
PREMIUM: { requests: 3000, messages: 0, tokens: 5000000, voice_duration: 0, email: 200, chatbots: 20, namespace: 3, kbs: 300 },
|
22
|
+
TEAM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 0, email: 200, chatbots: 50, namespace: 10, kbs: 1000 },
|
23
|
+
//CUSTOM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 120000, email: 200, chatbots: 50, namespace: 10, kbs: 1000 },
|
24
|
+
// FROM MARCH 2025
|
25
|
+
FREE_TRIAL: { requests: 3000, messages: 0, tokens: 5000000, voice_duration: 120000, email: 200, chatbots: 5, namespace: 1, kbs: 50 }, // same as PRO
|
26
|
+
STARTER: { requests: 800, messages: 0, tokens: 2000000, voice_duration: 0, email: 200, chatbots: 5, namespace: 1, kbs: 150 },
|
27
|
+
PRO: { requests: 3000, messages: 0, tokens: 5000000, voice_duration: 0, email: 200, chatbots: 20, namespace: 3, kbs: 300 },
|
28
|
+
BUSINESS: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 0, email: 200, chatbots: 50, namespace: 10, kbs: 1000 },
|
29
|
+
CUSTOM: { requests: 5000, messages: 0, tokens: 10000000, voice_duration: 120000, email: 200, chatbots: 50, namespace: 10, kbs: 1000 }
|
25
30
|
}
|
26
31
|
|
32
|
+
|
33
|
+
|
27
34
|
const typesList = ['requests', 'messages', 'email', 'tokens', 'voice_duration', 'chatbots', 'kbs']
|
28
35
|
|
29
36
|
let quotes_enabled = true;
|
@@ -88,7 +95,7 @@ class QuoteManager {
|
|
88
95
|
winston.debug("QUOTES DISABLED - incrementTokenCount")
|
89
96
|
return key;
|
90
97
|
}
|
91
|
-
|
98
|
+
|
92
99
|
let tokens = data.tokens * data.multiplier;
|
93
100
|
await this.tdCache.incrbyfloat(key, tokens);
|
94
101
|
// await this.tdCache.incrby(key, tokens);
|
@@ -110,7 +117,7 @@ class QuoteManager {
|
|
110
117
|
if (request?.duration) {
|
111
118
|
let duration = Math.round(request.duration / 1000); // from ms to s
|
112
119
|
await this.tdCache.incrby(key, duration);
|
113
|
-
|
120
|
+
|
114
121
|
this.sendEmailIfQuotaExceeded(project, request, 'voice_duration', key);
|
115
122
|
}
|
116
123
|
}
|
@@ -200,7 +207,6 @@ class QuoteManager {
|
|
200
207
|
* Get current quote for a single type (tokens or request or ...)
|
201
208
|
*/
|
202
209
|
async getCurrentQuote(project, object, type) {
|
203
|
-
|
204
210
|
this.project = project;
|
205
211
|
let key = await this.generateKey(object, type);
|
206
212
|
winston.verbose("[QuoteManager] getCurrentQuote key: " + key);
|
@@ -261,7 +267,7 @@ class QuoteManager {
|
|
261
267
|
}
|
262
268
|
|
263
269
|
async checkQuoteForAlert(project, object, type) {
|
264
|
-
|
270
|
+
|
265
271
|
if (quotes_enabled === false) {
|
266
272
|
winston.verbose("QUOTES DISABLED - checkQuote for type " + type);
|
267
273
|
return (null, null);
|
@@ -283,7 +289,7 @@ class QuoteManager {
|
|
283
289
|
}
|
284
290
|
|
285
291
|
async sendEmailIfQuotaExceeded(project, object, type, key) {
|
286
|
-
|
292
|
+
|
287
293
|
let data = await this.checkQuoteForAlert(project, object, type);
|
288
294
|
let limits = data.limits;
|
289
295
|
let limit = data.limits[type];
|
@@ -312,7 +318,7 @@ class QuoteManager {
|
|
312
318
|
}
|
313
319
|
|
314
320
|
emailEvent.emit('email.send.quote.checkpoint', data);
|
315
|
-
await this.tdCache.set(nKey, 'true', {EX: 2592000}); //seconds in one month = 2592000
|
321
|
+
await this.tdCache.set(nKey, 'true', { EX: 2592000 }); //seconds in one month = 2592000
|
316
322
|
} else {
|
317
323
|
winston.verbose("Quota checkpoint reached email already sent.")
|
318
324
|
}
|
@@ -320,7 +326,7 @@ class QuoteManager {
|
|
320
326
|
}
|
321
327
|
|
322
328
|
async percentageCalculator(limit, quote) {
|
323
|
-
|
329
|
+
|
324
330
|
let p = (quote / limit) * 100;
|
325
331
|
|
326
332
|
if (p >= 100) { return 100; }
|
@@ -339,10 +345,10 @@ class QuoteManager {
|
|
339
345
|
let requests_key = await this.generateKey(obj, 'requests');
|
340
346
|
let tokens_key = await this.generateKey(obj, 'tokens');
|
341
347
|
let email_key = await this.generateKey(obj, 'email');
|
342
|
-
|
348
|
+
|
343
349
|
let checkpoints = ['50', '75', '95', '100']
|
344
350
|
|
345
|
-
checkpoints.forEach(
|
351
|
+
checkpoints.forEach(async (checkpoint) => {
|
346
352
|
let nrequests_key = requests_key + ":notify:" + checkpoint;
|
347
353
|
let ntokens_key = tokens_key + ":notify:" + checkpoint;
|
348
354
|
let nemail_key = email_key + ":notify:" + checkpoint;
|
@@ -390,7 +396,22 @@ class QuoteManager {
|
|
390
396
|
|
391
397
|
if (this.project.profile.type === 'payment') {
|
392
398
|
|
399
|
+
if (this.project.isActiveSubscription === false) {
|
400
|
+
limits = PLANS_LIST.SANDBOX;
|
401
|
+
return limits;
|
402
|
+
|
403
|
+
}
|
404
|
+
|
393
405
|
switch (plan) {
|
406
|
+
case 'Starter':
|
407
|
+
limits = PLANS_LIST.STARTER
|
408
|
+
break;
|
409
|
+
case 'Pro':
|
410
|
+
limits = PLANS_LIST.PRO
|
411
|
+
break;
|
412
|
+
case 'Business':
|
413
|
+
limits = PLANS_LIST.BUSINESS
|
414
|
+
break;
|
394
415
|
case 'Basic':
|
395
416
|
limits = PLANS_LIST.BASIC;
|
396
417
|
break;
|
@@ -415,6 +436,7 @@ class QuoteManager {
|
|
415
436
|
default:
|
416
437
|
limits = PLANS_LIST.FREE_TRIAL;
|
417
438
|
}
|
439
|
+
|
418
440
|
} else {
|
419
441
|
|
420
442
|
if (this.project.trialExpired === false) {
|
@@ -424,6 +446,7 @@ class QuoteManager {
|
|
424
446
|
}
|
425
447
|
|
426
448
|
}
|
449
|
+
|
427
450
|
if (this.project?.profile?.quotes) {
|
428
451
|
let profile_quotes = this.project?.profile?.quotes;
|
429
452
|
const merged_quotes = Object.assign({}, limits, profile_quotes);
|
@@ -454,7 +477,7 @@ class QuoteManager {
|
|
454
477
|
winston.debug("Subscription date from project createdAt: " + subscriptionDate.toISOString());
|
455
478
|
}
|
456
479
|
}
|
457
|
-
|
480
|
+
|
458
481
|
let now = moment();
|
459
482
|
winston.debug("now: ", now);
|
460
483
|
|