@tiledesk/tiledesk-server 2.3.6 → 2.3.7-1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. package/.github/workflows/docker-community-worker-push-latest.yml +23 -0
  2. package/.github/workflows/docker-image-tag-worker-community-tag-push.yml +22 -0
  3. package/CHANGELOG.md +361 -3
  4. package/Dockerfile-jobs +31 -0
  5. package/app.js +62 -69
  6. package/channels/chat21/chat21Handler.js +37 -6
  7. package/channels/chat21/chat21WebHook.js +62 -34
  8. package/channels/chat21/package-lock.json +663 -706
  9. package/channels/chat21/package.json +2 -2
  10. package/config/labels/widget.json +337 -136
  11. package/deploy.sh +2 -0
  12. package/event/messageEvent.js +110 -9
  13. package/jobs.js +80 -0
  14. package/jobsManager.js +47 -0
  15. package/middleware/has-role.js +10 -3
  16. package/middleware/ipFilter.js +220 -0
  17. package/middleware/passport.js +8 -2
  18. package/models/department.js +1 -1
  19. package/models/faq.js +77 -25
  20. package/models/faq_kb.js +19 -0
  21. package/models/message.js +10 -8
  22. package/models/project.js +10 -0
  23. package/models/project_user.js +10 -0
  24. package/models/request.js +12 -1
  25. package/package.json +12 -11
  26. package/pubmodules/activities/activityArchiver.js +216 -90
  27. package/pubmodules/activities/routes/activity.js +1 -1
  28. package/pubmodules/apps/index.js +8 -0
  29. package/pubmodules/apps/listener.js +27 -0
  30. package/pubmodules/cache/index.js +2 -0
  31. package/pubmodules/cache/mongoose-cachegoose-fn.js +630 -0
  32. package/pubmodules/canned/cannedResponse.js +4 -0
  33. package/pubmodules/canned/cannedResponseRoute.js +10 -5
  34. package/pubmodules/dialogflow/index.js +10 -0
  35. package/pubmodules/dialogflow/listener.js +66 -0
  36. package/pubmodules/emailNotification/requestNotification.js +58 -28
  37. package/pubmodules/events/eventRoute.js +49 -24
  38. package/pubmodules/messageTransformer/messageHandlebarsTransformerInterceptor.js +6 -1
  39. package/pubmodules/messageTransformer/messageTransformerInterceptor.js +10 -4
  40. package/pubmodules/pubModulesManager.js +173 -7
  41. package/pubmodules/queue/index.js +4 -0
  42. package/pubmodules/queue/reconnect.js +331 -0
  43. package/pubmodules/queue/reconnectFanout.js +256 -0
  44. package/pubmodules/rasa/listener.js +5 -5
  45. package/pubmodules/routing-queue/index.js +3 -0
  46. package/pubmodules/routing-queue/listener.js +328 -0
  47. package/pubmodules/rules/conciergeBot.js +2 -2
  48. package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +6 -1
  49. package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +7 -1
  50. package/pubmodules/tilebot/index.js +11 -0
  51. package/pubmodules/tilebot/listener.js +85 -0
  52. package/pubmodules/trigger/rulesTrigger.js +137 -14
  53. package/pubmodules/trigger/start.js +5 -1
  54. package/pubmodules/whatsapp/index.js +7 -0
  55. package/pubmodules/whatsapp/listener.js +32 -0
  56. package/routes/auth.js +7 -2
  57. package/routes/campaigns.js +3 -3
  58. package/routes/department.js +3 -2
  59. package/routes/email.js +32 -2
  60. package/routes/faq.js +37 -2
  61. package/routes/faq_kb.js +496 -133
  62. package/routes/faqpub.js +5 -0
  63. package/routes/lead.js +56 -0
  64. package/routes/message.js +196 -14
  65. package/routes/messagesRoot.js +39 -0
  66. package/routes/project.js +76 -4
  67. package/routes/project_user.js +11 -1
  68. package/routes/project_user_test.js +19 -0
  69. package/routes/request.js +134 -30
  70. package/routes/troubleshooting.js +12 -0
  71. package/routes/users-util.js +39 -0
  72. package/routes/users.js +1 -1
  73. package/routes/widget.js +64 -2
  74. package/services/BotSubscriptionNotifier.js +5 -0
  75. package/services/banUserNotifier.js +86 -0
  76. package/services/cacheEnabler.js +56 -0
  77. package/services/chatbotService.js +101 -0
  78. package/services/departmentService.js +25 -3
  79. package/services/emailService.js +170 -28
  80. package/services/faqBotHandler.js +2 -3
  81. package/services/faqService.js +28 -3
  82. package/services/geoService.js +36 -6
  83. package/services/labelService.js +1 -1
  84. package/services/leadService.js +3 -2
  85. package/services/messageService.js +4 -2
  86. package/services/modulesManager.js +23 -76
  87. package/services/operatingHoursService.js +9 -4
  88. package/services/requestService.js +75 -39
  89. package/services/subscriptionNotifier.js +9 -4
  90. package/services/trainingService.js +106 -0
  91. package/template/email/assignedEmailMessage.html +21 -11
  92. package/template/email/assignedRequest.html +21 -11
  93. package/template/email/beenInvitedExistingUser.html +16 -6
  94. package/template/email/beenInvitedNewUser.html +16 -6
  95. package/template/email/emailDirect.html +130 -0
  96. package/template/email/newMessage.html +18 -8
  97. package/template/email/newMessageFollower.html +22 -12
  98. package/template/email/passwordChanged.html +15 -5
  99. package/template/email/pooledEmailMessage.html +21 -11
  100. package/template/email/pooledRequest.html +20 -10
  101. package/template/email/resetPassword.html +15 -5
  102. package/template/email/sendTranscript.html +7 -4
  103. package/template/email/ticket.html +17 -7
  104. package/template/email/verify.html +15 -5
  105. package/test/cannedRoute.js +157 -0
  106. package/test/chatbot-mock.js +127 -0
  107. package/test/example-json-intents.txt +1 -0
  108. package/test/example-json.txt +1 -0
  109. package/test/example.json +1 -0
  110. package/test/faqRoute.js +353 -208
  111. package/test/faqkbRoute.js +669 -64
  112. package/test/imageRoute.js +1 -1
  113. package/test/messageRoute.js +387 -5
  114. package/test/requestRoute.js +6 -6
  115. package/test/requestService.js +55 -4
  116. package/test-int/cache-project.js +90 -0
  117. package/test-int/cache-project_user.js +88 -0
  118. package/utils/UIDGenerator.js +20 -0
  119. package/utils/cacheUtil.js +2 -2
  120. package/utils/orgUtil.js +3 -3
  121. package/utils/promiseUtil.js +31 -0
  122. package/utils/recipientEmailUtil.js +66 -0
  123. package/utils/sendEmailUtil.js +34 -0
  124. package/utils/sendMessageUtil.js +1 -1
  125. package/utils/stringUtil.js +12 -0
  126. package/websocket/webSocketServer.js +33 -10
@@ -24,6 +24,7 @@ var licenseKey = process.env.LICENSE_KEY;
24
24
  if (licenseKey) {
25
25
  var maskedLicenseKey = MaskData.maskPhone(licenseKey, maskOptions);
26
26
  winston.info("LicenseKey: " + maskedLicenseKey);
27
+ // winston.info("LicenseKey: " + licenseKey);
27
28
  }
28
29
 
29
30
  class ModulesManager {
@@ -35,12 +36,8 @@ class ModulesManager {
35
36
  this.facebookRoute = undefined;
36
37
  this.jwthistoryArchiver = undefined;
37
38
  this.jwthistoryRoute = undefined;
38
- this.dialogflowListener = undefined;
39
39
  this.requestHistoryArchiver = undefined;
40
- this.requestHistoryRoute = undefined;
41
- this.routingQueue = undefined;
42
- this.queue = undefined;
43
- this.cache = undefined;
40
+ this.requestHistoryRoute = undefined;
44
41
  this.visitorCounterRoute = undefined;
45
42
  this.visitorCounterMiddleware = undefined;
46
43
  this.widgetsRoute = undefined;
@@ -201,62 +198,19 @@ class ModulesManager {
201
198
 
202
199
 
203
200
 
204
- try {
205
- this.dialogflowListener = require('@tiledesk-ent/tiledesk-server-dialogflow').listener;
206
- // this.dialogflowListener.listen();
207
- winston.debug("this.dialogflowListener:"+ this.dialogflowListener);
208
-
209
- winston.info("ModulesManager dialogflow initialized");
210
- } catch(err) {
211
- if (err.code == 'MODULE_NOT_FOUND') {
212
- winston.info("ModulesManager init dialogflow module not found");
213
- }else {
214
- winston.error("ModulesManager error initializing init dialogflow module", err);
215
- }
216
- }
217
-
218
-
219
- try {
220
- this.routingQueue = require('@tiledesk-ent/tiledesk-server-routing-queue').listener;
221
- // this.routingQueue.listen();
222
- winston.debug("this.routingQueue:"+ this.routingQueue);
223
-
224
- winston.info("ModulesManager routing queue initialized");
225
- } catch(err) {
226
- if (err.code == 'MODULE_NOT_FOUND') {
227
- winston.info("ModulesManager init routing queue module not found");
228
- }else {
229
- winston.error("ModulesManager error initializing init routing queue module", err);
230
- }
231
- }
232
-
233
-
234
-
235
- try {
236
- this.queue = require('@tiledesk-ent/tiledesk-server-queue');
237
- winston.debug("this.queue:"+ this.queue);
238
-
239
- winston.info("ModulesManager queue initialized");
240
- } catch(err) {
241
- if (err.code == 'MODULE_NOT_FOUND') {
242
- winston.info("ModulesManager init queue module not found");
243
- }else {
244
- winston.error("ModulesManager error initializing init queue module", err);
245
- }
246
- }
247
-
201
+ // try {
202
+ // this.dialogflowListener = require('@tiledesk-ent/tiledesk-server-dialogflow').listener;
203
+ // // this.dialogflowListener.listen();
204
+ // winston.debug("this.dialogflowListener:"+ this.dialogflowListener);
248
205
 
249
- try {
250
- this.cache = require('@tiledesk-ent/tiledesk-server-cache').cachegoose(config.mongoose);
251
- winston.debug("this.cache:"+ this.cache);
252
- winston.info("ModulesManager cache initialized");
253
- } catch(err) {
254
- if (err.code == 'MODULE_NOT_FOUND') {
255
- winston.info("ModulesManager init cache module not found");
256
- }else {
257
- winston.error("ModulesManager error initializing init cache module", err);
258
- }
259
- }
206
+ // winston.info("ModulesManager dialogflow initialized");
207
+ // } catch(err) {
208
+ // if (err.code == 'MODULE_NOT_FOUND') {
209
+ // winston.info("ModulesManager init dialogflow module not found");
210
+ // }else {
211
+ // winston.error("ModulesManager error initializing init dialogflow module", err);
212
+ // }
213
+ // }
260
214
 
261
215
 
262
216
 
@@ -329,22 +283,15 @@ class ModulesManager {
329
283
  winston.info("ModulesManager error starting requestHistoryArchiver module", err);
330
284
  }
331
285
  }
332
- if (this.routingQueue) {
333
- try {
334
- this.routingQueue.listen();
335
- winston.info("ModulesManager routingQueue started");
336
- } catch(err) {
337
- winston.info("ModulesManager error starting routingQueue module", err);
338
- }
339
- }
340
- if (this.dialogflowListener) {
341
- try {
342
- this.dialogflowListener.listen();
343
- winston.info("ModulesManager dialogflowListener started");
344
- } catch(err) {
345
- winston.info("ModulesManager error starting dialogflowListener module", err);
346
- }
347
- }
286
+
287
+ // if (this.dialogflowListener) {
288
+ // try {
289
+ // this.dialogflowListener.listen();
290
+ // winston.info("ModulesManager dialogflowListener started");
291
+ // } catch(err) {
292
+ // winston.info("ModulesManager error starting dialogflowListener module", err);
293
+ // }
294
+ // }
348
295
 
349
296
 
350
297
 
@@ -4,16 +4,19 @@ var Project = require("../models/project");
4
4
  var moment_tz = require('moment-timezone');
5
5
  var winston = require('../config/winston');
6
6
  var cacheUtil = require('../utils/cacheUtil');
7
-
7
+ var cacheEnabler = require("../services/cacheEnabler");
8
8
 
9
9
  class OperatingHoursService {
10
10
 
11
11
  projectIsOpenNow(projectId, callback) {
12
12
 
13
13
  // winston.debug('O ---> [ OHS ] -> PROJECT ID ', projectId)
14
- Project.findOne({_id: projectId, status: 100})
15
- //@DISABLED_CACHE .cache(cacheUtil.defaultTTL, "projects:id:"+projectId)
16
- .exec(function (err, project) {
14
+ let q = Project.findOne({_id: projectId, status: 100});
15
+ if (cacheEnabler.project) {
16
+ q.cache(cacheUtil.longTTL, "projects:id:"+projectId) //project_cache
17
+ winston.debug('project cache enabled');
18
+ }
19
+ q.exec(function (err, project) {
17
20
  // winston.debug("XXXXXXXX project", project);
18
21
  if (err) {
19
22
  winston.error("O ---> [ OHS ] -> ERROR GETTING PROJECT ", err);
@@ -36,6 +39,8 @@ class OperatingHoursService {
36
39
 
37
40
  // IF THE TRIAL IS EXPIRED OR IF THE SUBSCIPTION IS NOT ACTIVE THE PROJECT IS ALWAYS OPEN EVEN IF activeOperatingHours IS SETTED TO true AND, FOR EXAMPLE,
38
41
  // THE USER HAS SETTED ALL DAYS TO CLOSED
42
+
43
+ //secondo me qui manca un parentesi tonda per gli or
39
44
  if (project.profile && (project.profile.type === 'free' && project.trialExpired === true) || (project.profile.type === 'payment' && project.isActiveSubscription === false)) {
40
45
  winston.debug('O ---> [ OHS ] -> trial Expired OR Subscription NOT Active - PROJECT ALWAYS OPEN')
41
46
  callback(true, null) ;
@@ -7,11 +7,12 @@ var messageService = require('../services/messageService');
7
7
  const requestEvent = require('../event/requestEvent');
8
8
  const leadEvent = require('../event/leadEvent');
9
9
  var winston = require('../config/winston');
10
- const uuidv4 = require('uuid/v4');
11
10
  var RequestConstants = require("../models/requestConstants");
12
11
  var requestUtil = require("../utils/requestUtil");
13
12
  var cacheUtil = require("../utils/cacheUtil");
14
13
  var arrayUtil = require("../utils/arrayUtil");
14
+ var cacheEnabler = require("../services/cacheEnabler");
15
+ var UIDGenerator = require("../utils/UIDGenerator");
15
16
 
16
17
  class RequestService {
17
18
 
@@ -62,7 +63,8 @@ class RequestService {
62
63
 
63
64
 
64
65
  sendMessageUpdateLead() {
65
- leadEvent.on('lead.fullname.update', function(lead) {
66
+ leadEvent.on('lead.fullname.email.update', function(lead) {
67
+ winston.debug("lead.fullname.email.update ");
66
68
  // leadEvent.on('lead.update', function(lead) {
67
69
 
68
70
  setImmediate(() => {
@@ -226,16 +228,21 @@ class RequestService {
226
228
  winston.debug("id_project:" + id_project);
227
229
  winston.debug("nobot:"+ nobot);
228
230
 
229
- return Request
230
- .findOne({request_id: request_id, id_project: id_project})
231
- //@DISABLED_CACHE .cache(cacheUtil.defaultTTL, id_project+":requests:request_id:"+request_id)
232
- .exec( function(err, request) {
231
+ let q= Request
232
+ .findOne({request_id: request_id, id_project: id_project});
233
+
234
+ // if (cacheEnabler.request) { //(node:60837) UnhandledPromiseRejectionWarning: VersionError: No matching document found for id "633efe246a6cc0eda5732684" version 0 modifiedPaths "status, participants, participantsAgents, department, assigned_at, snapshot, snapshot.department, snapshot.department.updatedAt, snapshot.agents"
235
+ // q.cache(cacheUtil.defaultTTL, id_project+":requests:request_id:"+request_id+":simple") //request_cache
236
+ // winston.debug('request cache enabled');
237
+ // }
238
+ return q.exec( function(err, request) {
233
239
 
234
240
  if (err) {
235
241
  winston.error(err);
236
242
  return reject(err);
237
243
  }
238
244
 
245
+ winston.debug('request return',request);
239
246
 
240
247
  // cambia var in let
241
248
 
@@ -378,10 +385,15 @@ class RequestService {
378
385
  // winston.debug("request_id", request_id);
379
386
  // winston.debug("newstatus", newstatus);
380
387
 
381
- return Request
382
- .findOne({request_id: request_id, id_project: id_project})
383
- //@DISABLED_CACHE .cache(cacheUtil.defaultTTL, id_project+":requests:request_id:"+request_id)
384
- .exec( function(err, request) {
388
+ let q = Request
389
+ .findOne({request_id: request_id, id_project: id_project});
390
+
391
+ if (cacheEnabler.request) {
392
+ q.cache(cacheUtil.defaultTTL, id_project+":requests:request_id:"+request_id+":simple") //request_cache
393
+ winston.debug('request cache enabled');
394
+ }
395
+
396
+ return q.exec( function(err, request) {
385
397
 
386
398
  if (err) {
387
399
  winston.error(err);
@@ -407,7 +419,7 @@ class RequestService {
407
419
 
408
420
  createWithRequester(project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes, subject, preflight) {
409
421
 
410
- var request_id = 'support-group-'+ id_project + "-" + uuidv4();
422
+ var request_id = 'support-group-'+ id_project + "-" + UIDGenerator.generate();
411
423
  winston.debug("request_id: "+request_id);
412
424
 
413
425
  return this.createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes, subject, preflight);
@@ -502,6 +514,8 @@ class RequestService {
502
514
  try {
503
515
  // getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
504
516
  var result = await departmentService.getOperators(departmentid, id_project, false, undefined, context);
517
+ // console.log("************* after get operator: "+new Date().toISOString());
518
+
505
519
  winston.debug("getOperators", result);
506
520
  } catch(err) {
507
521
  return reject(err);
@@ -809,6 +823,7 @@ class RequestService {
809
823
 
810
824
 
811
825
  return new Promise(function (resolve, reject) {
826
+ winston.debug("changeFirstTextAndPreflightByRequestId", request_id);
812
827
  // winston.debug("request_id", request_id);
813
828
  // winston.debug("newstatus", newstatus);
814
829
 
@@ -933,41 +948,53 @@ class RequestService {
933
948
 
934
949
  }
935
950
 
936
- // unused
937
- incrementMessagesCountByRequestId(request_id, id_project) {
938
951
 
939
- return new Promise(function (resolve, reject) {
940
- // winston.debug("request_id", request_id);
941
- // winston.debug("newstatus", newstatus);
942
952
 
943
- return Request
944
- .findOneAndUpdate({request_id: request_id, id_project: id_project}, {$inc : {'messages_count' : 1}}, {new: true, upsert:false}, function(err, updatedRequest) {
945
- if (err) {
946
- winston.error(err);
947
- return reject(err);
948
- }
949
- winston.debug("Message count +1");
950
- return resolve(updatedRequest);
951
- });
952
- });
953
+ // unused
954
+ incrementMessagesCountByRequestId(request_id, id_project) {
953
955
 
954
- }
956
+ return new Promise(function (resolve, reject) {
957
+ // winston.debug("request_id", request_id);
958
+ // winston.debug("newstatus", newstatus);
959
+
960
+ return Request
961
+ .findOneAndUpdate({request_id: request_id, id_project: id_project}, {$inc : {'messages.messages_count' : 1}}, {new: true, upsert:false}, function(err, updatedRequest) {
962
+ if (err) {
963
+ winston.error(err);
964
+ return reject(err);
965
+ }
966
+ winston.debug("Message count +1");
967
+ return resolve(updatedRequest);
968
+ });
969
+ });
970
+
971
+ }
955
972
 
956
- updateWaitingTimeByRequestId(request_id, id_project) {
973
+ updateWaitingTimeByRequestId(request_id, id_project, enable_populate) {
957
974
 
958
975
  return new Promise(function (resolve, reject) {
959
976
  // winston.debug("request_id", request_id);
960
977
  // winston.debug("newstatus", newstatus);
961
978
 
962
- return Request
963
- .findOne({request_id: request_id, id_project: id_project})
964
- .populate('lead')
965
- .populate('department')
966
- .populate('participatingBots')
967
- .populate('participatingAgents')
968
- .populate({path:'requester',populate:{path:'id_user'}})
969
- //@DISABLED_CACHE .cache(cacheUtil.defaultTTL, id_project+":requests:request_id:"+request_id)
970
- .exec(function(err, request) {
979
+ let q = Request
980
+ .findOne({request_id: request_id, id_project: id_project});
981
+
982
+ if (enable_populate==true) {
983
+ winston.debug("updateWaitingTimeByRequestId enable_populate");
984
+
985
+ q.populate('lead')
986
+ .populate('department')
987
+ .populate('participatingBots')
988
+ .populate('participatingAgents')
989
+ .populate({path:'requester',populate:{path:'id_user'}});
990
+ }
991
+
992
+
993
+ // if (cacheEnabler.request) { //attention this cache is not usable bacause cacheoose don't support populate without .lean.. so if cached populated field is not returned with cacheoose, updateWaitingTime is only used in chat21webhook but i thik it is important for messages route
994
+ // q.cache(cacheUtil.defaultTTL, id_project+":requests:request_id:"+request_id) //request_cache
995
+ // winston.debug('request cache enabled');
996
+ // }
997
+ q.exec(function(err, request) {
971
998
  if (err) {
972
999
  winston.error(err);
973
1000
  return reject(err);
@@ -999,12 +1026,19 @@ class RequestService {
999
1026
  }
1000
1027
 
1001
1028
 
1002
- closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by) {
1029
+ closeRequestByRequestId(request_id, id_project, skipStatsUpdate, notify, closed_by, force) {
1003
1030
 
1004
1031
  var that = this;
1005
1032
  return new Promise(function (resolve, reject) {
1006
1033
  // winston.debug("request_id", request_id);
1007
1034
 
1035
+ if (force==undefined) {
1036
+ winston.debug("force is undefined ");
1037
+ force = false;
1038
+ }
1039
+ // else {
1040
+ // winston.info("force is: " + force);
1041
+ // }
1008
1042
 
1009
1043
  return Request
1010
1044
  .findOne({request_id: request_id, id_project: id_project})
@@ -1025,13 +1059,15 @@ class RequestService {
1025
1059
  winston.error("Request not found for request_id "+ request_id + " and id_project " + id_project);
1026
1060
  return reject({"success":false, msg:"Request not found for request_id "+ request_id + " and id_project " + id_project});
1027
1061
  }
1028
- if (request.status == RequestConstants.CLOSED) {
1062
+ if (force == false && request.status == RequestConstants.CLOSED) {
1029
1063
  // qui1000
1030
1064
  // if (request.statusObj.closed) {
1031
1065
  winston.debug("Request already closed for request_id "+ request_id + " and id_project " + id_project);
1032
1066
  return resolve(request);
1033
1067
  }
1034
1068
 
1069
+ winston.debug("sono qui");
1070
+
1035
1071
  // un utente può chiudere se appartiene a participatingAgents oppure meglio agents del progetto?
1036
1072
 
1037
1073
 
@@ -21,6 +21,7 @@ var jwt = require('jsonwebtoken');
21
21
  var config = require('../config/database'); // get db config file
22
22
  var cacheUtil = require("../utils/cacheUtil");
23
23
 
24
+ var cacheEnabler = require("../services/cacheEnabler");
24
25
 
25
26
  var webhook_origin = process.env.WEBHOOK_ORIGIN || "http://localhost:3000";
26
27
  winston.debug("webhook_origin: "+webhook_origin);
@@ -36,9 +37,13 @@ class SubscriptionNotifier {
36
37
 
37
38
  findSubscriber(event, id_project) {
38
39
  return new Promise(function (resolve, reject) {
39
- Subscription.find({event:event, $or:[{id_project: id_project}, {global: true}]})
40
- .cache(cacheUtil.longTTL, id_project+":subscriptions:event:"+event)
41
- .select("+secret +global")
40
+ let q = Subscription.find({event:event, $or:[{id_project: id_project}, {global: true}]});
41
+ if (cacheEnabler.subscription) {
42
+ q.cache(cacheUtil.longTTL, id_project+":subscriptions:event:"+event); //CACHE_SUBSCRIPTION
43
+ winston.debug('subscription cache enabled');
44
+ }
45
+
46
+ q.select("+secret +global")
42
47
  .exec(function (err, subscriptions) {
43
48
  // if (subscriptions && subscriptions.length>0) {
44
49
  // winston.debug("Subscription.notify", event, item , "length", subscriptions.length);
@@ -81,7 +86,7 @@ class SubscriptionNotifier {
81
86
 
82
87
  if (s.global==true){
83
88
  signOptions.audience = 'https://tiledesk.com';
84
- secret = config.secret;
89
+ secret = process.env.GLOBAL_SECRET || config.secret;
85
90
  }
86
91
 
87
92
  var token = jwt.sign(sJson, secret, signOptions);
@@ -0,0 +1,106 @@
1
+ const faqBotEvent = require('../event/faqBotEvent');
2
+ const Faq_kb = require('../models/faq_kb');
3
+ const Faq = require('../models/faq');
4
+ var winston = require('../config/winston');
5
+ const axios = require("axios").default;
6
+
7
+
8
+ let chatbot_training_api_url = "http://34.65.210.38/model/train"
9
+
10
+ class TrainingService {
11
+
12
+
13
+
14
+ train(eventName, faq) {
15
+
16
+ Faq_kb.findById(faq.id_faq_kb, (err, faq_kb) => {
17
+ winston.debug("faq_kb: ", faq_kb)
18
+
19
+ if (faq_kb.intentsEngine !== 'tiledesk-ai') {
20
+ winston.info("intentsEngine: off")
21
+ return null;
22
+ }
23
+
24
+ winston.info("intentsEngine: on")
25
+ Faq.find({ id_faq_kb: faq.id_faq_kb }, (err, faqs) => {
26
+
27
+ if (err) {
28
+ winston.error("[Training] find all error: ", err);
29
+ } else {
30
+
31
+ let json = {
32
+ "configuration": {
33
+ "language": faq_kb.language,
34
+ "pipeline": [""]
35
+ },
36
+ "model": faq_kb._id,
37
+ "nlu": []
38
+ }
39
+
40
+ faqs.forEach((f) => {
41
+ if (f.enabled == true) {
42
+ let intent = {
43
+ "intent": f.intent_display_name,
44
+ "examples": []
45
+ }
46
+ let questions = f.question.split("\n");
47
+ intent.examples = questions;
48
+ json.nlu.push(intent);
49
+ }
50
+ })
51
+
52
+ winston.debug("training json: \n" + JSON.stringify(json, null, 2));
53
+
54
+ axios({
55
+ url: chatbot_training_api_url,
56
+ headers: {
57
+ 'Content-Type': 'application/json'
58
+ },
59
+ data: json,
60
+ method: 'POST'
61
+ }).then((resbody) => {
62
+ winston.info("[Training] resbody: ", resbody.data);
63
+ return true;
64
+ }).catch((err) => {
65
+ winston.error("[Training] error: ", err.response.data);
66
+ })
67
+ }
68
+ })
69
+
70
+ })
71
+
72
+
73
+
74
+ }
75
+
76
+ start() {
77
+ winston.info('TrainingService start');
78
+
79
+ faqBotEvent.on('faq.create', (faq) => {
80
+ setImmediate(() => {
81
+ trainingService.train('faq.create', faq);
82
+ })
83
+ })
84
+
85
+ faqBotEvent.on('faq.update', (faq) => {
86
+ winston.debug("--> event faq: ", faq);
87
+ setImmediate(() => {
88
+ trainingService.train('faq.update', faq);
89
+ })
90
+ })
91
+
92
+ faqBotEvent.on('faq.delete', (faq) => {
93
+ console.log("--> event faq: ", faq);
94
+ setImmediate(() => {
95
+ trainingService.train('faq.delete', faq);
96
+ })
97
+ })
98
+
99
+
100
+ }
101
+
102
+ }
103
+
104
+ var trainingService = new TrainingService();
105
+
106
+ module.exports = trainingService;
@@ -11,9 +11,19 @@
11
11
  img {
12
12
  max-width: 100%;
13
13
  margin-left:16px;
14
- margin-bottom:16px;
15
14
  text-align:center !important;
16
15
  }
16
+ img.CToWUd {
17
+ margin-bottom: 16px;
18
+ max-width: 200px !important;
19
+ width: 200px !important;
20
+ min-width: 200px !important;
21
+ outline: none;
22
+ text-decoration: none;
23
+ border: none;
24
+ height: auto;
25
+ margin-left: 0px;
26
+ }
17
27
  body {
18
28
  -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em;
19
29
  }
@@ -82,7 +92,7 @@
82
92
 
83
93
  <div style="text-align:center">
84
94
  <a href="http://www.tiledesk.com" style="color:#2daae1;font-weight:bold;text-decoration:none;word-break:break-word" target="_blank">
85
- <img src="https://tiledesk.com/wp-content/uploads/2022/07/tiledesk_v2.png" style="width:10%;outline:none;text-decoration:none;border:none;min-height:36px" class="CToWUd">
95
+ <img src="https://tiledesk.com/wp-content/uploads/2023/01/tiledesk_log_email_200.png" class="CToWUd">
86
96
  </a>
87
97
  </div>
88
98
  </tr>
@@ -102,7 +112,7 @@
102
112
  <table width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
103
113
 
104
114
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
105
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
115
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
106
116
  {{#ifEquals message.type "text"}}
107
117
  <div style="white-space: pre-wrap;">{{{msgText}}}</div>
108
118
  {{/ifEquals}}
@@ -120,26 +130,26 @@
120
130
 
121
131
 
122
132
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
123
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
133
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
124
134
  Project name : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{project.name}}</strong>
125
135
  </td>
126
136
  </tr>
127
137
 
128
138
 
129
139
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
130
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
140
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
131
141
  Department name : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{request.department.name}}</strong>
132
142
  </td>
133
143
  </tr>
134
144
 
135
145
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
136
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
146
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
137
147
  From email : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{request.lead.email}}</strong>
138
148
  </td>
139
149
  </tr>
140
150
 
141
151
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
142
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
152
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
143
153
  Contact name : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">{{request.lead.fullname}}</strong>
144
154
  </td>
145
155
  </tr>
@@ -151,7 +161,7 @@
151
161
  </tr> -->
152
162
 
153
163
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
154
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
164
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
155
165
  Channel : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
156
166
  {{#ifEquals request.channel.name "chat21"}}
157
167
  Chat
@@ -163,7 +173,7 @@
163
173
  </tr>
164
174
 
165
175
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
166
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
176
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
167
177
  <a href="{{baseScope.baseUrl}}/#/project/{{request.id_project}}/wsrequest/{{request.request_id}}/messages">Open the dashboard</a>.
168
178
 
169
179
  </td>
@@ -174,7 +184,7 @@
174
184
 
175
185
 
176
186
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
177
- <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 0 0 20px;" valign="top">
187
+ <td class="content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top">
178
188
  </td>
179
189
  </tr>
180
190
  </table>
@@ -184,7 +194,7 @@
184
194
  <div class="footer" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; clear: both; color: #999; margin: 0; padding: 20px;">
185
195
  <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
186
196
  <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
187
- <td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0; padding: 0 0 20px;" align="center" valign="top">
197
+ <td class="aligncenter content-block" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; vertical-align: top; color: #999; text-align: center; margin: 0;" align="center" valign="top">
188
198
  <span><a href="http://www.tiledesk.com" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;" > Tiledesk.com </a></span>
189
199
  <br><span><a href="%unsubscribe_url%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 12px; color: #999; text-decoration: underline; margin: 0;">Unsubscribe</a></span>
190
200
  </td>