Co-authored-by: Cursor <cursoragent@cursor.com>
Important
This project was developed entirely with AI coding assistance (Claude Opus 4.6 via Cursor IDE) and has not undergone rigorous review. It is provided as-is and may require adjustments for other environments.
Kosmi-IRC Relay via Matterbridge
A Matterbridge-based bridge that relays messages bidirectionally between Kosmi chat rooms and IRC channels, with optional Jackbox Game Picker integration for live voting and game announcements.
Features
- Real-time bidirectional message relay between Kosmi and IRC
- Native GraphQL-over-WebSocket connection to Kosmi (no browser required for basic use)
- Anonymous or authenticated Kosmi access (email/password login with token caching)
- Jackbox Game Picker integration: live vote detection, game announcements, room code images
- IRC commands:
!kreconnect,!jreconnect,!reconnect,!votes - Ticker-symbol voting for specific games (e.g.
QPL3++,TMP2--) - SIGUSR1 mute toggle for Jackbox announcements
- Automatic reconnection on connection loss
- Docker deployment with persistent token cache
Architecture
This project is a trimmed fork of Matterbridge with two registered bridges: Kosmi and IRC. The Kosmi bridge connects directly to wss://engine.kosmi.io/gql-ws using the graphql-transport-ws protocol -- no headless browser is needed for the primary connection path.
How It Works
- Anonymous access (default): The bridge calls Kosmi's
anonLoginHTTP mutation to obtain a JWT, then opens a native WebSocket connection. - Authenticated access (optional): If
EmailandPasswordare configured, headless Chrome (chromedp) performs a one-time browser login to extract a JWT. The token is cached locally and reused across restarts. - Room subscription: After connecting, the bridge subscribes to
newMessageevents via GraphQL and joins the configured room. - Message relay: Incoming Kosmi messages are forwarded to IRC (and vice versa) through the Matterbridge gateway, with configurable nick formatting.
Message Flow
IRC User --> IRC Server --> Matterbridge Gateway --> Kosmi GraphQL WS --> Kosmi Room
Kosmi User --> Kosmi Room --> GraphQL subscription --> Matterbridge Gateway --> IRC Channel
Jackbox Integration (Optional)
When enabled, the relay connects to a Jackbox Game Picker API via WebSocket (or webhook fallback) to:
- Detect
thisgame++/thisgame--votes and ticker-symbol votes in chat - Announce upcoming games with room codes (optionally as uploaded images)
- Respond to
!votesqueries with current vote tallies
Installation
Option 1: Docker (Recommended)
# 1. Copy and edit configuration
cp matterbridge.toml.example matterbridge.toml
nano matterbridge.toml
# 2. Build and run
docker-compose up -d
# 3. View logs
docker-compose logs -f
See DOCKER_QUICKSTART.md for a 5-minute setup guide.
Option 2: Build from Source
Prerequisites
- Go 1.23 or higher
- Chrome/Chromium (only required if using email/password authentication)
- Access to an IRC server
- A Kosmi room URL
Building
git clone <repository-url>
cd irc-kosmi-relay
go mod download
go build -o matterbridge .
Configuration
Copy matterbridge.toml.example to matterbridge.toml and edit it. The key sections:
# Kosmi configuration
[kosmi.hyperspaceout]
RoomURL="https://app.kosmi.io/room/@yourroom"
# Optional: Email/password for authenticated access
# Requires Chrome/Chromium for browser automation
Email=""
Password=""
RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
# IRC configuration
[irc.zeronode]
Server="irc.libera.chat:6697"
Nick="kosmi-relay"
UseTLS=true
RemoteNickFormat="[{PROTOCOL}] <{NICK}> "
# Gateway to connect Kosmi and IRC
[[gateway]]
name="kosmi-irc-gateway"
enable=true
[[gateway.inout]]
account="kosmi.hyperspaceout"
channel="main"
[[gateway.inout]]
account="irc.zeronode"
channel="#your-channel"
# Jackbox integration (optional)
[jackbox]
Enabled=false
APIURL="https://your-jackbox-api.example.com"
AdminPassword=""
UseWebSocket=true
EnableRoomCodeImage=true
RoomCodeImageDelay=28
RoomCodePlaintextDelay=22
Configuration Reference
Kosmi Settings
| Key | Required | Description |
|---|---|---|
RoomURL |
Yes | Full URL to the Kosmi room |
Email |
No | Email for authenticated access |
Password |
No | Password for authenticated access |
RemoteNickFormat |
No | Format for nicks from other bridges |
IRC Settings
| Key | Required | Description |
|---|---|---|
Server |
Yes | IRC server address with port |
Nick |
Yes | Bot's IRC nickname |
UseTLS |
No | Enable TLS (recommended) |
SkipTLSVerify |
No | Skip TLS cert verification |
NickServNick |
No | NickServ service nick |
NickServPassword |
No | NickServ password |
UseSASL |
No | Use SASL authentication |
RemoteNickFormat |
No | Format for nicks from other bridges |
Channels |
No | Channels to auto-join |
Jackbox Settings
| Key | Required | Description |
|---|---|---|
Enabled |
Yes | Enable/disable Jackbox integration |
APIURL |
Yes | Jackbox Game Picker API URL |
AdminPassword |
Yes | API admin password for JWT auth |
UseWebSocket |
No | Use WebSocket transport (default: true) |
WebhookPort |
No | Webhook listen port (if not using WS) |
WebhookSecret |
No | HMAC secret for webhook verification |
EnableRoomCodeImage |
No | Generate room code images |
RoomCodeImageDelay |
No | Seconds before sending image announcement |
RoomCodePlaintextDelay |
No | Seconds before sending plaintext room code |
Usage
# Run the bridge
./matterbridge -conf matterbridge.toml
# Run with debug logging
./matterbridge -conf matterbridge.toml -debug
# Start with Jackbox announcements muted
./matterbridge -conf matterbridge.toml -muted
CLI Flags
| Flag | Description |
|---|---|
-conf |
Path to config file (default: matterbridge.toml) |
-debug |
Enable debug logging |
-version |
Show version |
-muted |
Start with Jackbox announcements muted |
-gops |
Enable gops diagnostic agent |
IRC Commands
Users can issue commands in IRC chat. See docs/IRC.md for full details.
| Command | Description |
|---|---|
!kreconnect |
Reconnect the Kosmi bridge |
!jreconnect |
Reconnect the Jackbox WebSocket |
!reconnect |
Reconnect all non-IRC services |
!votes |
Show vote tally for the current game |
thisgame++ / thisgame-- |
Vote on the current game |
SYMBOL++ / SYMBOL-- |
Vote on a game by ticker symbol |
Mute Toggle
Jackbox announcements can be toggled at runtime without restarting:
# Local process
kill -SIGUSR1 $(pgrep matterbridge)
# Docker
docker kill -s SIGUSR1 kosmi-irc-relay
See MUTE_CONTROL.md for details.
Environment Variables
| Variable | Description |
|---|---|
DEBUG=1 |
Enable debug logging |
MATTERBRIDGE_DATA_DIR |
Directory for persistent data (token cache) |
TZ |
Timezone for container logs |
CHROME_BIN |
Path to Chrome binary (for auth only) |
File Structure
irc-kosmi-relay/
├── matterbridge.go # Entry point: flags, logger, router, mute toggle
├── matterbridge.toml.example # Example configuration
├── Dockerfile # Docker build (Go 1.23 + Chromium for auth)
├── docker-compose.yml # Docker Compose deployment
│
├── bridge/
│ ├── config/
│ │ └── config.go # Message types, events, protocol config
│ ├── kosmi/
│ │ ├── kosmi.go # Kosmi bridge: Connect, Send, message handling
│ │ ├── graphql_ws_client.go # Native GraphQL-over-WebSocket client
│ │ ├── graphql.go # GraphQL message/payload structs
│ │ ├── auth.go # Anonymous login (anonLogin HTTP mutation)
│ │ ├── browser_auth.go # Chromedp browser login for email/password
│ │ ├── token_cache.go # JWT token caching (file-based)
│ │ ├── image_upload.go # Image upload to Kosmi CDN
│ │ └── errors.go # Error types
│ ├── irc/
│ │ ├── irc.go # IRC bridge: Connect, Send, NAMES handling
│ │ ├── handlers.go # PRIVMSG handler, commands, vote detection
│ │ └── formatting.go # IRC formatting helpers
│ └── jackbox/
│ ├── client.go # Jackbox API client (REST + WebSocket)
│ ├── votes.go # Vote detection (thisgame/ticker parsing)
│ ├── tickers.go # Ticker symbol -> game title lookup table
│ ├── webhook.go # Webhook transport (alternative to WS)
│ ├── image_upload.go # Room code image generation + upload
│ └── roomcode_image.go # Room code GIF rendering
│
├── gateway/
│ ├── gateway.go # Gateway message routing and transformation
│ ├── router.go # Router: message bus, Jackbox manager, broadcast
│ ├── handlers.go # Event handlers: reconnect, votes, files
│ └── bridgemap/
│ ├── bkosmi.go # Registers "kosmi" protocol
│ └── birc.go # Registers "irc" protocol
│
├── docs/
│ ├── IRC.md # IRC command reference
│ ├── setup/ # Setup and deployment guides
│ └── archive/ # Historical development notes
│
└── cmd/ # Standalone test/debug tools
Troubleshooting
Kosmi Connection Issues
Bridge fails to connect to Kosmi
- Verify
RoomURLis correct and the room exists - Check network connectivity to
app.kosmi.ioandengine.kosmi.io - Enable debug logging (
-debug) to see WebSocket handshake details - Look for
"Successfully connected to Kosmi"in logs
Authentication fails (email/password)
- Verify Chrome/Chromium is installed and accessible
- Check credentials are correct
- Delete
data/kosmi_token_cache.jsonto force a fresh login - See BROWSER_AUTH_GUIDE.md
IRC Connection Issues
- Verify server address and port
- Check TLS settings match the server's requirements
- Confirm the bot's nick is not already in use
- Check NickServ/SASL credentials if authentication is configured
Messages Not Relaying
- Verify both bridges show as connected in logs
- Check gateway configuration: Kosmi channel must be
"main", IRC channel must include# - Enable debug logging to trace message flow
- Look for
"Forwarding to Matterbridge"and"Sending message"in logs
Jackbox Integration Issues
- Verify
APIURLis accessible andAdminPasswordis correct - Check that a Jackbox session is active with games being played
- Confirm
Enabled=truein the[jackbox]config section - See JACKBOX_INTEGRATION.md
Documentation
| Document | Description |
|---|---|
| IRC.md | IRC commands, voting syntax, ticker symbols |
| DOCKER_QUICKSTART.md | 5-minute Docker setup |
| DOCKER_DEPLOYMENT.md | Full Docker deployment guide |
| QUICKSTART.md | Build-from-source quickstart |
| JACKBOX_INTEGRATION.md | Jackbox Game Picker setup |
| BROWSER_AUTH_GUIDE.md | Email/password authentication |
| TOKEN_PERSISTENCE.md | Token caching details |
| MUTE_CONTROL.md | Mute toggle guide |
Credits
- Based on Matterbridge by 42wim
- Kosmi API integration via reverse-engineered GraphQL protocol
License
Same as Matterbridge (Apache 2.0)