@tiledesk/tiledesk-server 2.1.41 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>