diff --git a/package.json b/package.json index 7e06e779..ab2bc3d4 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ } }, "dependencies": { + "axios": "^1.6.2", "concurrently": "^8.2.2", "husky": "^8.0.3", "lint-staged": "^15.1.0" diff --git a/server/api/controllers/cards/create.js b/server/api/controllers/cards/create.js index b847c3e0..23ee0d9e 100755 --- a/server/api/controllers/cards/create.js +++ b/server/api/controllers/cards/create.js @@ -1,4 +1,5 @@ const moment = require('moment'); +const services = require('../../services/slack'); const Errors = { NOT_ENOUGH_RIGHTS: { @@ -109,6 +110,12 @@ module.exports = { }) .intercept('positionMustBeInValues', () => Errors.POSITION_MUST_BE_PRESENT); + const cardUrl = services.buildCardUrl(card); + const messageText = cardUrl + ' was created by ' + currentUser.name + ' in *' + list.name + '*'; + services.sendSlackMessage(messageText) + .then(() => { console.log('Slack message sent successfully.'); }) + .catch((error) => { console.error('Failed to send Slack message:', error.message); }); + return { item: card, }; diff --git a/server/api/controllers/cards/delete.js b/server/api/controllers/cards/delete.js index dad82de1..51d14a4b 100755 --- a/server/api/controllers/cards/delete.js +++ b/server/api/controllers/cards/delete.js @@ -1,3 +1,5 @@ +const services = require('../../services/slack'); + const Errors = { NOT_ENOUGH_RIGHTS: { notEnoughRights: 'Not enough rights', @@ -55,6 +57,11 @@ module.exports = { throw Errors.CARD_NOT_FOUND; } + const messageText = '*' + card.name + '* was deleted by ' + currentUser.name; + services.sendSlackMessage(messageText) + .then(() => { console.log('Slack message sent successfully.'); }) + .catch((error) => { console.error('Failed to send Slack message:', error.message); }); + return { item: card, }; diff --git a/server/api/controllers/cards/update.js b/server/api/controllers/cards/update.js index 8ee37523..2c0a2c29 100755 --- a/server/api/controllers/cards/update.js +++ b/server/api/controllers/cards/update.js @@ -1,4 +1,5 @@ const moment = require('moment'); +const services = require('../../services/slack'); const Errors = { NOT_ENOUGH_RIGHTS: { @@ -175,6 +176,8 @@ module.exports = { 'isSubscribed', ]); + const cardPositionBefore = card.position; + card = await sails.helpers.cards.updateOne .with({ board, @@ -195,6 +198,17 @@ module.exports = { throw Errors.CARD_NOT_FOUND; } + const cardPositionAfter = card.position; + const cardMoved = cardPositionBefore !== cardPositionAfter; + + if (cardMoved) { + const cardUrl = services.buildCardUrl(card); + const messageText = cardUrl + ' was moved by ' + currentUser.name + ' to *' + nextList.name + '*'; + services.sendSlackMessage(messageText) + .then(() => { console.log('Slack message sent successfully.'); }) + .catch((error) => { console.error('Failed to send Slack message:', error.message); }); + } + return { item: card, }; diff --git a/server/api/controllers/comment-actions/create.js b/server/api/controllers/comment-actions/create.js index 7712a3a5..30463fd9 100755 --- a/server/api/controllers/comment-actions/create.js +++ b/server/api/controllers/comment-actions/create.js @@ -1,3 +1,5 @@ +const services = require('../../services/slack'); + const Errors = { NOT_ENOUGH_RIGHTS: { notEnoughRights: 'Not enough rights', @@ -64,6 +66,12 @@ module.exports = { request: this.req, }); + const cardUrl = services.buildCardUrl(card); + const messageText = '*' + currentUser.name + '* commented on ' + cardUrl + ':\n>' + inputs.text; + services.sendSlackMessage(messageText) + .then(() => { console.log('Slack message sent successfully.'); }) + .catch((error) => { console.error('Failed to send Slack message:', error.message); }); + return { item: action, }; diff --git a/server/api/services/slack.js b/server/api/services/slack.js new file mode 100644 index 00000000..c06aa5fe --- /dev/null +++ b/server/api/services/slack.js @@ -0,0 +1,58 @@ +const axios = require('axios'); +const slackPostUrl = 'https://slack.com/api/chat.postMessage'; +const channelId = process.env.SLACK_CHANNEL_ID; +const slackAPIToken = process.env.SLACK_BOT_TOKEN; +const plankaProdUrl = process.env.BASE_URL; + +async function sendSlackMessage(messageText) { + if (!slackAPIToken) { + throw new Error('No Slack BOT token found'); + } + + console.log('Sending to Slack'); + + const postData = { + blocks: [ { + type: 'section', + text: { + type: 'mrkdwn', + text: messageText, + }, + }] + }; + + try { + const config = { + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${slackAPIToken}`, + }, + }; + + axios.post(slackPostUrl, { ...postData, channel: channelId }, config) + .then(response => { + console.log('Slack response:', response.data); + }) + .catch(error => { + console.error('Error sending to Slack:', error.message); + }); + + console.log('Slack response:', response.data); + return response.data; + } catch (error) { + console.error('Error sending to Slack:', error.message); + throw error; + } + } + + function buildCardUrl(card) { + const url = plankaProdUrl + '/cards/' + card.id; + const cardUrl = '<' + url + '|' + card.name + '>'; + console.log(cardUrl); + return cardUrl; + } + + module.exports = { + sendSlackMessage, + buildCardUrl + };