CLI tool
rahiel/telegram-send avatar
rahiel/telegram-send

telegram-send: your terminal's notifications channel, with a bot behind it

Send messages and files over Telegram from the command-line.

1,016 stars109 forksPythonGPL-3.0

At a glance

What is it?
telegram-send is a command-line tool that sends messages, files, images, video, audio, stickers and locations to your Telegram account, a group or a channel, and it is designed to be called from other programs. Its configuration model is per-target files with a global option for a system-wide setup, and the GPLv3+ licence is the one thing to weigh before shipping it in a product.
Who is it for?
telegram-send suits a system administrator or a developer who wants alerts, cron output and build results pushed to their phone, because a single command with a --stdin option turns any program's output into a notification and a bot token means no account credentials are involved.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 156 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A bot, a target, and one command

telegram-send is a command-line tool to send messages and files over Telegram to your account, to a group or to a channel. The README says it provides a simple interface that can be easily called from other programs, and that is the whole design goal.

shell
telegram-send "Hello, World!"

The three target types are configured separately, with three flags: --configure to send to your account, --configure-group to send to a group, and --configure-channel to send to a channel. Each writes a configuration file, and you can select among them with --config.

The mechanism underneath is a Telegram bot. The pyproject.toml pins python-telegram-bot at exactly 22.5, so the tool is a thin client over the Bot API rather than a user account client, and the README's cron example says it plainly: create a bot by talking to the BotFather, create a public channel and add your bot as administrator to the channel. You will need to explicitly search for your bot's username when adding it.

That last step is the friction point worth knowing about. Adding a bot as a channel administrator requires searching for the bot by username, and people regularly get stuck there.

The other dependency is platformdirs at 4.5.1 or newer, which is where the configuration files live, and colorama at 0.4.6 or newer only on Windows, for terminal colour.

Every media type the Bot API accepts, with the size limits spelled out

The flag set is wide, and the size limits are documented per type, which is the detail to read before you build a workflow on top of it.

Text messages have a maximum length of 4096 characters, and larger messages will be automatically split up into smaller ones and sent separately. That automatic splitting is convenient and also a trap: a reader receiving a chopped message has no way to know it was one message, and a notification that gets split mid-sentence reads badly.

Files go through --file with a maximum file size of 50 MB and an optional caption. Images use --image with a maximum of 10 MB. Stickers use --sticker. Animations, described as a GIF or a soundless MP4 video encoded as H.264/MPEG-4 AVC with a maximum file size of 50 MB, use --animation, and MP4 video uses --video with the same 50 MB limit. Audio uses --audio, and a location is sent with --location followed by latitude and longitude.

Every caption can be formatted with Markdown or HTML, and the formatting flag applies to the message body as well.

shell
telegram-send --image moon.jpg --caption "The __Moon__ at *Night*" --format markdown

Two formatting details are worth knowing. The --format markdown option uses the MarkdownV2 style for Markdown, which is Telegram's own flavour and not CommonMark, so a Markdown document that renders correctly elsewhere will not necessarily render here. And the README warns that not all Markdown syntax or all HTML tags are supported, linking to the Bot API formatting options page for the authoritative list.

Two convenience flags round it out. --pre formats the message as fixed-width text, and --disable-web-page-preview suppresses link previews.

Piping any program into a message

The feature that turns telegram-send from a toy into a tool is --stdin.

shell
printf 'With\nmultiple\nlines' | telegram-send --stdin

The README says that with this option you can send the output of any program, and the cron example that follows is built on exactly that: a job that sends the Astronomy Picture of the Day to a channel, using the apod.py script in the examples directory of the repository.

That pairing is the pattern. A script produces a file or a line of text, and the output becomes a message. The alternative the README suggests for long-running commands is ntfy with the Telegram backend, which is a separate project at github.com/dschep/ntfy.

There is also a shell alias that sends you the command you just ran, which is a neat trick.

shell
alias tg='telegram-send "$([ $? = 0 ] && echo "" || echo "error: ") $(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*tg$//'\'')"'

With that in your ~/.bashrc, running sleep 10; tg sends you a message with the completed command, and the alias prefixes error: when the previous command exited non-zero. The README also covers the case where you forgot to set the alert, suggesting you suspend the program with Ctrl+Z and then enter fg; telegram-send "your message here".

The file manager integration is the other convenience: the tool integrates into Thunar, Nautilus and Nemo, which is how a right-click send action gets added.

And the cron example is doubled by a section on cron job output, which is the case where a scheduled job's stdout goes to a chat rather than to a mail spool.

Configuration files, and the system-wide option that needs sudo

The configuration model is worth understanding because it has an unusual global mode.

Per-target configuration is created with the three --configure flags and selected with --config, and the README gives the example of setting up a channel in a non-default configuration with telegram-send --config channel.conf --configure-channel, then always specifying the config file to use it with telegram-send --config channel.conf "Bismillah".

The -g option uses the global configuration at /etc/telegram-send.conf. The README says to configure it once with sudo telegram-send -g --configure, and then all users on the system can send messages with this config using telegram-send -g "GNU". The catch is stated immediately: to use this option you need to install telegram-send with sudo, and the given command is sudo pip3 install telegram-send.

That is a system-wide Python install with sudo, which is exactly the practice most packaging guidance discourages, because it can shadow packages in the system site-packages and it leaves no record for an uninstall. The apt route exists for Ubuntu and Debian, and the README notes a Debian package badge and an Ubuntu package version badge, so on those distributions the system-wide install should go through the package manager rather than pip.

The uninstallation section is part of the README's table of contents, which suggests the removal path is documented. The other installation routes are pipx, which is what the macOS instructions use.

shell
brew install pipx
pipx ensurepath
pipx install telegram-send

The pipx route is the better default on any system, because it isolates the tool and its dependencies in their own environment rather than in the system Python.

Package layout, versioning and where the code lives

The packaging metadata is small and tells you what kind of project this is.

The build backend is hatchling, and the version is dynamic, read from telegram_send/version.py by the hatch version hook. The console script is telegram-send, mapped to telegram_send.telegram_send:main, and the wheel packages the telegram_send directory.

There is a mismatch worth flagging. The pyproject.toml sets requires-python to 3.10 or newer, and the classifiers list Programming Language :: Python :: 3.9, so the metadata declares 3.9 as supported while the install requirement refuses it. The repository also has a .python-version file, which is the pin the project actually develops against.

The dev dependency group is mypy at 1.19.1 or newer, pdoc at 16.0.0 or newer and ruff at 0.14.11 or newer, so the documentation is generated with pdoc rather than Sphinx, and there is a flake8 configuration with a max line length of 120 that excludes the build directory, which is a leftover alongside ruff.

The repository root has run_tests.bash and release.bash, and a uv.lock, so the development workflow uses uv rather than plain pip. There is a .github/ directory for the workflows.

The licence is GPL-3.0-or-later, with the classifier for GNU General Public License v3 or later. For a script you install on your own machines that is unremarkable. For a product that bundles it, GPLv3+ is a serious constraint, and a thin wrapper that shells out to the command is the usual way teams avoid that, at the cost of losing the Python API.

The last push was on 2026-05-19, so the tree has not moved much in the last few months.

Editorial conclusion

telegram-send suits a system administrator or a developer who wants alerts, cron output and build results pushed to their phone, because a single command with a --stdin option turns any program's output into a notification and a bot token means no account credentials are involved. It is the wrong tool if you need end-to-end private messaging, since a bot conversation is a chat the bot can read, and it is the wrong choice for a commercial product you intend to redistribute, because the licence is GPLv3+. Before you adopt it, create the bot and configure one target with telegram-send --configure, and decide early whether the 4096 character limit and the automatic splitting of longer messages matter for the notifications you plan to send.

Frequently asked questions

How do I install telegram-send?

On macOS, install pipx with brew install pipx, run pipx ensurepath, then pipx install telegram-send. On Ubuntu and Debian, sudo apt install telegram-send works, and pipx is the recommended route on other Linux systems or if you need a newer version.

How do I set up telegram-send for the first time?

You need a bot created through the BotFather, and then you configure the target with telegram-send --configure for your own account, --configure-group for a group, or --configure-channel for a channel. For a channel you also need to add the bot as an administrator and explicitly search for its username when adding it.

How do I send the output of another program to Telegram?

Pipe it in and use the --stdin option, for example printf 'With\nmultiple\nlines' | telegram-send --stdin. The README notes that with this option you can send the output of any program.

What is the maximum message length telegram-send supports?

There is a maximum message length of 4096 characters, and larger messages are automatically split up into smaller ones and sent separately.

How do I send a file to a Telegram channel with telegram-send?

Use the --file flag with an optional --caption, for example telegram-send --file quran.pdf --caption "The Noble Qur'an". The maximum file size is 50 MB, while images through --image are limited to 10 MB.

Official sources

  1. Issues
  2. License: GPL-3.0
  3. Project website
  4. rahiel/telegram-send on GitHub
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rahiel-telegram-send.svg)](https://hysenlabs.com/projects/rahiel-telegram-send)

Was this useful?