Zero-dependency, stdlib-only Telegram bridge for two-way CLI automation. Simple alerts or interactive command-and-control using nothing but the Python standard library.
Project description
tgzero
Lightweight, zero-dependency Telegram C2 bridge.
Bridges server-side processes with a designated Telegram chat — from fire-and-forget alerts to interactive deployment gatekeepers.
Installation
pip install tgzero
Configuration
Create a telegram.env file in your working directory (or export the variables in your shell):
TELEGRAM_TOKEN=1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi
TELEGRAM_CHAT_ID=1234567890
Secure the file:
chmod 600 telegram.env
Commands
tgzero send — Fire-and-forget notification
# Basic alert
tgzero send --msg "✅ Weekly backup uploaded to S3."
# Silent (no sound on phone)
tgzero send -m "Server load is high (85%)" --silent
# Machine-readable output
tgzero send -m "Done" --json
# → {"status": "success", "action": "send", "exit_code": 0, "latency_ms": 312}
tgzero ask — Interactive gatekeeper
Pauses your script until you tap a button in Telegram.
# Simple yes/no gate (default OK button)
tgzero ask --prompt "Ready to restart nginx?"
# Custom buttons — first button = exit 0, any other = exit 1
if tgzero ask --prompt "Deploy to production?" --buttons "Deploy,Abort"; then
./deploy.sh
tgzero send -m "🚀 Deployment successful!"
else
echo "Aborted."
fi
# With timeout
tgzero ask -p "Approve migration?" -b "Approve,Skip" --timeout 300
# Multi-branch with --json
RESULT=$(tgzero ask -p "Choose environment" -b "Staging,Prod,Dev" --json)
ENV=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin)['reply_string'])")
echo "Deploying to: $ENV"
Exit codes:
| Code | Meaning |
|---|---|
0 |
First button clicked (success / go) |
1 |
Any other button clicked — literal label printed to stdout |
2 |
Timeout — no reply within --timeout seconds |
3 |
Network / API failure |
4 |
Queue timeout — another ask is holding the lock |
5 |
Terminated by SIGTERM / SIGINT |
tgzero daemon — Persistent remote-control agent
Runs in the background (systemd / Docker) and executes allow-listed commands sent via Telegram.
tgzero daemon --allow-list "status,reboot,clear-logs" --interval 3
From your phone: type status → bot replies with command output.
Unrecognised commands get a ⚠️ Command not permitted reply.
systemd unit example
[Unit]
Description=tgzero Telegram C2 daemon
After=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/myapp
EnvironmentFile=/opt/myapp/telegram.env
ExecStart=tgzero daemon --allow-list "status,restart-nginx,clear-logs"
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Security Notes
- All messages are validated against
TELEGRAM_CHAT_ID. Messages from any other sender are logged and ignored. - The
daemonallow-list uses exact string matching — no shell interpolation. - HTML special characters are automatically escaped before sending.
- Messages longer than 4096 characters are cleanly truncated.
- The
.envfile permissions are checked on startup; a warning is printed if the file is world-readable.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tgzero-0.2.0.tar.gz.
File metadata
- Download URL: tgzero-0.2.0.tar.gz
- Upload date:
- Size: 18.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e7a9f96d7c9611d4f7ed7a20fc0833ec6c25180f699141a7d6f77a7d693591d
|
|
| MD5 |
98ee2cc6030e5658523cb8c4618f3d49
|
|
| BLAKE2b-256 |
e26ed15dc404cbc2453a9144d1355fa516ae00180de7f2a603c316f5b7c37929
|
Provenance
The following attestation bundles were made for tgzero-0.2.0.tar.gz:
Publisher:
publish.yml on shipsweights/tgzero
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tgzero-0.2.0.tar.gz -
Subject digest:
6e7a9f96d7c9611d4f7ed7a20fc0833ec6c25180f699141a7d6f77a7d693591d - Sigstore transparency entry: 1212351856
- Sigstore integration time:
-
Permalink:
shipsweights/tgzero@8bbb8282b909747df3e445055bc7d159a629b673 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/shipsweights
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8bbb8282b909747df3e445055bc7d159a629b673 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tgzero-0.2.0-py3-none-any.whl.
File metadata
- Download URL: tgzero-0.2.0-py3-none-any.whl
- Upload date:
- Size: 22.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3343d9d280b1fbfc27b9ddc7d8e159aba20ad1cf3b0dafea27267b3b84135ff
|
|
| MD5 |
ea23650c32f49c46d07eeb17b69a72e6
|
|
| BLAKE2b-256 |
c18ce650be9f4df60365c2bcf07f46a6a53609c8826e7230e3df62d03da11bc1
|
Provenance
The following attestation bundles were made for tgzero-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on shipsweights/tgzero
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tgzero-0.2.0-py3-none-any.whl -
Subject digest:
e3343d9d280b1fbfc27b9ddc7d8e159aba20ad1cf3b0dafea27267b3b84135ff - Sigstore transparency entry: 1212351894
- Sigstore integration time:
-
Permalink:
shipsweights/tgzero@8bbb8282b909747df3e445055bc7d159a629b673 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/shipsweights
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8bbb8282b909747df3e445055bc7d159a629b673 -
Trigger Event:
push
-
Statement type: