Skip to content

sagebeme/Spotify-Youtube

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎡 Music Downloader Telegram Bot

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.

Python Telegram License Stars

🌟 Features

🎧 Multi-Platform Support

  • 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

πŸ“± Telegram Bot Features

  • 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

🎡 Audio Features

  • 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

πŸš€ Quick Start

Prerequisites

  • 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)

Installation

  1. Clone the repository
git clone https://github.com/sagebeme/Spotify-Youtube.git
cd Spotify-Youtube
  1. Install dependencies
pip install -r requirements.txt
  1. Install FFmpeg
# Ubuntu/Debian
sudo apt update && sudo apt install ffmpeg

# macOS
brew install ffmpeg

# Windows
# Download from https://ffmpeg.org/download.html
  1. Configure environment variables
cp .env.example .env
# Edit .env with your credentials
  1. Run the bot
python bot.py

βš™οΈ Configuration

Environment Variables

Create 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

Bot Commands

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

πŸ“‹ Supported Platforms

Spotify

  • 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

Deezer

  • 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

YouTube/YouTube Music

  • 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

SoundCloud

  • Tracks: Individual SoundCloud track downloads
  • Playlists: SoundCloud playlist downloads
  • Features:
    • High-quality audio extraction
    • Track metadata preservation
    • Artist information embedding

HeartThis

  • Tracks: HeartThis track downloads
  • Features:
    • Direct audio extraction
    • Metadata preservation

Shazam

  • 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

πŸ—οΈ Architecture

Core Components

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

Service Architecture

# 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

πŸ”§ API Integration

Spotify API (Undocumented)

# 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 API (Undocumented)

# 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 API

# 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 API (Undocumented)

# 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 None

πŸ“Š Database Schema

Users Table

CREATE 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
);

Downloads Table

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)
);

πŸš€ Deployment

Docker Deployment

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"]

Docker Compose

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

Heroku Deployment

# 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

πŸ§ͺ Testing

Running Tests

# 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/

Test Structure

# 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

πŸ“ˆ Performance Optimization

Caching Strategy

# 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

# 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 True

πŸ”’ Security Considerations

Input Validation

import 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 False

File Size Limits

async 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

🀝 Contributing

Development Setup

# 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

Code Style

# Format code
black bot/
isort bot/

# Lint code
flake8 bot/
mypy bot/

Pull Request Process

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

πŸ“ž Support

⚠️ Disclaimer

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

About

Spotify & youtube music downloader

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages