slack.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * slack
  3. */
  4. module.exports = function(crowi) {
  5. 'use strict';
  6. var debug = require('debug')('crowi:util:slack'),
  7. Config = crowi.model('Config'),
  8. Botkit = require('botkit'),
  9. bot = null,
  10. slack = {};
  11. slack.controller = undefined;
  12. slack.createBot = function() {
  13. // alreay created
  14. if (bot) {
  15. return bot;
  16. }
  17. var config = crowi.getConfig();
  18. if (!slack.controller) {
  19. slack.configureSlackApp();
  20. }
  21. if (!slack.controller) {
  22. return false;
  23. }
  24. if (Config.hasSlackToken(config)) {
  25. bot = slack.controller.spawn({token: config.notification['slack:token']});
  26. } else {
  27. bot = slack.controller.spawn();
  28. }
  29. return bot;
  30. };
  31. slack.configureSlackApp = function ()
  32. {
  33. var config = crowi.getConfig();
  34. if (Config.hasSlackConfig(config)) {
  35. slack.controller = Botkit.slackbot();
  36. slack.controller.configureSlackApp({
  37. clientId: config.notification['slack:clientId'],
  38. clientSecret: config.notification['slack:clientSecret'],
  39. redirectUri: slack.getSlackAuthCallbackUrl(),
  40. scopes: ['chat:write:bot']
  41. });
  42. return true;
  43. }
  44. return false;
  45. }
  46. // hmmm
  47. slack.getSlackAuthCallbackUrl = function()
  48. {
  49. var config = crowi.getConfig();
  50. // Web アクセスがきてないと app:url がセットされないので crowi.setupSlack 時にはできない
  51. // cli, bot 系作るときに問題なりそう
  52. return (config.crowi['app:url'] || '') + '/admin/notification/slackAuth';
  53. }
  54. slack.getAuthorizeURL = function () {
  55. if (!slack.controller) {
  56. slack.configureSlackApp();
  57. }
  58. if (!slack.controller) {
  59. return '';
  60. }
  61. return slack.controller.getAuthorizeURL();
  62. }
  63. slack.post = function (message) {
  64. var bot = slack.createBot();
  65. return new Promise(function(resolve, reject) {
  66. bot.api.chat.postMessage(message, function(err, res) {
  67. if (err) {
  68. debug('Post error', err, res);
  69. debug('Sent data to slack is:', message);
  70. return reject(err);
  71. }
  72. resolve(res);
  73. });
  74. });
  75. };
  76. slack.convertMarkdownToMrkdwn = function(body) {
  77. var config = crowi.getConfig();
  78. var url = '';
  79. if (config.crowi && config.crowi['app:url']) {
  80. url = config.crowi['app:url'];
  81. }
  82. body = body
  83. .replace(/\n\*\s(.+)/g, '\n• $1')
  84. .replace(/#{1,}\s?(.+)/g, '\n*$1*')
  85. .replace(/(\[(.+)\]\((https?:\/\/.+)\))/g, '<$3|$2>')
  86. .replace(/(\[(.+)\]\((\/.+)\))/g, '<' + url + '$3|$2>')
  87. ;
  88. return body;
  89. };
  90. slack.prepareAttachmentTextForCreate = function(page, user) {
  91. var body = page.revision.body;
  92. if (body.length > 2000) {
  93. body = body.substr(0, 2000) + '...';
  94. }
  95. return this.convertMarkdownToMrkdwn(body);
  96. };
  97. slack.prepareAttachmentTextForUpdate = function(page, user, previousRevision) {
  98. var diff = require('diff');
  99. var diffText = ''
  100. diff.diffLines(previousRevision.body, page.revision.body).forEach(function(line) {
  101. debug('diff line', line)
  102. var value = line.value.replace(/\r\n|\r/g, '\n');
  103. if (line.added) {
  104. diffText += `:pencil2: ...\n${line.value}`;
  105. } else if (line.removed) {
  106. // diffText += '-' + line.value.replace(/(.+)?\n/g, '- $1\n');
  107. // 1以下は無視
  108. if (line.count > 1) {
  109. diffText += `:wastebasket: ... ${line.count} lines\n`;
  110. }
  111. } else {
  112. //diffText += '...\n';
  113. }
  114. });
  115. debug('diff is', diffText)
  116. return diffText;
  117. };
  118. slack.prepareSlackMessage = function(page, user, channel, updateType, previousRevision) {
  119. var config = crowi.getConfig();
  120. var url = config.crowi['app:url'] || '';
  121. var body = page.revision.body;
  122. if (updateType == 'create') {
  123. body = this.prepareAttachmentTextForCreate(page, user);
  124. } else {
  125. body = this.prepareAttachmentTextForUpdate(page, user, previousRevision);
  126. }
  127. var attachment = {
  128. color: '#263a3c',
  129. author_name: '@' + user.username,
  130. author_link: url + '/user/' + user.username,
  131. author_icon: user.image,
  132. title: page.path,
  133. title_link: url + '/' + page._id,
  134. text: body,
  135. mrkdwn_in: ["text"],
  136. };
  137. if (user.image) {
  138. attachment.author_icon = user.image;
  139. }
  140. var message = {
  141. channel: '#' + channel,
  142. username: 'Crowi',
  143. text: this.getSlackMessageText(page.path, user, updateType),
  144. attachments: [attachment],
  145. };
  146. return message;
  147. };
  148. slack.getSlackMessageText = function(path, user, updateType) {
  149. var text;
  150. if (updateType == 'create') {
  151. text = `:white_check_mark: ${user.username} created a new page! ${path}`;
  152. } else {
  153. text = `:up: ${user.username} updated ${path}`;
  154. }
  155. return text;
  156. };
  157. return slack;
  158. };