comment.ts 3.3 KB

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