slack.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. const debug = require('debug')('growi:util:slack');
  2. const urljoin = require('url-join');
  3. /**
  4. * slack
  5. */
  6. /* eslint-disable no-use-before-define */
  7. const convertMarkdownToMarkdown = function(body, siteUrl) {
  8. return body
  9. .replace(/\n\*\s(.+)/g, '\n• $1')
  10. .replace(/#{1,}\s?(.+)/g, '\n*$1*')
  11. .replace(/(\[(.+)\]\((https?:\/\/.+)\))/g, '<$3|$2>')
  12. .replace(/(\[(.+)\]\((\/.+)\))/g, `<${siteUrl}$3|$2>`);
  13. };
  14. const prepareAttachmentTextForCreate = function(page, siteUrl) {
  15. let body = page.revision.body;
  16. if (body.length > 2000) {
  17. body = `${body.substr(0, 2000)}...`;
  18. }
  19. return convertMarkdownToMarkdown(body, siteUrl);
  20. };
  21. const prepareAttachmentTextForUpdate = function(page, siteUrl, previousRevision) {
  22. const diff = require('diff');
  23. let diffText = '';
  24. diff.diffLines(previousRevision.body, page.revision.body).forEach((line) => {
  25. debug('diff line', line);
  26. const value = line.value.replace(/\r\n|\r/g, '\n'); // eslint-disable-line no-unused-vars
  27. if (line.added) {
  28. diffText += `${line.value} ... :lower_left_fountain_pen:`;
  29. }
  30. else if (line.removed) {
  31. // diffText += '-' + line.value.replace(/(.+)?\n/g, '- $1\n');
  32. // 1以下は無視
  33. if (line.count > 1) {
  34. diffText += `:wastebasket: ... ${line.count} lines\n`;
  35. }
  36. }
  37. else {
  38. // diffText += '...\n';
  39. }
  40. });
  41. debug('diff is', diffText);
  42. return diffText;
  43. };
  44. const prepareAttachmentTextForComment = function(comment) {
  45. let body = comment.comment;
  46. if (body.length > 2000) {
  47. body = `${body.substr(0, 2000)}...`;
  48. }
  49. if (comment.isMarkdown) {
  50. return convertMarkdownToMarkdown(body);
  51. }
  52. return body;
  53. };
  54. const generateSlackMessageTextForPage = function(path, pageId, user, siteUrl, updateType) {
  55. let text;
  56. const pageUrl = `<${urljoin(siteUrl, pageId)}|${path}>`;
  57. if (updateType === 'create') {
  58. text = `:rocket: ${user.username} created a new page! ${pageUrl}`;
  59. }
  60. else {
  61. text = `:heavy_check_mark: ${user.username} updated ${pageUrl}`;
  62. }
  63. return text;
  64. };
  65. export const prepareSlackMessageForPage = (page, user, appTitle, siteUrl, channel, updateType, previousRevision) => {
  66. let body = page.revision.body;
  67. if (updateType === 'create') {
  68. body = prepareAttachmentTextForCreate(page, siteUrl);
  69. }
  70. else {
  71. body = prepareAttachmentTextForUpdate(page, siteUrl, previousRevision);
  72. }
  73. const attachment = {
  74. color: '#263a3c',
  75. author_name: `@${user.username}`,
  76. author_link: urljoin(siteUrl, 'user', user.username),
  77. author_icon: user.image,
  78. title: page.path,
  79. title_link: urljoin(siteUrl, page.id),
  80. text: body,
  81. mrkdwn_in: ['text'],
  82. };
  83. if (user.image) {
  84. attachment.author_icon = user.image;
  85. }
  86. const message = {
  87. channel: (channel != null) ? `#${channel}` : undefined,
  88. username: appTitle,
  89. text: generateSlackMessageTextForPage(page.path, page.id, user, siteUrl, updateType),
  90. attachments: [attachment],
  91. };
  92. return message;
  93. };
  94. export const prepareSlackMessageForComment = (comment, user, appTitle, siteUrl, channel, path) => {
  95. const body = prepareAttachmentTextForComment(comment);
  96. const attachment = {
  97. color: '#263a3c',
  98. author_name: `@${user.username}`,
  99. author_link: urljoin(siteUrl, 'user', user.username),
  100. author_icon: user.image,
  101. text: body,
  102. mrkdwn_in: ['text'],
  103. };
  104. if (user.image) {
  105. attachment.author_icon = user.image;
  106. }
  107. const pageUrl = `<${urljoin(siteUrl, String(comment.page))}|${path}>`;
  108. const text = `:speech_balloon: ${user.username} commented on ${pageUrl}`;
  109. const message = {
  110. channel: (channel != null) ? `#${channel}` : undefined,
  111. username: appTitle,
  112. text,
  113. attachments: [attachment],
  114. };
  115. return message;
  116. };
  117. /**
  118. * For GlobalNotification
  119. *
  120. * @param {string} messageBody
  121. * @param {string} attachmentBody
  122. * @param {string} slackChannel
  123. */
  124. export const prepareSlackMessageForGlobalNotification = (messageBody, attachmentBody, appTitle, slackChannel) => {
  125. const attachment = {
  126. color: '#263a3c',
  127. text: attachmentBody,
  128. mrkdwn_in: ['text'],
  129. };
  130. const message = {
  131. channel: (slackChannel != null) ? `#${slackChannel}` : undefined,
  132. username: appTitle,
  133. text: messageBody,
  134. attachments: JSON.stringify([attachment]),
  135. };
  136. return message;
  137. };