A powerful Telegram bot that downloads music from multiple platforms including Spotify, YouTube, SoundCloud, HeartThis, and more. Built with Python and designed to provide high-quality music downloads with metadata preservation.
- Undocumented APIs: Uses internal APIs for better reliability and features
- Spotify: Download tracks, albums, and playlists
- Deezer: Download tracks, albums, and playlists
- YouTube: Extract audio from videos and YouTube Music
- SoundCloud: Download tracks and playlists
- HeartThis: Support for HeartThis tracks
- YouTube Music: Direct YouTube Music track downloads
- Shazam: Music identification from audio files and voice messages
- Inline Mode: Search and download directly from chat
- Batch Downloads: Download entire playlists and albums
- Progress Tracking: Real-time download progress updates
- Quality Selection: Choose from multiple audio quality options
- Metadata Preservation: Automatic ID3 tag embedding
- Thumbnail Support: Album art and track thumbnails
- User Management: Rate limiting and user statistics
- Multiple Formats: MP3, M4A, FLAC, OGG support
- Quality Options: 128kbps to 320kbps MP3, Lossless FLAC
- Metadata Tags: Artist, title, album, year, genre
- Album Art: Automatic cover art embedding
- Lyrics: Optional lyrics fetching and embedding
- Python 3.8 or higher
- FFmpeg installed on your system
- Telegram API credentials (api_id and api_hash from my.telegram.org)
- Telegram Bot Token
- Spotify API credentials (optional, for enhanced features)
- Clone the repository
git clone https://github.com/sagebeme/Spotify-Youtube.git
cd Spotify-Youtube- Install dependencies
pip install -r requirements.txt- Install FFmpeg
# Ubuntu/Debian
sudo apt update && sudo apt install ffmpeg
# macOS
brew install ffmpeg
# Windows
# Download from https://ffmpeg.org/download.html- Configure environment variables
cp .env.example .env
# Edit .env with your credentials- Run the bot
python bot.pyCreate a .env file with the following variables:
# Telegram Bot Configuration
TELEGRAM_API_ID=your_telegram_api_id
TELEGRAM_API_HASH=your_telegram_api_hash
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
TELEGRAM_WEBHOOK_URL=https://your-domain.com/webhook
# Spotify API (Optional - for enhanced metadata)
SPOTIFY_CLIENT_ID=your_spotify_client_id
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
# YouTube API (Optional - for enhanced search)
YOUTUBE_API_KEY=your_youtube_api_key
# Shazam API (Optional - for song identification)
SHAZAM_API_KEY=your_shazam_api_key
# Genius API (Optional - for lyrics)
GENIUS_API=your_genius_api_key
# Internal API Keys (Undocumented APIs)
SPOTIFY_INTERNAL_KEY=your_spotify_internal_key
DEEZER_INTERNAL_KEY=your_deezer_internal_key
SHAZAM_INTERNAL_KEY=your_shazam_internal_key
# Proxy Configuration (Optional)
FIXIE_SOCKS_HOST=your_proxy_url
# File Subscriptions (Optional)
F_SUB=False
F_SUB_CHANNEL_ID=your_channel_id
F_SUB_CHANNEL_INVITE_LINK=https://t.me/your_channel
# Database Configuration
DATABASE_URL=sqlite:///music_bot.db
# Storage Configuration
DOWNLOAD_PATH=./downloads
MAX_FILE_SIZE=50000000 # 50MB in bytes
# Rate Limiting
MAX_DOWNLOADS_PER_HOUR=10
MAX_DOWNLOADS_PER_DAY=50
# Authorization
OWNER_ID=your_telegram_user_id
SUDO_USERS=user_id1 user_id2 user_id3
AUTH_CHATS=chat_id1 chat_id2 chat_id3
LOG_GROUP=your_log_group_id
BUG=your_bug_report_group_id
# Audio Quality Settings
DEFAULT_QUALITY=320
SUPPORTED_FORMATS=mp3,m4a,flac,ogg| Command | Description |
|---|---|
/start |
Start the bot and get welcome message |
/help |
Show help information and available commands |
/download <url> |
Download music from supported platforms |
/search <query> |
Search for music across platforms |
/playlist <url> |
Download entire playlist |
/album <url> |
Download entire album |
/quality <format> |
Set preferred audio quality |
/identify |
Identify music from audio file or voice message |
/status |
Check bot status and your download stats |
/cancel |
Cancel current download |
/auth |
Authorize user to use the bot |
/unauth |
Remove user authorization |
- Tracks: Individual song downloads
- Albums: Complete album downloads with metadata
- Playlists: Full playlist downloads
- Features:
- Automatic metadata extraction
- Album art embedding
- Artist and album information
- Release date and genre tags
- Tracks: Individual song downloads
- Albums: Complete album downloads with metadata
- Playlists: Full playlist downloads
- Features:
- High-quality FLAC downloads (up to 1411 kbps)
- Automatic metadata extraction
- Album art embedding
- Artist and album information
- Release date and genre tags
- Videos: Audio extraction from YouTube videos
- Music: Direct YouTube Music track downloads
- Playlists: YouTube playlist audio extraction
- Features:
- Multiple quality options (128kbps - 320kbps)
- Automatic format detection
- Thumbnail preservation
- Tracks: Individual SoundCloud track downloads
- Playlists: SoundCloud playlist downloads
- Features:
- High-quality audio extraction
- Track metadata preservation
- Artist information embedding
- Tracks: HeartThis track downloads
- Features:
- Direct audio extraction
- Metadata preservation
- Audio Identification: Identify songs from audio files and voice messages
- Features:
- Automatic song recognition
- Artist and title detection
- Direct download after identification
- Support for various audio formats
- Voice message processing
music_bot/
βββ bot/
β βββ __init__.py
β βββ handlers/
β β βββ __init__.py
β β βββ download.py
β β βββ search.py
β β βββ playlist.py
β β βββ identify.py
β β βββ admin.py
β βββ services/
β β βββ __init__.py
β β βββ spotify_service.py
β β βββ deezer_service.py
β β βββ youtube_service.py
β β βββ soundcloud_service.py
β β βββ shazam_service.py
β β βββ metadata_service.py
β βββ utils/
β βββ __init__.py
β βββ audio_processor.py
β βββ rate_limiter.py
β βββ database.py
βββ config/
β βββ __init__.py
β βββ settings.py
β βββ constants.py
βββ tests/
β βββ __init__.py
β βββ test_spotify.py
β βββ test_youtube.py
β βββ test_bot.py
βββ requirements.txt
βββ bot.py
βββ README.md
# Example service structure
class SpotifyService:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(
client_id=client_id,
client_secret=client_secret
))
async def get_track_info(self, track_url):
"""Extract track information from Spotify URL"""
pass
async def download_track(self, track_url, quality="320"):
"""Download track from Spotify"""
pass
async def get_playlist_tracks(self, playlist_url):
"""Get all tracks from a playlist"""
pass
class DeezerService:
def __init__(self, api_key=None):
self.api_key = api_key
self.deezer_api = DeezerAPI()
async def get_track_info(self, track_url):
"""Extract track information from Deezer URL"""
pass
async def download_track(self, track_url, quality="flac"):
"""Download track from Deezer in FLAC quality"""
pass
async def get_playlist_tracks(self, playlist_url):
"""Get all tracks from a Deezer playlist"""
pass
async def get_album_tracks(self, album_url):
"""Get all tracks from a Deezer album"""
pass
class ShazamService:
def __init__(self, api_key=None):
self.api_key = api_key
self.shazam = Shazam()
async def identify_song(self, audio_file_path):
"""Identify song from audio file"""
pass
async def identify_from_voice(self, voice_file_path):
"""Identify song from voice message"""
pass
async def get_song_details(self, song_id):
"""Get detailed song information"""
pass# Spotify track download using undocumented APIs
async def download_spotify_track(track_url, quality="320"):
# Extract track ID from URL
track_id = extract_spotify_id(track_url)
# Use undocumented Spotify API for better access
spotify_api = SpotifyAPI()
track_info = await spotify_api.get_track_metadata(track_id)
# Get direct download links using internal APIs
download_links = await spotify_api.get_download_links(track_id, quality)
# Download using direct links
audio_file = await download_from_direct_link(download_links['mp3'])
# Embed metadata
embed_metadata(audio_file, track_info)
return audio_file# Deezer track download using undocumented APIs
async def download_deezer_track(track_url, quality="flac"):
# Extract track ID from URL
track_id = extract_deezer_id(track_url)
# Use undocumented Deezer API for FLAC downloads
deezer_api = DeezerAPI()
track_info = await deezer_api.get_track_metadata(track_id)
# Get direct FLAC download links
download_links = await deezer_api.get_flac_links(track_id)
# Download FLAC file
audio_file = await download_flac_from_link(download_links['flac'])
# Embed metadata
embed_metadata(audio_file, track_info)
return audio_file# YouTube audio extraction example
async def download_youtube_audio(video_url, quality="320"):
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': quality,
}],
'outtmpl': '%(title)s.%(ext)s',
'writethumbnail': True,
'embedthumbnail': True,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(video_url, download=True)
return info# Shazam song identification using undocumented APIs
async def identify_song_from_audio(audio_file_path):
# Use undocumented Shazam API for better results
shazam_api = ShazamAPI()
# Read and process audio file
audio_data = await process_audio_for_shazam(audio_file_path)
# Send to Shazam's internal API
result = await shazam_api.identify_song(audio_data)
if result['success']:
track_info = result['track']
return {
'title': track_info['title'],
'artist': track_info['artist'],
'album': track_info.get('album', ''),
'shazam_id': track_info['id'],
'confidence': result['confidence'],
'genius_url': track_info.get('genius_url', ''),
'apple_music_url': track_info.get('apple_music_url', ''),
'spotify_url': track_info.get('spotify_url', '')
}
return NoneCREATE TABLE users (
id INTEGER PRIMARY KEY,
telegram_id INTEGER UNIQUE NOT NULL,
username TEXT,
first_name TEXT,
last_name TEXT,
downloads_count INTEGER DEFAULT 0,
total_downloads_size INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE downloads (
id INTEGER PRIMARY KEY,
user_id INTEGER,
platform TEXT NOT NULL,
track_url TEXT NOT NULL,
track_title TEXT,
artist TEXT,
album TEXT,
quality TEXT,
file_size INTEGER,
download_path TEXT,
status TEXT DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (id)
);FROM python:3.9-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
ffmpeg \
&& rm -rf /var/lib/apt/lists/*
# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Create downloads directory
RUN mkdir -p downloads
# Expose port
EXPOSE 8000
# Run the bot
CMD ["python", "bot.py"]version: '3.8'
services:
music-bot:
build: .
environment:
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- SPOTIFY_CLIENT_ID=${SPOTIFY_CLIENT_ID}
- SPOTIFY_CLIENT_SECRET=${SPOTIFY_CLIENT_SECRET}
volumes:
- ./downloads:/app/downloads
- ./data:/app/data
restart: unless-stopped# Create Heroku app
heroku create your-music-bot
# Set environment variables
heroku config:set TELEGRAM_BOT_TOKEN=your_token
heroku config:set SPOTIFY_CLIENT_ID=your_client_id
heroku config:set SPOTIFY_CLIENT_SECRET=your_client_secret
# Deploy
git push heroku main# Install test dependencies
pip install -r requirements-test.txt
# Run all tests
pytest
# Run specific test file
pytest tests/test_spotify.py
# Run with coverage
pytest --cov=bot tests/# Example test
import pytest
from bot.services.spotify_service import SpotifyService
class TestSpotifyService:
@pytest.fixture
def spotify_service(self):
return SpotifyService("test_id", "test_secret")
async def test_get_track_info(self, spotify_service):
track_url = "https://open.spotify.com/track/4iV5W9uYEdYUVa79Axb7Rh"
track_info = await spotify_service.get_track_info(track_url)
assert track_info['title'] is not None
assert track_info['artist'] is not None
assert track_info['album'] is not None# Redis caching for API responses
import redis
import json
class CacheService:
def __init__(self):
self.redis = redis.Redis(host='localhost', port=6379, db=0)
async def get_cached_track(self, track_id):
cached = self.redis.get(f"track:{track_id}")
return json.loads(cached) if cached else None
async def cache_track(self, track_id, track_data, ttl=3600):
self.redis.setex(f"track:{track_id}", ttl, json.dumps(track_data))# Rate limiting implementation
from datetime import datetime, timedelta
class RateLimiter:
def __init__(self):
self.user_limits = {}
async def check_limit(self, user_id, limit_type="hourly"):
now = datetime.now()
user_key = f"{user_id}:{limit_type}"
if user_key not in self.user_limits:
self.user_limits[user_key] = []
# Clean old entries
self.user_limits[user_key] = [
time for time in self.user_limits[user_key]
if now - time < timedelta(hours=1)
]
if len(self.user_limits[user_key]) >= 10: # 10 downloads per hour
return False
self.user_limits[user_key].append(now)
return Trueimport re
from urllib.parse import urlparse
def validate_url(url):
"""Validate and sanitize input URLs"""
try:
parsed = urlparse(url)
if parsed.scheme not in ['http', 'https']:
return False
# Check for supported domains
supported_domains = [
'open.spotify.com',
'youtube.com',
'youtu.be',
'soundcloud.com',
'hearthis.at'
]
return any(domain in parsed.netloc for domain in supported_domains)
except:
return Falseasync def check_file_size(file_path, max_size=50*1024*1024): # 50MB
"""Check if downloaded file exceeds size limit"""
file_size = os.path.getsize(file_path)
if file_size > max_size:
os.remove(file_path)
raise ValueError(f"File size {file_size} exceeds limit {max_size}")
return True# Fork the repository
git clone https://github.com/your-username/Spotify-Youtube.git
cd Spotify-Youtube
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install development dependencies
pip install -r requirements-dev.txt
# Run pre-commit hooks
pre-commit install# Format code
black bot/
isort bot/
# Lint code
flake8 bot/
mypy bot/- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- SpotiFlyer - Inspiration for multi-platform music downloading
- MusicDownloader-Telegram-Bot - Telegram bot implementation patterns
- spot-seek-bot - Spotify integration techniques
- spotify2mp3 - Spotify to MP3 conversion methods
- spotDL - Advanced Spotify downloading capabilities
- Telegram: @MusicDownloaderBot
- Issues: GitHub Issues
- Discussions: GitHub Discussions
This bot is for educational purposes only. Please respect copyright laws and support artists by purchasing their music when possible. The developers are not responsible for any misuse of this software.
Made with β€οΈ by the Music Downloader Bot Team