|
|
||
|---|---|---|
| .github/workflows | ||
| docs | ||
| scripts | ||
| skills | ||
| src | ||
| tests | ||
| .cgcignore | ||
| .env.example | ||
| .gitignore | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| CLAUDE.md.example | ||
| GEMINI.md | ||
| LICENSE | ||
| README.md | ||
| TODOS.md | ||
🤖 claude-code-telegram
A personal AI assistant you can message from anywhere via Telegram. Text your bot, it runs Claude Code, sends back the response.
Rewritten in Rust from the original Python version — single binary, no runtime dependencies, 78x faster startup, 3x less memory.
✨ Features
- 💬 Text messages — send prompts to Claude Code, get formatted responses
- 📷 Photo messages — send screenshots or images with optional caption; Claude sees the file
- 📎 Document messages — send any file (PDF, code, data); filename preserved
- 📤 File output — Claude can write files to an outbox directory, delivered back as Telegram documents
- 📁 Project switching —
/projectto list or switch workspaces; per-project sessions persist across restarts - 🧠 Session persistence — conversations maintain context across messages, per-project
- 🎤 Voice messages — transcribe and forward to Claude (optional,
--features voice) - 📝 Markdown → Telegram HTML — headings, bold, italic, code blocks, links, lists, blockquotes
- ✂️ Message splitting — long responses split at paragraph boundaries with HTML tag tracking
- 📤 Send subcommand — send messages from scripts or other Claude sessions
- ⚙️ Service management — install as systemd/launchd service with auto-restart
🔄 How It Works
📱 Inbound (you → Claude):
Telegram → claude-code-telegram → claude -p "message" → response → Telegram
📢 Outbound (Claude → you):
Claude skill → send.sh / claude-code-telegram send → Telegram API → you
🚀 Quick Start
Prerequisites
- Rust toolchain
- Claude Code CLI installed and authenticated
Build & Run
# Clone and install
git clone https://codeberg.org/alan090/claude-code-telegram-rs.git
cd claude-code-telegram-rs
cargo install --path .
# Configure
cp .env.example .env
# Edit .env with your bot token and user ID (see Configuration below)
# Run
claude-code-telegram
Note:
cargo installplaces the binary in~/.cargo/bin/— outside the source tree, socargo cleancan never accidentally remove it. Prefer this over running fromtarget/release/for any persistent deployment.
🔧 Configuration
Copy .env.example to .env and set:
| Variable | Required | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
✅ | Bot token from @BotFather |
TELEGRAM_CHAT_ID |
For send |
Your user ID from @userinfobot |
ALLOWED_USERS |
⚠️ Recommended | Comma-separated user IDs (empty = allow all) |
CLAUDE_WORKSPACE |
No | Path to workspace with CLAUDE.md (default: $HOME) |
CLAUDE_PATH |
No | Path to claude binary (default: claude) |
CLAUDE_TIMEOUT_SECS |
No | Task timeout in seconds (default: 1800) |
CLAUDE_MODEL |
No | Override Claude model selection |
PROJECTS |
No | Comma-separated name=path pairs for project switching |
CLAUDE_PROJECTS_ROOT |
No | Directory to scan for git projects (immediate children) |
🤖 Getting Your Bot Token
- Message @BotFather on Telegram
- Send
/newbotand follow the prompts - Copy the token into
TELEGRAM_BOT_TOKEN
🆔 Getting Your User ID
- Message @userinfobot on Telegram
- Copy your numeric ID into
ALLOWED_USERSandTELEGRAM_CHAT_ID
💬 Usage
Bot Commands
| Command | Description |
|---|---|
/new |
🔄 Clear active project's session |
/cancel |
🛑 Cancel running task (second /cancel abandons stuck tasks) |
/status |
ℹ️ Show user ID, session status, running task, voice support |
/project |
📁 List registered projects with active one marked |
/project <name> |
📁 Switch to a project (exact or unique prefix match) |
| (any text) | 🧠 Send to Claude with session context |
CLI
# Run the bot (default)
claude-code-telegram
claude-code-telegram run
# Send a message
claude-code-telegram send "Build completed successfully ✅"
claude-code-telegram send --chat-id 12345 "Custom target"
# Install as system service
claude-code-telegram install
# Remove service
claude-code-telegram uninstall
🖥️ Service Management
Linux — the recommended setup uses a system service with EnvironmentFile= so the
binary and config are decoupled:
# /etc/systemd/system/claude-telegram-bot.service
[Unit]
Description=Claude Code Telegram Bot
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=alan
ExecStart=/home/alan/.cargo/bin/claude-code-telegram
EnvironmentFile=/path/to/claude-code-telegram-rs/.env
Restart=on-failure
RestartSec=10
Environment=PATH=/home/alan/.local/bin:/usr/local/bin:/usr/bin:/bin
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now claude-telegram-bot
journalctl -u claude-telegram-bot -f
Alternatively, the built-in install subcommand creates a systemd user service:
claude-code-telegram install
systemctl --user status claude-code-telegram
journalctl --user -u claude-code-telegram -f
macOS — creates a launchd agent with auto-restart on failure and network dependency.
🎤 Voice Support
Build with the voice feature to enable voice message transcription via whisper.cpp:
cargo build --release --features voice
Requirements:
cmakeand a C++ compiler at build time- The whisper model (~140MB) is downloaded and cached automatically on first voice message
- Audio is decoded from OGG/Opus → 16kHz mono PCM → transcribed locally
🔌 Skills
The skills/ directory contains Claude Code skills for automation:
| Skill | Description |
|---|---|
| 📤 telegram-sender | Send messages from Claude Code sessions — notifications, alerts, reminders |
| 🌅 daily-brief | Automated morning briefing with weather, news, and quotes |
Installing Skills Globally
cp -r skills/telegram-sender ~/.claude/skills/
Once installed, Claude can proactively send you messages:
"Send me a Telegram message when the build finishes"
"Remind me at 3pm to take a break"
📊 Performance
Benchmarked against the Python version on the same machine:
| Metric | Python | Rust | Improvement |
|---|---|---|---|
| 🚀 Startup time | 233 ms | 3 ms | 78x faster |
| 💾 Idle memory | 55 MB | 7 MB | 8x less |
| 📝 Markdown conversion | 1.26 ms | 0.05 ms | 26x faster |
| ✂️ Message splitting | 0.78 ms | 0.48 ms | 1.6x faster |
| 📦 Deployment size | 26 MB (venv) | 14 MB (binary) | 1.9x smaller |
| ⚡ Runtime dependencies | Python 3.10+ | None | Zero deps |
🔄 Session Compatibility
Uses ~/.telegram-claude-sessions.json. The v0.2.1 session schema (v2: per-project sessions) is not backwards-compatible with the Python version. On first run, v1 files are migrated automatically and backed up to .v1.bak.
🔒 Security
⚠️ ALLOWED_USERS is critical
Always set ALLOWED_USERS in your .env file. If left empty, anyone who discovers your bot's username can send it messages and run Claude with full tool access on your machine.
🛠️ Tool access
The bot runs Claude with these tools enabled:
Read · Write · Edit · Bash · Glob · Grep · WebFetch · WebSearch · Task · Skill
This is powerful and intentional for a personal assistant, but understand that messages you send can trigger real actions on your system.
🔑 Protect your tokens
- 🚫 Never commit
.env(already in.gitignore) - 🤖 Your bot token lets anyone impersonate your bot
- 💬 Your chat ID lets anyone send you messages via the bot
📁 Session file
Sessions are stored in ~/.telegram-claude-sessions.json. On shared systems:
chmod 600 ~/.telegram-claude-sessions.json
📁 Project Structure
claude-code-telegram-rs/
├── src/
│ ├── main.rs # CLI entry (clap): run, send, install, uninstall
│ ├── config.rs # .env loading + Config struct
│ ├── error.rs # thiserror Error enum
│ ├── bot.rs # teloxide dispatcher + handler wiring
│ ├── handlers.rs # /new, /cancel, /status, /project, text, voice, photo, document handlers
│ ├── project.rs # Project registry (PROJECTS env, CLAUDE_PROJECTS_ROOT scan)
│ ├── claude.rs # Claude CLI NDJSON streaming parser + subprocess
│ ├── task.rs # Task registry, spawn/kill discipline, progress watch
│ ├── taskdir.rs # Per-task inbox/outbox directory lifecycle
│ ├── lib.rs # Library crate root (integration test access)
│ ├── session.rs # Session file read/write (Python-compatible, quarantine)
│ ├── markdown.rs # comrak AST → Telegram-safe HTML
│ ├── message.rs # Message splitting with HTML tag tracking
│ ├── voice.rs # whisper-rs transcription (feature-gated)
│ └── service.rs # systemd/launchd install/uninstall
├── skills/
│ ├── telegram-sender/ # Send messages from Claude sessions
│ └── daily-brief/ # Morning briefing skill
├── tests/
│ ├── kill_path.rs # Integration tests: kill discipline, retry
│ ├── taskdir_tests.rs # Integration tests: task dir lifecycle, outbox
│ ├── add_dir_spike.rs # Permission spike: --add-dir flag (#[ignore])
│ ├── canary.rs # CLI canary test (#[ignore])
│ ├── bin/fake-claude.sh # Fake CLI for integration tests
│ └── fixtures/ # NDJSON test fixtures
├── scripts/
│ └── capture-fixture.sh # Regenerate NDJSON fixtures from CLI
├── .env.example
├── CLAUDE.md.example # Template for your Claude workspace
└── LICENSE
📄 License
GPL-3.0-or-later — see LICENSE