Add WEBHOOK_SECRET env var for authenticating incoming Owncast webhooks via a ?secret= query parameter. Requests with a missing or incorrect secret are rejected with 401. If unset, all requests are accepted (with a startup warning). Also includes previously uncommitted work: - IRC server password support (IRC_PASSWORD env var, PASS command) - IRC username/ident field in config - IRC_PASSWORD and SELinux volume flag in docker-compose.yml Made-with: Cursor
4.1 KiB
Important
This project was developed entirely with AI coding assistance (Claude Opus 4.6 via Cursor IDE) and has not undergone rigorous human review. It is provided as-is and may require adjustments for other environments.
owncast-irc-bridge
Bidirectional chat bridge between Owncast and IRC. Messages sent in your Owncast chat appear in an IRC channel and vice versa.
Quick Start (Docker Compose)
1. Create your config file
cp config.example.toml config.toml
Edit config.toml with your IRC server/channel and Owncast URL.
2. Get an Owncast access token
In your Owncast admin panel, go to Integrations > Access Tokens and create a token with "send messages" permission.
3. Set the token
export OWNCAST_ACCESS_TOKEN="your-token-here"
Or create a .env file (git-ignored):
OWNCAST_ACCESS_TOKEN=your-token-here
WEBHOOK_SECRET=some-random-secret
4. Configure the Owncast webhook
In your Owncast admin, go to Integrations > Webhooks and add a webhook pointing to:
http://<bridge-host>:9078/webhook?secret=some-random-secret
If WEBHOOK_SECRET is set, the bridge rejects any request that doesn't include a matching ?secret= query parameter. If unset, all requests are accepted (a warning is logged at startup).
Select the events: Chat Message, Stream Started, Stream Stopped.
5. Run it
docker compose up -d
Check logs:
docker compose logs -f
Running Without Docker
Requires Rust 1.75+.
cargo build --release
export OWNCAST_ACCESS_TOKEN="your-token-here"
./target/release/owncast-irc-bridge --config config.toml
Configuration
See config.example.toml for all options. The only required sections are [irc] (with server and channel) and [owncast] (with url). Everything else has defaults.
| Section | Key | Default | Description |
|---|---|---|---|
irc |
server |
(required) | IRC server hostname |
irc |
port |
6667 |
IRC server port |
irc |
tls |
false |
Use TLS for IRC |
irc |
nick |
owncast-bridge |
IRC nickname |
irc |
channel |
(required) | IRC channel to join |
owncast |
url |
(required) | Owncast instance URL |
owncast |
webhook_port |
9078 |
Port the webhook server listens on |
owncast |
websocket_enabled |
false |
Also connect via WebSocket (redundant with webhook, useful as fallback) |
owncast |
health_poll_interval_secs |
30 |
How often to poll Owncast status |
bridge |
irc_prefix |
[IRC] |
Prefix for IRC messages in Owncast |
bridge |
owncast_prefix |
[OC] |
Prefix for Owncast messages in IRC |
control |
socket_path |
/tmp/owncast-irc-bridge.sock |
Unix socket for bridge-ctl |
Secrets are always read from environment variables (not the config file):
| Variable | Required | Description |
|---|---|---|
OWNCAST_ACCESS_TOKEN |
Yes | Owncast integration API token |
IRC_PASSWORD |
No | IRC server password (PASS command) |
WEBHOOK_SECRET |
No | Shared secret for webhook authentication |
Runtime Control
Use bridge-ctl to interact with a running bridge:
bridge-ctl status # Show bridge status as JSON
bridge-ctl irc reconnect # Reconnect to IRC
bridge-ctl owncast reconnect # Reconnect to Owncast
bridge-ctl quit # Shut down the bridge
Inside Docker:
docker compose exec bridge bridge-ctl status
How It Works
- Owncast → IRC: Owncast sends webhook events to the bridge. The bridge formats the message and sends it to IRC via PRIVMSG.
- IRC → Owncast: The bridge listens for PRIVMSG in the configured channel and posts to Owncast via the integration API.
- Deduplication: If both webhook and WebSocket are enabled, duplicate messages are detected by ID and dropped.
- Echo suppression: Messages the bridge itself sent are recognized and not re-bridged.
- Stream events: Stream start/stop events are announced in IRC.
- Health polling: The bridge polls Owncast's
/api/statusendpoint and announces state changes in IRC.