Send or forward any file to the bot and it replies with a share link. Anyone who opens that link gets the file back, straight from Telegram's servers.
you → bot bot → you friend opens link
[photo.jpg] t.me/yourbot?start=Ab3xK9 [photo.jpg]
Nothing is re-uploaded or stored on your disk. The bot keeps Telegram's
file_id and re-sends it, so delivery is instant and costs no bandwidth.
Admin panel — an inline keyboard inside the chat, no web UI.
- Media library with rename, enable/disable, preview and delete
- Captions per item, plus a global template that wraps them
- Photo watermark — tiled low-opacity text, applied on delivery and cached
- Auto-delete — remove delivered media after a delay you choose
- Join gate — require channel membership before a link pays out
- Statistics — today / 7d / 30d / all time
- Broadcast — throttled and cancellable, with a test-send to yourself first
- Admins — add and remove, with a permanent owner
Regular users only ever see links working. No internals leak into their view.
Needs Docker and a bot token from @BotFather.
git clone https://github.com/abolix/TelegramDownloaderBot.git
cd TelegramDownloaderBot
cp .env.example .env
nano .env # set BOT_TOKEN and OWNER_ID
mkdir -p data
sudo chown -R 10001:10001 data # the container runs as uid 10001
docker compose up -d --build
docker compose logs -fThen message your bot /panel.
OWNER_ID is your numeric Telegram id. Send /id to the bot to find it.
python -m venv .venv
. .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # set BOT_TOKEN and OWNER_ID
python -m botDeveloped and tested on Python 3.14, which is what the image pins.
python -m bot.preflight # check the token and connectivity
pip install -r requirements-dev.txt && pytestOnly deploy-time settings live in .env. Everything else is in the panel.
| Variable | Required | Notes |
|---|---|---|
BOT_TOKEN |
yes | From @BotFather |
OWNER_ID |
yes | Permanent admin, cannot be removed |
PROXY_URL |
no | For local use where Telegram is blocked. Leave empty when deployed |
DATA_DIR |
no | Defaults to data |
LOG_LEVEL |
no | INFO by default |
Auto-delete, captions, watermark and the join gate are all set from the panel and stored in the database. They apply immediately, with no restart.
/start |
Open the bot, or redeem a media link |
/help |
What the bot does |
/id |
Your numeric user id |
/panel |
Admin panel (admins only) |
/stats |
Statistics (admins only) |
git pull
docker compose up -d --buildChanged only .env? Then docker compose up -d is enough — but note that
docker compose restart will not pick it up, because env_file is read
when the container is created, not when it starts.
Everything lives in one SQLite file, data/bot.db. Back it up by copying that
file while the bot is stopped; a clean shutdown folds the write-ahead log back
in, so the single file is complete.
Two things worth knowing:
file_ids are tied to your bot token. ChangeBOT_TOKENand every saved link breaks. Keep the token and the database together.- One instance per token. Telegram allows a single poller, so running the bot in two places at once produces 409 conflicts.