A powerful Telegram bot that downloads YouTube videos and audio with multiple quality options, built with Python, yt-dlp, and Pyrogram.
๐ง Pyrogram-based: This bot uses Telegram's User API (via Pyrogram) instead of the Bot API to bypass the strict 50MB file size limit, allowing downloads up to 2GB.
- Multiple Quality Options: Choose from available video resolutions (144p to 4K+)
- Format Support: Automatic MP4 conversion with audio merging
- Progress Tracking: Real-time download and upload progress bars
- MP3 Extraction: High-quality MP3 audio extraction
- Metadata Integration: Automatic ID3 tags with title, artist, and album art
- Thumbnail Support: Downloads and embeds video thumbnails as album art
- Optional User Whitelist: Toggleable user authorization (disabled by default)
- Large File Support: Up to 2GB file uploads (vs 50MB limit for regular bots)
- Error Handling: Comprehensive error handling with user-friendly messages
- Async Processing: Non-blocking downloads with threading
- FFmpeg Integration: Automatic FFmpeg detection for video processing
- Session Isolation: Uses dedicated incognito cookies to prevent behavioral conflicts
- Clean Downloads: Automatic cleanup of temporary files
- Python 3.7+
- FFmpeg
- Deno (required for YouTube JavaScript challenge solving)
pyrogram # User API client for large file uploads (up to 2GB)
tgcrypto # Cryptography speedup for Pyrogram
yt-dlp # YouTube video downloader
yt-dlp-ejs # JavaScript challenge solver for yt-dlp
mutagen # Audio metadata handling
requests # HTTP requests for thumbnails
python-dotenv # Environment variable management
Download ZIP or Git clone the repo:
- ZIP Download: https://github.com/LeeseTheFox/YouTubeBot โ Code โ Download ZIP
- Git Clone:
git clone https://github.com/LeeseTheFox/YouTubeBot.git
# Install the latest nightly version of yt-dlp (recommended)
pip install --upgrade --pre yt-dlp
# Install other dependencies
pip install -r requirements.txtUbuntu/Debian:
sudo apt update
sudo apt install ffmpegmacOS:
brew install ffmpegWindows: Download from ffmpeg.org and add to PATH.
Linux/macOS:
curl -fsSL https://deno.land/install.sh | shThen add Deno to your PATH by adding these lines to your ~/.bashrc or ~/.zshrc:
export DENO_INSTALL="$HOME/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"Reload your shell:
source ~/.bashrc # or source ~/.zshrcWindows:
irm https://deno.land/install.ps1 | iexVerify installation:
deno --versionWhy both bot token and API credentials? This bot uses Pyrogram (Telegram User API) instead of the standard Bot API to bypass the 50MB file size limit. Regular bots can only send files up to 50MB, but User API allows up to 2GB uploads.
-
Create a bot:
- Message @BotFather on Telegram
- Use
/newbotcommand - Follow the prompts to get your bot token
-
Get user API credentials (required for large files):
- Visit my.telegram.org
- Log in with your Telegram account
- Go to "API Development Tools"
- Create a new application to get
api_idandapi_hash - These credentials allow the bot to upload files up to 2GB
Create a .env file in the project root (you can copy from .env.example):
cp .env.example .envThen edit .env with your values:
# Telegram Bot Configuration
API_ID=your_api_id_here
API_HASH=your_api_hash_here
BOT_TOKEN=your_bot_token_here
# User Access Control
WHITELIST_ENABLED=false
WHITELIST=123456789,987654321
# File Paths
COOKIES_PATH=cookies.txtBy default, the bot is open to all users. To restrict access:
- Enable the whitelist by setting
WHITELIST_ENABLED=truein.env - Find user IDs by messaging @userinfobot
- Add authorized user IDs to the
WHITELISTin.env(comma-separated) - this is used only for initial seeding on first run - After first run, the whitelist is stored in
data/whitelist.jsonand persists across restarts
Important: The WHITELIST environment variable is only used to seed the whitelist on the first run. After that, the bot reads from data/whitelist.json. To add or remove users after first run, edit data/whitelist.json directly or use admin commands (if implemented).
YouTube analyzes session behavior patterns to detect automation. When you use cookies from your regular browsing session in the bot while simultaneously browsing YouTube in your browser, it creates conflicting behavioral signatures that trigger bot detection systems. Follow these steps:
- Open YouTube in incognito/private mode and log into your account
- Install the cookies.txt browser extension
- Navigate to any YouTube video in the incognito tab
- Export cookies using the extension - save as
cookies.txtin the project directory
Why incognito is required:
- Prevents session behavior conflicts between browser and bot usage
- Isolates automated requests from human browsing patterns
- Avoids triggering YouTube's session analysis algorithms that detect mixed usage patterns
- Using shared sessions will cause the bot to fail when you browse YouTube normally
python main.py-
Start the bot:
/start -
Send a YouTube URL:
- Paste any supported YouTube URL
- The bot will analyze and show available qualities
-
Choose quality:
- Click on your preferred video quality
- Or click "๐ต Download MP3" for audio only
-
Download:
- The bot will download and send your file
- Progress is shown in real-time
https://www.youtube.com/watch?v=VIDEO_ID
https://youtu.be/VIDEO_ID
https://www.youtube.com/shorts/VIDEO_ID
https://music.youtube.com/watch?v=VIDEO_ID
https://www.youtube.com/embed/VIDEO_ID
Important: Mount the data/ directory as a persistent volume to preserve runtime state (whitelist, session, cookies) across container restarts.
docker build -t youtube-bot .
docker run -d \
--name youtube-bot \
--restart unless-stopped \
-v $(pwd)/data:/app/data \
-e API_ID=your_api_id \
-e API_HASH=your_api_hash \
-e BOT_TOKEN=your_bot_token \
-e WHITELIST_ENABLED=false \
-e COOKIES_PATH=data/cookies.txt \
youtube-botversion: '3.8'
services:
youtube-bot:
build: .
restart: unless-stopped
volumes:
- ./data:/app/data
environment:
- API_ID=${API_ID}
- API_HASH=${API_HASH}
- BOT_TOKEN=${BOT_TOKEN}
- WHITELIST_ENABLED=${WHITELIST_ENABLED:-false}
- COOKIES_PATH=data/cookies.txtNote: The WHITELIST env var is only used on first run to seed data/whitelist.json. After that, edit the JSON file directly.
Public mode (default)
- Anyone can use the bot
- No user restrictions
- Set
WHITELIST_ENABLED=falsein.env
Private mode (whitelist)
- Only authorized users can use the bot
- Set
WHITELIST_ENABLED=truein.env - Whitelist is stored in
data/whitelist.json(persists across restarts) - Unauthorized users are silently ignored
-
Set whitelist enabled:
WHITELIST_ENABLED=true
-
Add authorized users (initial seed only):
WHITELIST=123456789,987654321,555666777
Note: This environment variable is only used to seed the whitelist on the first run. After that, the bot uses
data/whitelist.json. -
Start the bot - it will create
data/whitelist.jsonwith the users from the env var
After the initial setup, the whitelist is stored in data/whitelist.json. To add or remove users:
Option 1: Edit the JSON file directly
The file has this structure:
{
"user_ids": [123456789, 987654321, 555666777],
"version": 1
}Simply add or remove user IDs from the user_ids array and restart the bot.
Option 2: Delete and reseed (not recommended for production)
If you want to completely reset the whitelist:
- Stop the bot
- Delete
data/whitelist.json - Update the
WHITELISTenv var with new user IDs - Start the bot - it will recreate the file from the env var
Important for Docker/Kubernetes deployments: The data/ directory must be mounted as a persistent volume. Otherwise, whitelist.json will be lost on container restart, and the bot will reseed from the env var each time.
When the bot starts, it will display the current access mode:
- Public mode:
๐ Public mode: Bot is open to all users - Private mode:
๐ Whitelist enabled: X authorized users
YouTubeBot/
โโโ main.py # Main bot application
โโโ runtime_state.py # Runtime state management (whitelist persistence)
โโโ .env # Environment configuration (static config only)
โโโ requirements.txt # Python dependencies
โโโ data/ # Persistent data directory (mount as volume in Docker)
โ โโโ whitelist.json # User whitelist (runtime-mutable state)
โ โโโ cookies.txt # Incognito browser cookies (critical for reliability)
โ โโโ youtube_quality_bot.session # Telegram session file
โโโ downloads/ # Temporary download directory
โโโ README.md # This file
Important: The data/ directory contains runtime-mutable state and should be mounted as a persistent volume in containerized deployments. This ensures that the whitelist, session, and cookies persist across container restarts.
| Variable | Description | Example |
|---|---|---|
API_ID |
Telegram User API ID (enables 2GB uploads) | 12345678 |
API_HASH |
Telegram User API Hash (enables 2GB uploads) | abcdef123456... |
BOT_TOKEN |
Bot token from BotFather | 123456:ABC-DEF... |
WHITELIST_ENABLED |
Enable user whitelist (true/false) | false |
WHITELIST |
Initial seed for authorized user IDs (first run only, then stored in data/whitelist.json) |
123456789,987654321 |
COOKIES_PATH |
Path to incognito cookies file | data/cookies.txt |
-
"FFmpeg not found"
- Install FFmpeg and ensure it's in your PATH
- The bot will show a warning but continue working
-
"Bot is not responding"
- Check your bot token in
.env - Verify
API_IDandAPI_HASHare correctly set (required for Pyrogram) - Ensure the bot is started with BotFather
- Check your bot token in
-
"User not authorized"
- Check if
WHITELIST_ENABLED=truein.env - If whitelist is enabled, check
data/whitelist.jsonto see if your user ID is in the list - To add your user ID:
- If first run: Add it to the
WHITELISTenv var in.envbefore starting the bot - After first run: Edit
data/whitelist.jsondirectly and add your user ID to theuser_idsarray
- If first run: Add it to the
- Restart the bot after making changes to
data/whitelist.json
- Check if
-
Videos fail to download / "Sign in to confirm you're not a bot"
- Most common cause: Missing Deno or yt-dlp-ejs package
- Solution:
- Install Deno:
curl -fsSL https://deno.land/install.sh | sh - Install yt-dlp-ejs:
pip install yt-dlp-ejs - Ensure Deno is in your PATH
- Install Deno:
- Alternative cause: Session behavior conflict from using shared cookies
- Solution: Re-export cookies from an incognito tab using cookies.txt
- Ensure
cookies.txtfile exists in the project directory
-
Age-restricted videos fail
- Ensure you're logged into YouTube in the incognito tab before exporting cookies
- Re-export cookies from an incognito session
-
Bot works initially but stops after a few hours/days
- Cause: Session behavior analysis detected conflicting usage patterns or Deno/yt-dlp-ejs missing
- Solution:
- Verify Deno is installed and in PATH:
deno --version - Verify yt-dlp-ejs is installed:
pip list | grep yt-dlp-ejs - Use dedicated incognito cookies and avoid browsing YouTube with the same session
- Verify Deno is installed and in PATH:
- Keep your
.envfile secure - it contains sensitive API credentials - Consider enabling whitelist - for public instances, restrict access to trusted users
- Monitor usage - the bot can download large files that consume bandwidth
- Regular updates - keep yt-dlp updated for best compatibility
- Cookie security - protect your
cookies.txtfile as it contains login session data