Feature request · Report a bug · Support: Discussions & Telegram Community
Download all media files from a conversation or a channel that you are a part of from telegram. A meta of last read/downloaded message is stored in the config file so that in such a way it won't download the same media file again.
| Category | Support |
|---|---|
| Language | Python 3.8 and above |
| Download media types | audio, document, photo, video, video_note, voice |
- Interactive Web UI: Added a sleek web-based interface for configuration and execution monitoring.
- Rate Limiting: Added
max_concurrent_downloadsto limit simultaneous downloads and prevent Telegram bans. - Download Delay: Added
download_delaywith support for fixed or random delays between downloading files. - Improved Gentle Exit: The script safely remembers the last downloaded file when stopping.
- Multiple Chats Support: Configure and download from multiple chats at once using a new
chatslist inconfig.yaml. - Parallel Downloading: Added
parallel_chatsoption to download from multiple chats concurrently usingasyncio.gather. - Per-Chat Configurations: Customize
media_types,download_directory,start_date, and other filters locally for each specific chat without losing the ability to use global defaults. - Dynamic Directories: Downloaded media is automatically organized into subdirectories by
chat_idwhen relying on the default structure. - State Separation: Maintains tracking (
last_read_message_idand retry states) completely separated for each chat.
This version (3.0.0) contains breaking changes due to migration from Pyrogram to Telethon.
- Backend Migration: Complete migration from Pyrogram to Telethon library
- API Changes: Some configuration options may have changed
- Dependencies: Updated to use Telethon-specific dependencies
- Python Requirement: Now requires Python 3.8 or higher (previously 3.7+)
If you're upgrading from a previous version:
- Backup your
config.yamland downloaded media - Use
make installto ensure all dependencies are properly installed - Review your configuration as some options may have changed
- Test with a small channel first to verify everything works
⚠️ Important: We strongly recommend usingmaketo ensure all dependencies are properly installed with correct Python version compatibility. By default,make installonly installs the minimal CLI dependencies.
For *nix OS distributions:
git clone https://github.com/Dineshkarthik/telegram_media_downloader.git
cd telegram_media_downloader
make installFor Windows or systems without make:
git clone https://github.com/Dineshkarthik/telegram_media_downloader.git
cd telegram_media_downloader
pip3 install -r requirements.txtIf you plan to use the graphical web interface, you must install the optional Web UI dependencies (requires Python 3.10+):
For *nix OS distributions:
make install_webuiFor Windows or systems without make:
pip3 install -r requirements-webui.txtNote: The
make installcommand automatically detects your Python version and installs the appropriate dependencies for optimal compatibility.
For contributors and developers who need additional development tools:
git clone https://github.com/Dineshkarthik/telegram_media_downloader.git
cd telegram_media_downloader
make dev_install # Installs both runtime and development dependenciesNote:
make dev_installalso automatically detects your Python version and installs version-specific development dependencies.
All the configurations are passed to the Telegram Media Downloader via config.yaml file.
- Copy
config.yaml.exampletoconfig.yaml:cp config.yaml.example config.yaml
- Update the values in
config.yamlwith your specific details (API keys, chat ID, etc.).
Note:
config.yamlis ignored by git to prevent accidental commits of sensitive information. Always useconfig.yaml.exampleas the template.
Getting your API Keys: The very first step requires you to obtain a valid Telegram API key (API id/hash pair):
- Visit https://my.telegram.org/apps and log in with your Telegram Account.
- Fill out the form to register a new Telegram application.
- Done! The API key consists of two parts: api_id and api_hash.
Getting chat id:
1. Using web telegram:
- Open https://web.telegram.org/?legacy=1#/im
- Now go to the chat/channel and you will see the URL as something like
https://web.telegram.org/?legacy=1#/im?p=u853521067_2449618633394here853521067is the chat id.https://web.telegram.org/?legacy=1#/im?p=@somenameheresomenameis the chat id.https://web.telegram.org/?legacy=1#/im?p=s1301254321_6925449697188775560here take1301254321and add-100to the start of the id =>-1001301254321.https://web.telegram.org/?legacy=1#/im?p=c1301254321_6925449697188775560here take1301254321and add-100to the start of the id =>-1001301254321.
2. Using bot:
- Use @username_to_id_bot to get the chat_id of
- almost any telegram user: send username to the bot or just forward their message to the bot
- any chat: send chat username or copy and send its joinchat link to the bot
- public or private channel: same as chats, just copy and send to the bot
- id of any telegram bot
api_hash: your_api_hash
api_id: your_api_id
# The downloader can process multiple chats (either sequentially or in parallel).
# The 'chats' list is highly customizable per chat. If an option is not provided
# in a chat dictionary, it will fall back to the global option defined above.
parallel_chats: false
chats:
- chat_id: telegram_chat_id_1
last_read_message_id: 0
ids_to_retry: []
# Local chat options map exactly as the globals (media_types, file_formats, etc.)
- chat_id: telegram_chat_id_2
last_read_message_id: 0
# GLOBAL SETTINGS (act as fallback for local chats)
chat_id: telegram_chat_id
last_read_message_id: 0
ids_to_retry: []
media_types:
- audio
- document
- photo
- video
- voice
- video_note
file_formats:
audio:
- all
document:
- all
video:
- all
# Optional filters (Can also be set in individual chats)
download_directory: null # Custom directory path for downloads (absolute or relative path)
start_date: null # Filter messages after this date (ISO format, e.g., '2023-01-01' or '2023-01-01T00:00:00')
end_date: null # Filter messages before this date (ISO format)
max_messages: null # Limit the number of media items to download (integer)
# Download Pacing / Rate Limiting (optional, can also be set per-chat)
max_concurrent_downloads: 4 # Max files downloading at once per batch (1 = fully sequential)
download_delay: null # Delay between files: fixed (2) or random range ([1, 5])| Option | Description |
|---|---|
api_hash |
The api_hash you got from telegram apps |
api_id |
The api_id you got from telegram apps |
parallel_chats |
If true, downloads chats inside the chats list concurrently. |
chats |
A list of discrete chats/channels to download from. Setting media_types, download_directory, etc., locally inside here overrides global options. |
chat_id |
The id of the chat/channel you want to download media for. Can be set globally or locally. |
last_read_message_id |
If it is the first time you are going to read the channel let it be 0 or if you have already used this script it will have auto-updated. |
ids_to_retry |
Leave it as it is. This keeps track of all skipped downloads to retry. |
media_types |
Type of media to download. |
file_formats |
File types to download. Default is all. |
download_directory |
Optional: Custom directory path where media files will be downloaded. Can be absolute or relative path. If null, uses default directory structure. |
start_date |
Optional: Filter messages to download only those sent after this date (ISO format). Leave null to disable. |
end_date |
Optional: Filter messages to download only those sent before this date (ISO format). Leave null to disable. |
max_messages |
Optional: Limit the number of media items to download (integer). Leave null for unlimited. |
max_concurrent_downloads |
Optional: Maximum number of files downloading simultaneously per batch. Lower values reduce ban risk. 1 = fully sequential. Default: 4. |
download_delay |
Optional: Pause between starting each file download (seconds). Use a number for a fixed delay (2) or a list for a random range ([1, 5]). Leave null for no delay. |
To reduce the risk of Telegram rate-limiting or banning your account, you can slow down the downloader with two optional settings:
| Option | Type | Default | Description |
|---|---|---|---|
max_concurrent_downloads |
int | 4 |
Max files downloading simultaneously per batch. Set to 1 for fully sequential. |
download_delay |
float | [float, float] | null | null |
Pause between files. Fixed seconds (2) or random range ([1, 5]). |
Both options can be set globally or overridden per-chat:
# Global (applies to all chats unless overridden)
max_concurrent_downloads: 2
download_delay: [1, 5] # random 1–5 second pause between files
chats:
- chat_id: 123456789
# This chat downloads faster since it's a trusted source
max_concurrent_downloads: 8
download_delay: null
- chat_id: 987654321
# Falls back to global settings (2 concurrent, random 1–5 s delay)python3 media_downloader.pyNote: The Web UI relies on NiceGUI and requires Python 3.10 or higher. It is an optional installation (see Web UI Installation).
For an interactive experience that lets you configure downloads, track progress visually, and view historical downloads within a built-in media player, you can start the built-in Web UI.
python3 webui.pyThis will start a local web server (usually at http://127.0.0.1:8080).
📚 Click here to read the full Web UI Getting Started Guide to see screenshots of the Configuration, Execution, and History tabs.
By default, all downloaded media will be stored in respective directories named after the media type and scoped to their specific chat_id in the same path as the python script.
| Media type | Default Download directory |
|---|---|
| audio | path/to/project/<chat_id>/audio |
| document | path/to/project/<chat_id>/document |
| photo | path/to/project/<chat_id>/photo |
| video | path/to/project/<chat_id>/video |
| voice | path/to/project/<chat_id>/voice |
| voice_note | path/to/project/<chat_id>/voice_note |
You can specify a custom download directory by setting the download_directory option in your config.yaml. This allows you to organize all downloads in a single custom location while maintaining the media type subdirectories.
Examples:
download_directory: "/home/user/downloads/telegram"(absolute path)download_directory: "downloads/telegram"(relative path)download_directory: null(use default directory structure)
If the specified directory doesn't exist, it will be automatically created. The media type subdirectories (audio/, photo/, etc.) will still be created within your custom directory.
socks4, socks5, http proxies are supported in this project currently. To use it, add the following to the bottom of your config.yaml file
proxy:
scheme: socks5
hostname: 11.22.33.44
port: 1234
username: your_username
password: your_passwordIf your proxy doesn’t require authorization you can omit username and password. Then the proxy will automatically be enabled.
Read through our contributing guidelines to learn about our submission process, coding rules and more.
Want to file a bug, contribute some code, or improve documentation? Excellent! Read up on our guidelines for contributing.
Help us keep Telegram Media Downloader open and inclusive. Please read and follow our Code of Conduct.