Skip to content

Repository files navigation

Telegram yt-dlp Bot

Private, whitelist-only Telegram bot for downloading media with yt-dlp, optional timestamp clipping with ffmpeg, and SQLite-backed access control.

This project is designed for responsible use. It does not include cookies, login automation, DRM tooling, paywall bypasses, or platform-protection evasion. Only download media you have the right to download and share.

Features

  • aiogram 3.x async Telegram bot.
  • Whitelist-only mode enabled by default.
  • Admin dashboard commands for status, queue, storage, users, failed jobs, cleanup, and whitelist management.
  • SQLite whitelist repository behind a service abstraction that can later be replaced by PostgreSQL.
  • yt-dlp metadata extraction without downloading before showing options.
  • Practical grouped quality choices: best, best under limit, common resolutions, and audio-only M4A/MP3.
  • Timestamp clipping after download with ffmpeg, including first/last shortcuts and multiple ranges.
  • Progress status updates by editing one Telegram message during metadata, queueing, download, clipping, upload, completion, failure, and cleanup.
  • SQLite-backed cache for metadata, processed files, and Telegram file_id reuse.
  • Per-user cooldown, concurrent job limit, /cancel, temp directory cleanup, and filename sanitization.
  • Tests for timestamp parsing, format grouping, and whitelist behavior without Telegram/network/downloads.

Requirements

  • Python 3.12+
  • ffmpeg available on PATH
  • A Telegram bot token from BotFather
  • uv recommended, but standard pip also works

Local Setup

cd /root/telegram-ytdlp-bot
cp .env.example .env

Edit .env:

BOT_TOKEN=123456:your-token
ADMIN_IDS=123456789
WHITELIST_IDS=123456789
WHITELIST_ONLY=true

Install and run:

uv sync --extra dev
uv run python -m app.bot

With pip:

python -m venv .venv
. .venv/bin/activate
pip install -e ".[dev]"
python -m app.bot

Docker

cd /root/telegram-ytdlp-bot
cp .env.example .env
# edit .env
docker compose up --build -d

The compose file persists SQLite data in ./data, temporary downloads in ./downloads, and reusable processed-file cache in ./cache.

Usage

  1. Send the bot a supported http:// or https:// video URL.
  2. The bot extracts metadata and displays title, duration, uploader, thumbnail when available, and grouped download choices.
  3. Choose a quality option.
  4. Choose full video, a shortcut, or custom timestamp ranges.
  5. Confirm the final selection before processing starts.
  6. For custom ranges, send examples like:
00:01:20-00:03:45
1:20-3:45
80-225
1:20-
-3:45
first 60s
last 30s
00:10-00:30, 01:00-01:45

Multiple ranges are rendered as temporary normalized clips and merged into one final output with ffmpeg concat. Single ranges keep the faster stream-copy clipping path.

Commands

The bot registers its command menu with Telegram automatically on startup using the Bot API. Regular users see the safe user commands. Configured admins get a private-chat scoped command menu with admin commands when Telegram can resolve their chat ID.

User commands:

  • /start or /help - usage help.
  • /ping - measure Telegram Bot API response latency.
  • /cancel - cancels an active job when possible and clears pending selections.

Admin commands:

  • /admin - dashboard-style admin menu.
  • /status - job counters.
  • /queue - active queued/running jobs.
  • /jobs - recent jobs.
  • /failed_jobs - recent failed jobs.
  • /storage - disk/cache usage.
  • /cleanup - remove old temporary files.
  • /users - list whitelisted user count and IDs.
  • /whitelist_add <user_id> - add a user.
  • /whitelist_remove <user_id> - remove a user. Admins remain effectively allowed.
  • /whitelist_list - list persisted whitelist IDs.

Admin commands are restricted to ADMIN_IDS.

Telegram Limits

MAX_UPLOAD_BYTES defaults to about 49 MiB to stay conservative for bot uploads. If a processed result is larger, the bot refuses to upload it and asks the user to choose a lower quality or shorter timestamp range.

MAX_DOWNLOAD_BYTES is a separate guardrail for downloaded source media before clipping.

Configuration

All runtime configuration comes from environment variables or .env.

Variable Default Notes
BOT_TOKEN empty Required to run the bot
ADMIN_IDS empty Comma-separated Telegram user IDs
WHITELIST_IDS empty Comma-separated initial whitelist IDs persisted at startup
WHITELIST_ONLY true Private mode by default
DATABASE_PATH data/bot.sqlite3 SQLite database path
DOWNLOADS_DIR downloads Temporary job directories
CACHE_DIR cache Processed media cache directory
CACHE_ENABLED true Enables metadata/media/file_id cache
CACHE_TTL_HOURS 24 Cache entry lifetime
MAX_CACHE_SIZE_MB 5000 Local cache size cap
CLEANUP_ON_STARTUP true Cleanup temp/cache on bot startup
MAX_UPLOAD_BYTES 51380224 Upload limit guardrail
MAX_DOWNLOAD_BYTES 262144000 yt-dlp download guardrail
YTDLP_PROXY empty Optional HTTP proxy used for all yt-dlp operations; keep this value secret
CLEANUP_MAX_AGE_SECONDS 21600 Cleanup threshold
CONCURRENT_JOBS 2 Global worker limit
PER_USER_COOLDOWN_SECONDS 30 Simple per-user rate limit
DEFAULT_AUDIO_FORMAT m4a Reserved default for audio workflows; both M4A and MP3 buttons are shown
LOG_LEVEL INFO Python logging level

Development

Run tests:

uv run pytest

Recommended checks:

uv run ruff format .
uv run ruff check .
uv run mypy app

Tests intentionally avoid Telegram tokens, network calls, and actual video downloads.

Assumptions

  • The bot is intended primarily for private chats.
  • File-size estimates depend on metadata supplied by extractors and may be missing or approximate.
  • Single timestamp clipping uses stream copy for speed. Multiple ranges are normalized into temporary segment clips before concatenation for more reliable merging.
  • PostgreSQL can be added later by implementing the WhitelistRepository protocol and wiring it in app/bot.py.

Releases

Packages

Contributors

Languages