db123 6bbc87a7c8
All checks were successful
CI / build (push) Successful in 35s
fix: prevent context cancellation from blocking file delivery on cancel race
When a download completes but the user clicks Cancel at the same time,
handleDownloadCompletion's Telegram calls used the cancelled download
context and failed. Use context.Background() for all notification calls
so the file is always delivered regardless of download state.
2026-06-26 13:01:25 +03:30

uptodownbot

Telegram bot for downloading media from any site yt-dlp supports.

Features

  • Download audio, video, or combined audio+video from YouTube, Spotify, SoundCloud, Vimeo, and hundreds more
  • Search support: search YouTube/YouTube Music by name when no URL is provided
  • DRM fallback: automatically searches YouTube when Spotify/DRM-protected content is detected
  • Thumbnail preview with metadata (title, uploader, duration) before download
  • Audio-only sites (Spotify, SoundCloud, YouTube Music, etc.) auto-detect and skip to audio quality selection
  • Multi-step format selection: quality, secondary format (audio/video combine), language
  • Download progress updates (with speed and ETA)
  • Cancel downloads at any time (terminates yt-dlp process)
  • Per-user quota system (daily, weekly, monthly; 0 = unlimited)
  • User preferences (default audio/video quality, language)
  • Download history with pagination
  • Configurable file size limit (default 50 MB)
  • Cookies support for age-restricted content
  • Proxy support via HTTP_PROXY/HTTPS_PROXY env vars
  • Webhook and polling modes
  • SQLite database for persistence
  • yt-dlp plugin support — hanime-plugin bundled in Docker image

Commands

  • /start - Show main menu
  • /download - Prompt for a download URL
  • /settings - Open settings
  • /help - Show help text
  • /history - View download history

You can also send a URL directly to start downloading immediately.

Configuration

Copy .env.example to .env and configure:

Variable Default Description
BOT_TOKEN (required) Telegram Bot API token
HTTP_PROXY empty Outbound HTTP proxy
HTTPS_PROXY empty Outbound HTTPS proxy
DB_PATH data/uptodown.db SQLite database path
DOWNLOAD_DIR /tmp/uptodown Temporary download directory
MAX_FILE_SIZE_MB 50 Maximum upload file size in MB
COOKIES_FILE empty Path to cookies.txt for auth
TZ UTC Timezone
BOT_ALLOWED_USERS empty Comma-separated allowed user IDs
BOT_WEBHOOK_URL empty Webhook URL (omit for polling)
BOT_LISTEN :8080 Webhook listen address
BOT_TLS_CERT empty TLS certificate path
BOT_TLS_KEY empty TLS key path

Running

Polling mode (default)

cp .env.example .env
# edit .env with your BOT_TOKEN
make run-dev

Webhook mode

export BOT_WEBHOOK_URL=https://your.domain.com/webhook
make run-dev

Docker

make docker-run

The Docker image bundles the hanime-plugin and the Deno JS runtime for sites like hanime.tv, hstream.moe, and hentaihaven.com. See yt-dlp plugins for details.

Local (non-Docker)

If running outside Docker, the bot uses whatever yt-dlp is in your PATH. Install plugins and a JS runtime as described below under yt-dlp plugins.

yt-dlp plugins

Some sites require yt-dlp plugins or a JavaScript runtime to work. The Docker image bundles these automatically; for local installs you need to set them up manually.

hanime-plugin

Adds support for hanime.tv, hstream.moe, hentaihaven.com and others.

pip install hanime-plugin

The plugin requires a JavaScript runtime. Deno is recommended:

# Linux/macOS
curl -fsSL https://deno.land/install.sh | sh

# Add to your shell config:
export PATH="$HOME/.deno/bin:$PATH"

Adding other plugins

yt-dlp plugins are Python packages installed via pip. Most work without additional runtimes. Install any pip-installable yt-dlp plugin with:

pip install <plugin-name>

Development

make build      # build binary
make test       # run tests
make fmt        # format code
make vet        # vet code
make check      # fmt + vet
Description
No description provided
Readme 493 KiB
Languages
Go 99%
Dockerfile 0.7%
Makefile 0.3%