@tiledesk/tiledesk-server 2.4.100 → 2.4.102

Sign up to get free protection for your applications and to get access to all the features.
package/routes/users.js CHANGED
@@ -195,7 +195,11 @@ router.post('/loginemail', function (req, res) {
195
195
  let chatbot_id = req.body.bot_id;
196
196
 
197
197
  if (!project_id) {
198
- res.status(500).send({ success: false, error: "missing 'id_project' field" })
198
+ res.status(500).send({ success: false, error: "missing 'id_project' field" });
199
+ }
200
+
201
+ if (!chatbot_id) {
202
+ res.status(500).send({ success: false, error: "missing 'bot_id' field" });
199
203
  }
200
204
 
201
205
  if (!chatbot_id) {
@@ -0,0 +1,304 @@
1
+ const { ceil, floor } = require('lodash');
2
+ let winston = require('../config/winston');
3
+ const requestEvent = require('../event/requestEvent');
4
+ const messageEvent = require('../event/messageEvent');
5
+ const emailEvent = require('../event/emailEvent');
6
+
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 }
13
+ }
14
+
15
+ const typesList = ['requests', 'messages', 'email', 'tokens']
16
+
17
+ let quotes_enabled = true;
18
+
19
+ class QuoteManager {
20
+
21
+ constructor(config) {
22
+
23
+ if (!config) {
24
+ throw new Error('config is mandatory')
25
+ }
26
+
27
+ if (!config.tdCache) {
28
+ throw new Error('config.tdCache is mandatory')
29
+ }
30
+
31
+ this.tdCache = config.tdCache;
32
+ this.project;
33
+
34
+ }
35
+
36
+ // INCREMENT KEY SECTION - START
37
+ async incrementRequestsCount(project, request) {
38
+
39
+ this.project = project;
40
+ let key = await this.generateKey(request, 'requests');
41
+ winston.verbose("[QuoteManager] incrementRequestsCount key: " + key);
42
+
43
+ await this.tdCache.incr(key)
44
+ return key;
45
+ }
46
+
47
+ async incrementMessagesCount(project, message) {
48
+
49
+ this.project = project;
50
+ let key = await this.generateKey(message, 'messages');
51
+ winston.verbose("[QuoteManager] incrementMessagesCount key: " + key);
52
+
53
+ await this.tdCache.incr(key)
54
+ return key;
55
+ }
56
+
57
+ async incrementEmailCount(project, email) {
58
+
59
+ this.project = project;
60
+ let key = await this.generateKey(email, 'email');
61
+ winston.info("[QuoteManager] incrementEmailCount key: " + key);
62
+
63
+ await this.tdCache.incr(key)
64
+ return key;
65
+ }
66
+
67
+ async incrementTokenCount(project, data) { // ?? cosa passo? il messaggio per vedere la data?
68
+
69
+ this.project = project;
70
+ let key = await this.generateKey(data, 'tokens');
71
+ winston.info("[QuoteManager] incrementTokenCount key: " + key);
72
+
73
+ if (quotes_enabled === false) {
74
+ winston.debug("QUOTES DISABLED - incrementTokenCount")
75
+ return key;
76
+ }
77
+
78
+ await this.tdCache.incrby(key, data.tokens);
79
+ return key;
80
+ }
81
+ // INCREMENT KEY SECTION - END
82
+
83
+
84
+ async generateKey(object, type) {
85
+
86
+ winston.info("generateKey object ", object)
87
+ winston.info("generateKey type " + type)
88
+ let subscriptionDate;
89
+ if (this.project.profile.subStart) {
90
+ subscriptionDate = this.project.profile.subStart;
91
+ } else {
92
+ subscriptionDate = this.project.createdAt;
93
+ }
94
+ let objectDate = object.createdAt;
95
+ winston.info("objectDate " + objectDate);
96
+
97
+ // converts date in timestamps and transform from ms to s
98
+ const objectDateTimestamp = ceil(objectDate.getTime() / 1000);
99
+ const subscriptionDateTimestamp = ceil(subscriptionDate.getTime() / 1000);
100
+
101
+ let ndays = (objectDateTimestamp - subscriptionDateTimestamp) / 86400; // 86400 is the number of seconds in 1 day
102
+ let nmonths = floor(ndays / 30); // number of month to add to the initial subscription date;
103
+
104
+ let date = new Date(subscriptionDate);
105
+ date.setMonth(date.getMonth() + nmonths);
106
+
107
+ return "quotes:" + type + ":" + this.project._id + ":" + date.toLocaleDateString();
108
+ }
109
+
110
+ /**
111
+ * Get current quote for a single type (tokens or request or ...)
112
+ */
113
+ async getCurrentQuote(project, object, type) {
114
+
115
+ this.project = project;
116
+ let key = await this.generateKey(object, type);
117
+ winston.info("[QuoteManager] getCurrentQuote key: " + key);
118
+
119
+ let quote = await this.tdCache.get(key);
120
+ return Number(quote);
121
+ }
122
+
123
+ /**
124
+ * Get quotes for a all types (tokens and request and ...)
125
+ */
126
+ async getAllQuotes(project, obj) {
127
+
128
+ this.project = project;
129
+
130
+ let quotes = {}
131
+ for (let type of typesList) {
132
+
133
+ let key = await this.generateKey(obj, type);
134
+ let quote = await this.tdCache.get(key);
135
+
136
+ quotes[type] = {
137
+ quote: Number(quote)
138
+ };
139
+ }
140
+ return quotes;
141
+ }
142
+
143
+ /**
144
+ * Perform a check on a single type.
145
+ * Returns TRUE if the limit is not reached --> operation can be performed
146
+ * Returns FALSE if the limit is reached --> operation can't be performed
147
+ */
148
+ async checkQuote(project, object, type) {
149
+
150
+ winston.info("checkQuote project ", project);
151
+ winston.info("checkQuote object ", object);
152
+ winston.info("checkQuote type " + type);
153
+ if (quotes_enabled === false) {
154
+ winston.info("QUOTES DISABLED - checkQuote for type " + type);
155
+ return true;
156
+ }
157
+
158
+ this.project = project;
159
+ let limits = await this.getPlanLimits();
160
+ winston.info("limits for current plan: ", limits)
161
+ let quote = await this.getCurrentQuote(project, object, type);
162
+ winston.info("getCurrentQuote resp: ", quote)
163
+
164
+ if (quote == null) {
165
+ return true;
166
+ }
167
+
168
+ if (quote < limits[type]) {
169
+ return true;
170
+ } else {
171
+ return false;
172
+ }
173
+ }
174
+
175
+
176
+ async getPlanLimits() {
177
+
178
+ let limits;
179
+ if (this.project.profile.type === 'payment') {
180
+
181
+ const plan = this.project.profile.name;
182
+ switch (plan) {
183
+ case 'Sandbox':
184
+ limits = PLANS_LIST.SANDBOX;
185
+ break;
186
+ case 'Basic':
187
+ limits = PLANS_LIST.BASIC;
188
+ break;
189
+ case 'Premium':
190
+ limits = PLANS_LIST.PREMIUM;
191
+ break;
192
+ case 'Custom':
193
+ limits = PLANS_LIST.CUSTOM;
194
+ break;
195
+ case 'Sandbox':
196
+ limits = PLANS_LIST.SANDBOX;
197
+ break;
198
+ case 'Growth':
199
+ limits = PLANS_LIST.BASIC
200
+ break;
201
+ case 'Scale':
202
+ limits = PLANS_LIST.PREMIUM
203
+ break;
204
+ case 'Plus':
205
+ limits = PLANS_LIST.CUSTOM
206
+ break;
207
+ default:
208
+ limits = PLANS_LIST.FREE_TRIAL;
209
+ }
210
+ } else {
211
+ limits = PLANS_LIST.FREE_TRIAL;
212
+ }
213
+ return limits;
214
+ }
215
+
216
+
217
+
218
+ start() {
219
+ winston.verbose('QuoteManager start');
220
+
221
+ if (process.env.QUOTES_ENABLED !== undefined) {
222
+ if (process.env.QUOTES_ENABLED === false || process.env.QUOTES_ENABLED === 'false') {
223
+ quotes_enabled = false;
224
+ }
225
+ }
226
+
227
+ // TODO - Try to generalize to avoid repetition
228
+ let incrementEventHandler = (object) => { }
229
+ let checkEventHandler = (object) => { }
230
+
231
+
232
+ // REQUESTS EVENTS - START
233
+ // requestEvent.on('request.create.quote.before', async (payload) => {
234
+ // let result = await this.checkQuote(payload.project, payload.request, 'requests');
235
+ // if (result == true) {
236
+ // winston.info("Limit not reached - a request can be created")
237
+ // } else {
238
+ // winston.info("Requests limit reached for the current plan!")
239
+ // }
240
+ // return result;
241
+ // });
242
+
243
+ requestEvent.on('request.create.quote', async (payload) => {
244
+ if (quotes_enabled === true) {
245
+ winston.verbose("request.create.quote event catched");
246
+ let result = await this.incrementRequestsCount(payload.project, payload.request);
247
+ return result;
248
+ } else {
249
+ winston.info("QUOTES DISABLED - request.create.quote event")
250
+ }
251
+ })
252
+ // REQUESTS EVENTS - END
253
+
254
+
255
+ // MESSAGES EVENTS - START
256
+ // messageEvent.on('message.create.quote.before', async (payload) => {
257
+ // let result = await this.checkQuote(payload.project, payload.message, 'messages');
258
+ // if (result == true) {
259
+ // winston.info("Limit not reached - a message can be created")
260
+ // } else {
261
+ // winston.info("Messages limit reached for the current plan!")
262
+ // }
263
+ // return result;
264
+ // })
265
+
266
+ messageEvent.on('message.create.quote', async (payload) => {
267
+ if (quotes_enabled === true) {
268
+ winston.verbose("message.create.quote event catched");
269
+ let result = await this.incrementMessagesCount(payload.project, payload.message);
270
+ return result;
271
+ } else {
272
+ winston.info("QUOTES DISABLED - message.create.quote event")
273
+ }
274
+ })
275
+ // MESSAGES EVENTS - END
276
+
277
+
278
+ // EMAIL EVENTS - START - Warning! Can't be used for check quote
279
+ // emailEvent.on('email.send.before', async (payload) => {
280
+ // let result = await this.checkQuote(payload.project, payload.email, 'email');
281
+ // if (result == true) {
282
+ // winston.info("Limit not reached - a message can be created")
283
+ // } else {
284
+ // winston.info("Email limit reached for the current plan!")
285
+ // }
286
+ // return result;
287
+ // })
288
+
289
+ emailEvent.on('email.send.quote', async (payload) => {
290
+ if (quotes_enabled === true) {
291
+ winston.info("email.send event catched");
292
+ let result = await this.incrementEmailCount(payload.project, payload.email);
293
+ return result;
294
+ } else {
295
+ winston.info("QUOTES DISABLED - email.send event")
296
+ }
297
+ })
298
+ // EMAIL EVENTS - END
299
+ }
300
+
301
+
302
+ }
303
+
304
+ module.exports = { QuoteManager };
@@ -42,6 +42,11 @@ class CacheEnabler {
42
42
  this.widgets = false;
43
43
  }
44
44
 
45
+ this.integrations = true;
46
+ if (process.env.CACHE_INTEGRATIONS_ENABLED=="false" || process.env.CACHE_INTEGRATIONS_ENABLED==false) {
47
+ this.integrations = false;
48
+ }
49
+
45
50
  // this.user = true;
46
51
  // if (process.env.CACHE_USER_ENABLED=="false" || process.env.CACHE_USER_ENABLED==false) {
47
52
  // this.user = false;
@@ -32,7 +32,6 @@ class ChatbotService {
32
32
  async getBotById(id_faq_kb, published, api_url, chatbot_templates_api_url, token, project_id, globals) {
33
33
 
34
34
  winston.debug("[CHATBOT SERVICE] getBotById");
35
- console.log("getBotById globals: ", globals);
36
35
 
37
36
  // private bot
38
37
  if (published == "false") {