Small Rust Telegram bot that forwards prompts to a local zeroclaw binary and can also run a limited set of host shell commands.
- Accepts Telegram messages from one authorized user.
- Sends normal bridge prompts to
zeroclaw agent --provider openai-codex --model gpt-5.4 -m "<prompt>". - Supports a faster plain path with
zeroclaw agent -m "<prompt>". - Downloads Telegram documents and photos into a local workspace directory and passes their paths to ZeroClaw.
- Can send local files and images back into Telegram.
- Supports helper commands such as
/ping,/date,/free,/uptime, and/status. - Supports direct shell execution with
/sh .... - Serializes requests so it behaves predictably on low-power hardware such as Raspberry Pi 1.
This bot is intentionally minimal and powerful:
- It only trusts one Telegram user ID defined in
TG_ALLOWED_USER_ID. - The
/shcommand executes arbitrary shell commands on the host as the bot process user. - The bot should be used only on a machine you control, in a private chat, with a token you keep secret.
Do not expose this bot to multiple users unless you redesign the authorization model.
- Rust toolchain
crossfor Raspberry Pi 1 ARMv6 builds- A Telegram bot token from BotFather
- A working local
zeroclawbinary - Linux shell utilities if you want to use
/date,/free,/uptime,/status
The bot reads configuration from environment variables:
| Variable | Required | Default | Description |
|---|---|---|---|
TG_BOT_TOKEN |
yes | none | Telegram bot token |
TG_ALLOWED_USER_ID |
yes | none | Only this Telegram user ID is allowed to use the bot |
ZEROCLAW_BIN |
no | /home/konst/zeroclaw |
Path to the local zeroclaw executable |
ZEROCLAW_PROVIDER |
no | openai-codex |
Provider override used for normal chat, /ask, and /raw |
ZEROCLAW_MODEL |
no | gpt-5.4 |
Model override paired with ZEROCLAW_PROVIDER |
ZEROCLAW_WORKSPACE_DIR |
no | $HOME/.zeroclaw/workspace |
Workspace root used to resolve relative files for Telegram uploads |
CHAT_STORE_PATH |
no | ./.chat_store.json |
JSON file used to persist per-chat history, recent paths, and remembered facts |
ZEROCLAW_TIMEOUT_SEC |
no | 240 |
Timeout for both zeroclaw and /sh commands |
Use .env.example as a reference, then export the variables in your shell or define them in your service manager.
To discover TG_ALLOWED_USER_ID, you can:
- Set
TG_ALLOWED_USER_ID=0temporarily. - Start the bot.
- Send it any message from your Telegram account.
- Read the stderr log line
unauthorized access attempt: user_id=.... - Restart the bot with that user ID configured.
Install cross if needed:
cargo install cross --git https://github.com/cross-rs/crossBuild for Raspberry Pi 1 ARMv6:
cross build --release --target arm-unknown-linux-gnueabihfThe binary will be written to:
target/arm-unknown-linux-gnueabihf/release/tg-zeroclaw-bridgeThen set the runtime environment and run it on the target machine:
export TG_BOT_TOKEN="1234567890:your_token"
export TG_ALLOWED_USER_ID="123456789"
export ZEROCLAW_BIN="/home/konst/zeroclaw"
export ZEROCLAW_PROVIDER="openai-codex"
export ZEROCLAW_MODEL="gpt-5.4"
export ZEROCLAW_WORKSPACE_DIR="$HOME/.zeroclaw/workspace"
export CHAT_STORE_PATH="$PWD/.chat_store.json"
export ZEROCLAW_TIMEOUT_SEC="240"For a local native run during development:
export TG_BOT_TOKEN="1234567890:your_token"
export TG_ALLOWED_USER_ID="123456789"
export ZEROCLAW_BIN="/home/konst/zeroclaw"
export ZEROCLAW_PROVIDER="openai-codex"
export ZEROCLAW_MODEL="gpt-5.4"
export ZEROCLAW_WORKSPACE_DIR="$HOME/.zeroclaw/workspace"
export CHAT_STORE_PATH="$PWD/.chat_store.json"
export ZEROCLAW_TIMEOUT_SEC="240"
cargo run --releaseIf you want it to stay running on a server or Raspberry Pi, run the compiled binary under systemd --user, tmux, or another supervisor.
| Command | Description |
|---|---|
/ping |
Health check |
/id |
Show your Telegram user ID |
/raw <prompt> |
Send a raw prompt directly to ZeroClaw using the default Codex/OpenAI invocation |
/ask <prompt> |
Ask ZeroClaw with bridge context using --provider openai-codex --model gpt-5.4 |
/askfast <prompt> |
Ask ZeroClaw with bridge context using plain agent -m |
/sh <command> |
Run a shell command on the host |
/ls [path] |
Run ls -la for the current directory or a provided path |
/cat <path> |
Print a local file with cat |
/date |
Run date |
/free |
Run free -h |
/uptime |
Run uptime |
/status |
Run systemctl --user status zeroclaw -n 40 --no-pager |
/sendfile <path> |
Send a local file into Telegram |
/sendphoto <path> |
Send a local image into Telegram as a photo |
/help |
Show built-in command help |
Any non-command text message is also forwarded to ZeroClaw.
- Long replies are split into Telegram-sized chunks.
- ANSI escape sequences are stripped from command output.
- Normal chat,
/ask, and/rawusezeroclaw agent --provider openai-codex --model gpt-5.4 -m .... /askfastuseszeroclaw agent -m ...without the provider/model override.- Bridge-mode prompts include the last 10 stored chat messages for that
chat_idas context. - The bot persists recent chat history, recent file references, and simple remembered facts in
CHAT_STORE_PATH. - Simple user facts like
my favorite color is redare captured and injected into future bridge prompts. - That history is used for normal chat,
/ask, and/askfast, but not for/raw,/sh,/ls, or/cat. - Telegram documents and photos are stored under
.telegram_uploads/so ZeroClaw can inspect them with local tools. - Relative upload paths are resolved against both the bot working directory and
ZEROCLAW_WORKSPACE_DIR. - ZeroClaw can request a real Telegram upload by emitting one of these lines on its own line:
[[telegram_document:relative/or/absolute/path|optional caption]][[telegram_photo:relative/or/absolute/path|optional caption]] - Some interactive shell commands are blocked and replaced with a hint.
- Unauthorized access attempts are logged to stderr.
MIT. See LICENSE.