@tiledesk/tiledesk-server 2.3.1 → 2.3.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.
@@ -3,10 +3,22 @@ var router = express.Router();
3
3
  var Message = require("../models/message");
4
4
  var Request = require("../models/request");
5
5
  var User = require("../models/user");
6
- var Project = require("../models/project");
7
- var emailService = require("../services/emailService");
8
6
  var winston = require('../config/winston');
9
7
 
8
+ var fonts = {
9
+ Roboto: {
10
+ normal: 'fonts/Roboto-Regular.ttf',
11
+ bold: 'fonts/Roboto-Medium.ttf',
12
+ italics: 'fonts/Roboto-Italic.ttf',
13
+ bolditalics: 'fonts/Roboto-MediumItalic.ttf'
14
+ }
15
+ };
16
+
17
+ var PdfPrinter = require('pdfmake');
18
+ var printer = new PdfPrinter(fonts);
19
+ // var fs = require('fs');
20
+
21
+
10
22
 
11
23
 
12
24
 
@@ -49,6 +61,131 @@ var winston = require('../config/winston');
49
61
  });
50
62
 
51
63
 
64
+ router.get('/:requestid/messages.csv', function(req, res) {
65
+
66
+ winston.debug(req.params);
67
+ winston.debug("here");
68
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).lean().exec(function(err, messages) {
69
+ if (err) {
70
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
71
+ }
72
+
73
+ if(!messages){
74
+ return res.status(404).send({success: false, msg: 'Object not found.'});
75
+ }
76
+
77
+ messages.forEach(function(element) {
78
+
79
+ var channel_name = "";
80
+ if (element.channel && element.channel.name) {
81
+ channel_name = element.channel.name;
82
+ }
83
+ delete element.channel;
84
+ element.channel_name = channel_name;
85
+
86
+ delete element.attributes;
87
+ });
88
+
89
+ return res.csv(messages, true);
90
+ });
91
+
92
+ });
93
+
94
+
95
+ router.get('/:requestid/messages.txt', function(req, res) {
96
+
97
+ winston.debug(req.params);
98
+ winston.debug("here");
99
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
100
+ if (err) {
101
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
102
+ }
103
+
104
+ if(!messages){
105
+ return res.status(404).send({success: false, msg: 'Object not found.'});
106
+ }
107
+
108
+
109
+ var text = "Chat transcript:\n" //+ req.project.name;
110
+
111
+ messages.forEach(function(element) {
112
+ text = text + "[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text + "\n";
113
+ });
114
+
115
+
116
+ res.set({"Content-Disposition":"attachment; filename=\"transcript.txt\""});
117
+ res.send(text);
118
+ });
119
+
120
+ });
121
+
122
+
123
+
124
+ router.get('/:requestid/messages.pdf', function(req, res) {
125
+
126
+
127
+ winston.debug(req.params);
128
+ winston.debug("here");
129
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
130
+ if (err) {
131
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
132
+ }
133
+
134
+
135
+ if(!messages){
136
+ return res.status(404).send({success: false, msg: 'Object not found.'});
137
+ }
138
+
139
+
140
+ var docDefinition = {
141
+ content: [
142
+ { text: 'Chat Transcript', style: 'header' },
143
+ {
144
+ ul: [
145
+ // 'item 1',
146
+ // 'item 2',
147
+ // 'item 3'
148
+ ]
149
+ },
150
+
151
+ ],
152
+ styles: {
153
+ header: {
154
+ bold: true,
155
+ fontSize: 15
156
+ }
157
+ },
158
+ defaultStyle: {
159
+ fontSize: 12
160
+ }
161
+ };
162
+
163
+
164
+
165
+ messages.forEach(function(element) {
166
+ docDefinition.content[1].ul.push("[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text );
167
+ });
168
+
169
+ console.log(docDefinition);
170
+
171
+ var pdfDoc = printer.createPdfKitDocument(docDefinition);
172
+ // pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
173
+
174
+ res.setHeader('Content-Type', 'application/pdf');
175
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.pdf');
176
+
177
+
178
+ pdfDoc.pipe(res);
179
+ pdfDoc.end();
180
+
181
+
182
+
183
+ });
184
+
185
+ });
186
+
187
+
188
+
52
189
  router.get('/:requestid/messages-user.html', function(req, res) {
53
190
 
54
191
  winston.debug(req.params);
@@ -60,6 +197,7 @@ var winston = require('../config/winston');
60
197
 
61
198
  var messages = messages.filter(m => m.sender != "system" );
62
199
 
200
+
63
201
  //skip info message
64
202
  if(!messages){
65
203
  return res.status(404).send({success: false, msg: 'Object not found.'});
@@ -70,4 +208,138 @@ var winston = require('../config/winston');
70
208
 
71
209
  });
72
210
 
211
+
212
+
213
+ router.get('/:requestid/messages-user.txt', function(req, res) {
214
+
215
+ winston.debug(req.params);
216
+ winston.debug("here");
217
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
218
+ if (err) {
219
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
220
+ }
221
+
222
+ if(!messages){
223
+ return res.status(404).send({success: false, msg: 'Object not found.'});
224
+ }
225
+
226
+
227
+ var messages = messages.filter(m => m.sender != "system" );
228
+
229
+ var text = "Chat transcript:\n" //+ req.project.name;
230
+
231
+ messages.forEach(function(element) {
232
+ text = text + "[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text + "\n";
233
+ });
234
+
235
+
236
+ res.set({"Content-Disposition":"attachment; filename=\"transcript.txt\""});
237
+ res.send(text);
238
+ });
239
+
240
+ });
241
+
242
+
243
+ router.get('/:requestid/messages-user.pdf', function(req, res) {
244
+
245
+
246
+ winston.debug(req.params);
247
+ winston.debug("here");
248
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).exec(function(err, messages) {
249
+ if (err) {
250
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
251
+ }
252
+
253
+ var messages = messages.filter(m => m.sender != "system" );
254
+
255
+
256
+ //skip info message
257
+ if(!messages){
258
+ return res.status(404).send({success: false, msg: 'Object not found.'});
259
+ }
260
+
261
+
262
+ var docDefinition = {
263
+ content: [
264
+ { text: 'Chat Transcript', style: 'header' },
265
+ {
266
+ ul: [
267
+ // 'item 1',
268
+ // 'item 2',
269
+ // 'item 3'
270
+ ]
271
+ },
272
+
273
+ ],
274
+ styles: {
275
+ header: {
276
+ bold: true,
277
+ fontSize: 15
278
+ }
279
+ },
280
+ defaultStyle: {
281
+ fontSize: 12
282
+ }
283
+ };
284
+
285
+
286
+
287
+ messages.forEach(function(element) {
288
+ docDefinition.content[1].ul.push("[ " + element.createdAt.toLocaleString('en', { timeZone: 'UTC' })+ "] " + element.senderFullname + ": " + element.text );
289
+ });
290
+
291
+ console.log(docDefinition);
292
+
293
+ var pdfDoc = printer.createPdfKitDocument(docDefinition);
294
+ // pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
295
+
296
+ res.setHeader('Content-Type', 'application/pdf');
297
+ res.setHeader('Content-Disposition', 'attachment; filename=transcript.pdf');
298
+
299
+ pdfDoc.pipe(res);
300
+ pdfDoc.end();
301
+
302
+
303
+
304
+ });
305
+
306
+ });
307
+
308
+
309
+ router.get('/:requestid/messages-user.csv', function(req, res) {
310
+
311
+ winston.debug(req.params);
312
+ winston.debug("here");
313
+ return Message.find({"recipient": req.params.requestid}).sort({createdAt: 'asc'}).lean().exec(function(err, messages) {
314
+ if (err) {
315
+ return res.status(500).send({success: false, msg: 'Error getting object.'});
316
+ }
317
+
318
+ var messages = messages.filter(m => m.sender != "system" );
319
+
320
+
321
+ //skip info message
322
+ if(!messages){
323
+ return res.status(404).send({success: false, msg: 'Object not found.'});
324
+ }
325
+
326
+
327
+ messages.forEach(function(element) {
328
+
329
+ var channel_name = "";
330
+ if (element.channel && element.channel.name) {
331
+ channel_name = element.channel.name;
332
+ }
333
+ delete element.channel;
334
+ element.channel_name = channel_name;
335
+
336
+ delete element.attributes;
337
+ });
338
+
339
+
340
+ return res.csv(messages, true);
341
+ });
342
+
343
+ });
344
+
73
345
  module.exports = router;
package/routes/request.js CHANGED
@@ -196,8 +196,9 @@ router.patch('/:requestid', function (req, res) {
196
196
  router.put('/:requestid/close', function (req, res) {
197
197
  winston.debug(req.body);
198
198
 
199
- // closeRequestByRequestId(request_id, id_project)
200
- return requestService.closeRequestByRequestId(req.params.requestid, req.projectid).then(function(closedRequest) {
199
+ // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
200
+ const closed_by = req.user.id;
201
+ return requestService.closeRequestByRequestId(req.params.requestid, req.projectid, false, true, closed_by).then(function(closedRequest) {
201
202
 
202
203
  winston.verbose("request closed", closedRequest);
203
204
 
@@ -518,6 +519,72 @@ router.delete('/:requestid/notes/:noteid', function (req, res) {
518
519
 
519
520
  });
520
521
 
522
+
523
+
524
+
525
+
526
+
527
+ router.post('/:requestid/followers',
528
+ [
529
+ check('member').notEmpty(),
530
+ ],
531
+ function (req, res) {
532
+ winston.info("followers add", req.body);
533
+
534
+ const errors = validationResult(req);
535
+ if (!errors.isEmpty()) {
536
+ return res.status(422).json({ errors: errors.array() });
537
+ }
538
+
539
+ //addParticipantByRequestId(request_id, id_project, member)
540
+ return requestService.addFollowerByRequestId(req.params.requestid, req.projectid, req.body.member ).then(function(updatedRequest) {
541
+
542
+ winston.verbose("participant added", updatedRequest);
543
+
544
+ return res.json(updatedRequest);
545
+ });
546
+
547
+ });
548
+
549
+
550
+ router.put('/:requestid/followers', function (req, res) {
551
+ winston.debug("req.body", req.body);
552
+
553
+ var followers = [];
554
+ req.body.forEach(function(follower,index) {
555
+ followers.push(follower);
556
+ });
557
+ winston.debug("var followers", followers);
558
+
559
+ // setFollowersByRequestId(request_id, id_project, newfollowers)
560
+ return requestService.setFollowersByRequestId(req.params.requestid, req.projectid, followers ).then(function(updatedRequest) {
561
+
562
+ winston.debug("followers set", updatedRequest);
563
+
564
+ return res.json(updatedRequest);
565
+ });
566
+
567
+ });
568
+
569
+ router.delete('/:requestid/followers/:followerid', function (req, res) {
570
+ winston.debug(req.body);
571
+
572
+ //removeFollowerByRequestId(request_id, id_project, member)
573
+ return requestService.removeFollowerByRequestId(req.params.requestid, req.projectid, req.params.followerid ).then(function(updatedRequest) {
574
+
575
+ winston.verbose("follower removed", updatedRequest);
576
+
577
+ return res.json(updatedRequest);
578
+ });
579
+
580
+
581
+ });
582
+
583
+
584
+
585
+
586
+
587
+
521
588
  // TODO make a synchronous chat21 version (with query parameter?) with request.support_group.created
522
589
  router.delete('/:requestid', function (req, res) {
523
590
 
@@ -589,6 +656,8 @@ router.delete('/id/:id', function (req, res) {
589
656
 
590
657
  router.get('/', function (req, res, next) {
591
658
 
659
+ const startExecTime = new Date();
660
+
592
661
  winston.debug("req projectid", req.projectid);
593
662
  winston.debug("req.query.sort", req.query.sort);
594
663
  winston.debug('REQUEST ROUTE - QUERY ', req.query)
@@ -709,6 +778,7 @@ router.get('/', function (req, res, next) {
709
778
  * THE SEARCH FOR DATE INTERVAL OF THE HISTORY OF REQUESTS ARE DISABLED AND
710
779
  * ARE DISPLAYED ONLY THE REQUESTS OF THE LAST 14 DAYS
711
780
  */
781
+ //secondo me qui manca un parentesi tonda per gli or
712
782
  if ( history_search === true && req.project && req.project.profile && (req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false)) {
713
783
 
714
784
 
@@ -813,7 +883,14 @@ router.get('/', function (req, res, next) {
813
883
  }
814
884
 
815
885
  if (req.query.channel) {
816
- query["channel.name"] = req.query.channel
886
+ if (req.query.channel === "offline") {
887
+ query["channel.name"] = {"$in" : ["email", "form"]}
888
+ } else if (req.query.channel === "online") {
889
+ query["channel.name"] = {"$nin" : ["email", "form"]}
890
+ } else {
891
+ query["channel.name"] = req.query.channel
892
+ }
893
+
817
894
  winston.debug('REQUEST ROUTE - QUERY channel', query.channel);
818
895
  }
819
896
 
@@ -835,14 +912,17 @@ router.get('/', function (req, res, next) {
835
912
 
836
913
  winston.debug("sort query", sortQuery);
837
914
 
838
- winston.verbose('REQUEST ROUTE - REQUEST FIND ', query);
915
+ winston.debug('REQUEST ROUTE - REQUEST FIND ', query);
839
916
 
840
917
  var projection = undefined;
841
918
 
842
919
  if (req.query.full_text) {
843
- winston.debug('fulltext projection');
844
920
 
845
- projection = {score: { $meta: "textScore" } };
921
+ if (req.query.no_textscore!= "true" && req.query.no_textscore!= true) {
922
+ winston.info('fulltext projection on');
923
+ projection = {score: { $meta: "textScore" } };
924
+ }
925
+
846
926
  }
847
927
  // requestcachefarequi populaterequired
848
928
  var q1 = Request.find(query, projection).
@@ -890,6 +970,11 @@ router.get('/', function (req, res, next) {
890
970
 
891
971
  var q2 = Request.countDocuments(query).exec();
892
972
 
973
+ if (req.query.no_count && req.query.no_count =="true") {
974
+ winston.info('REQUEST ROUTE - no_count ');
975
+ q2 = 0;
976
+ }
977
+
893
978
  var promises = [
894
979
  q1,
895
980
  q2
@@ -901,7 +986,12 @@ router.get('/', function (req, res, next) {
901
986
  count: results[1],
902
987
  requests: results[0]
903
988
  };
989
+ winston.debug('REQUEST ROUTE - objectToReturn ');
904
990
  winston.debug('REQUEST ROUTE - objectToReturn ', objectToReturn);
991
+
992
+ const endExecTime = new Date();
993
+ winston.info('REQUEST ROUTE - exec time: ' + (endExecTime-startExecTime));
994
+
905
995
  return res.json(objectToReturn);
906
996
 
907
997
  }).catch(function(err){
@@ -1025,7 +1115,11 @@ router.get('/csv', function (req, res, next) {
1025
1115
  winston.debug("sort query", sortQuery);
1026
1116
 
1027
1117
 
1118
+ // TODO ORDER BY SCORE
1119
+ // return Faq.find(query, {score: { $meta: "textScore" } })
1120
+ // .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
1028
1121
 
1122
+ // aggiungi filtro per data marco
1029
1123
 
1030
1124
  winston.debug('REQUEST ROUTE - REQUEST FIND ', query)
1031
1125
  return Request.find(query, '-transcript -status -__v').
@@ -1126,14 +1220,6 @@ router.get('/csv', function (req, res, next) {
1126
1220
 
1127
1221
  winston.debug('REQUEST ROUTE - REQUEST AS CSV', requests);
1128
1222
 
1129
- // return Request.count(query, function(err, totalRowCount) {
1130
-
1131
- // var objectToReturn = {
1132
- // perPage: limit,
1133
- // count: totalRowCount,
1134
- // requests : requests
1135
- // };
1136
- // console.log('REQUEST ROUTE - objectToReturn ', objectToReturn);
1137
1223
  return res.csv(requests, true);
1138
1224
  });
1139
1225
 
@@ -59,8 +59,9 @@ router.patch('/:requestid/rating', function (req, res) {
59
59
  router.put('/:requestid/closeg', function (req, res) {
60
60
  winston.debug(req.body);
61
61
 
62
- // closeRequestByRequestId(request_id, id_project)
63
- return requestService.closeRequestByRequestId(req.params.requestid, req.projectid).then(function(closedRequest) {
62
+ // closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by)
63
+ const closed_by = req.user.id;
64
+ return requestService.closeRequestByRequestId(req.params.requestid, req.projectid, false, true, closed_by).then(function(closedRequest) {
64
65
 
65
66
  winston.verbose("request closed", closedRequest);
66
67
 
package/routes/widget.js CHANGED
@@ -96,6 +96,7 @@ router.get('/', function(req, res, next) {
96
96
  winston.debug("req.project:" + JSON.stringify(req.project));
97
97
 
98
98
  if (req.project) {
99
+ //secondo me qui manca un parentesi tonda per gli or
99
100
  if (req.project.profile && (req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false)) {
100
101
  query.default = true;
101
102
  }
@@ -129,7 +130,21 @@ router.get('/', function(req, res, next) {
129
130
  return reject({err: "Project Not Found"});
130
131
  }
131
132
 
132
- if (project && project.profile && (project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false)) {
133
+
134
+ winston.debug("project", project);
135
+
136
+ // ProjectSetter project not found with id: 62d8cf8b2b10b30013bb9b99
137
+ // Informazioni
138
+ // 2022-07-27 14:32:14.772 CESTerror: Error getting widget. {"err":"Project Not Found"}
139
+ // Informazioni
140
+ // 2022-07-27 14:32:14.778 CESTerror: uncaughtException: Cannot read property 'profile' of null
141
+ // Informazioni
142
+ // 2022-07-27 14:32:14.778 CESTTypeError: Cannot read property 'profile' of null at /usr/src/app/routes/widget.js:132:124 at /usr/src/app/node_modules/mongoose/lib/model.js:5074:18 at processTicksAndRejections (internal/process/task_queues.js:79:11) {"date":"Wed Jul 27 2022 12:32:14 GMT+0000 (Coordinated Universal Time)","error":{},"exception":true,"os":{"loadavg":[0.26,0.51,0.58],"uptime":1028128},"process":{"argv":["/usr/local/bin/node","/usr/src/app/bin/www"],"cwd":"/usr/src/app","execPath":"/usr/local/bin/node","gid":0,"memoryUsage":{"arrayBuffers":128833077,"external":130521753,"heapTotal":110641152,"heapUsed":85605912,"rss":310054912},"pid":26,"uid":0,"version":"v12.22.12"},"stack":"TypeError: Cannot read property 'profile' of null\n at /usr/src/app/routes/widget.js:132:124\n at /usr/src/app/node_modules/mongoose/lib/model.js:5074:18\n at processTicksAndRejections (internal/process/task_queues.js:79:11)","trace":[{"column":124,"file":"/usr/src/app/routes/widget.js","function":null,"line":132,"method":null,"native":false},{"column":18,"file":"/usr/src/app/node_modules/mongoose/lib/model.js","function":null,"line":5074,"method":null,"native":false},{"column":11,"file":"internal/process/task_queues.js","function":"processTicksAndRejections","line":79,"method":null,"native":false}]}
143
+
144
+ // console.log("project!=null",project!=null);
145
+ // console.log("project.profile",project.profile);
146
+ //secondo me qui manca un parentesi tonda per gli or
147
+ if (project && project.profile && ((project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false))) {
133
148
  winston.debug('getProject remove poweredBy tag', project);
134
149
  project.widget.poweredBy = undefined;
135
150
  project.widget.baloonImage = undefined;
@@ -12,9 +12,40 @@ router.get('/load', function(req, res) {
12
12
  winston.debug(query);
13
13
  // TODO chech if query is null
14
14
  res.redirect(widgetLocation+'?'+query);
15
+
15
16
  });
16
17
 
17
18
 
19
+ router.get('/v5/:project_id', function(req, res) {
20
+
21
+ var project_id = req.params.project_id;
22
+ winston.debug("project_id: " + project_id);
23
+
24
+ res.type('.js');
25
+
26
+ var js = `
27
+ window.tiledeskSettings=
28
+ {
29
+ projectid: "${project_id}"
30
+ };
31
+ (function(d, s, id) {
32
+ var w=window; var d=document; var i=function(){i.c(arguments);};
33
+ i.q=[]; i.c=function(args){i.q.push(args);}; w.Tiledesk=i;
34
+ var js, fjs=d.getElementsByTagName(s)[0];
35
+ if (d.getElementById(id)) return;
36
+ js=d.createElement(s);
37
+ js.id=id; js.async=true; js.src="${widgetLocation}/launch.js";
38
+ fjs.parentNode.insertBefore(js, fjs);
39
+ }(document,'script','tiledesk-jssdk'));
40
+ `;
41
+
42
+ winston.debug("js: " + js);
43
+
44
+ res.send(js);
45
+
46
+ });
47
+
48
+
18
49
  var widgetTestLocation = process.env.WIDGET_TEST_LOCATION || widgetConfig.testLocation;
19
50
 
20
51
  router.get('/test/load', function(req, res) {