@tiledesk/tiledesk-server 2.1.41 → 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. package/.circleci/config.yml +54 -0
  2. package/.env.sample +1 -1
  3. package/.github/workflows/docker-community-push-latest.yml +22 -0
  4. package/.github/workflows/{docker-image-push.yml → docker-image-en-tag-push.yml} +1 -1
  5. package/.github/workflows/docker-image-tag-community-tag-push.yml +21 -0
  6. package/.github/workflows/{docker-push-latest.yml → docker-push-en-push-latest.yml} +1 -1
  7. package/CHANGELOG.md +198 -1
  8. package/Dockerfile +1 -1
  9. package/Dockerfile-en +1 -1
  10. package/README.md +5 -7
  11. package/app.js +12 -1
  12. package/channels/chat21/chat21Contact.js +34 -8
  13. package/channels/chat21/chat21Handler.js +48 -5
  14. package/channels/chat21/chat21WebHook.js +34 -5
  15. package/channels/chat21/nativeauth.js +2 -2
  16. package/config/email.js +2 -1
  17. package/config/global.js +3 -0
  18. package/config/labels/widget.json +170 -16
  19. package/event/messageEvent.js +18 -1
  20. package/middleware/passport.js +10 -4
  21. package/models/actionsConstants.js +7 -0
  22. package/models/department.js +3 -0
  23. package/models/faq.js +8 -2
  24. package/models/faq_kb.js +6 -0
  25. package/models/message.js +10 -4
  26. package/models/messageConstants.js +3 -3
  27. package/models/request.js +33 -3
  28. package/package.json +31 -28
  29. package/pubmodules/emailNotification/requestNotification.js +380 -62
  30. package/pubmodules/messageActions/messageActionsInterceptor.js +20 -7
  31. package/pubmodules/messageTransformer/index.js +1 -1
  32. package/pubmodules/messageTransformer/microLanguageAttributesTransformerInterceptor.js +67 -0
  33. package/pubmodules/pubModulesManager.js +66 -14
  34. package/pubmodules/rules/conciergeBot.js +81 -49
  35. package/routes/auth.js +34 -10
  36. package/routes/campaigns.js +117 -25
  37. package/routes/faq.js +19 -0
  38. package/routes/faq_kb.js +13 -4
  39. package/routes/faqpub.js +1 -1
  40. package/routes/images.js +1 -1
  41. package/routes/jwt.js +0 -1
  42. package/routes/logs.js +26 -0
  43. package/routes/message.js +7 -2
  44. package/routes/messagesRoot.js +73 -16
  45. package/routes/project_user.js +36 -1
  46. package/routes/request.js +88 -12
  47. package/routes/requestUtilRoot.js +30 -0
  48. package/routes/urls.js +12 -0
  49. package/routes/users.js +5 -1
  50. package/services/BotSubscriptionNotifier.js +1 -0
  51. package/services/departmentService.js +29 -5
  52. package/services/emailService.js +1103 -298
  53. package/services/faqBotHandler.js +176 -61
  54. package/services/faqBotSupport.js +181 -117
  55. package/services/faqService.js +17 -14
  56. package/services/messageService.js +57 -9
  57. package/services/modulesManager.js +86 -23
  58. package/services/requestService.js +58 -17
  59. package/template/email/assignedEmailMessage.html +205 -0
  60. package/template/email/assignedRequest.html +44 -14
  61. package/template/email/beenInvitedExistingUser.html +2 -2
  62. package/template/email/beenInvitedNewUser.html +1 -1
  63. package/template/email/newMessage.html +31 -12
  64. package/template/email/passwordChanged.html +2 -3
  65. package/template/email/pooledEmailMessage.html +208 -0
  66. package/template/email/pooledRequest.html +41 -14
  67. package/template/email/resetPassword.html +2 -3
  68. package/template/email/sendTranscript.html +1 -1
  69. package/template/email/test.html +1 -1
  70. package/template/email/ticket.html +78 -52
  71. package/template/email/ticket.txt +5 -1
  72. package/template/email/verify.html +1 -1
  73. package/test/authentication.js +76 -4
  74. package/test/authenticationJwt.js +76 -2
  75. package/test/campaignsRoute.js +226 -0
  76. package/test/faqService.js +3 -3
  77. package/test/faqkbRoute.js +3 -2
  78. package/test/messageRootRoute.js +193 -0
  79. package/test/messageRoute.js +75 -0
  80. package/test/messageService.js +5 -5
  81. package/test/requestRoute.js +27 -9
  82. package/test/requestService.js +472 -11
  83. package/test-int/bot.js +673 -8
  84. package/websocket/webSocketServer.js +7 -4
  85. package/template/email/ticket-taking.txt +0 -7
@@ -178,7 +178,7 @@ class ModulesManager {
178
178
  winston.debug("this.trigger:"+ this.trigger);
179
179
  this.triggerRoute = require('@tiledesk-ent/tiledesk-server-triggers').triggerRoute;
180
180
  winston.debug("this.triggerRoute:"+ this.triggerRoute);
181
- winston.info("ModulesManager init trigger loaded.");
181
+ winston.info("ModulesManager trigger initialized");
182
182
  } catch(err) {
183
183
  if (err.code == 'MODULE_NOT_FOUND') {
184
184
  winston.info("ModulesManager init trigger module not found");
@@ -190,7 +190,7 @@ class ModulesManager {
190
190
 
191
191
  try {
192
192
  this.stripe = require('@tiledesk-ent/tiledesk-server-payments').stripeRoute;
193
- winston.info("ModulesManager init stripe loaded");
193
+ winston.info("ModulesManager stripe initialized");
194
194
  } catch(err) {
195
195
  if (err.code == 'MODULE_NOT_FOUND') {
196
196
  winston.info("ModulesManager init stripe module not found");
@@ -203,8 +203,8 @@ class ModulesManager {
203
203
  this.resthookRoute = require('@tiledesk-ent/tiledesk-server-resthook').resthookRoute;
204
204
  winston.debug("this.resthookRoute:"+ this.resthookRoute);
205
205
  this.subscriptionNotifier = require('@tiledesk-ent/tiledesk-server-resthook').subscriptionNotifier;
206
- this.subscriptionNotifier.start();
207
- winston.info("ModulesManager init resthook loaded");
206
+ // this.subscriptionNotifier.start();
207
+ winston.info("ModulesManager resthook initialized");
208
208
  } catch(err) {
209
209
  if (err.code == 'MODULE_NOT_FOUND') {
210
210
  winston.info("ModulesManager init resthookRoute module not found");
@@ -217,7 +217,7 @@ class ModulesManager {
217
217
  try {
218
218
  this.analyticsRoute = require('@tiledesk-ent/tiledesk-server-analytics').analyticsRoute;
219
219
  winston.debug("this.analyticsRoute:"+ this.analyticsRoute);
220
- winston.info("ModulesManager init analyticsRoute loaded");
220
+ winston.info("ModulesManager analyticsRoute initialized");
221
221
  } catch(err) {
222
222
  if (err.code == 'MODULE_NOT_FOUND') {
223
223
  winston.info("ModulesManager init analytics module not found");
@@ -229,13 +229,13 @@ class ModulesManager {
229
229
 
230
230
  try {
231
231
  this.activityArchiver = require('@tiledesk-ent/tiledesk-server-activities').activityArchiver;
232
- this.activityArchiver.listen();
232
+ // this.activityArchiver.listen();
233
233
  winston.debug("this.activityArchiver:"+ this.activityArchiver);
234
234
 
235
235
  this.activityRoute = require('@tiledesk-ent/tiledesk-server-activities').activityRoute;
236
236
  winston.debug("this.activityRoute:"+ this.activityRoute);
237
237
 
238
- winston.info("ModulesManager init activities loaded");
238
+ winston.info("ModulesManager activities initialized");
239
239
  } catch(err) {
240
240
  if (err.code == 'MODULE_NOT_FOUND') {
241
241
  winston.info("ModulesManager init activities module not found");
@@ -248,13 +248,13 @@ class ModulesManager {
248
248
 
249
249
  try {
250
250
  this.jwthistoryArchiver = require('@tiledesk-ent/tiledesk-server-jwthistory').jwthistoryArchiver;
251
- this.jwthistoryArchiver.listen();
251
+ // this.jwthistoryArchiver.listen();
252
252
  winston.debug("this.jwthistoryArchiver:"+ this.jwthistoryArchiver);
253
253
 
254
254
  this.jwthistoryRoute = require('@tiledesk-ent/tiledesk-server-jwthistory').jwthistoryRoute;
255
255
  winston.debug("this.jwthistoryRoute:"+ this.jwthistoryRoute);
256
256
 
257
- winston.info("ModulesManager init jwthistory loaded");
257
+ winston.info("ModulesManager jwthistory initialized");
258
258
  } catch(err) {
259
259
  if (err.code == 'MODULE_NOT_FOUND') {
260
260
  winston.info("ModulesManager init jwthistory module not found");
@@ -268,13 +268,13 @@ class ModulesManager {
268
268
 
269
269
  try {
270
270
  this.requestHistoryArchiver = require('@tiledesk-ent/tiledesk-server-request-history').listener;
271
- this.requestHistoryArchiver.listen();
271
+ // this.requestHistoryArchiver.listen();
272
272
  winston.debug("this.requestHistoryArchiver:"+ this.requestHistoryArchiver);
273
273
 
274
274
  this.requestHistoryRoute = require('@tiledesk-ent/tiledesk-server-request-history').route;
275
275
  winston.debug("this.requestHistoryRoute:"+ this.requestHistoryRoute);
276
276
 
277
- winston.info("ModulesManager init requestHistory loaded");
277
+ winston.info("ModulesManager requestHistory initialized");
278
278
  } catch(err) {
279
279
  if (err.code == 'MODULE_NOT_FOUND') {
280
280
  winston.info("ModulesManager init requestHistory module not found");
@@ -289,10 +289,10 @@ class ModulesManager {
289
289
 
290
290
  try {
291
291
  this.dialogflowListener = require('@tiledesk-ent/tiledesk-server-dialogflow').listener;
292
- this.dialogflowListener.listen();
292
+ // this.dialogflowListener.listen();
293
293
  winston.debug("this.dialogflowListener:"+ this.dialogflowListener);
294
294
 
295
- winston.info("ModulesManager init dialogflow loaded");
295
+ winston.info("ModulesManager dialogflow initialized");
296
296
  } catch(err) {
297
297
  if (err.code == 'MODULE_NOT_FOUND') {
298
298
  winston.info("ModulesManager init dialogflow module not found");
@@ -304,10 +304,10 @@ class ModulesManager {
304
304
 
305
305
  try {
306
306
  this.routingQueue = require('@tiledesk-ent/tiledesk-server-routing-queue').listener;
307
- this.routingQueue.listen();
307
+ // this.routingQueue.listen();
308
308
  winston.debug("this.routingQueue:"+ this.routingQueue);
309
309
 
310
- winston.info("ModulesManager init routing queue loaded");
310
+ winston.info("ModulesManager routing queue initialized");
311
311
  } catch(err) {
312
312
  if (err.code == 'MODULE_NOT_FOUND') {
313
313
  winston.info("ModulesManager init routing queue module not found");
@@ -322,7 +322,7 @@ class ModulesManager {
322
322
  this.queue = require('@tiledesk-ent/tiledesk-server-queue');
323
323
  winston.debug("this.queue:"+ this.queue);
324
324
 
325
- winston.info("ModulesManager init queue loaded");
325
+ winston.info("ModulesManager queue initialized");
326
326
  } catch(err) {
327
327
  if (err.code == 'MODULE_NOT_FOUND') {
328
328
  winston.info("ModulesManager init queue module not found");
@@ -335,7 +335,7 @@ class ModulesManager {
335
335
  try {
336
336
  this.cache = require('@tiledesk-ent/tiledesk-server-cache').cachegoose(config.mongoose);
337
337
  winston.debug("this.cache:"+ this.cache);
338
- winston.info("ModulesManager init cache loaded");
338
+ winston.info("ModulesManager cache initialized");
339
339
  } catch(err) {
340
340
  if (err.code == 'MODULE_NOT_FOUND') {
341
341
  winston.info("ModulesManager init cache module not found");
@@ -347,7 +347,7 @@ class ModulesManager {
347
347
  try {
348
348
  this.cannedResponseRoute = require('@tiledesk-ent/tiledesk-server-canned').cannedResponseRoute;
349
349
  winston.debug("this.cannedResponseRoute:"+ this.cannedResponseRoute);
350
- winston.info("ModulesManager init cannedResponseRoute loaded");
350
+ winston.info("ModulesManager cannedResponseRoute initialized");
351
351
  } catch(err) {
352
352
  if (err.code == 'MODULE_NOT_FOUND') {
353
353
  winston.info("ModulesManager init canned module not found");
@@ -359,7 +359,7 @@ class ModulesManager {
359
359
  try {
360
360
  this.tagRoute = require('@tiledesk-ent/tiledesk-server-tags').tagRoute;
361
361
  winston.debug("this.tagRoute:"+ this.tagRoute);
362
- winston.info("ModulesManager init tagRoute loaded");
362
+ winston.info("ModulesManager tagRoute initialized");
363
363
  } catch(err) {
364
364
  if (err.code == 'MODULE_NOT_FOUND') {
365
365
  winston.info("ModulesManager init tag module not found");
@@ -371,7 +371,7 @@ class ModulesManager {
371
371
  try {
372
372
  this.groupsRoute = require('@tiledesk-ent/tiledesk-server-groups').groupsRoute;
373
373
  winston.debug("this.groupsRoute:"+ this.groupsRoute);
374
- winston.info("ModulesManager init groupsRoute loaded");
374
+ winston.info("ModulesManager groupsRoute initialized");
375
375
  } catch(err) {
376
376
  if (err.code == 'MODULE_NOT_FOUND') {
377
377
  winston.info("ModulesManager init group module not found");
@@ -385,7 +385,7 @@ class ModulesManager {
385
385
  if (config && config.routes && config.routes.departmentsRoute) {
386
386
  try {
387
387
  require('@tiledesk-ent/tiledesk-server-departments').ext(config.routes.departmentsRoute, config.passport);
388
- winston.info("ModulesManager init departmentsRoute loaded");
388
+ winston.info("ModulesManager departmentsRoute initialized");
389
389
  } catch(err) {
390
390
  if (err.code == 'MODULE_NOT_FOUND') {
391
391
  winston.info("ModulesManager init departments module not found");
@@ -398,7 +398,7 @@ class ModulesManager {
398
398
  if (config && config.routes && config.routes.projectsRoute) {
399
399
  try {
400
400
  require('@tiledesk-ent/tiledesk-server-mt').ext(config.routes.projectsRoute, config.passport);
401
- winston.info("ModulesManager init mt loaded");
401
+ winston.info("ModulesManager mt initialized");
402
402
  } catch(err) {
403
403
  if (err.code == 'MODULE_NOT_FOUND') {
404
404
  winston.info("ModulesManager init mt module not found");
@@ -416,7 +416,7 @@ class ModulesManager {
416
416
  this.widgetsRoute = config.routes.widgetsRoute;
417
417
  winston.debug(" this.widgetsRoute:"+ this.widgetsRoute);
418
418
 
419
- winston.info("ModulesManager init visitorCounter loaded");
419
+ winston.info("ModulesManager visitorCounter initialized");
420
420
  } catch(err) {
421
421
  if (err.code == 'MODULE_NOT_FOUND') {
422
422
  winston.info("ModulesManager init visitorCounter module not found");
@@ -454,6 +454,69 @@ class ModulesManager {
454
454
 
455
455
 
456
456
 
457
+ }
458
+
459
+
460
+ start() {
461
+
462
+ // stampa log
463
+ if (this.subscriptionNotifier) {
464
+ try {
465
+ this.subscriptionNotifier.start();
466
+ winston.info("ModulesManager subscriptionNotifier started");
467
+ } catch(err) {
468
+ winston.info("ModulesManager error starting subscriptionNotifier module", err);
469
+ }
470
+ }
471
+
472
+ if (this.activityArchiver) {
473
+ try {
474
+ this.activityArchiver.listen();
475
+ winston.info("ModulesManager activityArchiver started");
476
+ } catch(err) {
477
+ winston.info("ModulesManager error starting activityArchiver module", err);
478
+ }
479
+ }
480
+
481
+ if (this.jwthistoryArchiver) {
482
+ try {
483
+ this.jwthistoryArchiver.listen();
484
+ winston.info("ModulesManager jwthistoryArchiver started");
485
+ } catch(err) {
486
+ winston.info("ModulesManager error starting jwthistoryArchiver module", err);
487
+ }
488
+ }
489
+
490
+ if (this.requestHistoryArchiver) {
491
+ try {
492
+ this.requestHistoryArchiver.listen();
493
+ winston.info("ModulesManager requestHistoryArchiver started");
494
+ } catch(err) {
495
+ winston.info("ModulesManager error starting requestHistoryArchiver module", err);
496
+ }
497
+ }
498
+ if (this.routingQueue) {
499
+ try {
500
+ this.routingQueue.listen();
501
+ winston.info("ModulesManager routingQueue started");
502
+ } catch(err) {
503
+ winston.info("ModulesManager error starting routingQueue module", err);
504
+ }
505
+ }
506
+ if (this.dialogflowListener) {
507
+ try {
508
+ this.dialogflowListener.listen();
509
+ winston.info("ModulesManager dialogflowListener started");
510
+ } catch(err) {
511
+ winston.info("ModulesManager error starting dialogflowListener module", err);
512
+ }
513
+ }
514
+
515
+
516
+
517
+
518
+
519
+
457
520
  }
458
521
 
459
522
 
@@ -123,6 +123,9 @@ class RequestService {
123
123
  winston.debug("routeInternal assigned_operator_id: "+ assigned_operator_id);
124
124
  winston.debug("routeInternal status: "+ status);
125
125
 
126
+
127
+
128
+ // cosi modifica la request originale forse devi fare il clone?????
126
129
  request.status = status;
127
130
 
128
131
  request.participants = participants;
@@ -187,14 +190,29 @@ class RequestService {
187
190
 
188
191
  return that.routeInternal(request, departmentid, id_project, nobot ).then(function(routedRequest){
189
192
 
190
- winston.debug("after routeInternal");
193
+ winston.debug("after routeInternal",routedRequest);
191
194
  // winston.info("requestBeforeRoute.participants " +requestBeforeRoute.request_id , requestBeforeRoute.participants);
192
195
  // console.log("routedRequest.participants " +routedRequest.request_id , routedRequest.participants);
193
- winston.debug("request.status:" + requestBeforeRoute.status);
196
+ winston.debug("requestBeforeRoute.status:" + requestBeforeRoute.status);
194
197
  winston.debug("routedRequest.status:" + routedRequest.status);
195
198
 
199
+ let beforeDepartmentId;
200
+ if (requestBeforeRoute.department) { //requestBeforeRoute.department can be empty for internal ticket
201
+ beforeDepartmentId = requestBeforeRoute.department.toString();
202
+ winston.debug("beforeDepartmentId:"+ beforeDepartmentId);
203
+ }
204
+
205
+ let afterDepartmentId;
206
+ if (routedRequest.department) {
207
+ afterDepartmentId = routedRequest.department.toString();
208
+ winston.debug("afterDepartmentId:"+ afterDepartmentId);
209
+ }
210
+
211
+
212
+ if (requestBeforeRoute.status === routedRequest.status &&
213
+ beforeDepartmentId === afterDepartmentId &&
214
+ requestUtil.arraysEqual(beforeParticipants, routedRequest.participants)) {
196
215
 
197
- if (requestBeforeRoute.status === routedRequest.status && requestUtil.arraysEqual(beforeParticipants, routedRequest.participants)) {
198
216
  winston.verbose("Request " +request.request_id + " contains already the same participants at the same request status. Routed to the same participants");
199
217
 
200
218
  if (no_populate==="true" || no_populate===true) {
@@ -209,6 +227,8 @@ class RequestService {
209
227
  .populate('participatingAgents')
210
228
  .populate({path:'requester',populate:{path:'id_user'}})
211
229
  .execPopulate( function(err, requestComplete) {
230
+ winston.debug("requestComplete",requestComplete);
231
+
212
232
  return resolve(requestComplete);
213
233
  });
214
234
  }
@@ -222,7 +242,7 @@ class RequestService {
222
242
  return reject(err);
223
243
  }
224
244
 
225
- winston.debug("after save");
245
+ winston.debug("after save savedRequest", savedRequest);
226
246
 
227
247
  return savedRequest
228
248
  .populate('lead')
@@ -265,7 +285,6 @@ class RequestService {
265
285
 
266
286
  requestEvent.emit('request.update',requestComplete);
267
287
  requestEvent.emit("request.update.comment", {comment:"REROUTE",request:requestComplete});
268
- // requestEvent.emit('request.participants.update', {beforeRequest:request, request:requestComplete});
269
288
  requestEvent.emit('request.participants.update', {beforeRequest:request,
270
289
  removedParticipants:removedParticipants,
271
290
  addedParticipants:addedParticipants,
@@ -328,7 +347,7 @@ class RequestService {
328
347
 
329
348
  createWithRequester(project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes, subject, preflight) {
330
349
 
331
- var request_id = 'support-group-'+uuidv4();
350
+ var request_id = 'support-group-'+ id_project + "-" + uuidv4();
332
351
  winston.debug("request_id: "+request_id);
333
352
 
334
353
  return this.createWithIdAndRequester(request_id, project_user_id, lead_id, id_project, first_text, departmentid, sourcePage, language, userAgent, status, createdBy, attributes, subject, preflight);
@@ -354,11 +373,13 @@ class RequestService {
354
373
  var lead_id = request.lead_id;
355
374
  var id_project = request.id_project;
356
375
 
357
- //TODO rimuovi ritorni a capo first_text, fai anche trim
358
- var first_text;
359
- if (request.first_text) { //first_text can be empty for type image
360
- first_text = request.first_text.replace(/[\n\r]+/g, '');
361
- }
376
+ var first_text = request.first_text;
377
+ //removed for ticket
378
+ // // lascia che sia nico a fare il replace...certo tu devi fare il test che tutto sia ok quindi dopo demo
379
+ // var first_text;
380
+ // if (request.first_text) { //first_text can be empty for type image
381
+ // first_text = request.first_text.replace(/[\n\r]+/g, ' '); //replace new line with space
382
+ // }
362
383
 
363
384
  var departmentid = request.departmentid;
364
385
  var sourcePage = request.sourcePage;
@@ -373,6 +394,10 @@ class RequestService {
373
394
  var location = request.location;
374
395
  var participants = request.participants || [];
375
396
 
397
+ var tags = request.tags;
398
+ var notes = request.notes;
399
+ var priority = request.priority;
400
+
376
401
  if (!departmentid) {
377
402
  departmentid ='default';
378
403
  }
@@ -393,7 +418,8 @@ class RequestService {
393
418
  var context = {request: {request_id:request_id, project_user_id:project_user_id, lead_id:lead_id, id_project:id_project,
394
419
  first_text:first_text, departmentid:departmentid, sourcePage:sourcePage, language:language, userAgent:userAgent, status:status,
395
420
  createdBy:createdBy, attributes:attributes, subject:subject, preflight: preflight, channel: channel, location: location,
396
- participants:participants}};
421
+ participants:participants, tags: tags, notes:notes,
422
+ priority: priority}};
397
423
 
398
424
  winston.debug("context",context);
399
425
 
@@ -409,9 +435,14 @@ class RequestService {
409
435
 
410
436
  var snapshot = {};
411
437
 
412
- // getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
413
- var result = await departmentService.getOperators(departmentid, id_project, false, undefined, context);
414
- winston.debug("getOperators", result);
438
+ try {
439
+ // getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {
440
+ var result = await departmentService.getOperators(departmentid, id_project, false, undefined, context);
441
+ winston.debug("getOperators", result);
442
+ } catch(err) {
443
+ return reject(err);
444
+ }
445
+
415
446
 
416
447
 
417
448
  agents = result.agents;
@@ -513,7 +544,10 @@ class RequestService {
513
544
  preflight: preflight,
514
545
  channel: channel,
515
546
  location: location,
516
- snapshot: snapshot
547
+ snapshot: snapshot,
548
+ tags: tags,
549
+ notes: notes,
550
+ priority: priority
517
551
  });
518
552
 
519
553
 
@@ -704,10 +738,16 @@ class RequestService {
704
738
 
705
739
  changeFirstTextAndPreflightByRequestId(request_id, id_project, first_text, preflight) {
706
740
 
741
+
707
742
  return new Promise(function (resolve, reject) {
708
743
  // winston.debug("request_id", request_id);
709
744
  // winston.debug("newstatus", newstatus);
710
745
 
746
+ if (!first_text) {
747
+ winston.error(err);
748
+ return reject({err:" Error changing first text. The field first_text is empty"});
749
+ }
750
+
711
751
  return Request
712
752
  .findOneAndUpdate({request_id: request_id, id_project: id_project}, {first_text: first_text, preflight: preflight}, {new: true, upsert:false})
713
753
  .populate('lead')
@@ -1569,7 +1609,7 @@ class RequestService {
1569
1609
 
1570
1610
 
1571
1611
  // return Request.findById(id).then(function (request) {
1572
- if (request.participants.indexOf(tag)==-1){
1612
+ if (request.tags.indexOf(tag)==-1){
1573
1613
  request.tags.push(tag);
1574
1614
  // check error here
1575
1615
 
@@ -1678,3 +1718,4 @@ var requestService = new RequestService();
1678
1718
 
1679
1719
 
1680
1720
  module.exports = requestService;
1721
+
@@ -0,0 +1,205 @@
1
+
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html lang="en" xmlns="http://www.w3.org/1999/xhtml" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
4
+
5
+ <head>
6
+ <meta name="viewport" content="width=device-width" />
7
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
8
+ <title>New message ticket from TileDesk</title>
9
+
10
+ <style type="text/css">
11
+ img {
12
+ max-width: 100%;
13
+ margin-left:16px;
14
+ margin-bottom:16px;
15
+ text-align:center !important;
16
+ }
17
+ body {
18
+ -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em;
19
+ }
20
+ body {
21
+ background-color: #f6f6f6;
22
+ }
23
+
24
+ @media only screen and (max-width: 640px) {
25
+ body {
26
+ padding: 0 !important;
27
+ }
28
+ h1 {
29
+ font-weight: 800 !important; margin: 20px 0 5px !important;
30
+ text-align:center !important;
31
+ }
32
+ h2 {
33
+ font-weight: 800 !important; margin: 20px 0 5px !important;
34
+ }
35
+ h3 {
36
+ font-weight: 800 !important; margin: 20px 0 5px !important;
37
+ }
38
+ h4 {
39
+ font-weight: 800 !important; margin: 20px 0 5px !important;
40
+ }
41
+ h1 {
42
+ font-size: 22px !important;
43
+ }
44
+ h2 {
45
+ font-size: 18px !important;
46
+ }
47
+ h3 {
48
+ font-size: 16px !important;
49
+ }
50
+ .container {
51
+ padding: 0 !important; width: 100% !important;
52
+ }
53
+ .content {
54
+ padding: 0 !important;
55
+ }
56
+ .content-wrap {
57
+ padding: 10px !important;
58
+ }
59
+ .invoice {
60
+ width: 100% !important;
61
+ }
62
+ }
63
+ </style>
64
+ </head>
65
+
66
+ <body itemscope itemtype="http://schema.org/EmailMessage" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none; width: 100% !important; height: 100%; line-height: 1.6em; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
67
+
68
+ {{#if baseScope.replyEnabled}}
69
+ <div>\# Please type your reply above this line \#</div>
70
+ {{/if}}
71
+
72
+ <!-- <table class="body-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; width: 100%; background-color: #f6f6f6; margin: 0;" bgcolor="#f6f6f6">
73
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
74
+ <td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>
75
+ <td class="container" width="600" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; display: block !important; max-width: 600px !important; clear: both !important; margin: 0 auto;" valign="top">
76
+ <div class="content" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; max-width: 600px; display: block; margin: 0 auto; padding: 20px;"> -->
77
+
78
+
79
+ <table class="main" width="100%" cellpadding="0" cellspacing="0" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; border-radius: 3px; background-color: #fff; margin: 0; border: 1px solid #e9e9e9;" bgcolor="#fff">
80
+
81
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
82
+
83
+ <div style="text-align:center">
84
+ <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/tiledesk-logo-x1.png" style="width:10%;outline:none;text-decoration:none;border:none;min-height:36px" class="CToWUd">
86
+ </a>
87
+ </div>
88
+ </tr>
89
+
90
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
91
+
92
+ <td class="alert alert-warning" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 16px; vertical-align: top; font-weight: 500; text-align: center; border-radius: 3px 3px 0 0; margin: 0;" align="center" valign="top">
93
+ <div>
94
+ <h2>New Message from a ticket assigned to you</h2>
95
+ </div>
96
+
97
+ </td>
98
+ </tr>
99
+
100
+ <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
101
+ <td class="content-wrap" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0; padding: 20px;" valign="top">
102
+ <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
+
104
+ <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">
106
+ {{#ifEquals message.type "text"}}
107
+ <div style="white-space: pre-wrap;">{{{msgText}}}</div>
108
+ {{/ifEquals}}
109
+ {{#ifEquals message.type "image"}}
110
+ <img src="{{message.metadata.src}}"/>
111
+ {{/ifEquals}}
112
+ {{#ifEquals message.type "file"}}
113
+ <a href="{{message.metadata.src}}">{{message.metadata.name}}</a>
114
+ {{/ifEquals}}
115
+
116
+ </td>
117
+ </tr>
118
+
119
+
120
+
121
+
122
+ <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">
124
+ 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
+ </td>
126
+ </tr>
127
+
128
+
129
+ <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">
131
+ 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
+ </td>
133
+ </tr>
134
+
135
+ <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">
137
+ 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
+ </td>
139
+ </tr>
140
+
141
+ <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">
143
+ 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
+ </td>
145
+ </tr>
146
+
147
+ <!-- <tr style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
148
+ <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">
149
+ Assignee : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;"></strong>
150
+ </td>
151
+ </tr> -->
152
+
153
+ <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">
155
+ Channel : <strong style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
156
+ {{#ifEquals request.channel.name "chat21"}}
157
+ Chat
158
+ {{else}}
159
+ {{request.channel.name}}
160
+ {{/ifEquals}}
161
+ </strong>
162
+ </td>
163
+ </tr>
164
+
165
+ <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">
167
+ <a href="{{baseScope.baseUrl}}/#/project/{{request.id_project}}/wsrequest/{{request.request_id}}/messages">Open the dashboard</a>.
168
+
169
+ </td>
170
+ </tr>
171
+
172
+
173
+
174
+
175
+
176
+ <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">
178
+ </td>
179
+ </tr>
180
+ </table>
181
+ </td>
182
+ </tr>
183
+ </table>
184
+ <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
+ <table width="100%" style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; margin: 0;">
186
+ <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">
188
+ <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
+ <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
+ </td>
191
+ </tr>
192
+ </table>
193
+
194
+
195
+
196
+ <!-- </div>
197
+ </div>
198
+ </td>
199
+ <td style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; vertical-align: top; margin: 0;" valign="top"></td>
200
+ </tr>
201
+ </table> -->
202
+
203
+
204
+ </body>
205
+ </html>