@tiledesk/tiledesk-server 2.2.37 → 2.3.1

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/LICENSE +14 -657
  3. package/README.md +21 -18
  4. package/app.js +27 -3
  5. package/config/labels/widget.json +320 -0
  6. package/event/subscriptionEvent.js +11 -0
  7. package/models/subscriptionEvent.js +11 -0
  8. package/models/subscriptionLog.js +34 -0
  9. package/models/tagLibrary.js +42 -0
  10. package/package.json +5 -11
  11. package/pubmodules/activities/activityArchiver.js +295 -0
  12. package/pubmodules/activities/index.js +3 -0
  13. package/pubmodules/activities/models/activity.js +88 -0
  14. package/pubmodules/activities/routes/activity.js +710 -0
  15. package/pubmodules/activities/test/activityRoute.js +85 -0
  16. package/pubmodules/analytics/analytics.js +1719 -0
  17. package/pubmodules/analytics/index.js +3 -0
  18. package/pubmodules/canned/cannedResponse.js +51 -0
  19. package/pubmodules/canned/cannedResponseRoute.js +157 -0
  20. package/pubmodules/canned/index.js +3 -0
  21. package/pubmodules/pubModulesManager.js +115 -7
  22. package/pubmodules/rasa/index.js +8 -1
  23. package/pubmodules/rasa/listener.js +28 -7
  24. package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +2 -2
  25. package/pubmodules/trigger/default.js +271 -0
  26. package/pubmodules/trigger/event/actionEventEmitter.js +10 -0
  27. package/pubmodules/trigger/event/flowEventEmitter.js +10 -0
  28. package/pubmodules/trigger/event/triggerEventEmitter.js +10 -0
  29. package/pubmodules/trigger/index.js +3 -0
  30. package/pubmodules/trigger/models/trigger.js +149 -0
  31. package/pubmodules/trigger/rulesTrigger.js +1180 -0
  32. package/pubmodules/trigger/start.js +114 -0
  33. package/pubmodules/trigger/triggerRoute.js +150 -0
  34. package/routes/department.js +51 -0
  35. package/routes/group.js +140 -0
  36. package/routes/project.js +52 -0
  37. package/routes/request.js +3 -2
  38. package/routes/subscription.js +140 -0
  39. package/routes/tag.js +138 -0
  40. package/services/faqBotHandler.js +2 -2
  41. package/services/faqBotSupport.js +0 -1
  42. package/services/faqService.js +1 -1
  43. package/services/modulesManager.js +16 -182
  44. package/services/subscriptionNotifier.js +485 -0
  45. package/template/email/assignedEmailMessage.html +1 -1
  46. package/template/email/assignedRequest.html +1 -1
  47. package/template/email/newMessage.html +1 -1
  48. package/template/email/passwordChanged.html +1 -1
  49. package/template/email/pooledEmailMessage.html +1 -1
  50. package/template/email/pooledRequest.html +1 -1
  51. package/template/email/resetPassword.html +2 -2
  52. package/template/email/ticket.html +1 -1
  53. package/views/messages.jade +1 -1
@@ -0,0 +1,295 @@
1
+ const authEvent = require('../../event/authEvent');
2
+ const requestEvent = require('../../event/requestEvent');
3
+ var Activity = require('./models/activity');
4
+ var winston = require('../../config/winston');
5
+
6
+ class ActivityArchiver {
7
+
8
+ listen() {
9
+
10
+ winston.debug('ActivityArchiver listen');
11
+
12
+ var enabled = process.env.ACTIVITY_HISTORY_ENABLED || "false";
13
+ winston.debug('ActivityArchiver enabled:'+enabled);
14
+
15
+ if (enabled==="true") {
16
+ winston.debug('ActivityArchiver enabled');
17
+ }else {
18
+ winston.info('ActivityArchiver disabled');
19
+ return 0;
20
+ }
21
+
22
+ if (process.env.MONGOOSE_SYNCINDEX) {
23
+ Activity.syncIndexes();
24
+ winston.info("Activity.syncIndexes called");
25
+ }
26
+
27
+ var that = this;
28
+
29
+ //modify all to async
30
+
31
+
32
+ /*
33
+ activityEvent.on('user.verify.email', this.save);
34
+
35
+ activityEvent.on('group.create', this.save);
36
+ activityEvent.on('group.update', this.save);
37
+ activityEvent.on('group.delete', this.save);
38
+
39
+ // activityEvent.on('lead.create', this.save);
40
+ activityEvent.on('lead.update', this.save);
41
+ activityEvent.on('lead.delete', this.save);
42
+ activityEvent.on('lead.download.csv', this.save);
43
+ */
44
+
45
+ authEvent.on('project_user.invite.pending', function(event) {
46
+ setImmediate(() => {
47
+ if (event.skipArchive) {
48
+ return 0;
49
+ }
50
+ var activity = new Activity({actor: {type:"user", id: event.req.user.id, name: event.req.user.fullName },
51
+ verb: "PROJECT_USER_INVITE", actionObj: event.req.body,
52
+ target: {type:"pendinginvitation", id:event.savedPendingInvitation._id.toString(), object: event.savedPendingInvitation },
53
+ id_project: event.req.projectid });
54
+ that.save(activity);
55
+
56
+ });
57
+
58
+ });
59
+
60
+ authEvent.on('project_user.invite', function(event) {
61
+ setImmediate(() => {
62
+ if (event.skipArchive) {
63
+ return 0;
64
+ }
65
+
66
+
67
+ var activity = new Activity({actor: {type:"user", id: event.req.user.id, name: event.req.user.fullName },
68
+ verb: "PROJECT_USER_INVITE", actionObj: event.req.body,
69
+ target: {type:"project_user", id: event.savedProject_userPopulated._id.toString(), object: event.savedProject_userPopulated },
70
+ id_project: event.req.projectid });
71
+ that.save(activity);
72
+
73
+ });
74
+ });
75
+
76
+
77
+ authEvent.on('project_user.update', function(event) {
78
+ setImmediate(() => {
79
+ console.log("project_user.update");
80
+ /*
81
+ 2019-11-20T10:40:52.686991+00:00 app[web.1]: TypeError: Cannot read property '_id' of undefined
82
+ */
83
+ if (event.skipArchive) {
84
+ return 0;
85
+ }
86
+
87
+ var project_user = undefined;
88
+ if (event.updatedProject_userPopulated.toObject) {
89
+ project_user = event.updatedProject_userPopulated.toObject()
90
+ }else {
91
+ project_user = event.updatedProject_userPopulated;
92
+ }
93
+ var activity = new Activity({actor: {type:"user", id: event.req.user.id, name: event.req.user.fullName },
94
+ verb: "PROJECT_USER_UPDATE", actionObj: event.req.body,
95
+ target: {type:"project_user", id: event.updatedProject_userPopulated._id.toString(), object: project_user},
96
+ id_project: event.req.projectid });
97
+ that.save(activity);
98
+
99
+ });
100
+
101
+ });
102
+
103
+ authEvent.on('project_user.delete', function(event) {
104
+ setImmediate(() => {
105
+ if (event.skipArchive) {
106
+ return 0;
107
+ }
108
+
109
+ var activity = new Activity({actor: {type:"user", id: event.req.user.id, name: event.req.user.fullName },
110
+ verb: "PROJECT_USER_DELETE", actionObj: event.req.body,
111
+ target: {type:"project_user", id:event.req.params.project_userid, object: event.project_userPopulated.toObject() }, //Error saving activity Maximum call stack size exceeded
112
+ id_project: event.req.projectid });
113
+ that.save(activity);
114
+
115
+ });
116
+ });
117
+
118
+
119
+ authEvent.on('user.signin', function(event) {
120
+ winston.debug('ActivityArchiver user.login');
121
+ setImmediate(() => {
122
+
123
+
124
+ if (event.skipArchive) {
125
+ return 0;
126
+ }
127
+
128
+ var activity = new Activity({actor: {type:"user", id: event.user._id, name: event.user.fullName },
129
+ verb: "USER_SIGNIN", actionObj: event.req.body,
130
+ target: {type:"user", id:event.user._id.toString(), object: null },
131
+ id_project: '*' });
132
+ that.save(activity);
133
+
134
+ });
135
+ });
136
+ authEvent.on('user.login.error', function(event) {
137
+ setImmediate(() => {
138
+
139
+ if (event.skipArchive) {
140
+ return 0;
141
+ }
142
+
143
+ var activity = new Activity({actor: {type:"user"},
144
+ verb: "USER_SIGNIN_ERROR", actionObj: event.req.body,
145
+ target: {type:"user", id:null, object: null },
146
+ id_project: '*' });
147
+ that.save(activity);
148
+
149
+ });
150
+ });
151
+
152
+ authEvent.on('user.requestresetpassword', function(event) {
153
+ setImmediate(() => {
154
+
155
+ if (event.skipArchive) {
156
+ return 0;
157
+ }
158
+
159
+ var activity = new Activity({actor: {type:"user", id: event.updatedUser._id, name: event.updatedUser.fullName },
160
+ verb: "USER_REQUEST_RESETPASSWORD", actionObj: event.req.body,
161
+ target: {type:"user", id:event.updatedUser._id.toString(), object: null },
162
+ id_project: '*' });
163
+ that.save(activity);
164
+
165
+ });
166
+ });
167
+
168
+ authEvent.on('user.resetpassword', function(event) {
169
+ setImmediate(() => {
170
+
171
+ if (event.skipArchive) {
172
+ return 0;
173
+ }
174
+
175
+ var activity = new Activity({actor: {type:"user", id: event.saveUser._id, name: event.saveUser.fullName },
176
+ verb: "USER_RESETPASSWORD", actionObj: null, //req.body otherwise print password
177
+ target: {type:"user", id:event.saveUser._id.toString(), object: null },
178
+ id_project: '*' });
179
+ that.save(activity);
180
+
181
+ });
182
+ });
183
+
184
+
185
+ authEvent.on('user.signup', function(event) {
186
+ setImmediate(() => {
187
+ if (event.skipArchive) {
188
+ return 0;
189
+ }
190
+
191
+ var activity = new Activity({actor: {type:"user", id: event.savedUser._id, name: event.savedUser.fullName },
192
+ verb: "USER_SIGNUP", actionObj: event.req.body,
193
+ target: {type:"user", id: event.savedUser._id.toString(), object: null },
194
+ id_project: '*' });
195
+ that.save(activity);
196
+
197
+ });
198
+ });
199
+
200
+ authEvent.on('user.signup.error', function(event) {
201
+ setImmediate(() => {
202
+ if (event.skipArchive) {
203
+ return 0;
204
+ }
205
+
206
+
207
+ var activity = new Activity({actor: {type:"user"},
208
+ verb: "USER_SIGNUP_ERROR", actionObj: event.req.body,
209
+ target: {type:"user", id:null, object: null },
210
+ id_project: '*' });
211
+ that.save(activity);
212
+
213
+ });
214
+ });
215
+
216
+ requestEvent.on('request.create', function(request) {
217
+ setImmediate(() => {
218
+ // problema requester_id
219
+
220
+ // Error saving activity {"_id":"5e06189c6e226d358896d733","actor":{"_id":"5e06189c6e226d358896d734","type":"user","id":null},"verb":"REQUEST_CREATE","actionObj":{"status":200,"participants":["5e06189c6e226d358896d728"],"messages_count":0,"tags":[],"_id":"5e06189c6e226d358896d72e","request_id":"request_id-closeRequest","first_text":"first_text","department":{"routing":"assigned","default":true,"status":1,"_id":"5e06189c6e226d358896d72b","name":"Default Department","id_project":"5e06189c6e226d358896d729","createdBy":"5e06189c6e226d358896d728","createdAt":"2019-12-27T14:43:40.327Z","updatedAt":"2019-12-27T14:43:40.327Z","__v":0},"agents":[{"_id":"5e06189c6e226d358896d72a","id_project":"5e06189c6e226d358896d729","id_user":"5e06189c6e226d358896d728","role":"owner","user_available":true,"createdBy":"5e06189c6e226d358896d728","createdAt":"2019-12-27T14:43:40.324Z","updatedAt":"2019-12-27T14:43:40.324Z","__v":0}],"id_project":"5e06189c6e226d358896d729","createdBy":"requester_id1","channel":{"name":"chat21"},"createdAt":"2019-12-27T14:43:40.586Z","updatedAt":"2019-12-27T14:43:40.586Z","__v":0},"target":{"type":"request","id":"5e06189c6e226d358896d72e","object":{"status":200,"participants":["5e06189c6e226d358896d728"],"messages_count":0,"tags":[],"_id":"5e06189c6e226d358896d72e","request_id":"request_id-closeRequest","first_text":"first_text","department":{"routing":"assigned","default":true,"status":1,"_id":"5e06189c6e226d358896d72b","name":"Default Department","id_project":"5e06189c6e226d358896d729","createdBy":"5e06189c6e226d358896d728","createdAt":"2019-12-27T14:43:40.327Z","updatedAt":"2019-12-27T14:43:40.327Z","__v":0},"agents":[{"_id":"5e06189c6e226d358896d72a","id_project":"5e06189c6e226d358896d729","id_user":"5e06189c6e226d358896d728","role":"owner","user_available":true,"createdBy":"5e06189c6e226d358896d728","createdAt":"2019-12-27T14:43:40.324Z","updatedAt":"2019-12-27T14:43:40.324Z","__v":0}],"id_project":"5e06189c6e226d358896d729","createdBy":"requester_id1","channel":{"name":"chat21"},"createdAt":"2019-12-27T14:43:40.586Z","updatedAt":"2019-12-27T14:43:40.586Z","__v":0}},"id_project":"5e06189c6e226d358896d729"}
221
+
222
+ // TODO error: Error saving activity {"activity":{"_id":"5e273b31f13e801703d52515","actor":{"_id":"5e273b31f13e801703d52516","type":"user","id":null},"verb":"REQUEST_CREATE","actionObj":{"status":200,"participants":["5e273b30f13e801703d52508"],"messages_count":0,"tags":[],"_id":"5e273b31f13e801703d52511","request_id":"request_id1","first_text":"first_text","department":{"routing":"assigned","default":false,"status":1,"_id":"5e273b31f13e801703d5250f","name":"PooledDepartment-for-createWithIdWith","id_project":"5e273b31f13e801703d5250a","createdBy":"5e273b30f13e801703d52507","createdAt":"2020-01-21T17:56:01.471Z","updatedAt":"2020-01-21T17:56:01.471Z","__v":0},"agents":[{"_id":"5e273b31f13e801703d5250b","id_project":"5e273b31f13e801703d5250a","id_user":"5e273b30f13e801703d52507","role":"owner","user_available":true,"createdBy":"5e273b30f13e801703d52507","createdAt":"2020-01-21T17:56:01.465Z","updatedAt":"2020-01-21T17:56:01.465Z","__v":0},{"_id":"5e273b31f13e801703d5250e","id_project":"5e273b31f13e801703d5250a","id_user":"5e273b30f13e801703d52508","role":"agent","user_available":true,"createdBy":"5e273b30f13e801703d52508","createdAt":"2020-01-21T17:56:01.469Z","updatedAt":"2020-01-21T17:56:01.469Z","__v":0}],"id_project":"5e273b31f13e801703d5250a","createdBy":"requester_id1","channel":{"name":"chat21"},"createdAt":"2020-01-21T17:56:01.480Z","updatedAt":"2020-01-21T17:56:01.480Z","__v":0},"target":{"type":"request","id":"5e273b31f13e801703d52511","object":{"status":200,"participants":["5e273b30f13e801703d52508"],"messages_count":0,"tags":[],"_id":"5e273b31f13e801703d52511","request_id":"request_id1","first_text":"first_text","department":{"routing":"assigned","default":false,"status":1,"_id":"5e273b31f13e801703d5250f","name":"PooledDepartment-for-createWithIdWith","id_project":"5e273b31f13e801703d5250a","createdBy":"5e273b30f13e801703d52507","createdAt":"2020-01-21T17:56:01.471Z","updatedAt":"2020-01-21T17:56:01.471Z","__v":0},"agents":[{"_id":"5e273b31f13e801703d5250b","id_project":"5e273b31f13e801703d5250a","id_user":"5e273b30f13e801703d52507","role":"owner","user_available":true,"createdBy":"5e273b30f13e801703d52507","createdAt":"2020-01-21T17:56:01.465Z","updatedAt":"2020-01-21T17:56:01.465Z","__v":0},{"_id":"5e273b31f13e801703d5250e","id_project":"5e273b31f13e801703d5250a","id_user":"5e273b30f13e801703d52508","role":"agent","user_available":true,"createdBy":"5e273b30f13e801703d52508","createdAt":"2020-01-21T17:56:01.469Z","updatedAt":"2020-01-21T17:56:01.469Z","__v":0}],"id_project":"5e273b31f13e801703d5250a","createdBy":"requester_id1","channel":{"name":"chat21"},"createdAt":"2020-01-21T17:56:01.480Z","updatedAt":"2020-01-21T17:56:01.480Z","__v":0}},"id_project":"5e273b31f13e801703d5250a"},"err":{"errors":{"actor.id":{"message":"Path `id` is required.","name":"ValidatorError","properties":{"message":"Path `id` is required.","type":"required","path":"id","value":null},"kind":"required","path":"id","value":null},"actor":{"errors":{"id":{"message":"Path `id` is required.","name":"ValidatorError","properties":{"message":"Path `id` is required.","type":"required","path":"id","value":null},"kind":"required","path":"id","value":null}},"_message":"Validation failed","message":"Validation failed: id: Path `id` is required.","name":"ValidationError"}},"_message":"activity validation failed","message":"activity validation failed: actor.id: Path `id` is required., actor: Validation failed: id: Path `id` is required.","name":"ValidationError"}}
223
+
224
+ // request is plain object must be mongoose object oto populate
225
+
226
+ // if (event.skipArchive) {
227
+ // return 0;
228
+ // }
229
+
230
+ //TODO remove preflight
231
+
232
+ try {
233
+
234
+ if (request.preflight === true) {
235
+ winston.debug("preflight request disable archiver")
236
+ return 0;
237
+ }
238
+ var activity = new Activity({actor: {type:"user", id: request.requester_id},
239
+ verb: "REQUEST_CREATE", actionObj: request,
240
+ target: {type:"request", id:request._id, object: request },
241
+ id_project: request.id_project });
242
+ that.save(activity);
243
+ } catch(e) {
244
+ winston.error('ActivityArchiver error saving activity',e);
245
+ }
246
+
247
+
248
+ });
249
+ });
250
+
251
+
252
+ requestEvent.on('request.update.preflight', function(request) {
253
+ setImmediate(() => {
254
+
255
+ try {
256
+
257
+ if (request.preflight === true) {
258
+ winston.debug("preflight request disable archiver")
259
+ return 0;
260
+ }
261
+ var activity = new Activity({actor: {type:"user", id: request.requester_id},
262
+ verb: "REQUEST_CREATE", actionObj: request,
263
+ target: {type:"request", id:request._id, object: request },
264
+ id_project: request.id_project });
265
+ that.save(activity);
266
+ } catch(e) {
267
+ winston.error('ActivityArchiver error saving activity',e);
268
+ }
269
+
270
+
271
+ });
272
+ });
273
+
274
+
275
+
276
+
277
+ winston.info('ActivityArchiver listening');
278
+
279
+ }
280
+
281
+ save(activity) {
282
+ activity.save(function(err, savedActivity) {
283
+ if (err) {
284
+ winston.error('Error saving activity ', {activity: activity.toObject(), err:err});
285
+ }else {
286
+ winston.debug('Activity saved', savedActivity.toObject());
287
+ }
288
+ });
289
+ }
290
+ }
291
+
292
+ var activityArchiver = new ActivityArchiver();
293
+
294
+
295
+ module.exports = activityArchiver;
@@ -0,0 +1,3 @@
1
+ const activityRoute = require("./routes/activity");
2
+ const activityArchiver = require("./activityArchiver");
3
+ module.exports = {activityArchiver:activityArchiver,activityRoute:activityRoute};
@@ -0,0 +1,88 @@
1
+ var mongoose = require('mongoose');
2
+ var Schema = mongoose.Schema;
3
+
4
+ // https://getstream.io/blog/designing-activity-stream-newsfeed-w3c-spec/
5
+ // {
6
+ // "@context": "http://www.w3.org/ns/activitystreams",
7
+ // "type": "added",
8
+ // "published": "2015-02-10T15:04:55Z",
9
+ // "actor": {
10
+ // "type": "Person",
11
+ // "id": "http://www.test.example/jack",
12
+ // "name": "Jack Hill",
13
+ // "url": "http://example.org/jack",
14
+ // "image": {
15
+ // "type": "Link",
16
+ // "href": "http://example.org/jack/profile.jpg",
17
+ // "mediaType": "image/jpeg"
18
+ // }
19
+ // },
20
+ // "object" : {
21
+ // "id": "http://www.test.example/jack/hill_photos/the_hill1.jpg",
22
+ // "type": "Photo",
23
+ // "label": "Great Photo of The Hill"
24
+ // },
25
+ // "target" : {
26
+ // "id": "http://example.org/jack/albums/great_hill_pics",
27
+ // "type": "OrderedCollection",
28
+ // "name": "Great Hill Pics"
29
+ // }
30
+ // }
31
+
32
+ //actor: {type:"user", id: event.req.user.id, name: event.req.user.fullName },
33
+ var ActorActivitySchema = new Schema({
34
+ type: {
35
+ type: String,
36
+ required: true,
37
+ index:true
38
+ },
39
+ id: {
40
+ type: String,
41
+ required: true,
42
+ index:true
43
+ },
44
+ name: {
45
+ type: String,
46
+ required: false
47
+ },
48
+ });
49
+
50
+ var ActivitySchema = new Schema({
51
+
52
+ actor: {
53
+ // type: String,
54
+ type: ActorActivitySchema,
55
+ required: true,
56
+ //index: true //error saving activity Btree::insert: key too large to index, failing heroku_hwhg3xtx.activities.$target_1 2359 { : { object: { __v: 0, updatedAt: new Date(1555407053615), createdAt: new Date(1555407053615), request_id: "support-group-Lc_Tz_hoCZ9REHC9FbY", requester_id: "5c8a38012d8e6d0017bce22a", first_text: "test 81", department: ObjectId('5b8eb48b5ca4d300141fb2cb'), sourcePage: "https://www.tiledesk.com/", language: "it",
57
+ },
58
+ verb: {
59
+ type: String,
60
+ required: true,
61
+ index: true
62
+ },
63
+
64
+ actionObj: {
65
+ type: Object,
66
+ required: false
67
+ },
68
+ target: {
69
+ // type: String,
70
+ type: Object,
71
+ required: true,
72
+ // index: true
73
+ },
74
+ // summary A natural language summarization of the object encoded as HTML. Multiple language tagged summaries may be provided.
75
+ // summaryMap https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary
76
+ id_project: {
77
+ type: String,
78
+ required: true,
79
+ index: true
80
+ }
81
+ },{
82
+ timestamps: true
83
+ }
84
+ );
85
+
86
+ // TODO metti indice per query è lentina
87
+
88
+ module.exports = mongoose.model('activity', ActivitySchema);