tg-exec — any command's result in Telegram
A wrapper for cron jobs, backups, deploys and CI: exit code, duration and output arrive in Telegram. Proxy support, own Bot API endpoint for closed networks, encrypted token.
Run a backup, an upgrade or a deploy — and learn how it ended without logging into the server. tg-exec runs the command, shows its output in the terminal as usual and sends a short report to Telegram when it finishes.
❌ Failed · exit 2 · backup-db01
pg_dump app | gzip > /backup/app.sql.gz
🕒 2026-10-16 03:00:00 → 03:02:03 UTC · 2m 3s
💬 Output:
pg_dump: error: connection to server on socket "/run/postgresql/.s.PGSQL.5432" failed
What it does
- The exit code is passed through. The wrapper does not break cron, systemd or CI:
tg-exec -- backup.shreturns exactly whatbackup.shreturned. A signal gives128+N, a timeout gives124. - The job comes first. If the token is missing or Telegram is unreachable, the command still runs and the problem goes to stderr.
- Clean output. The message carries the output tail without ANSI colours or redrawn progress bars. If it does not fit, the full log arrives as a file (up to 45 MB).
- Arguments stay intact.
tg-exec -- rsync -a "/src dir/" host:/dstis executed directly, without re-parsing by a shell. A single quoted string goes throughbash -c, so pipes and&&work. - Errors only, if you like.
--on-failurereports failures only,--silentdelivers successes without sound,--timeout 2hstops a stuck job. - Groups, channels, forum topics. The
--setupwizard finds the chat id from recent messages to the bot.
Closed networks
tg-exec talks to nothing but the Telegram Bot API and does not need RunStack to work.
- Proxies:
http://,https://,socks5://,socks5h://with username and password. - Your own API endpoint — a self-hosted telegram-bot-api or an nginx gateway, plus a custom CA for an internal certificate.
- One static binary with no dependencies: Linux amd64 / arm64 / armv7 / 386 and macOS. deb, rpm and apk packages.
A protected token
To be honest: if a program reads a token without a password — and cron leaves no other option — whoever gets that account's rights can read it too. So tg-exec closes what can actually be closed:
- the config with the token is created with mode
0600, and a more open one triggers a warning; sudo tg-exec --sealencrypts the token with systemd-creds using the host key and TPM2 when available. A copied disk or backup is useless without this server;TOKEN_CMDworks like aws-clicredential_process: the token comes from Vault,passor any other secrets manager;- systemd
LoadCredentialEncrypted=exposes the token to one service only.
Getting started
- Create a bot with @BotFather.
- Install tg-exec — package and source links are available after sign-in.
- Run
sudo tg-exec --setup: token check → pick a chat → test message.
tg-exec -- apt-get -y upgrade
tg-exec --on-failure -n nightly-backup -t 3h -- /usr/local/bin/backup.sh
tg-exec "pg_dump app | gzip > /backup/app.sql.gz"
All settings are in man tg-exec and tg-exec --help. Current settings and a delivery test: tg-exec --check.
