diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 8fd6c3606..a7304bd24 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -67,8 +67,12 @@ services: # - SLACK_BOT_TOKEN= # - SLACK_CHANNEL_ID= + + # - TELEGRAM_BOT_TOKEN= + # - TELEGRAM_CHAT_ID= + # - TELEGRAM_THREAD_ID= working_dir: /app - command: ["sh", "-c", "npm run start"] + command: ['sh', '-c', 'npm run start'] depends_on: postgres: condition: service_healthy @@ -101,7 +105,7 @@ services: # - DEFAULT_ADMIN_NAME=Demo Demo # - DEFAULT_ADMIN_USERNAME=demo working_dir: /app - command: ["sh", "-c", "npm run db:init"] + command: ['sh', '-c', 'npm run db:init'] volumes: - ./server:/app - /app/node_modules @@ -118,10 +122,10 @@ services: POSTGRES_USER: user POSTGRES_PASSWORD: password ports: - - "5432:5432" + - '5432:5432' restart: unless-stopped healthcheck: - test: ["CMD-SHELL", "pg_isready -U user -d planka_db"] + test: ['CMD-SHELL', 'pg_isready -U user -d planka_db'] interval: 10s timeout: 5s retries: 5 @@ -129,7 +133,7 @@ services: proxy: image: nginx:alpine ports: - - "3000:80" + - '3000:80' volumes: - ./config/development/nginx.conf:/etc/nginx/nginx.conf depends_on: diff --git a/docker-compose.yml b/docker-compose.yml index 939e378ee..cd8dbe030 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -75,6 +75,10 @@ services: # - SLACK_BOT_TOKEN= # - SLACK_CHANNEL_ID= # - GOOGLE_CHAT_WEBHOOK_URL= + + # - TELEGRAM_BOT_TOKEN= + # - TELEGRAM_CHAT_ID= + # - TELEGRAM_THREAD_ID= depends_on: postgres: condition: service_healthy @@ -88,7 +92,7 @@ services: - POSTGRES_DB=planka - POSTGRES_HOST_AUTH_METHOD=trust healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres -d planka"] + test: ['CMD-SHELL', 'pg_isready -U postgres -d planka'] interval: 10s timeout: 5s retries: 5 diff --git a/server/.env.sample b/server/.env.sample index 8393b1db9..53d9cd051 100644 --- a/server/.env.sample +++ b/server/.env.sample @@ -67,6 +67,11 @@ SECRET_KEY=notsecretkey # SLACK_CHANNEL_ID= # GOOGLE_CHAT_WEBHOOK_URL= +# TELEGRAM_BOT_TOKEN= +# TELEGRAM_CHAT_ID= +# TELEGRAM_THREAD_ID= + + ## Do not edit this TZ=UTC diff --git a/server/api/helpers/actions/create-one.js b/server/api/helpers/actions/create-one.js index eb9badf72..7e0344480 100644 --- a/server/api/helpers/actions/create-one.js +++ b/server/api/helpers/actions/create-one.js @@ -38,6 +38,32 @@ const buildAndSendMessage = async (card, action, actorUser, send) => { await send(markdown); }; +const buildAndSendMessageForTelegramBot = async (card, action, actorUser, send) => { + const cardLink = `${card.name}`; + + let html; + switch (action.type) { + case Action.Types.CREATE_CARD: + html = `${cardLink} was created by ${actorUser.name} in ${action.data.list.name}`; + + break; + case Action.Types.MOVE_CARD: + html = `${cardLink} was moved by ${actorUser.name} to ${action.data.toList.name}`; + + break; + case Action.Types.COMMENT_CARD: { + const commentedText = + action.data.text.length > 30 ? `${action.data.text.substring(0, 30)}...` : action.data.text; + html = `${actorUser.name} commented on ${cardLink}: ${commentedText}`; + + break; + } + default: + return; + } + await send(html); +}; + module.exports = { inputs: { values: { @@ -119,6 +145,15 @@ module.exports = { buildAndSendMessage(values.card, action, values.user, sails.helpers.utils.sendSlackMessage); } + if (sails.config.custom.telegramChatId) { + buildAndSendMessageForTelegramBot( + values.card, + action, + values.user, + sails.helpers.utils.sendTelegramMessage, + ); + } + if (sails.config.custom.googleChatWebhookUrl) { buildAndSendMessage( values.card, diff --git a/server/api/helpers/cards/delete-one.js b/server/api/helpers/cards/delete-one.js index a7a35967e..2f69d6166 100644 --- a/server/api/helpers/cards/delete-one.js +++ b/server/api/helpers/cards/delete-one.js @@ -2,6 +2,10 @@ const buildAndSendMessage = async (card, actorUser, send) => { await send(`*${card.name}* was deleted by ${actorUser.name}`); }; +const buildAndSendMessageForTelegramBot = async (card, actorUser, send) => { + await send(`${card.name} was deleted by ${actorUser.name}`); +}; + module.exports = { inputs: { record: { @@ -59,6 +63,14 @@ module.exports = { buildAndSendMessage(card, inputs.actorUser, sails.helpers.utils.sendSlackMessage); } + if (sails.config.custom.telegramChatId) { + buildAndSendMessageForTelegramBot( + card, + inputs.actorUser, + sails.helpers.utils.sendTelegramMessage, + ); + } + if (sails.config.custom.googleChatWebhookUrl) { buildAndSendMessage(card, inputs.actorUser, sails.helpers.utils.sendGoogleChatMessage); } diff --git a/server/api/helpers/utils/send-telegram-message.js b/server/api/helpers/utils/send-telegram-message.js new file mode 100644 index 000000000..11206c534 --- /dev/null +++ b/server/api/helpers/utils/send-telegram-message.js @@ -0,0 +1,43 @@ +const POST_MESSAGE_API_URL = (telegramBotToken) => + `https://api.telegram.org/bot${telegramBotToken}/sendMessage`; + +module.exports = { + inputs: { + html: { + type: 'string', + required: true, + }, + }, + async fn(inputs) { + const headers = { + 'Content-Type': 'application/json; charset=utf-8', + }; + + const body = { + chat_id: sails.config.custom.telegramChatId, + text: inputs.html, + parse_mode: 'HTML', + }; + + if (sails.config.custom.telegramThreadId) { + body.message_thread_id = sails.config.custom.telegramThreadId; + } + + let response; + try { + response = await fetch(POST_MESSAGE_API_URL(sails.config.custom.telegramBotToken), { + headers, + method: 'POST', + body: JSON.stringify(body), + }); + } catch (error) { + sails.log.error(`Error sending to Telegram: ${error}`); + return; + } + + if (!response.ok) { + const responseErrorJson = await response.json(); + sails.log.error(`Error sending to Telegram: ${responseErrorJson.description}`); + } + }, +}; diff --git a/server/config/custom.js b/server/config/custom.js index c10cf5edb..d9ac4e1f2 100644 --- a/server/config/custom.js +++ b/server/config/custom.js @@ -83,4 +83,8 @@ module.exports.custom = { slackBotToken: process.env.SLACK_BOT_TOKEN, slackChannelId: process.env.SLACK_CHANNEL_ID, googleChatWebhookUrl: process.env.GOOGLE_CHAT_WEBHOOK_URL, + + telegramBotToken: process.env.TELEGRAM_BOT_TOKEN, + telegramChatId: process.env.TELEGRAM_CHAT_ID, + telegramThreadId: process.env.TELEGRAM_THREAD_ID, };