Telegram bot for downloading videos ·
One step instead of a downloader website
Five social media platforms hand over video in five different ways, and nearly every one of them trips over Telegram. Inside the bot, all of that is sorted out; on the outside, it’s a link sent to the chat and a finished file back, up to a gigabyte and a half.

The task
Video has to be pulled out of social media regularly, and almost always on someone else’s terms. Your own clip that now exists only in the feed. A reference that will be deleted tomorrow. Material that needs to move from Instagram into your work. Social media platforms either have no “download” button at all, or it gives you a file with a logo over the picture.
The usual route is downloader websites, and it looks the same every time: full-screen ads, a couple of redirects, quality worse than the original, and the service’s own watermark. And after that, the file still has to get to your phone.
The bot removes that route entirely. The link goes where the person already is, the messenger, and what comes back is a file that can be forwarded, saved, or dropped into an edit right away. For people who work with content every day (social media marketing, video editing, stores), what this saves is not minutes but the switching itself: there is no need to leave the messenger and come back.
The project started as a tool for one specific task, so nothing in it is there “to grow into”: only what gets used. The paid subscription inside is not for show but a working part: the bot counts downloads, tells free users from paying ones, sells the subscription in Telegram Stars by itself, and is run from the admin panel.
What it delivered
A link from any of five social media platforms turns into a finished file right in the chat: no websites with ads and no third-party logo over the picture. Not just short clips: videos up to a gigabyte and a half, in the best quality that fits within that. Inside are a free limit, a subscription paid right in Telegram, and a queue. This is not a one-evening script but a product that takes payment by itself and renews it by itself.
Where bots like this usually break
A ready-made open-source tool can download a video, and up to that point the work takes an evening. After that comes everything that most often gets bots like this abandoned halfway.
The video arrived, but there is no picture
Facebook often serves the video track in a codec that Telegram’s player does not show: the sound plays, the screen is black. To a person this looks like “the bot is broken,” even though the file downloaded intact.
Sound only instead of video
On TikTok and YouTube, the set of tracks changes on its own. A naive “take the best” regularly brings back either audio with no picture or 240p instead of real HD.
Fifty megabytes for everything
An ordinary bot in Telegram cannot send a file larger than fifty megabytes. That is enough for a short clip but not for a long video in good quality: it either does not arrive at all or arrives blurry.
A big file, then silence
A gigabyte takes minutes to download and to go out to Telegram. If the bot says nothing that whole time, the person decides it has frozen: they send the link again, press buttons, or just leave.
Half of a carousel arrives
Telegram accepts an album of only two to ten items and does not allow mixing images with files in it. A post of twelve photos, one of which weighs more than ten megabytes, falls apart out of nowhere.
The platform is in a bad mood today
A captcha, a lost login, geo and age restrictions, a request limit. All of this is temporary and gets fixed in different ways, but the user should not see red text with file names because of it.
The second person gets in the way of the first
While one person is downloading a long video, a second sends their own link, and a third presses a button ten times in a row. If this is not managed, memory runs out, the database locks up, and the bot stops answering everyone at once, including the person whose download was almost finished.
None of this shows in a demo: there, it’s a link and a video. But this is exactly what separates a bot people use every day from a script that “mostly downloads.”
What I did
One step and no instructions
A person sends a link, and the bot sends back a file. Nothing else needs to be done: no choosing a platform, no setting the quality, no trimming extras off the link.
A link is recognized in whatever form people send it: the short addresses from
the “Share” button (vm.tiktok.com, fb.watch, pin.it, youtu.be),
regional Pinterest addresses, a link without https://, and even a link in the
caption of a photo or video. These are exactly the links people usually send,
and the ones such bots usually trip over.
Five platforms and what is taken from each: Reels, videos, carousels, and single photos from Instagram; videos and photo slideshows from TikTok; videos from Facebook; images and whole boards from Pinterest; videos from YouTube.

Each platform gets its own recipe
This is the main invisible part of the work. Each of the five social media platforms has its own order of preference: which format to take first, what to switch to if it is missing, and what to reject no matter what.
For Facebook, first comes the codec that Telegram shows on every device, and the bot goes through four ways of getting it before settling for the trendy new one, precisely so that “sound with no picture” does not arrive. For YouTube, the bot takes the highest resolution the video has, even 4K, if the file fits within the limit, and steps down a level by itself if it does not; the size is estimated in advance, so that the bot does not download something it could not send anyway. Up to 1080p, the bot takes the most compatible format where it can; above that, YouTube stores videos only in newer compression formats, and the bot takes those: here the choice is quality, not compatibility with old phones. Audio for long videos is picked separately, so that an hour-long video does not fail because of a single track. For TikTok, the version without a watermark is taken first, and the watermarked copy is kept for the very last resort: better with a mark than nothing. For Instagram, the higher resolution that the platform hides in separate tracks is pulled out separately.
These sound like small things, but it is exactly these small things that add up to the difference between “it downloaded” and “it downloaded in a form you can watch.”
Where one tool gives up, a second takes over
The main downloader works very well with video and cannot handle Pinterest boards, mixed Instagram carousels, or TikTok photo slideshows at all: on those, it either returns nothing or silently loses half the images.
For these three cases, the bot goes straight to a different tool, and if that one brings nothing back either, it returns to the first. The person knows nothing about this fork: they simply get their album in full.

Videos up to a gigabyte and a half
An ordinary bot runs into a ceiling of fifty megabytes: Telegram does not accept more than that from bots. So the bot has its own Telegram server running next to it on the same machine: the official open-source software from Telegram itself, made for exactly such cases. Files of up to a gigabyte and a half go out through it.
The ceiling could have been two gigabytes, but the bot’s own Telegram server drops the connection if there is no response for a little over eight minutes. At the speed of a home connection, two gigabytes go out almost right up against that limit, and if the upload outlasts it, the bot will never find out whether the file arrived. A gigabyte and a half goes out with room to spare.
Big files bring their own failures, and those are handled in advance. If Telegram drops the connection after a long upload, the file has most likely already gone through: the bot does not send it a second time but says that Telegram is still processing the file and that it will most likely appear in the chat within the next few minutes. Otherwise the person would get two identical videos. If YouTube fails to hand over a piece of the video, the bot does not stitch together a video with a hole in it; it says honestly that the download failed and does not count that download. A file that still comes out larger than the limit is not sent: the bot says how big it turned out and suggests a shorter video.
Downloads go to a separate external drive. If it dropped out, the files would go to the small system drive, and a one-gigabyte video would bring down the whole server along with the database. So before every download, the bot checks that there is enough space, and if there is not, it asks the person to try again in a few minutes and does not deduct the attempt.
You can see how much is left
A gigabyte takes minutes to download and send, so the bot does not stay quiet. The status lives in a single message and updates as the work goes on.
Before the download starts, you can see what quality and size the video will arrive in. If it is not the maximum, the bot explains why: in 4K the video weighs more than can be sent, so the best that fits will arrive, for example 1080p.
During the download, there is a progress bar with a percentage and the time remaining. When the video is being joined with the audio, the status says so. While sending to Telegram, there is an approximate percentage: Telegram itself does not report how the upload is going, so the bot calculates it from the average speed of recent large uploads. That is why the percentage is honestly labeled as approximate.
The point is simple: as long as it is clear that work is under way, there is no reason to send the link a second time or to think the bot has frozen.

Up to five links at a time
Links can be sent in a batch: up to five, in one message or one at a time. The bot puts them in a queue and downloads them one by one; each has its own message with a status and its place in the queue (“In queue: 2nd”). There is no need to send them again: the bot will get to each one by itself. The same link does not enter the queue twice, and the bot does not silently lose links beyond the five: it lists which ones it did not queue and why.
The queue is built so that it cannot be used to get around the limit and so that a link cannot silently disappear. A free download is reserved the moment a link enters the queue, not when its turn comes, so a batch of five links will not slip past the limit of three. If the free downloads run out in the middle of a batch, the subscription offer comes once, not for every link. And if the bot restarts while links are waiting or downloading, on startup the person gets a list of what was not downloaded, and those downloads are not counted against them.
Files are arranged by Telegram’s rules
An album goes out in parts, large images are sent as files, the order of the items is kept, and mixed “video plus photo” sets do not fall apart. If the connection to Telegram drops for a moment, the upload is retried with a growing pause, and when Telegram itself asks to wait, the bot waits exactly as long as it was asked to, not a guessed amount. The short silent clips that Pinterest serves in place of GIFs go to the chat as a GIF, not as a video with an empty audio track.
Where there is a wide choice of tracks, on YouTube and Facebook, the bot estimates the size in advance and takes the option that will fit within the limit instead of running into it at the end of a long download.
Errors are written in plain words
A private video, a deleted link, a geo-block, an age restriction, a file that is too large, a lost login, “too many requests”: each case has its own human answer, and where there is something to advise, a hint about what to do next. The ten most common failures are covered. For an eleventh, one the bot has not met yet, a short technical line will go out. That is an edge case, not the norm, and the line shows right away what to fix. Keys and internal addresses are cut out of it.
This is not cosmetic. A clear error heads off a support request: the person understands for themselves that the link is private and does not write “your bot doesn’t work.”
Free limit, subscription, and profile
Three downloads a day are free, and the day is counted from each download, not from midnight. A failed download is not deducted. When the free downloads run out, the bot does not simply refuse: it says how long until the next one opens up and offers the subscription right there.
The subscription is a month with no limits, with payment in Telegram Stars right inside Telegram: one button, with no bank details, transfers, or screenshots sent to the owner. Stars are Telegram’s internal currency, bought in the app itself. The subscription renews by itself every thirty days and is canceled in Telegram’s settings. The terms, support, and payment questions open with separate commands: Telegram requires this of bots that sell.
The main work here is not the payment button but making sure money does not get lost anywhere. If the bot was down while a person was paying, on startup it finds that payment and credits it, and throws out the old links that were waiting in the same queue. A repeat notice about the same payment will not extend the subscription a second time. A renewal moves the date by exactly thirty days, even if the person sent a link in that same second.
The “My status” section shows how many free downloads are left for the day, the date the subscription runs until, and how many downloads there have been in total.
An admin panel instead of server access
The owner needs neither a database nor a console: everything is done right in Telegram. Find a person by name or number, grant a subscription for the number of days needed, block and unblock, view a summary: how many people in total, how many active subscriptions, how many downloads over a day, a week, and a month.
The owner learns of every payment and every renewal by message. A person’s card lists their payments, and any of them can be refunded in two taps: the Stars go back, auto-renewal is turned off, and the subscription is removed. A single payment cannot be refunded twice, and no one but the owner can do this.
Nothing is left after sending
A downloaded file is deleted as soon as it has gone to the chat. Separately, every few minutes, the bot cleans up anything that could have been left hanging after a failure, including when the process was cut off in the middle of a download.
For a bot like this, it is a matter of trust, not tidiness: the bot does not stockpile other people’s videos; its copy lives exactly as long as it takes to send it.
Need a bot like this for your own task, with a subscription, limits, and an admin panel?
Message meWhy this case study has no numbers
The bot is running and people use it, but as of September 12, 2026, there are so few of them that any percentages would say nothing.
It was not advertised anywhere or submitted anywhere: it came about for a specific task, and after that it was opened by people who were given the link. “Growth” on numbers like these is chance, not a result.
The means to count are there, though. From day one, the bot has recorded every download: who, which platform, whether it succeeded, how much the file weighed. This is not analytics bolted on after the fact: the summary in the admin panel is built from these same records. When there are more users, this is where the numbers for the case study will come from.
The bot can be checked without statistics too: open it, send a link from any of the five social media platforms, and get a file. Everything else can be seen in the source code, which is open on GitHub.
What this gives the business going forward
Where does it run?
On a home mini server; it does not need the cloud. Its own Telegram server for big files runs alongside, and downloads go to a separate drive. Everything is packed into containers and, using the setup description already in the repository, can be deployed on a rented server if the load grows.
What if a platform changes its format?
That is exactly what happens, regularly. So all the work with the platforms is moved out into open-source tools that are updated by other people and more often than any custom code: updating them is one line, not a rewrite of the bot. What does not depend on the tools is fixed in the bot itself. On September 27, YouTube began putting requests from one of the server’s addresses through a robot check, and the fix appeared the same day: the bot now reaches YouTube through a different address.
How many people can it handle?
Three videos download at the same time; the rest wait and get theirs next. One person can have up to five links in the queue, and they download one at a time; rapid button presses are suppressed. The numbers are small and are set in the code in one line: if it hits the ceiling, they go up together with the server.
Can it really take money?
Yes, and without the owner being involved. A person pays in Telegram Stars, the subscription turns on at once and renews by itself every month; the owner gets a message about the payment and can refund it from the admin panel. The hard cases are worked out in advance: a repeat notice about the same payment, a renewal, a refund, bot downtime during a payment.
What carries over to another project?
Almost everything except the downloading itself. Keeping track of users and quotas, a subscription with payment and refunds, an admin panel in Telegram, a task queue that does not silently lose links after a restart, a live status for long jobs, flood protection, errors in plain words, automatic file cleanup: this is the skeleton of any paid bot. The only thing that changes is what the bot does between “request received” and “result delivered”: instead of a video, it could be a report, a calculation, a document, or an appointment booking.
How it works technically
Python 3.12, aiogram 3.x, fully asynchronous. Downloading is done by yt-dlp;
for Pinterest boards, mixed Instagram /p/ carousels, and TikTok /photo/
slideshows, by gallery-dl (first, with a fallback to yt-dlp). Video processing
is ffmpeg, with the Deno JS runtime for YouTube and curl-cffi for HTTP
impersonation on TikTok and Instagram. Per-platform format selectors.
Facebook: avc1 instead of av01, with size-aware selection of DASH streams.
YouTube: the sort -S res,fps,hdr:sdr,+codec:avc:m4a (resolution matters more
than codec, SDR before HDR, and at equal resolution avc1 → vp9 → av01);
filesize_approx filters on every track, derived from the limit; an audio
budget of one fifth of the limit, with a cap, and a fallback branch
wa[acodec^=mp4a] for long videos; formats=dashy and
--concurrent-fragments 8, so that a cold googlevideo node serves the format
in parallel ranges; --abort-on-unavailable-fragments, so a hole in a fragment
produces an error with the quota returned rather than a broken file;
--force-ipv4, to get around YouTube’s bot check over IPv6. TikTok: H.264,
excluding the watermark formats download/download_addr. Instagram:
bv*+ba.
Transport is a self-hosted telegram-bot-api in --local mode next to the
bot; the cloud or the self-hosted server is switched with the
USE_LOCAL_BOT_API flag; files go to the self-hosted server as a multipart
upload over loopback, and the downloads directory is not mounted into the
server. The ceiling is 1,500 MB instead of 2,000 because of the server’s IDLE_TIMEOUT=500 s. An upload that
breaks off after 400 s is treated as a probable delivery, with no retry and no
duplicate in the chat; TelegramEntityTooLarge is not retried; before a download, free disk space is checked. Progress comes from line-by-line parsing
of yt-dlp output and the format plan before the start; the upload percentage is
an estimate from a moving average of the speed of recent large uploads; status
edits are throttled and cannot bring down a download.
Concurrency is capped by a semaphore (3); the queue is FIFO, up to 5 links
per user, with the quota reserved on enqueue and a pending_download journal:
after a restart, a notice about what was not downloaded and the reservations
returned. Flood protection is a throttle middleware: messages once every
3 seconds with headroom for a batch of links, button presses every
0.7 seconds, and successful_payment bypasses it.
Storage is SQLAlchemy 2.x (async) + SQLite: write transactions are short, and
downloading and uploading run outside the session so as not to hold the write
lock for the whole download.
The free quota is a journal of reservations in a rolling 24-hour window; a reservation is a single INSERT … SELECT under the write lock, with no race
for the last slot. Payment is Telegram Stars (XTR), with the subscription
created through createInvoiceLink with a 30-day period; a payment is
idempotent by telegram_payment_charge_id, and a refund is
refundStarPayment plus editUserStarSubscription by the ID of the
subscription’s first payment. On startup, the backlog from downtime is
processed manually: successful_payment is fed to the dispatcher, and the rest
is acknowledged and discarded.
Media is sent in chunks of 5, images heavier than 10 MB go as documents, and
retries use exponential backoff and honor retry_after from the Telegram API.
Configuration is pydantic-settings and .env, with a check for typos in key
names; logs are loguru with rotation. Deployment is Docker Compose in
host-network mode (behind NAT, large uploads break because of path MTU), with
downloads on the host’s disk and the container running as an unprivileged user
with memory and process caps; the telegram-bot-api image is pinned to a version, and for checks there is a separate test bot with its own token and
database, so a new build can be run without touching the production one.
Cookies are handed to the tools as a one-time copy so that they cannot
overwrite the master file with a truncated cookie jar during a transient
logout.
Who did the work
It’s just me behind jw-dev.pro, not a studio or an agency. That means you talk directly to the person doing the work: no manager, no brief relayed through third parties, and no passing the project to another contractor partway through.
My time zone is UTC+7, the same as Bangkok and Hanoi. I build websites, Telegram bots, and automation: a task rarely ends with a page, and it usually has to be connected to what you already have running.
As time goes on, the task sounds like “build a website” less and less often. One person needs a price to be changed in one place, not on twenty pages. Another needs the channel to run without them. A third needs the whole price list to sit inside Telegram, where their customers already go every day. That’s why the list of what I do is open-ended: if your task isn’t on it, that doesn’t necessarily mean it can’t be solved.
I write case studies so that they can be checked: what was there, what was done, and how it was measured. If there is analytics data, I give the numbers and the period they cover; if it is too early to measure, I say so. You won’t find “increased sales” here: that is a promise, not a result.
Need something similar?
Whether it’s a website, a bot, or something that is now done by hand, tell me what’s going on, and I’ll tell you whether it can be solved or not.
This kind of work is the service “Custom Telegram bot development for business.”
Your request was not sent
Your text is not lost: go back and try again. Or contact me directly: on Telegram, on WhatsApp, or by email.
If it’s easier, contact me directly: on Telegram, on WhatsApp, or by email.
Not sure what’s wrong with your website? Check it for free on Telegram: @jw_site_check_bot.
Who owns everything afterward and what happens if I disappear: answers on the home page.