A Discord voice bot with multi-bot architecture for enhanced audio playback, featuring a web dashboard and comprehensive voice control.
Rainbot uses a Yarn workspaces monorepo with a 4-bot orchestrated architecture:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Railway Project โ
โ โ
โ โโโโโโโโโโโโโโโ โ
โ โ UI โโโโโโ Public URL (only public-facing service) โ
โ โ (React) โ โ
โ โโโโโโโโฌโโโโโโโ โ
โ โ Proxy /api, /auth (internal network) โ
โ โผ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ Raincloud โโโโโโบโ Rainbot โ โ Pranjeet โ โ
โ โ(Orchestrator)โ โ (Music) โ โ (TTS) โ โ
โ โโโโโโโโฌโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโบโโโโโโโโโโโโโโโ โ
โ โ HungerBot โ โ
โ โ (Soundboard)โ โ
โ โโโโโโโโโโโโโโโ โ
โ โ
โ All backend services use Railway internal networking โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
rainbot/
โโโ apps/
โ โโโ raincloud/ # Orchestrator - commands, API, coordination
โ โโโ rainbot/ # Music worker - queue-based playback
โ โโโ pranjeet/ # TTS worker - text-to-speech
โ โโโ hungerbot/ # Soundboard worker - sound effects
โโโ packages/
โ โโโ shared/ # Shared utilities and types
โ โโโ redis-client/ # Redis client wrapper
โ โโโ worker-protocol/ # Worker communication protocol
โโโ ui/ # React + Tailwind dashboard
โโโ package.json # Root workspace config
See Multi-Bot Architecture Documentation for details.
- ๐ต Multi-source audio playback: Local files, YouTube, SoundCloud, Spotify
- ๐ญ Separated audio channels: Music, TTS, and soundboard on independent bots
- ๐ Smart voice management: Auto-join with per-user channel fallback
- ๐ Queue system: Advanced queue management with pre-buffering
- ๐ค Voice interaction: Optional voice command control
- ๐๏ธ Web Dashboard: Beautiful React + Tailwind interface
- ๐ค Sound upload: Manage sound files through the dashboard
- ๐ฎ Slash commands: Easy-to-use Discord commands
- ๐ Statistics: Comprehensive tracking with PostgreSQL
- ๐ Redis state: Persistent session management
- Node.js v22.12.0 or higher
- Yarn 4+ (Corepack enabled)
- Redis 7+
- PostgreSQL 15+
- FFmpeg
- yt-dlp
- 4 Discord bot tokens (Raincloud, Rainbot, Pranjeet, HungerBot)
- Clone the repository:
git clone <repository-url>
cd rainbot- Enable Corepack and install dependencies:
corepack enable
yarn install-
Install system dependencies:
FFmpeg:
- macOS:
brew install ffmpeg - Linux:
sudo apt-get install ffmpeg
yt-dlp:
- macOS:
brew install yt-dlp - Linux:
pip install yt-dlp
- macOS:
-
Configure the bot:
Create a
.envfile in the project root:cp .env.example .env
Edit
.envand fill in your bot credentials.Note: For production (Railway), set environment variables in the platform dashboard.
-
Build TypeScript:
yarn build:ts- Start local infrastructure (Redis + PostgreSQL):
docker-compose up -d- Start the services:
# In separate terminals:
node apps/raincloud/index.js
node apps/rainbot/dist/index.js
node apps/pranjeet/dist/index.js
node apps/hungerbot/dist/index.js
# For UI development:
yarn workspace @rainbot/ui devEach service needs specific environment variables. Create a .env file based on .env.example:
Required for all bots:
DISCORD_CLIENT_ID- Discord application client IDRAINCLOUD_TOKEN- Raincloud bot token (orchestrator)RAINBOT_TOKEN- Rainbot worker tokenPRANJEET_TOKEN- Pranjeet worker tokenHUNGERBOT_TOKEN- HungerBot worker token
For Web Dashboard (OAuth):
DISCORD_CLIENT_SECRET- OAuth client secretSESSION_SECRET- Session encryption keyREQUIRED_ROLE_ID- Discord role ID for dashboard access
Infrastructure:
DATABASE_URL- PostgreSQL connection stringREDIS_URL- Redis connection string
Optional:
SPOTIFY_CLIENT_ID/SPOTIFY_CLIENT_SECRET- For Spotify URL supportAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/S3_BUCKET- For S3 storage
See OAUTH_SETUP.md for detailed OAuth configuration.
Each bot needs these Discord permissions:
- Connect to voice channels
- Speak in voice channels
- Use slash commands
- View Channels
- Read Message History (optional)
/join- Join your current voice channel/leave- Leave the current voice channel/play <source>- Play a sound file, YouTube/SoundCloud URL, or playlist/queue- View the current queue/skip- Skip the current track/pause- Pause playback/stop- Stop playback/clear- Clear the queue/autoplay [enabled]- Toggle autoplay mode
/ping- Check bot latency
The dashboard is served separately and proxies API requests to Raincloud over Railway's internal network.
- Voice Connections: View active voice channel connections
- Server List: Browse all servers the bots are in
- URL Player: Play YouTube, SoundCloud, or direct audio URLs
- Sound Library: Browse and play uploaded sound files
- Statistics Dashboard: Command usage, playback stats, user activity
# Start Raincloud (API server)
node apps/raincloud/index.js
# Start UI dev server (in another terminal)
yarn workspace @rainbot/ui dev# Install all dependencies
yarn install
# Build TypeScript
yarn build:ts
# Build UI for production
yarn workspace @rainbot/ui build
# Type check
yarn type-check
# Lint
yarn lint
# Format
yarn format
# Run all validations
yarn validate- Create a new file in
commands/[category]/[command-name].js - Export a command object with
data(SlashCommandBuilder) andexecutefunction - Commands auto-deploy when bots start
- Place audio files in the
sounds/directory, or - Upload files through the web dashboard
This project uses Jest with ts-jest for test coverage.
# Run all tests
yarn test
# Run tests in watch mode
yarn test:watch
# Run tests with coverage
yarn test:coverageTests are organized in __tests__ directories next to source files.
The project deploys to Railway as 5 separate services using Nixpacks:
| Service | Package | Public |
|---|---|---|
| Raincloud | @rainbot/raincloud |
No (internal API) |
| Rainbot | @rainbot/rainbot |
No |
| Pranjeet | @rainbot/pranjeet |
No |
| HungerBot | @rainbot/hungerbot |
No |
| UI | @rainbot/ui |
Yes (only public service) |
Each service has its own railway.json with Turborepo-scoped builds:
{
"$schema": "https://railway.com/railway.schema.json",
"build": {
"builder": "NIXPACKS",
"buildCommand": "yarn install --immutable && yarn turbo run build:ts --filter=@rainbot/raincloud"
}
}The UI proxies to Raincloud using Railway's internal network:
UI Service โ http://raincloud.railway.internal:3001 โ Raincloud API
Set RAINCLOUD_URL in the UI service to use internal networking.
Raincloud:
RAINCLOUD_TOKEN- Bot tokenDATABASE_URL,REDIS_URL- InfrastructureDISCORD_CLIENT_ID,DISCORD_CLIENT_SECRET- OAuth
Workers (Rainbot, Pranjeet, HungerBot):
RAINBOT_TOKEN/PRANJEET_TOKEN/HUNGERBOT_TOKENREDIS_URL
UI:
RAINCLOUD_URL- Internal URL to Raincloud (e.g.,http://raincloud.railway.internal:3001)
- Ensure the bot has "Connect" and "Speak" permissions
- Check that you're in a voice channel when using
/join
- Verify FFmpeg is installed:
ffmpeg -version - Verify yt-dlp is installed:
yt-dlp --version - Check logs in
logs/error.log
- Export YouTube cookies and set
YTDLP_COOKIESenvironment variable
- Ensure Raincloud is running (API server)
- Check
RAINCLOUD_URLis set correctly in UI service - Verify Railway internal networking for production
- Architecture - System design and multi-bot architecture
- Voice Module - Voice subsystem design and concurrency
- OAuth Setup - Dashboard authentication
- Railway Deploy - Railway deployment guide
- Voice Interaction - Voice command setup
ISC