Last active
July 18, 2025 08:04
-
-
Save nimboya/41a774758e4f063d7bd243529cbc38e8 to your computer and use it in GitHub Desktop.
SlackBot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require('dotenv').config(); | |
| const express = require('express'); | |
| const axios = require('axios'); | |
| const bodyParser = require('body-parser'); | |
| const app = express(); | |
| const port = process.env.PORT || 3000; | |
| app.use(bodyParser.json()); | |
| app.post('/slack/events', async (req, res) => { | |
| console.log('π Event Received:', JSON.stringify(req.body, null, 2)); | |
| // Handle Slack URL verification | |
| if (req.body.type === 'url_verification') { | |
| return res.status(200).json({ challenge: req.body.challenge }); | |
| } | |
| if (req.body.event && req.body.event.type === 'app_mention') { | |
| const text = req.body.event.text.toLowerCase(); | |
| const user = req.body.event.user; | |
| const channel = req.body.event.channel; | |
| if (text.includes('create a jira ticket')) { | |
| const match = text.match(/title:(.+)/i); | |
| const title = match ? match[1].trim() : null; | |
| if (!title) { | |
| await sendMessage(channel, `β οΈ Please provide a title. Try: "create a jira ticket with the title: Bug in production"`); | |
| return res.status(200).end(); | |
| } | |
| try { | |
| // 1. Create Jira Ticket | |
| const jiraResponse = await axios.post( | |
| `${process.env.JIRA_BASE_URL}/rest/api/3/issue`, | |
| { | |
| fields: { | |
| project: { key: process.env.JIRA_PROJECT_KEY }, | |
| summary: title, | |
| issuetype: { name: "Bug" }, | |
| description: "Creating associated Slack channel..." | |
| }, | |
| }, | |
| { | |
| auth: { | |
| username: process.env.JIRA_EMAIL, | |
| password: process.env.JIRA_API_TOKEN, | |
| }, | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| } | |
| ); | |
| const issueKey = jiraResponse.data.key; | |
| // 2. Create Slack channel | |
| const sanitized = title.toLowerCase().replace(/[^a-z0-9\-]/gi, '-').replace(/--+/g, '-').substring(0, 21); | |
| const channelName = `inc-${sanitized}`; | |
| const slackResponse = await axios.post('https://slack.com/api/conversations.create', { | |
| name: channelName, | |
| is_private: false, | |
| }, { | |
| headers: { | |
| Authorization: `Bearer ${process.env.SLACK_BOT_TOKEN}`, | |
| 'Content-Type': 'application/json', | |
| } | |
| }); | |
| if (!slackResponse.data.ok) { | |
| throw new Error(`Slack error: ${slackResponse.data.error}`); | |
| } | |
| const newChannelId = slackResponse.data.channel.id; | |
| const slackChannelLink = `<https://slack.com/app_redirect?channel=${newChannelId}|#${channelName}>`; | |
| // 3. Post in the new Slack channel | |
| await sendMessage(newChannelId, `π§ Channel created for Jira ticket: *${issueKey}* - ${title}`); | |
| // 4. Update Jira ticket with Slack link | |
| await axios.put( | |
| `${process.env.JIRA_BASE_URL}/rest/api/3/issue/${issueKey}`, | |
| { | |
| fields: { | |
| description: { | |
| type: "doc", | |
| version: 1, | |
| content: [ | |
| { | |
| type: "paragraph", | |
| content: [ | |
| { | |
| type: "text", | |
| text: `Slack discussion: ${slackChannelLink}`, | |
| }, | |
| ], | |
| }, | |
| ], | |
| }, | |
| }, | |
| }, | |
| { | |
| auth: { | |
| username: process.env.JIRA_EMAIL, | |
| password: process.env.JIRA_API_TOKEN, | |
| }, | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| } | |
| } | |
| ); | |
| // 5. Confirm back in original Slack channel | |
| await sendMessage(channel, `β Created Jira ticket *${issueKey}* and Slack channel: ${slackChannelLink}`); | |
| } catch (err) { | |
| console.error('β Error:', err.response?.data || err.message); | |
| await sendMessage(channel, `β Failed to create Jira ticket or Slack channel: ${err.response?.data?.errors || err.message}`); | |
| } | |
| return res.status(200).end(); | |
| } | |
| await sendMessage(channel, `π Hi <@${user}>! Try: "create a jira ticket with the title: Something broke"`); | |
| return res.status(200).end(); | |
| } | |
| res.status(200).end(); | |
| }); | |
| // Helper: Send message to a Slack channel | |
| async function sendMessage(channel, text) { | |
| try { | |
| await axios.post('https://slack.com/api/chat.postMessage', { | |
| channel, | |
| text, | |
| }, { | |
| headers: { | |
| Authorization: `Bearer ${process.env.SLACK_BOT_TOKEN}`, | |
| 'Content-Type': 'application/json', | |
| } | |
| }); | |
| } catch (err) { | |
| console.error('β Failed to send message:', err.response?.data || err.message); | |
| } | |
| } | |
| app.listen(port, () => { | |
| console.log(`π Server running on http://localhost:${port}`); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment