Skip to content

Instantly share code, notes, and snippets.

@nimboya
Last active July 18, 2025 08:04
Show Gist options
  • Select an option

  • Save nimboya/41a774758e4f063d7bd243529cbc38e8 to your computer and use it in GitHub Desktop.

Select an option

Save nimboya/41a774758e4f063d7bd243529cbc38e8 to your computer and use it in GitHub Desktop.
SlackBot
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