A retro-styled interactive CD player web application showcasing music from Neuko. Features a nostalgic Walkman interface with a CRT-inspired UI, allowing users to browse playlists, play tracks, and manage volume controls.
- 🎵 Interactive CD Player Interface - Retro Walkman-style player with visual controls
- 📻 Dynamic Playlist Management - Playlists automatically sync from remote FTP storage
- 🎛️ Full Playback Controls - Play, pause, stop, next/previous track, volume control
- 📱 Playlist Navigation - Browse multiple playlists and view track listings
- 🤖 Telegram Bot Integration - Community-driven song submissions via Telegram bot
- Framework: Astro with React components
- Styling: CSS with custom retro-themed styles
- Deployment: Vercel (serverless)
- Storage: DreamHost FTP/SFTP for music files
- Bot: Telegram Bot API (local polling mode)
- Node.js 18+ and npm
- Python 3.7+ (for Telegram bot song downloads)
- ffmpeg (for audio conversion)
- spotify-dl (
pip3 install spotify_dl)
# Clone the repository
git clone <repository-url>
cd pirate-radio
# Install dependencies
npm install
# Set up environment variables (see Configuration section)
cp .env.example .env
# Edit .env with your credentials# Start both Astro dev server and Telegram bot concurrently
npm run dev
# Or run individually:
npm run dev:astro # Just the Astro dev server (port 4321)
npm run bot:local # Just the Telegram bot (polling mode)The website will be available at http://localhost:4321.
pirate-radio/
├── src/
│ ├── components/ # React components (CD player, display, controls)
│ ├── pages/ # Astro pages and API routes
│ │ ├── api/ # API endpoints (playlists, updates)
│ │ └── index.astro # Main page
│ ├── utils/ # Utility functions
│ │ ├── ftp-scanner.ts # Shared FTP/SFTP scanning logic
│ │ ├── telegram-bot.ts # Telegram bot helpers
│ │ └── ...
│ ├── styles/ # CSS files
│ ├── types/ # TypeScript type definitions
│ └── config/ # Configuration files
├── public/ # Static assets and music files
├── scripts/ # Build and utility scripts
└── dist/ # Build output (generated)
Playlists are dynamically generated by scanning the remote FTP server:
- API Endpoint (
/api/playlists.json) scans DreamHost FTP for music files - Playlist Structure is generated from directory structure (each folder = playlist)
- Frontend fetches playlists on page load and displays tracks
- Updates happen automatically when new songs are added via Telegram bot
The Telegram bot runs locally only (not deployed to Vercel):
- Uses polling mode to receive updates
- Automatically deletes webhooks to enable polling
- Handles song submissions from users
- Downloads songs from YouTube/Spotify
- Uploads to DreamHost FTP
- Triggers playlist regeneration
See TELEGRAM_BOT_SETUP.md for detailed bot setup instructions.
Create a .env file in the project root:
# DreamHost FTP (Required for production)
DREAMHOST_FTP_HOST=files.bloc.rocks
DREAMHOST_FTP_USER=your-ftp-username
DREAMHOST_FTP_PASSWORD=your-ftp-password
DREAMHOST_FTP_PATH=/public/music
DREAMHOST_USE_SFTP=false # Set to "true" for SFTP
# Telegram Bot (Required for bot functionality)
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_ADMIN_IDS=123456789,987654321 # Comma-separated admin user IDs
# Spotify API (Required for Spotify song downloads)
SPOTIPY_CLIENT_ID=your-spotify-client-id
SPOTIPY_CLIENT_SECRET=your-spotify-client-secret
# Site Configuration
PUBLIC_SITE_URL=https://your-site.vercel.app
MAX_FILE_SIZE=52428800 # 50MB in bytes
# Optional
PLAYLIST_UPDATE_TOKEN=optional-auth-token # For securing playlist update endpointFor production deployment, set these in the Vercel dashboard:
DREAMHOST_FTP_HOSTDREAMHOST_FTP_USERDREAMHOST_FTP_PASSWORDDREAMHOST_FTP_PATHPUBLIC_SITE_URLSPOTIPY_CLIENT_ID(if using Spotify features)SPOTIPY_CLIENT_SECRET(if using Spotify features)
Note: Telegram bot variables are only needed locally, not in Vercel.
| Script | Description |
|---|---|
npm run dev |
Start Astro dev server and Telegram bot concurrently |
npm run dev:astro |
Start only the Astro dev server |
npm run bot:local |
Run Telegram bot locally (polling mode) |
npm run build |
Build for production |
npm run preview |
Preview production build locally |
npm run generate-playlists |
Generate playlists.json from local music files |
npm run setup-webhook |
Set Telegram webhook (for non-Vercel deployments) |
npm run delete-webhook |
Delete Telegram webhook (for local development) |
npm run upload-music |
Upload music files to DreamHost FTP |
The website is deployed to Vercel. The Telegram bot runs locally and is not deployed.
- Set Environment Variables in Vercel dashboard (see Configuration section)
- Deploy:
vercel --prod
For detailed deployment instructions, see VERCEL_DEPLOYMENT.md.
The bot runs locally using polling mode:
npm run bot:localThe bot will:
- Automatically delete any active webhooks
- Continuously poll Telegram for updates
- Handle song submissions and uploads
- Run until stopped (Ctrl+C)
-
Local Development:
- Run
npm run devto start both website and bot - Make changes to components, styles, or API routes
- Test locally at
http://localhost:4321
- Run
-
Adding Music:
- Use the Telegram bot to submit songs
- Songs are uploaded to DreamHost FTP
- Playlists regenerate automatically
-
Testing:
- Test website functionality locally
- Test bot commands via Telegram
- Verify playlist generation
-
Deployment:
- Push changes to main branch
- Vercel automatically deploys
- Bot continues running locally
Returns current playlists by scanning DreamHost FTP.
Response:
{
"playlists": [
{
"name": "playlist-name",
"path": "/music/playlist-name",
"index": 1,
"total": 5,
"tracks": [...]
}
]
}Regenerates playlists and updates local files. Optional authentication via Authorization: Bearer <token> header.
- Fork the repository
- Create a feature branch
- Make your changes
- Test locally
- Submit a pull request
[Add your license here]
- Website: https://bloc.rocks
- Telegram Bot Setup: TELEGRAM_BOT_SETUP.md
- Vercel Deployment: VERCEL_DEPLOYMENT.md
Created by @afkboom - neuko walkman