penguinpowernz/ytdlbot

★ 0Forks 0GoGitHub ↗Compare

README

ytdlbot

A personal Telegram bot that accepts YouTube URLs in a private chat, downloads the best video+audio format that fits under 12 MB, and sends the file back to you — all without leaving Telegram.

The bot is designed for a single user. It ignores every message that does not come from your configured Telegram user ID.


How it works

  1. Send a YouTube URL to your bot in Telegram.
  2. The bot fetches video metadata, picks the best format under the size limit, and queues the download.
  3. It reports progress as it goes ("Downloading… 480p, ~8.1 MB", "Uploading…").
  4. The finished video lands in your chat.

Multiple URLs are queued and processed one at a time so the server is never overwhelmed.


Prerequisites

Requirement Notes
A Linux server (Debian/Ubuntu recommended) Needs to be online to receive Telegram updates
ffmpeg Used to mux separate video/audio streams into a single .mp4
A Telegram account To create the bot and find your user ID
Go 1.22+ Only needed if building from source

yt-dlp does not need to be installed manually — the bot downloads it automatically on first run.


Step 1 — Create a Telegram bot

  1. Open Telegram and start a chat with @BotFather.

  2. Send /newbot.

  3. Choose a display name (e.g. My Download Bot) and a username ending in bot (e.g. mydownload_bot).

  4. BotFather replies with a token that looks like:

    5555555555:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    

    Keep this token secret. Anyone who has it can control your bot.

  5. Optionally send /setprivacy → select your bot → Disable so the bot can read messages in groups if you ever need that. For a private bot the default (enabled) is fine.


Step 2 — Find your Telegram user ID

The bot only responds to one user. You need your numeric user ID (not your username).

  1. Start a chat with @userinfobot and send any message.
  2. It replies with your ID, e.g. Id: 123456789.
  3. Note this number — you will put it in the config as allowed_user_id.

Step 3 — Install

Option A: Debian package (recommended)

# Install build dependencies
sudo apt-get install golang ffmpeg dpkg-dev debhelper

# Clone and build
git clone https://github.com/penguinpowernz/ytdlbot
cd ytdlbot
make deb

# Install the package (adjust filename for your arch/version)
sudo dpkg -i ../ytdlbot_1.0.0-1_amd64.deb
sudo apt-get install -f   # installs ffmpeg if not already present

The package creates a ytdlbot system user, installs the binary to /usr/bin/ytdlbot, and places a template config at /etc/ytdlbot/config.yaml.

Option B: Build and run manually

sudo apt-get install golang ffmpeg

git clone https://github.com/penguinpowernz/ytdlbot
cd ytdlbot
make build          # produces ./bin/ytdlbot

# Create directories
sudo mkdir -p /var/lib/ytdlbot/bin /etc/ytdlbot

# Copy the example config
sudo cp config.example.yaml /etc/ytdlbot/config.yaml
sudo chmod 600 /etc/ytdlbot/config.yaml

Step 4 — Configure

Edit /etc/ytdlbot/config.yaml:

bot_token: "5555555555:AAFxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
allowed_user_id: 123456789

work_dir: /var/lib/ytdlbot
yt_dlp_path: /var/lib/ytdlbot/bin/yt-dlp
ffmpeg_path: /usr/bin/ffmpeg

max_file_bytes: 12582912       # 12 MB — Telegram Bot API hard limit
max_duration_seconds: 300      # reject videos longer than 5 minutes
disk_warn_bytes: 524288000     # warn in chat when < 500 MB free on disk
queue_depth: 20                # max number of jobs waiting at once
  • Set bot_token to the token from BotFather.
  • Set allowed_user_id to the number from Step 2.
  • Leave everything else at the defaults unless you have a reason to change it.

The config file contains your bot token, so permissions matter:

sudo chmod 600 /etc/ytdlbot/config.yaml
sudo chown ytdlbot:ytdlbot /etc/ytdlbot/config.yaml   # if using the package

Step 5 — Start the bot

With systemd (package install)

sudo systemctl enable --now ytdlbot
sudo systemctl status ytdlbot

The service starts automatically on boot and restarts itself if it crashes.

Manually (binary install)

./bin/ytdlbot -c /etc/ytdlbot/config.yaml

First-run behaviour

On the very first start, if yt-dlp is not present at yt_dlp_path, the bot downloads it automatically from the official GitHub releases before accepting any URLs. You will see log output like:

{"level":"INFO","msg":"yt-dlp not found, attempting bootstrap","path":"/var/lib/ytdlbot/bin/yt-dlp"}
{"level":"INFO","msg":"yt-dlp bootstrapped successfully","path":"/var/lib/ytdlbot/bin/yt-dlp"}

If the download fails (e.g. no internet at startup), the bot still starts but disables URL handling and sends you a Telegram message explaining the problem. Run /updateytdlp to retry.


Step 6 — Test it

  1. Open Telegram and find the bot you created in Step 1 (search for its username).
  2. Send /start — the bot should reply with a welcome message.
  3. Send a short YouTube URL. The bot will reply "✅ Queued. Position: 1" and then send progress updates as it downloads and uploads the video.

If the bot does not reply to /start, check the logs:

sudo journalctl -fu ytdlbot

Bot commands

Command What it does
/start Welcome message with usage instructions
/help List all commands
/queue Show what is currently downloading and what is waiting
/cancel Cancel the last queued job that has not started yet
/updateytdlp Download or update yt-dlp to the latest release

Updating yt-dlp

YouTube changes its format regularly and yt-dlp releases updates to keep up. Send /updateytdlp in chat at any time — the bot will download the latest release and report the result. No restart needed.


Logs

# Follow live logs (systemd)
sudo journalctl -fu ytdlbot

# Show the last 100 lines
sudo journalctl -u ytdlbot -n 100

Logs are JSON (structured), which makes them easy to search:

sudo journalctl -u ytdlbot | grep '"level":"WARN"'

Troubleshooting

Bot does not reply at all

  • Confirm the bot_token in the config is correct.
  • Check that the server can reach api.telegram.org (firewall / DNS).
  • Check logs: sudo journalctl -fu ytdlbot.

"unauthorized user" in logs but it is you sending the message

  • Your allowed_user_id is wrong. Double-check it with @userinfobot — it must be a number, not a username.

"yt-dlp or ffmpeg is missing" message in chat

  • ffmpeg: sudo apt-get install ffmpeg, then restart the bot.
  • yt-dlp: send /updateytdlp and the bot will download it. If that fails, check that work_dir is writable by the ytdlbot user.

"Queue is full"

  • Lower queue_depth is not the issue — the queue is simply at capacity. Wait for current downloads to finish. The default of 20 is generous for a personal bot.

Video is too large

  • The bot tries every available format from largest to smallest until one fits under max_file_bytes. If the smallest format still exceeds the limit, it reports the actual size. You can raise max_file_bytes but Telegram's Bot API hard limit is 50 MB for uploads; the default 12 MB matches Telegram's client-side sending limit for most clients.

Development

make build    # compile binary to ./bin/ytdlbot
make test     # run unit tests
make vet      # run go vet
make lint     # run go vet + staticcheck
make deb      # build installable .deb package
make clean    # remove ./bin/

Running the integration test

Requires a real bot token and Telegram account:

YTDLBOT_TOKEN=<token> \
YTDLBOT_USER_ID=<your_user_id> \
YTDLBOT_CHAT_ID=<chat_id> \
./scripts/integration_test.sh

The script starts the bot, sends a short public-domain video URL, and asserts that a video message is received back within 120 seconds.

Contributors

penguinpowernz

Issues