Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions slack-jira-bridge/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ── Slack ──────────────────────────────────────────────
SLACK_BOT_TOKEN=xoxb-your-bot-token
SLACK_SIGNING_SECRET=your-signing-secret
SLACK_APP_TOKEN=xapp-your-app-level-token

# ── Jira ──────────────────────────────────────────────
JIRA_HOST=https://your-org.atlassian.net
JIRA_EMAIL=you@example.com
JIRA_API_TOKEN=your-jira-api-token
JIRA_PROJECT_KEY=PROJ
JIRA_ISSUE_TYPE=Task

# ── Filters (optional) ───────────────────────────────
# Comma-separated Slack channel IDs to watch (empty = all channels)
# SLACK_CHANNEL_ALLOWLIST=C01ABC,C02DEF
# IGNORE_BOTS=true
# IGNORE_THREAD_REPLIES=true
# MIN_MESSAGE_LENGTH=1

# ── App ───────────────────────────────────────────────
# PORT=3000
# LOG_LEVEL=info
3 changes: 3 additions & 0 deletions slack-jira-bridge/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.env
*.log
12 changes: 12 additions & 0 deletions slack-jira-bridge/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:20-slim AS base
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --omit=dev

COPY src/ src/

USER node
EXPOSE 3000

CMD ["node", "src/index.js"]
108 changes: 108 additions & 0 deletions slack-jira-bridge/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Slack → Jira Bridge

Automatically creates a Jira ticket every time a new Slack message is posted. The bridge runs in **Socket Mode**, so no public URL or ingress is required.

## How It Works

1. The app connects to Slack via Socket Mode and listens for `message` events.
2. When a new message arrives, it passes through configurable filters (bot messages, thread replies, channel allowlist, minimum length).
3. A Jira ticket is created with the message text as the description and a link back to the original Slack message.
4. The app reacts to the Slack message with a 🎫 emoji and posts a threaded reply with the Jira ticket link.

## Prerequisites

| Service | What you need |
|---------|--------------|
| **Slack** | A Slack app with **Socket Mode** enabled, a **Bot Token** (`xoxb-…`), a **Signing Secret**, and an **App-Level Token** (`xapp-…`) with the `connections:write` scope. The bot needs the `message.channels`, `message.groups`, `message.im`, and `message.mpim` event subscriptions plus `reactions:write` and `chat:write` OAuth scopes. |
| **Jira** | A Jira Cloud instance, an **API token** (generated at https://id.atlassian.net/manage-profile/security/api-tokens), and the **project key** where tickets should be created. |
| **Node.js** | v20 or later |

## Quick Start

```bash
# 1. Clone and install
cd slack-jira-bridge
npm install

# 2. Configure
cp .env.example .env
# Edit .env with your Slack and Jira credentials

# 3. Run
npm start
```

## Configuration

All configuration is via environment variables (or a `.env` file).

### Required

| Variable | Description |
|----------|-------------|
| `SLACK_BOT_TOKEN` | Slack bot OAuth token (`xoxb-…`) |
| `SLACK_SIGNING_SECRET` | Slack app signing secret |
| `SLACK_APP_TOKEN` | Slack app-level token (`xapp-…`) for Socket Mode |
| `JIRA_HOST` | Jira Cloud URL, e.g. `https://your-org.atlassian.net` |
| `JIRA_EMAIL` | Email associated with the Jira API token |
| `JIRA_API_TOKEN` | Jira API token |
| `JIRA_PROJECT_KEY` | Jira project key, e.g. `PROJ` |

### Optional

| Variable | Default | Description |
|----------|---------|-------------|
| `JIRA_ISSUE_TYPE` | `Task` | Jira issue type for created tickets |
| `SLACK_CHANNEL_ALLOWLIST` | *(empty — all channels)* | Comma-separated Slack channel IDs to watch |
| `IGNORE_BOTS` | `true` | Skip messages from bots |
| `IGNORE_THREAD_REPLIES` | `true` | Only create tickets for top-level messages |
| `MIN_MESSAGE_LENGTH` | `1` | Minimum character length to create a ticket |
| `PORT` | `3000` | HTTP port (used internally by Bolt) |
| `LOG_LEVEL` | `info` | Logging level (`debug`, `info`, `warn`, `error`) |

## Docker

```bash
docker build -t slack-jira-bridge .
docker run --env-file .env slack-jira-bridge
```

## Testing

```bash
npm test
```

## Project Structure

```
slack-jira-bridge/
├── src/
│ ├── index.js # Entry point — starts the Slack Bolt app
│ ├── config.js # Environment variable parsing and validation
│ ├── logger.js # Winston logger setup
│ ├── jira-client.js # Jira API wrapper (ticket creation)
│ ├── message-handler.js # Message filtering and orchestration
│ └── message-handler.test.js # Unit tests
├── .env.example # Template for environment variables
├── Dockerfile # Container image
└── package.json
```

## Slack App Setup

1. Go to https://api.slack.com/apps and create a new app.
2. Under **Socket Mode**, enable it and generate an app-level token with `connections:write`.
3. Under **OAuth & Permissions**, add these bot scopes:
- `channels:history`
- `groups:history`
- `im:history`
- `mpim:history`
- `chat:write`
- `reactions:write`
4. Under **Event Subscriptions**, subscribe to these bot events:
- `message.channels`
- `message.groups`
- `message.im`
- `message.mpim`
5. Install the app to your workspace and invite the bot to the channels you want to monitor.
Loading