comment.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { getModelSafely } from '@growi/core';
  2. import { Types } from 'mongoose';
  3. import { SUPPORTED_TARGET_MODEL_TYPE, SUPPORTED_EVENT_MODEL_TYPE, SUPPORTED_ACTION_TYPE } from '~/interfaces/activity';
  4. import { stringifySnapshot } from '~/models/serializers/in-app-notification-snapshot/page';
  5. import loggerFactory from '../../utils/logger';
  6. import Crowi from '../crowi';
  7. const logger = loggerFactory('growi:service:CommentService');
  8. class CommentService {
  9. crowi!: Crowi;
  10. activityService!: any;
  11. inAppNotificationService!: any;
  12. commentEvent!: any;
  13. constructor(crowi: Crowi) {
  14. this.crowi = crowi;
  15. this.activityService = crowi.activityService;
  16. this.inAppNotificationService = crowi.inAppNotificationService;
  17. this.commentEvent = crowi.event('comment');
  18. // init
  19. this.initCommentEventListeners();
  20. }
  21. initCommentEventListeners(): void {
  22. // create
  23. this.commentEvent.on('create', async(savedComment) => {
  24. try {
  25. const Page = getModelSafely('Page') || require('../models/page')(this.crowi);
  26. await Page.updateCommentCount(savedComment.page);
  27. const page = await Page.findById(savedComment.page);
  28. if (page == null) {
  29. logger.error('Page is not found');
  30. return;
  31. }
  32. const activity = await this.createActivity(savedComment, SUPPORTED_ACTION_TYPE.ACTION_COMMENT_CREATE);
  33. await this.createAndSendNotifications(activity, page);
  34. }
  35. catch (err) {
  36. logger.error('Error occurred while handling the comment create event:\n', err);
  37. }
  38. });
  39. // update
  40. this.commentEvent.on('update', async(updatedComment) => {
  41. try {
  42. this.commentEvent.onUpdate();
  43. await this.createActivity(updatedComment, SUPPORTED_ACTION_TYPE.ACTION_COMMENT_UPDATE);
  44. }
  45. catch (err) {
  46. logger.error('Error occurred while handling the comment update event:\n', err);
  47. }
  48. });
  49. // remove
  50. this.commentEvent.on('remove', async(comment) => {
  51. this.commentEvent.onRemove();
  52. try {
  53. const Page = getModelSafely('Page') || require('../models/page')(this.crowi);
  54. await Page.updateCommentCount(comment.page);
  55. }
  56. catch (err) {
  57. logger.error('Error occurred while updating the comment count:\n', err);
  58. }
  59. });
  60. }
  61. private createActivity = async function(comment, action) {
  62. const parameters = {
  63. user: comment.creator,
  64. targetModel: SUPPORTED_TARGET_MODEL_TYPE.MODEL_PAGE,
  65. target: comment.page,
  66. eventModel: SUPPORTED_EVENT_MODEL_TYPE.MODEL_COMMENT,
  67. event: comment._id,
  68. action,
  69. };
  70. const activity = await this.activityService.createByParameters(parameters);
  71. return activity;
  72. };
  73. private createAndSendNotifications = async function(activity, page) {
  74. const snapshot = stringifySnapshot(page);
  75. // Get user to be notified
  76. let targetUsers: Types.ObjectId[] = [];
  77. targetUsers = await activity.getNotificationTargetUsers();
  78. // Create and send notifications
  79. await this.inAppNotificationService.upsertByActivity(targetUsers, activity, snapshot);
  80. await this.inAppNotificationService.emitSocketIo(targetUsers);
  81. };
  82. }
  83. module.exports = CommentService;