| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /**
- * slack
- */
- module.exports = function(crowi) {
- 'use strict';
- const debug = require('debug')('growi:util:slack'),
- config = crowi.getConfig(),
- Config = crowi.model('Config'),
- Slack = require('slack-node'),
- slack = {};
- const postWithIwh = function(messageObj) {
- return new Promise((resolve, reject) => {
- const client = new Slack();
- client.setWebhook(config.notification['slack:incomingWebhookUrl']);
- client.webhook(messageObj, function(err, res) {
- if (err) {
- debug('Post error', err, res);
- debug('Sent data to slack is:', messageObj);
- return reject(err);
- }
- resolve(res);
- });
- });
- };
- const postWithWebApi = function(messageObj) {
- return new Promise((resolve, reject) => {
- const client = new Slack(config.notification['slack:token']);
- // stringify attachments
- if (messageObj.attachments != null) {
- messageObj.attachments = JSON.stringify(messageObj.attachments);
- }
- client.api('chat.postMessage', messageObj, function(err, res) {
- if (err) {
- debug('Post error', err, res);
- debug('Sent data to slack is:', messageObj);
- return reject(err);
- }
- resolve(res);
- });
- });
- };
- const convertMarkdownToMrkdwn = function(body) {
- var url = '';
- if (config.crowi && config.crowi['app:url']) {
- url = config.crowi['app:url'];
- }
- body = body
- .replace(/\n\*\s(.+)/g, '\n• $1')
- .replace(/#{1,}\s?(.+)/g, '\n*$1*')
- .replace(/(\[(.+)\]\((https?:\/\/.+)\))/g, '<$3|$2>')
- .replace(/(\[(.+)\]\((\/.+)\))/g, '<' + url + '$3|$2>')
- ;
- return body;
- };
- const prepareAttachmentTextForCreate = function(page, user) {
- var body = page.revision.body;
- if (body.length > 2000) {
- body = body.substr(0, 2000) + '...';
- }
- return convertMarkdownToMrkdwn(body);
- };
- const prepareAttachmentTextForUpdate = function(page, user, previousRevision) {
- var diff = require('diff');
- var diffText = '';
- diff.diffLines(previousRevision.body, page.revision.body).forEach(function(line) {
- debug('diff line', line);
- /* eslint-disable no-unused-vars */
- var value = line.value.replace(/\r\n|\r/g, '\n');
- /* eslint-enable */
- if (line.added) {
- diffText += `:pencil2: ...\n${line.value}`;
- }
- else if (line.removed) {
- // diffText += '-' + line.value.replace(/(.+)?\n/g, '- $1\n');
- // 1以下は無視
- if (line.count > 1) {
- diffText += `:wastebasket: ... ${line.count} lines\n`;
- }
- }
- else {
- //diffText += '...\n';
- }
- });
- debug('diff is', diffText);
- return diffText;
- };
- 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);
- }
- else {
- body = prepareAttachmentTextForUpdate(page, user, previousRevision);
- }
- const attachment = {
- color: '#263a3c',
- author_name: '@' + user.username,
- author_link: url + '/user/' + user.username,
- author_icon: user.image,
- title: page.path,
- title_link: url + '/' + page._id,
- text: body,
- mrkdwn_in: ['text'],
- };
- if (user.image) {
- attachment.author_icon = user.image;
- }
- const message = {
- channel: '#' + channel,
- username: Config.appTitle(config),
- text: getSlackMessageTextForPage(page.path, user, updateType),
- attachments: [attachment],
- };
- return message;
- };
- 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'] || '';
- const pageUrl = `<${url}${path}|${path}>`;
- if (updateType == 'create') {
- text = `:white_check_mark: ${user.username} created a new page! ${pageUrl}`;
- }
- else {
- text = `:up: ${user.username} updated ${pageUrl}`;
- }
- 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.postPage = (page, user, channel, updateType, previousRevision) => {
- const messageObj = prepareSlackMessageForPage(page, user, channel, updateType, previousRevision);
- return slackPost(messageObj);
- };
- slack.postComment = (comment, user, channel, path) => {
- const messageObj = prepareSlackMessageForComment(comment, user, channel, path);
- return slackPost(messageObj);
- };
- const slackPost = (messageObj) => {
- // when incoming Webhooks is prioritized
- if (Config.isIncomingWebhookPrioritized(config)) {
- if (Config.hasSlackIwhUrl(config)) {
- debug('posting message with IncomingWebhook');
- return postWithIwh(messageObj);
- }
- else if (Config.hasSlackToken(config)) {
- debug('posting message with Web API');
- return postWithWebApi(messageObj);
- }
- }
- // else
- else {
- if (Config.hasSlackToken(config)) {
- debug('posting message with Web API');
- return postWithWebApi(messageObj);
- }
- else if (Config.hasSlackIwhUrl(config)) {
- debug('posting message with IncomingWebhook');
- return postWithIwh(messageObj);
- }
- }
- };
- return slack;
- };
|