global-notification-slack.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import { pagePathUtils } from '@growi/core/dist/utils';
  2. import { GlobalNotificationSettingEvent, GlobalNotificationSettingType } from '~/server/models/GlobalNotificationSetting';
  3. import loggerFactory from '~/utils/logger';
  4. import {
  5. prepareSlackMessageForGlobalNotification,
  6. } from '../../util/slack';
  7. const logger = loggerFactory('growi:service:GlobalNotificationSlackService'); // eslint-disable-line no-unused-vars
  8. const urljoin = require('url-join');
  9. const { encodeSpaces } = pagePathUtils;
  10. /**
  11. * sub service class of GlobalNotificationSetting
  12. */
  13. class GlobalNotificationSlackService {
  14. constructor(crowi) {
  15. this.crowi = crowi;
  16. }
  17. /**
  18. * send slack global notification
  19. *
  20. * @memberof GlobalNotificationSlackService
  21. *
  22. * @param {string} event
  23. * @param {string} id
  24. * @param {string} path
  25. * @param {User} triggeredBy user who triggered the event
  26. * @param {{ comment: Comment, oldPath: string }} _ event specific vars
  27. */
  28. async fire(event, id, path, triggeredBy, vars) {
  29. const { appService, slackIntegrationService } = this.crowi;
  30. const GlobalNotification = this.crowi.model('GlobalNotificationSetting');
  31. const notifications = await GlobalNotification.findSettingByPathAndEvent(event, path, GlobalNotificationSettingType.SLACK);
  32. const messageBody = this.generateMessageBody(event, id, path, triggeredBy, vars);
  33. const attachmentBody = this.generateAttachmentBody(event, id, path, triggeredBy, vars);
  34. const appTitle = appService.getAppTitle();
  35. await Promise.all(notifications.map((notification) => {
  36. const messageObj = prepareSlackMessageForGlobalNotification(messageBody, attachmentBody, appTitle, notification.slackChannels);
  37. return slackIntegrationService.postMessage(messageObj);
  38. }));
  39. }
  40. /**
  41. * generate slack message body
  42. *
  43. * @memberof GlobalNotificationSlackService
  44. *
  45. * @param {string} event event name triggered
  46. * @param {string} id page id
  47. * @param {string} path path triggered the event
  48. * @param {User} triggeredBy user triggered the event
  49. * @param {{ comment: Comment, oldPath: string }} _ event specific vars
  50. *
  51. * @return {string} slack message body
  52. */
  53. generateMessageBody(event, id, path, triggeredBy, { comment, oldPath }) {
  54. const siteUrl = this.crowi.appService.getSiteUrl();
  55. const parmaLink = `<${urljoin(siteUrl, id)}|${path}>`;
  56. const pathLink = `<${urljoin(siteUrl, encodeSpaces(path))}|${path}>`;
  57. const username = `<${urljoin(siteUrl, 'user', triggeredBy.username)}|${triggeredBy.username}>`;
  58. let messageBody;
  59. switch (event) {
  60. case GlobalNotificationSettingEvent.PAGE_CREATE:
  61. messageBody = `:bell: ${username} created ${parmaLink}`;
  62. break;
  63. case GlobalNotificationSettingEvent.PAGE_EDIT:
  64. messageBody = `:bell: ${username} edited ${parmaLink}`;
  65. break;
  66. case GlobalNotificationSettingEvent.PAGE_DELETE:
  67. messageBody = `:bell: ${username} deleted ${pathLink}`;
  68. break;
  69. case GlobalNotificationSettingEvent.PAGE_MOVE:
  70. // validate for page move
  71. if (oldPath == null) {
  72. throw new Error(`invalid vars supplied to GlobalNotificationSlackService.generateOption for event ${event}`);
  73. }
  74. // eslint-disable-next-line no-case-declarations
  75. messageBody = `:bell: ${username} moved ${oldPath} to ${parmaLink}`;
  76. break;
  77. case GlobalNotificationSettingEvent.PAGE_LIKE:
  78. messageBody = `:bell: ${username} liked ${parmaLink}`;
  79. break;
  80. case GlobalNotificationSettingEvent.COMMENT:
  81. // validate for comment
  82. if (comment == null) {
  83. throw new Error(`invalid vars supplied to GlobalNotificationSlackService.generateOption for event ${event}`);
  84. }
  85. messageBody = `:bell: ${username} commented on ${parmaLink}`;
  86. break;
  87. default:
  88. throw new Error(`unknown global notificaiton event: ${event}`);
  89. }
  90. return messageBody;
  91. }
  92. /**
  93. * generate slack attachment body
  94. *
  95. * @memberof GlobalNotificationSlackService
  96. *
  97. * @param {string} event event name triggered
  98. * @param {string} id page id
  99. * @param {string} path path triggered the event
  100. * @param {User} triggeredBy user triggered the event
  101. * @param {{ comment: Comment, oldPath: string }} _ event specific vars
  102. *
  103. * @return {string} slack attachment body
  104. */
  105. generateAttachmentBody(event, id, path, triggeredBy, { comment, oldPath }) {
  106. const attachmentBody = '';
  107. // TODO: create attachment
  108. // attachment body is intended for comment or page diff
  109. // switch (event) {
  110. // case GlobalNotificationSettingEvent.PAGE_CREATE:
  111. // break;
  112. // case GlobalNotificationSettingEvent.PAGE_EDIT:
  113. // break;
  114. // case GlobalNotificationSettingEvent.PAGE_DELETE:
  115. // break;
  116. // case GlobalNotificationSettingEvent.PAGE_MOVE:
  117. // break;
  118. // case GlobalNotificationSettingEvent.PAGE_LIKE:
  119. // break;
  120. // case GlobalNotificationSettingEvent.COMMENT:
  121. // break;
  122. // default:
  123. // throw new Error(`unknown global notificaiton event: ${event}`);
  124. // }
  125. return attachmentBody;
  126. }
  127. }
  128. module.exports = GlobalNotificationSlackService;