One-shot bot that joins a Discord voice channel, streams a netradio
source for a configured duration, then disconnects and exits. Meant to
be scheduled via cron.
- radio_bot.py: config load/validation, voice connect, ffmpeg stream
- run.sh: venv bootstrap + launcher, cron-safe (resolves own dir)
- radioconfig.json.template: source, channel_id, runtime_seconds, token
- install_deps_{arch,debian,raspbian,fedora}.sh: system deps per distro
- requirements.txt, README, .gitignore for local config
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|---|---|---|
| .gitignore | ||
| README.md | ||
| install_deps_arch.sh | ||
| install_deps_debian.sh | ||
| install_deps_fedora.sh | ||
| install_deps_raspbian.sh | ||
| radio_bot.py | ||
| radioconfig.json.template | ||
| requirements.txt | ||
| run.sh | ||
README.md
Dispy-P3BOT
A one-shot Discord bot that relays a netradio stream into a Discord voice channel for a fixed duration, then disconnects and exits. Built to be driven by cron — e.g. "transmit for 5 minutes every day at 6 pm".
How it works
Each invocation logs in, joins the configured voice channel, pipes the netradio
source through ffmpeg for runtime_seconds, then leaves and exits. There is no
long-running daemon — cron controls the schedule.
Requirements
- Python 3.9+
ffmpegon yourPATH- A Discord bot token (from the Developer Portal)
The bot needs permission to Connect and Speak in the target voice channel. Only the default gateway intents are used, so no privileged intents need to be enabled.
Setup
Install the system dependencies (Python, ffmpeg, build tools) using the script for your distro:
./install_deps_arch.sh # Arch Linux
./install_deps_debian.sh # Debian / Ubuntu
./install_deps_raspbian.sh # Raspberry Pi OS
./install_deps_fedora.sh # Fedora (enables RPM Fusion for full ffmpeg)
Then configure and run:
cp radioconfig.json.template radioconfig.json
# then edit radioconfig.json
./run.sh
The first ./run.sh creates a .venv/ and installs dependencies; later runs
just start the bot.
Configuration (radioconfig.json)
| Key | Description |
|---|---|
netradio_source |
URL of the stream (e.g. an Icecast/Shoutcast .mp3/.aac URL). |
channel_id |
Numeric ID of the target voice channel. |
runtime_seconds |
How long to transmit, in seconds (e.g. 300 = 5 minutes). |
token |
Bot token. Optional — prefer DISCORD_BOT_TOKEN (see below). |
Get a channel ID by enabling Developer Mode in Discord (Settings → Advanced), then right-click a voice channel → Copy Channel ID.
Token via environment variable (recommended)
DISCORD_BOT_TOKEN takes precedence over the token field, so you can keep the
token out of the config file:
export DISCORD_BOT_TOKEN="your-token-here"
./run.sh
radioconfig.json is gitignored so a token placed there won't be committed.
Scheduling with cron
Transmit for the configured duration every day at 18:00:
0 18 * * * DISCORD_BOT_TOKEN="your-token" /full/path/to/run.sh >> /full/path/to/radio.log 2>&1
Use absolute paths — run.sh resolves its own directory, so cron's working
directory does not matter.