@tiledesk/tiledesk-server 2.9.2 → 2.9.4
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
CHANGED
@@ -5,6 +5,13 @@
|
|
5
5
|
🚀 IN PRODUCTION 🚀
|
6
6
|
(https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
|
7
7
|
|
8
|
+
# 2.9.4
|
9
|
+
- Update tybot-connector to 0.2.86
|
10
|
+
- Added time-slots management
|
11
|
+
|
12
|
+
# 2.9.3
|
13
|
+
- Added log for AMQP error in closeOnErr
|
14
|
+
|
8
15
|
# 2.9.2
|
9
16
|
- Updated tybot-connector to 0.2.84
|
10
17
|
|
package/models/project.js
CHANGED
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.9.
|
4
|
+
"version": "2.9.4",
|
5
5
|
"scripts": {
|
6
6
|
"start": "node ./bin/www",
|
7
7
|
"pretest": "mongodb-runner start",
|
@@ -48,7 +48,7 @@
|
|
48
48
|
"@tiledesk/tiledesk-rasa-connector": "^1.0.10",
|
49
49
|
"@tiledesk/tiledesk-telegram-connector": "^0.1.14",
|
50
50
|
"@tiledesk/tiledesk-train-jobworker": "^0.0.11",
|
51
|
-
"@tiledesk/tiledesk-tybot-connector": "^0.2.
|
51
|
+
"@tiledesk/tiledesk-tybot-connector": "^0.2.86",
|
52
52
|
"@tiledesk/tiledesk-whatsapp-connector": "^0.1.72",
|
53
53
|
"@tiledesk/tiledesk-whatsapp-jobworker": "^0.0.8",
|
54
54
|
"@tiledesk/tiledesk-sms-connector": "^0.1.7",
|
package/routes/project.js
CHANGED
@@ -307,6 +307,10 @@ router.put('/:projectid', [passport.authenticate(['basic', 'jwt'], { session: fa
|
|
307
307
|
if (req.body.operatingHours!=undefined) {
|
308
308
|
update.operatingHours = req.body.operatingHours;
|
309
309
|
}
|
310
|
+
|
311
|
+
if (req.body.timeSlots!=undefined) {
|
312
|
+
update.timeSlots = req.body.timeSlots;
|
313
|
+
}
|
310
314
|
|
311
315
|
if (req.body.settings!=undefined) {
|
312
316
|
update.settings = req.body.settings;
|
@@ -849,16 +853,32 @@ router.get('/', [passport.authenticate(['basic', 'jwt'], { session: false }), va
|
|
849
853
|
|
850
854
|
// GET ALL PROJECTS BY CURRENT USER ID. usaed by unisalento to know if a project is open
|
851
855
|
router.get('/:projectid/isopen', function (req, res) {
|
852
|
-
operatingHoursService.projectIsOpenNow(req.params.projectid, function (isOpen, err) {
|
853
|
-
winston.debug('project', req.params.projectid, 'isopen: ', isOpen);
|
854
856
|
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
857
|
+
let project_id = req.params.projectid;
|
858
|
+
// Check if a timeSlot is passed
|
859
|
+
if (req.query.timeSlot) {
|
860
|
+
let slot_id = req.query.timeSlot;
|
861
|
+
operatingHoursService.slotIsOpenNow(project_id, slot_id, (isOpen, err) => {
|
862
|
+
|
863
|
+
if (err) {
|
864
|
+
winston.error("Error getting slotIsOpenNow ", err);
|
865
|
+
return res.status(500).send({ success: false, error: err });
|
866
|
+
}
|
867
|
+
return res.status(200).send({ isopen: isOpen})
|
868
|
+
})
|
869
|
+
|
870
|
+
} else {
|
861
871
|
|
872
|
+
operatingHoursService.projectIsOpenNow(project_id, function (isOpen, err) {
|
873
|
+
winston.debug('project', project_id, 'isopen: ', isOpen);
|
874
|
+
|
875
|
+
if (err) {
|
876
|
+
winston.error('Error getting projectIsOpenNow', err);
|
877
|
+
return res.status(500).send({ success: false, msg: err });
|
878
|
+
}
|
879
|
+
return res.status(200).send({ isopen: isOpen})
|
880
|
+
});
|
881
|
+
}
|
862
882
|
});
|
863
883
|
|
864
884
|
//togli questo route da qui e mettilo in altra route
|
@@ -175,7 +175,101 @@ class OperatingHoursService {
|
|
175
175
|
|
176
176
|
} // ./end projectIsOpenNow
|
177
177
|
|
178
|
+
slotIsOpenNow(projectId, slot_id, callback) {
|
178
179
|
|
180
|
+
let q = Project.findOne({ _id: projectId, status: 100});
|
181
|
+
if (cacheEnabler.project) {
|
182
|
+
q.cache(cacheUtil.longTTL, "projects:id:"+projectId) //project_cache
|
183
|
+
winston.debug('project cache enabled for slotIsOpenNow');
|
184
|
+
}
|
185
|
+
q.exec( async (err, project) => {
|
186
|
+
|
187
|
+
if (err) {
|
188
|
+
winston.error("(slotIsOpenNow) Error getting project: ", err);
|
189
|
+
callback(null, { errorCode: 1000, msg: "Error getting project." })
|
190
|
+
return;
|
191
|
+
}
|
192
|
+
if (!project) {
|
193
|
+
winston.warn("(slotIsOpenNow) Project not found with id: " + projectId);
|
194
|
+
callback(null, { errorCode: 1010, msg: 'Project not found for id' + projectId });
|
195
|
+
return;
|
196
|
+
}
|
197
|
+
|
198
|
+
// Return ALWAYS true if the plan is free, trial is expired or the subscription is not active
|
199
|
+
if (project.profile && (project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false)) {
|
200
|
+
winston.debug('(slotIsOpenNow) Trial Expired or Subscription NOT Active')
|
201
|
+
callback(true, null) ;
|
202
|
+
return;
|
203
|
+
}
|
204
|
+
|
205
|
+
if (!project.timeSlots) {
|
206
|
+
winston.warn("(slotIsOpenNow) No time slots specified for the project " + projectId);
|
207
|
+
callback(true, null)
|
208
|
+
return
|
209
|
+
}
|
210
|
+
|
211
|
+
let timeSlot = project.timeSlots[slot_id];
|
212
|
+
console.log("timeSlot: ", timeSlot);
|
213
|
+
|
214
|
+
if (!timeSlot) {
|
215
|
+
callback(null, { errorCode: 1030, msg: 'Slot not found with id ' + slot_id })
|
216
|
+
return;
|
217
|
+
}
|
218
|
+
|
219
|
+
if (timeSlot.active == false) {
|
220
|
+
winston.verbose("(slotIsOpenNow) selected slot is not active")
|
221
|
+
callback(true, null);
|
222
|
+
return;
|
223
|
+
}
|
224
|
+
|
225
|
+
if (!timeSlot.hours) {
|
226
|
+
callback(null, { errorCode: 1020, msg: 'Operating hours is empty' });
|
227
|
+
return;
|
228
|
+
}
|
229
|
+
|
230
|
+
const hours = JSON.parse(timeSlot.hours);
|
231
|
+
const tzname = hours.tzname;
|
232
|
+
delete hours.tzname;
|
233
|
+
|
234
|
+
// Get the current time in the specified timezone
|
235
|
+
const currentTime = moment_tz.tz(tzname);
|
236
|
+
const currentWeekday = currentTime.isoWeekday();
|
237
|
+
|
238
|
+
const daySlots = hours[currentWeekday];
|
239
|
+
if (!daySlots) {
|
240
|
+
callback(false, null)
|
241
|
+
}
|
242
|
+
|
243
|
+
let promises = [];
|
244
|
+
|
245
|
+
daySlots.forEach((slot) => {
|
246
|
+
promises.push(slotCheck(currentTime, slot))
|
247
|
+
})
|
248
|
+
|
249
|
+
await Promise.all(promises).then((resp) => {
|
250
|
+
if (resp.indexOf(true) != -1) {
|
251
|
+
callback(true, null);
|
252
|
+
return;
|
253
|
+
}
|
254
|
+
callback(false, null);
|
255
|
+
return;
|
256
|
+
})
|
257
|
+
})
|
258
|
+
}
|
259
|
+
}
|
260
|
+
|
261
|
+
function slotCheck(currentTime, slot) {
|
262
|
+
return new Promise((resolve) => {
|
263
|
+
|
264
|
+
const startTime = moment_tz(slot.start, 'HH:mm');
|
265
|
+
const endTime = moment_tz(slot.end, 'HH:mm');
|
266
|
+
|
267
|
+
if (currentTime.isBetween(startTime, endTime, null, '[)')) {
|
268
|
+
resolve(true)
|
269
|
+
} else {
|
270
|
+
resolve(false);
|
271
|
+
}
|
272
|
+
})
|
179
273
|
}
|
180
274
|
|
181
275
|
function addOrSubstractProjcTzOffsetFromDateNow(prjcTimezoneName) {
|
package/test/projectRoute.js
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
process.env.NODE_ENV = 'test';
|
3
3
|
process.env.ADMIN_EMAIL = "admin@tiledesk.com";
|
4
4
|
|
5
|
-
let log =
|
5
|
+
let log = true;
|
6
6
|
var projectService = require('../services/projectService');
|
7
7
|
var userService = require('../services/userService');
|
8
8
|
|
@@ -19,6 +19,26 @@ const path = require('path');
|
|
19
19
|
var expect = chai.expect;
|
20
20
|
var assert = chai.assert;
|
21
21
|
|
22
|
+
let timeSlotsSample = {
|
23
|
+
"819559cc": {
|
24
|
+
name: "Slot1",
|
25
|
+
active: true,
|
26
|
+
hours: "{\"1\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"3\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"5\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"tzname\":\"Europe/Rome\"}"
|
27
|
+
},
|
28
|
+
"5d4368de": {
|
29
|
+
name: "Slot2",
|
30
|
+
active: true,
|
31
|
+
hours: "{\"0\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"6\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"tzname\":\"Europe/Rome\"}"
|
32
|
+
},
|
33
|
+
"2975ec45": {
|
34
|
+
name: "Slot3",
|
35
|
+
active: false,
|
36
|
+
hours: "{\"0\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"6\":[{\"start\":\"09:00\",\"end\":\"13:00\"},{\"start\":\"14:00\",\"end\":\"18:00\"}],\"tzname\":\"Europe/Rome\"}"
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
|
41
|
+
|
22
42
|
chai.use(chaiHttp);
|
23
43
|
|
24
44
|
describe('ProjectRoute', () => {
|
@@ -50,7 +70,7 @@ describe('ProjectRoute', () => {
|
|
50
70
|
// .put('/projects/' + savedProject._id + "/update")
|
51
71
|
.put('/projects/' + savedProject._id)
|
52
72
|
.set('Authorization', superadmin_token)
|
53
|
-
.send({ profile: { name: "Custom", quotes: { kbs: 1000} } })
|
73
|
+
.send({ profile: { name: "Custom", quotes: { kbs: 1000 } } })
|
54
74
|
.end((err, res) => {
|
55
75
|
|
56
76
|
if (log) { console.log("update project profile res.body: ", res.body) };
|
@@ -78,7 +98,7 @@ describe('ProjectRoute', () => {
|
|
78
98
|
.put('/projects/' + savedProject._id)
|
79
99
|
// .put('/projects/' + savedProject._id + "/update")
|
80
100
|
.auth(email, pwd)
|
81
|
-
.send({ profile: { name: "Custom", quotes: { kbs: 1000} } })
|
101
|
+
.send({ profile: { name: "Custom", quotes: { kbs: 1000 } } })
|
82
102
|
.end((err, res) => {
|
83
103
|
|
84
104
|
if (log) { console.log("update project profile res.body: ", res.body) };
|
@@ -90,6 +110,72 @@ describe('ProjectRoute', () => {
|
|
90
110
|
})
|
91
111
|
})
|
92
112
|
}).timeout(10000)
|
113
|
+
|
114
|
+
it('updateProjectTimeSlots', (done) => {
|
115
|
+
|
116
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
117
|
+
var pwd = "pwd";
|
118
|
+
|
119
|
+
userService.signup(email, pwd, "Test Firstname", "Test Lastname").then((savedUser) => {
|
120
|
+
projectService.create("test-project-create", savedUser._id).then((savedProject) => {
|
121
|
+
|
122
|
+
chai.request(server)
|
123
|
+
// .put('/projects/' + savedProject._id + "/update")
|
124
|
+
.put('/projects/' + savedProject._id)
|
125
|
+
.auth(email, pwd)
|
126
|
+
.send({ timeSlots: timeSlotsSample })
|
127
|
+
.end((err, res) => {
|
128
|
+
|
129
|
+
if (log) { console.log("update project time slots res.body: ", res.body) };
|
130
|
+
res.should.have.status(200);
|
131
|
+
res.body.should.be.a('object');
|
132
|
+
|
133
|
+
done();
|
134
|
+
})
|
135
|
+
})
|
136
|
+
})
|
137
|
+
}).timeout(10000)
|
138
|
+
|
139
|
+
it('isOpenTimeSlot', (done) => {
|
140
|
+
|
141
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
142
|
+
var pwd = "pwd";
|
143
|
+
|
144
|
+
userService.signup(email, pwd, "Test Firstname", "Test Lastname").then((savedUser) => {
|
145
|
+
projectService.create("test-project-create", savedUser._id).then((savedProject) => {
|
146
|
+
|
147
|
+
chai.request(server)
|
148
|
+
// .put('/projects/' + savedProject._id + "/update")
|
149
|
+
.put('/projects/' + savedProject._id)
|
150
|
+
.auth(email, pwd)
|
151
|
+
.send({ timeSlots: timeSlotsSample })
|
152
|
+
.end((err, res) => {
|
153
|
+
|
154
|
+
if (log) { console.log("update project time slots res.body: ", res.body) };
|
155
|
+
res.should.have.status(200);
|
156
|
+
res.body.should.be.a('object');
|
157
|
+
|
158
|
+
chai.request(server)
|
159
|
+
.get('/projects/' + savedProject._id + '/isopen?timeSlot=819559cc')
|
160
|
+
.auth(email, pwd)
|
161
|
+
.end((err, res) => {
|
162
|
+
|
163
|
+
if (err) { console.error("err: ", err) };
|
164
|
+
if (log) { console.log("res.body isopen: ", res.body) };
|
165
|
+
|
166
|
+
// Unable to do other checks due to currentTime change.
|
167
|
+
res.should.have.status(200);
|
168
|
+
|
169
|
+
done();
|
170
|
+
|
171
|
+
})
|
172
|
+
})
|
173
|
+
|
174
|
+
|
175
|
+
})
|
176
|
+
})
|
177
|
+
}).timeout(10000)
|
178
|
+
|
93
179
|
});
|
94
180
|
|
95
181
|
});
|