# IRC <> Slack bridge This is a little bot in active development to bridge slack and irc for Hackclub! ## How do I hack on it? ### Development This is written in typescript so pretty easy to get started! ```bash bun install bun dev ``` To run tests: ```bash bun test ``` ### Slack App Setup 1. Go to [api.slack.com/apps](https://api.slack.com/apps) and create a new app 2. Choose "From an app manifest" 3. Copy the contents of `slack-manifest.yaml` and paste it 4. Install the app to your workspace 5. Copy the "Bot User OAuth Token" (starts with `xoxb-`) and "Signing Secret" 6. Invite the bot to your desired Slack channel: `/invite @IRC Bridge` ### Environment Setup Make a `.env` file with the following: ```bash # Slack Configuration SLACK_BOT_TOKEN=xoxb-your-bot-token-here SLACK_SIGNING_SECRET=your-signing-secret-here # Slack workspace URL (for admin API calls) SLACK_API_URL=https://hackclub.enterprise.slack.com # Optional: For channel manager permission checks SLACK_USER_COOKIE=your-slack-cookie-here SLACK_USER_TOKEN=your-user-token-here # Optional: Enable Cachet API for user lookups (recommended for better performance) CACHET_ENABLED=true # IRC Configuration IRC_NICK=slackbridge NICKSERV_PASSWORD=your-nickserv-password-here NICKSERV_EMAIL=your-email@example.com # Admin users (comma-separated Slack user IDs) ADMINS=U1234567890,U0987654321 # Hack Club CDN Token (for file uploads) CDN_TOKEN=your-cdn-token-here # Server Configuration (optional) PORT=3000 # Note: Channel and user mappings are now stored in the SQLite database (bridge.db) # Use the API or database tools to manage mappings ``` See `.env.example` for a template. ### Slash Commands The bridge provides interactive slash commands for managing mappings: - `/irc-bridge-channel` - Bridge current Slack channel to an IRC channel - `/irc-unbridge-channel` - Remove bridge from current channel - `/irc-bridge-user` - Link your Slack account to an IRC nickname - `/irc-unbridge-user` - Remove your IRC nickname link - `/irc-bridge-list` - List all channel and user bridges ### Managing Channel and User Mappings Channel and user mappings are stored in a SQLite database (`bridge.db`). You can manage them through: **Using Bun REPL:** ```bash bun repl > import { channelMappings, userMappings } from "./src/lib/db" > channelMappings.create("C1234567890", "#general") > userMappings.create("U1234567890", "myircnick") > channelMappings.getAll() ``` **Using SQLite directly:** ```bash bun:sqlite bridge.db sqlite> SELECT * FROM channel_mappings; sqlite> INSERT INTO channel_mappings (slack_channel_id, irc_channel) VALUES ('C1234567890', '#general'); ``` ### How it works The bridge connects to `irc.hackclub.com:6667` (no TLS) and forwards messages bidirectionally based on channel mappings: - **NickServ Authentication**: If `NICKSERV_PASSWORD` is configured, the bridge authenticates on connect - Waits for NickServ confirmation before joining channels - Auto-registers the nick if not registered (requires `NICKSERV_EMAIL`) - Prevents "No external channel messages" errors by ensuring proper authentication - **IRC → Slack**: Messages from mapped IRC channels appear in their corresponding Slack channels - Image URLs are automatically displayed as inline attachments - IRC mentions (`@nick` or `nick:`) are converted to Slack mentions for mapped users - IRC formatting codes are converted to Slack markdown - IRC `/me` actions are displayed in a context block with the user's avatar - Thread replies: Use `@xxxxx` (5-char thread ID) to reply to a Slack thread from IRC - **Slack → IRC**: Messages from mapped Slack channels are sent to their corresponding IRC channels - User display names: Uses name from Slack event if available, otherwise Cachet API (if `CACHET_ENABLED=true`), then Slack API fallback - All lookups are cached locally (1 hour TTL) to reduce API calls - Slack mentions are converted to mapped IRC nicks, or looked up via the above priority - Slack markdown is converted to IRC formatting codes - File attachments are uploaded to Hack Club CDN and URLs are shared - Thread messages are prefixed with `@xxxxx` (5-char thread ID) to show they're part of a thread - First reply in a thread includes a quote of the parent message - **User mappings** allow custom IRC nicknames for specific Slack users and enable proper mentions both ways - **Permissions**: Only channel creators, channel managers, or global admins can bridge/unbridge channels #### Thread Support The bridge supports Slack threads with a simple IRC-friendly syntax: - **Slack → IRC**: Thread messages appear with a `@xxxxx` prefix (5-character thread ID) - First reply in a thread includes a quote: ` @xxxxx > original message` - Subsequent replies: ` @xxxxx message text` - **IRC → Slack**: Reply to a thread by including the thread ID in your message - Example: `@abc12 this is my reply` - The bridge removes the `@xxxxx` prefix and sends your message to the correct thread - Thread IDs are unique per thread and persist across restarts (stored in SQLite) The bridge ignores its own messages and bot messages to prevent loops. ### Architecture The bridge consists of several modules: - **`src/index.ts`** - Main application entry point with IRC/Slack event handlers - **`src/commands.ts`** - Slash command handlers for managing bridges - **`src/lib/db.ts`** - SQLite database layer for channel/user/thread mappings - **`src/lib/parser.ts`** - Bidirectional message formatting conversion (IRC ↔ Slack) - **`src/lib/mentions.ts`** - User mention conversion with Cachet integration - **`src/lib/threads.ts`** - Thread tracking and ID generation - **`src/lib/user-cache.ts`** - Cached Slack user info lookups (1-hour TTL) - **`src/lib/permissions.ts`** - Channel management permission checks - **`src/lib/avatars.ts`** - Stable avatar URL generation for IRC users - **`src/lib/cdn.ts`** - File upload integration with Hack Club CDN - **`src/lib/cachet.ts`** - User profile lookups from Cachet API ### Testing The project includes comprehensive unit tests covering all core functionality: ```bash bun test ``` Tests cover: - Message format parsing (IRC ↔ Slack) - User mention conversion - Thread ID generation and tracking - User info caching - Database operations - Avatar generation If 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.

© 2025-present Kieran Klukas