@tiledesk/tiledesk-server 2.3.1 → 2.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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) {