Просмотр исходного кода

Merge pull request #525 from weseek/feat/post-comment-notification-sou

Feat/post comment notification sou
Yuki Takei 7 лет назад
Родитель
Сommit
f78bc4be75

+ 4 - 1
lib/form/comment.js

@@ -8,5 +8,8 @@ module.exports = form(
   field('commentForm.revision_id').trim().required(),
   field('commentForm.comment').trim().required(),
   field('commentForm.comment_position').trim().toInt(),
-  field('commentForm.is_markdown').trim().toBooleanStrict()
+  field('commentForm.is_markdown').trim().toBooleanStrict(),
+
+  field('slackNotificationForm.isNotification').trim().toBooleanStrict().required(),
+  field('slackNotificationForm.notifSlackChannel').trim(),
 );

+ 22 - 7
lib/routes/comment.js

@@ -3,8 +3,10 @@ module.exports = function(crowi, app) {
 
   const debug = require('debug')('growi:routs:comment')
     , Comment = crowi.model('Comment')
+    , User = crowi.model('User')
     , Page = crowi.model('Page')
     , ApiResponse = require('../util/apiResponse')
+    , slack = require('../util/slack')
     , actions = {}
     , api = {};
 
@@ -50,18 +52,19 @@ module.exports = function(crowi, app) {
    * @apiParam {Number} comment_position=-1 Line number of the comment
    */
   api.add = async function(req, res) {
-    const form = req.form.commentForm;
+    const commentForm = req.form.commentForm;
+    const slackNotificationForm = req.form.slackNotificationForm;
 
     if (!req.form.isValid) {
       // return res.json(ApiResponse.error('Invalid comment.'));
       return res.json(ApiResponse.error('コメントを入力してください。'));
     }
 
-    const pageId = form.page_id;
-    const revisionId = form.revision_id;
-    const comment = form.comment;
-    const position = form.comment_position || -1;
-    const isMarkdown = form.is_markdown;
+    const pageId = commentForm.page_id;
+    const revisionId = commentForm.revision_id;
+    const comment = commentForm.comment;
+    const position = commentForm.comment_position || -1;
+    const isMarkdown = commentForm.is_markdown;
 
     const createdComment = await Comment.create(pageId, req.user._id, revisionId, comment, position, isMarkdown)
       .catch(function(err) {
@@ -69,11 +72,23 @@ module.exports = function(crowi, app) {
       });
 
     // update page
-    await Page.findOneAndUpdate({ _id: pageId }, {
+    const page = await Page.findOneAndUpdate({ _id: pageId }, {
       lastUpdateUser: req.user,
       updatedAt: new Date()
     });
 
+    // slack notification
+    if (slackNotificationForm.isNotification) {
+      const slackNotify = new slack(crowi);
+      const user = await User.findUserByUsername(req.user.username);
+      const path = page.path;
+      const channels = slackNotificationForm.notifSlackChannel;
+
+      channels.split(',').map(function(chan) {
+        slackNotify.postComment(createdComment, user, chan, path);
+      });
+    }
+
     return res.json(ApiResponse.success({comment: createdComment}));
   };
 

+ 1 - 1
lib/routes/page.js

@@ -668,7 +668,7 @@ module.exports = function(crowi, app) {
 
           if (crowi.slack) {
             notify.slack.channel.split(',').map(function(chan) {
-              crowi.slack.post(pageData, req.user, chan, updateOrCreate, previousRevision);
+              crowi.slack.postPage(pageData, req.user, chan, updateOrCreate, previousRevision);
             });
           }
         }

+ 67 - 9
lib/util/slack.js

@@ -80,9 +80,23 @@ module.exports = function(crowi) {
     return diffText;
   };
 
-  const prepareSlackMessage = function(page, user, channel, updateType, previousRevision) {
-    var url = config.crowi['app:url'] || '';
-    var body = page.revision.body;
+  const prepareAttachmentTextForComment = function(comment) {
+    let body = comment.comment;
+    if (body.length > 2000) {
+      body = body.substr(0, 2000) + '...';
+    }
+
+    if (comment.isMarkdown) {
+      return convertMarkdownToMrkdwn(body);
+    }
+    else {
+      return body;
+    }
+  };
+
+  const prepareSlackMessageForPage = function(page, user, channel, updateType, previousRevision) {
+    const url = config.crowi['app:url'] || '';
+    let body = page.revision.body;
 
     if (updateType == 'create') {
       body = prepareAttachmentTextForCreate(page, user);
@@ -91,7 +105,7 @@ module.exports = function(crowi) {
       body = prepareAttachmentTextForUpdate(page, user, previousRevision);
     }
 
-    var attachment = {
+    const attachment = {
       color: '#263a3c',
       author_name: '@' + user.username,
       author_link: url + '/user/' + user.username,
@@ -105,17 +119,43 @@ module.exports = function(crowi) {
       attachment.author_icon = user.image;
     }
 
-    var message = {
+    const message = {
       channel: '#' + channel,
       username: Config.appTitle(config),
-      text: getSlackMessageText(page.path, user, updateType),
+      text: getSlackMessageTextForPage(page.path, user, updateType),
       attachments: [attachment],
     };
 
     return message;
   };
 
-  const getSlackMessageText = function(path, user, updateType) {
+  const prepareSlackMessageForComment = function(comment, user, channel, path) {
+    const url = config.crowi['app:url'] || '';
+    const body = prepareAttachmentTextForComment(comment);
+
+    const attachment = {
+      color: '#263a3c',
+      author_name: '@' + user.username,
+      author_link: url + '/user/' + user.username,
+      author_icon: user.image,
+      text: body,
+      mrkdwn_in: ['text'],
+    };
+    if (user.image) {
+      attachment.author_icon = user.image;
+    }
+
+    const message = {
+      channel: '#' + channel,
+      username: Config.appTitle(config),
+      text: getSlackMessageTextForComment(path, user),
+      attachments: [attachment],
+    };
+
+    return message;
+  };
+
+  const getSlackMessageTextForPage = function(path, user, updateType) {
     let text;
     const url = config.crowi['app:url'] || '';
 
@@ -130,10 +170,28 @@ module.exports = function(crowi) {
     return text;
   };
 
+  const getSlackMessageTextForComment = function(path, user) {
+    const url = config.crowi['app:url'] || '';
+    const pageUrl = `<${url}${path}|${path}>`;
+    const text = `:speech_balloon: ${user.username} commented on ${pageUrl}`;
+
+    return text;
+  };
+
   // slack.post = function (channel, message, opts) {
-  slack.post = (page, user, channel, updateType, previousRevision) => {
-    const messageObj = prepareSlackMessage(page, user, channel, updateType, previousRevision);
+  slack.postPage = (page, user, channel, updateType, previousRevision) => {
+    const messageObj = prepareSlackMessageForPage(page, user, channel, updateType, previousRevision);
+
+    return promisifiedSlackPost(messageObj);
+  };
+
+  slack.postComment = (comment, user, channel, path) => {
+    const messageObj = prepareSlackMessageForComment(comment, user, channel, path);
+
+    return promisifiedSlackPost(messageObj);
+  };
 
+  const promisifiedSlackPost = (messageObj) => {
     return new Promise((resolve, reject) => {
       // define callback function for Promise
       const callback = function(err, res) {

+ 4 - 0
resource/js/components/PageComment/CommentForm.js

@@ -127,6 +127,10 @@ export default class CommentForm extends React.Component {
         page_id: this.props.pageId,
         revision_id: this.props.revisionId,
         is_markdown: this.state.isMarkdown,
+      },
+      slackNotificationForm: {
+        isNotification: this.state.isNotification,
+        notifSlackChannel: this.state.notifSlackChannel,
       }
     })
       .then((res) => {

+ 6 - 2
test/util/slack.test.js

@@ -10,7 +10,11 @@ describe('Slack Util', function () {
   var crowi = new (require(ROOT_DIR + '/lib/crowi'))(ROOT_DIR, process.env);
   var slack = require(crowi.libDir + '/util/slack')(crowi);
 
-  it('post method exists', function() {
-    expect(slack).to.respondTo('post');
+  it('post comment method exists', function() {
+    expect(slack).to.respondTo('postComment');
+  });
+
+  it('post page method exists', function() {
+    expect(slack).to.respondTo('postPage');
   });
 });