Back to Writing
BotsOctober 23, 2026 · 4 min read

Building Dupload: A Telegram Media Pipeline

A source-grounded walkthrough of Dupload's queueing, yt-dlp downloads, FFmpeg processing, progress updates, cancellation, and Telegram Bot API delivery.

Building Dupload: A Telegram Media Pipeline cover

Dupload began with a simple interaction: send a supported media URL to a Telegram bot and receive the downloaded file. The hard part was making the full path behave sensibly when downloads are slow, formats differ, files are too large, or several requests arrive together.

This walkthrough reflects the current public repository, not a claim that every possible platform or file succeeds. The source code and setup notes are available on GitHub.

The pipeline

The current implementation separates Telegram handling from media retrieval and processing:

  1. The bot recognizes supported URLs and accepts options such as resolution, audio extraction, or a requested clip.
  2. yt-dlp retrieves the media.
  3. The downloader checks the result and uses FFmpeg tools when processing is needed.
  4. The bot sends the resulting file through the configured local Telegram Bot API endpoint.
  5. Temporary files are cleaned up after the job.

This division makes failures easier to locate. A successful download does not guarantee that a file can be processed or uploaded, so the application handles these stages separately.

Queueing work instead of starting everything at once

The bot maintains a queue per chat and uses a shared semaphore to cap concurrent work. The current source sets a maximum of five queued jobs per chat, thirty queued jobs globally, and three active jobs globally.

These are application-level limits, not a claim of unlimited scale. They are intended to prevent bursts of requests from immediately starting an unbounded number of download processes.

The /queue command exposes queue state, while /stop supports cancellation. Jobs keep a cancellation flag and a reference to the active child process so the bot can stop ongoing work and clear waiting jobs. Cancellation still needs careful cleanup because a process may finish or create a file while a cancellation request is being handled.

Progress and failure handling

The downloader reads yt-dlp progress output and reports updates to the user. The bot also retries Telegram upload attempts with increasing delays. A 413 or “Request Entity Too Large” response is treated differently because retrying the same oversized file will not solve a size limit.

This is a useful distinction: transient connection failures may justify retries, while permanent input or size errors usually need a different response.

Media processing is its own stage

The downloader supports resolution selection and audio-only extraction. FFmpeg is used for operations such as compression and clip creation. The code also checks for a missing audio stream in certain TikTok downloads and has a repair path that obtains a separate audio source and muxes it with the video.

That behavior is platform-specific handling, not a guarantee that every TikTok URL will work. yt-dlp and external platforms change, and a downloader must report unsupported or inaccessible media rather than promise universal coverage.

Delivery and deployment assumptions

Dupload is configured to use a local Telegram Bot API endpoint through LOCAL_API_URL. The README documents a self-hosted Bot API server for files larger than the public API's usual limit. The larger-file capability therefore depends on that deployment setup; it is not provided by the bot code alone.

The project also includes per-user hourly rate limiting, admin commands, temporary-file cleanup, and environment-based configuration. Tokens and credentials belong in the environment, not in committed source.

What I learned

A media bot is a small pipeline system, not just a wrapper around a downloader. Each boundary has its own failure modes: URL handling, external extraction, local processing, queue coordination, upload delivery, and cleanup.

The useful engineering lesson is to make those stages explicit, limit concurrent work, treat retries as a targeted recovery strategy, and avoid claiming reliability beyond the cases actually exercised.

Dupload is an evolving project. Its repository is the best source for current behavior, setup requirements, and known limitations.