No description
Find a file
flifloo c2afa3a63c
All checks were successful
Build Docker image and publish / docker (push) Successful in 7m56s
Fix web for MatrixRTC
2026-02-18 00:28:49 +01:00
.forgejo/workflows Add Docker image with CI 2026-02-14 01:21:32 +01:00
assets/sounds Add MatrixRTC join/leave sounds 2026-02-17 01:36:59 +01:00
src Fix web for MatrixRTC 2026-02-18 00:28:49 +01:00
.dockerignore Add Docker image with CI 2026-02-14 01:21:32 +01:00
.gitignore Init commit 2026-02-14 00:03:34 +01:00
Cargo.lock Rename to VoiceBridge 2026-02-17 01:33:47 +01:00
Cargo.toml Rename to VoiceBridge 2026-02-17 01:33:47 +01:00
CLAUDE.md Rename to VoiceBridge 2026-02-17 01:33:47 +01:00
config.example.toml Add MatrixRTC support 2026-02-17 01:29:59 +01:00
Dockerfile Rename to VoiceBridge 2026-02-17 01:33:47 +01:00
README.md Rename to VoiceBridge 2026-02-17 01:33:47 +01:00

VoiceBridge

Bidirectional voice bridge between a Discord voice channel and either a TeamSpeak server or a MatrixRTC room (Element Call / Matrix). When someone joins the configured backend channel/room, the bot joins Discord voice and relays audio in both directions.

A built-in web interface shows live status for both servers via SSE.

Backends

Two mutually exclusive cargo features select the backend:

Feature Backend Trigger
teamspeak (default) TeamSpeak 3 server Users join the configured TS channel
matrixrtc MatrixRTC / Element Call Call members detected via Matrix /sync (org.matrix.msc3401.call.member state events)

Requirements

  • Rust (edition 2024)
  • A Discord bot token

TeamSpeak backend

  • A TeamSpeak 3 server
  • opus development libraries

MatrixRTC backend

  • A Matrix homeserver with a bot account and access token
  • A LiveKit JWT service (lk-jwt-service) — auto-discovered via MSC4143 or well-known
  • cmake, g++, clang (for building webrtc-sys)

Discord Bot Setup

  1. Create an application at the Discord Developer Portal.
  2. Go to Bot and copy the bot token.
  3. Under Privileged Gateway Intents, enable:
    • Server Members Intent — required for displaying user names instead of IDs.
    • Message Content Intent — required for bridging text chat between Discord and the backend.
  4. Go to OAuth2 → URL Generator, select the bot scope with these permissions:
    • Connect — join voice channels
    • Speak — send audio
    • Use Voice Activity — receive audio without push-to-talk
    • Send Messages — relay backend chat to the Discord voice channel
    • Read Message History — read messages in the bridged channel
  5. Use the generated URL to invite the bot to your server.
  6. Enable Developer Mode in Discord settings (App Settings → Advanced) to copy guild and channel IDs by right-clicking.

Configuration

Copy the example config and fill in your values:

cp config.example.toml .credentials.toml

Common settings

Key Required Description
discord_token yes Bot token from the Developer Portal
discord_guild_id yes Discord server (guild) ID
discord_channel_id yes Discord voice channel ID to bridge
verbose no Log level: 0=warn, 1=info, 2=debug (default), 3+=trace
volume no Volume multiplier for backend→Discord audio (default: 1.0)
web_listen no Address for the web status page (e.g. 0.0.0.0:8080)
web_token no Shared secret to protect the web interface

TeamSpeak settings

Key Required Description
teamspeak_server yes TeamSpeak address (host or host:port, default port 9987)
teamspeak_identity no Persistent TS identity string (printed on first run if omitted)
teamspeak_name no Bot display name on TeamSpeak (default: VoiceBridge)
teamspeak_channel no TS channel path to join (e.g. Default Channel/Bridge)
teamspeak_channel_id no TS channel ID to join (alternative to path)
teamspeak_server_password no TS server password
teamspeak_channel_password no TS channel password

MatrixRTC settings

Key Required Description
matrix_homeserver_url yes Matrix homeserver URL (e.g. https://matrix.example.com)
matrix_access_token yes Bot's Matrix access token
matrix_room_id yes Matrix room ID (e.g. !abc123:matrix.org)
matrix_device_id no Bot device ID (default: VOICEBRIDGE)
livekit_service_url no Override JWT service URL (auto-discovered via MSC4143/well-known)
livekit_room_name no Direct LiveKit room name (overrides MSC4195 derivation)
livekit_identity no Bot display name in LiveKit (default: VoiceBridge)
livekit_slot_id no MatrixRTC slot ID (default: m.call#ROOM)

Build & Run

# TeamSpeak (default)
cargo clippy   # build + lint
cargo run      # run the bridge

# MatrixRTC
cargo clippy --features matrixrtc --no-default-features
cargo run --features matrixrtc --no-default-features

Docker

# TeamSpeak (default)
docker build -t voicebridge .

# MatrixRTC
docker build --build-arg FEATURES=matrixrtc -t teamcordvoice .

Web Interface

Set web_listen in your config to enable the status page. It shows a split-panel view:

  • Left panel: Backend status — TeamSpeak channel tree or MatrixRTC room participants
  • Right panel: Discord voice channels with users and mute/deaf/streaming indicators

The page updates in real time via Server-Sent Events.

How It Works

The Discord gateway connection and the backend task run permanently. The bot monitors the backend for occupancy:

  • TeamSpeak: When someone joins the configured TS channel, the bot joins Discord voice and starts relaying audio. When the TS channel empties, it leaves Discord voice.
  • MatrixRTC: The bot monitors the Matrix room via /sync for org.matrix.msc3401.call.member state events. When call members are present, it discovers the JWT service (MSC4143 or well-known), exchanges an OpenID token for a LiveKit JWT, sends its own membership state event, and connects to LiveKit. When all members leave, it clears its membership and disconnects.

Audio is bridged at 48 kHz stereo, 20 ms frames in both directions. Text messages in the configured Discord channel are forwarded to TeamSpeak channel chat (and vice versa); text bridging is not yet implemented for MatrixRTC.