this repo has no description
TypeScript 100.0%
24 1 0

Clone this repository

https://tangled.org/dunkirk.sh/irc-slack-bridge
git@knot.dunkirk.sh:dunkirk.sh/irc-slack-bridge

For self-hosted knots, clone URLs may differ based on your setup.

README.md

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!

bun install
bun dev

To run tests:

bun test

Slack App Setup#

  1. Go to 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:

# 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:

bun repl
> import { channelMappings, userMappings } from "./src/lib/db"
> channelMappings.create("C1234567890", "#general")
> userMappings.create("U1234567890", "myircnick")
> channelMappings.getAll()

Using SQLite directly:

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: <user> @xxxxx > original message
    • Subsequent replies: <user> @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:

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 and the github is just a mirror.

© 2025-present Kieran Klukas