this repo has no description
1# IRC <> Slack bridge
2
3This is a little bot in active development to bridge slack and irc for Hackclub!
4
5## How do I hack on it?
6
7### Development
8
9This is written in typescript so pretty easy to get started!
10
11```bash
12bun install
13bun dev
14```
15
16To run tests:
17```bash
18bun test
19```
20
21### Slack App Setup
22
231. Go to [api.slack.com/apps](https://api.slack.com/apps) and create a new app
242. Choose "From an app manifest"
253. Copy the contents of `slack-manifest.yaml` and paste it
264. Install the app to your workspace
275. Copy the "Bot User OAuth Token" (starts with `xoxb-`) and "Signing Secret"
286. Invite the bot to your desired Slack channel: `/invite @IRC Bridge`
29
30### Environment Setup
31
32Make a `.env` file with the following:
33
34```bash
35# Slack Configuration
36SLACK_BOT_TOKEN=xoxb-your-bot-token-here
37SLACK_SIGNING_SECRET=your-signing-secret-here
38
39# Slack workspace URL (for admin API calls)
40SLACK_API_URL=https://hackclub.enterprise.slack.com
41
42# Optional: For channel manager permission checks
43SLACK_USER_COOKIE=your-slack-cookie-here
44SLACK_USER_TOKEN=your-user-token-here
45
46# Optional: Enable Cachet API for user lookups (recommended for better performance)
47CACHET_ENABLED=true
48
49# IRC Configuration
50IRC_NICK=slackbridge
51NICKSERV_PASSWORD=your-nickserv-password-here
52NICKSERV_EMAIL=your-email@example.com
53
54# Admin users (comma-separated Slack user IDs)
55ADMINS=U1234567890,U0987654321
56
57# Hack Club CDN Token (for file uploads)
58CDN_TOKEN=your-cdn-token-here
59
60# Server Configuration (optional)
61PORT=3000
62
63# Note: Channel and user mappings are now stored in the SQLite database (bridge.db)
64# Use the API or database tools to manage mappings
65```
66
67See `.env.example` for a template.
68
69### Slash Commands
70
71The bridge provides interactive slash commands for managing mappings:
72
73- `/irc-bridge-channel` - Bridge current Slack channel to an IRC channel
74- `/irc-unbridge-channel` - Remove bridge from current channel
75- `/irc-bridge-user` - Link your Slack account to an IRC nickname
76- `/irc-unbridge-user` - Remove your IRC nickname link
77- `/irc-bridge-list` - List all channel and user bridges
78
79### Managing Channel and User Mappings
80
81Channel and user mappings are stored in a SQLite database (`bridge.db`). You can manage them through:
82
83**Using Bun REPL:**
84```bash
85bun repl
86> import { channelMappings, userMappings } from "./src/lib/db"
87> channelMappings.create("C1234567890", "#general")
88> userMappings.create("U1234567890", "myircnick")
89> channelMappings.getAll()
90```
91
92**Using SQLite directly:**
93```bash
94bun:sqlite bridge.db
95sqlite> SELECT * FROM channel_mappings;
96sqlite> INSERT INTO channel_mappings (slack_channel_id, irc_channel) VALUES ('C1234567890', '#general');
97```
98
99### How it works
100
101The bridge connects to `irc.hackclub.com:6667` (no TLS) and forwards messages bidirectionally based on channel mappings:
102
103- **NickServ Authentication**: If `NICKSERV_PASSWORD` is configured, the bridge authenticates on connect
104 - Waits for NickServ confirmation before joining channels
105 - Auto-registers the nick if not registered (requires `NICKSERV_EMAIL`)
106 - Prevents "No external channel messages" errors by ensuring proper authentication
107- **IRC → Slack**: Messages from mapped IRC channels appear in their corresponding Slack channels
108 - Image URLs are automatically displayed as inline attachments
109 - IRC mentions (`@nick` or `nick:`) are converted to Slack mentions for mapped users
110 - IRC formatting codes are converted to Slack markdown
111 - IRC `/me` actions are displayed in a context block with the user's avatar
112 - Thread replies: Use `@xxxxx` (5-char thread ID) to reply to a Slack thread from IRC
113- **Slack → IRC**: Messages from mapped Slack channels are sent to their corresponding IRC channels
114 - User display names: Uses name from Slack event if available, otherwise Cachet API (if `CACHET_ENABLED=true`), then Slack API fallback
115 - All lookups are cached locally (1 hour TTL) to reduce API calls
116 - Slack mentions are converted to mapped IRC nicks, or looked up via the above priority
117 - Slack markdown is converted to IRC formatting codes
118 - File attachments are uploaded to Hack Club CDN and URLs are shared
119 - Thread messages are prefixed with `@xxxxx` (5-char thread ID) to show they're part of a thread
120 - First reply in a thread includes a quote of the parent message
121- **User mappings** allow custom IRC nicknames for specific Slack users and enable proper mentions both ways
122- **Permissions**: Only channel creators, channel managers, or global admins can bridge/unbridge channels
123
124#### Thread Support
125
126The bridge supports Slack threads with a simple IRC-friendly syntax:
127
128- **Slack → IRC**: Thread messages appear with a `@xxxxx` prefix (5-character thread ID)
129 - First reply in a thread includes a quote: `<user> @xxxxx > original message`
130 - Subsequent replies: `<user> @xxxxx message text`
131- **IRC → Slack**: Reply to a thread by including the thread ID in your message
132 - Example: `@abc12 this is my reply`
133 - The bridge removes the `@xxxxx` prefix and sends your message to the correct thread
134 - Thread IDs are unique per thread and persist across restarts (stored in SQLite)
135
136The bridge ignores its own messages and bot messages to prevent loops.
137
138### Architecture
139
140The bridge consists of several modules:
141
142- **`src/index.ts`** - Main application entry point with IRC/Slack event handlers
143- **`src/commands.ts`** - Slash command handlers for managing bridges
144- **`src/lib/db.ts`** - SQLite database layer for channel/user/thread mappings
145- **`src/lib/parser.ts`** - Bidirectional message formatting conversion (IRC ↔ Slack)
146- **`src/lib/mentions.ts`** - User mention conversion with Cachet integration
147- **`src/lib/threads.ts`** - Thread tracking and ID generation
148- **`src/lib/user-cache.ts`** - Cached Slack user info lookups (1-hour TTL)
149- **`src/lib/permissions.ts`** - Channel management permission checks
150- **`src/lib/avatars.ts`** - Stable avatar URL generation for IRC users
151- **`src/lib/cdn.ts`** - File upload integration with Hack Club CDN
152- **`src/lib/cachet.ts`** - User profile lookups from Cachet API
153
154### Testing
155
156The project includes comprehensive unit tests covering all core functionality:
157
158```bash
159bun test
160```
161
162Tests cover:
163- Message format parsing (IRC ↔ Slack)
164- User mention conversion
165- Thread ID generation and tracking
166- User info caching
167- Database operations
168- Avatar generation
169
170If you want to report an issue the main repo is [the tangled repo](https://tangled.org/dunkirk.sh/irc-slack-bridge) and the github is just a mirror.
171
172<p align="center">
173 <img src="https://raw.githubusercontent.com/taciturnaxolotl/carriage/master/.github/images/line-break.svg" />
174</p>
175
176<p align="center">
177 © 2025-present <a href="https://github.com/taciturnaxolotl">Kieran Klukas</a>
178</p>
179
180<p align="center">
181 <a href="https://github.com/taciturnaxolotl/irc-slack-bridge/blob/main/LICENSE.md"><img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=MIT&logoColor=d9e0ee&colorA=363a4f&colorB=b7bdf8"/></a>
182</p>