Skip to content

liangyimingcom/claudecode-telegram

Repository files navigation

claudecode-telegram

中文文档

demo

Telegram bot bridge for Claude Code. Send messages from Telegram, get responses back.

How it Works

flowchart TB
    subgraph Telegram["Telegram"]
        TG[Telegram App]
        API[Telegram Bot API]
    end

    subgraph Internet["Internet"]
        CF[Cloudflare Tunnel]
    end

    subgraph Local["Local System"]
        subgraph Bridge["Bridge Server (bridge.py)"]
            HTTP[HTTP Handler<br/>Port 8091]
            CMD[Command Processor<br/>/status /clear /resume /stop]
            TMUX_CTRL[Tmux Controller<br/>send-keys injection]
        end

        subgraph Files["File System (~/.claude/)"]
            CHAT[telegram_chat_id]
            PEND[telegram_pending]
            SETTINGS[settings.json<br/>Stop Hook config]
            HOOK_FILE[hooks/send-to-telegram.sh]
        end

        subgraph Claude["Claude Code"]
            CC[claude --dangerously-skip-permissions]
            HOOK[Stop Hook Trigger]
            TRANSCRIPT[transcript.jsonl]
        end

        SESS[tmux Session: claude]
    end

    TG --> API
    API --> CF
    CF --> HTTP
    HTTP --> CMD
    CMD --> TMUX_CTRL
    TMUX_CTRL -->|"tmux send-keys"| SESS
    SESS --> CC
    CC -->|"Stop Hook"| HOOK
    HOOK -->|"Read transcript"| TRANSCRIPT
    HOOK -->|"Send Response"| API

    CMD -->|"Write"| CHAT
    CMD -->|"Write"| PEND
    HOOK -->|"Read"| CHAT
    HOOK -->|"Read/Delete"| PEND
    CC -->|"Load"| SETTINGS
Loading

Data Flow

  1. Message Receive: Telegram → Cloudflare Tunnel → Bridge Server
  2. Message Injection: Bridge Server → tmux send-keys → Claude Code
  3. Response Capture: Claude Code Stop Hook → Read transcript.jsonl → Parse output
  4. Response Send: Stop Hook → Telegram Bot API → Telegram

Prerequisites

# macOS
brew install tmux cloudflared

# Verify claude is installed
claude --version

# Setup Python env
uv venv && source .venv/bin/activate
uv pip install -e .

Quick Start

1. Clone the Project

git clone https://github.com/liangyimingcom/claudecode-telegram
cd claudecode-telegram

2. Create a Telegram Bot

  1. Search for @BotFather on Telegram
  2. Send /newbot and follow the prompts
  3. Get your Bot Token (looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz)

3. One-Click Start (Recommended)

# Set Bot Token
export TELEGRAM_BOT_TOKEN="your_token_from_botfather"

# Run startup script
./start-bridge.sh

The startup script will automatically:

  • Check environment variables and dependencies
  • Create ~/.claude/hooks directory
  • Install Hook script and update Bot Token
  • Merge Hook config into ~/.claude/settings.json (preserves existing settings)
  • Create tmux session and start Claude Code
  • Start Cloudflare Tunnel and set Telegram Webhook
  • Start Bridge Server

To stop everything:

./stop-clean-bridge.sh

4. Manual Setup (Alternative)

Install Hook Script

# Create directory
mkdir -p ~/.claude/hooks

# Copy hook script
cp hooks/send-to-telegram.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/send-to-telegram.sh

# Set your Bot Token in the hook
nano ~/.claude/hooks/send-to-telegram.sh
# Modify TELEGRAM_BOT_TOKEN="your_token_here"

Or set via environment variable (recommended):

export TELEGRAM_BOT_TOKEN="your_token"

Configure settings.json

Add Hook config to ~/.claude/settings.json:

{
  "hooks": {
    "Stop": [{"hooks": [{"type": "command", "command": "~/.claude/hooks/send-to-telegram.sh"}]}]
  }
}

Start tmux + Claude Code

tmux new -s claude
claude --dangerously-skip-permissions

Run Bridge Server

In another terminal:

export TELEGRAM_BOT_TOKEN="your_token"
python3 bridge.py

Expose to Internet

cloudflared tunnel --url http://localhost:8091

Set Telegram Webhook

curl "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/setWebhook?url=https://YOUR-TUNNEL-URL.trycloudflare.com"

Bot Commands

Command Description Behavior
/status Check status Returns tmux session status
/clear Clear conversation Sends /clear command to Claude Code
/stop Interrupt operation Sends Escape key to interrupt
/resume Resume session Shows recent sessions as inline keyboard
/continue_ Continue recent Auto-continues most recent session
/loop <prompt> Ralph Loop Runs prompt with max 5 iterations

Environment Variables

Variable Default Description
TELEGRAM_BOT_TOKEN required Bot token from BotFather
TMUX_SESSION claude tmux session name
PORT 8091 Bridge Server listen port
SKIP_TUNNEL unset Set to 1 to skip cloudflared tunnel
WEBHOOK_URL unset Manually specify Webhook URL (when SKIP_TUNNEL=1)

File Structure

.
├── bridge.py                           # Bridge Server
├── start-bridge.sh                     # One-click startup script
├── stop-clean-bridge.sh                # Stop and cleanup script
├── hooks/
│   └── send-to-telegram.sh             # Claude Code Stop Hook script
├── pyproject.toml                      # Python project config
├── README.md                           # English documentation
└── README-cn.md                        # Chinese documentation

Runtime Files

File Path Description
Settings ~/.claude/settings.json Claude Code settings, defines Stop Hook
Hook Script ~/.claude/hooks/send-to-telegram.sh Response sending script
Chat ID ~/.claude/telegram_chat_id Current Telegram chat ID
Pending Flag ~/.claude/telegram_pending Pending message timestamp
History ~/.claude/history.jsonl Claude session history (for /resume)

Hook Configuration

Claude Code uses ~/.claude/settings.json to configure hooks:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/send-to-telegram.sh"
          }
        ]
      }
    ]
  }
}
  • hooks.Stop: Defines Stop Hook, triggered when Claude Code completes a response
  • The hook reads transcript_path from stdin to extract the assistant's response
  • Response is converted from Markdown to HTML and sent to Telegram

Troubleshooting

Check tmux Session

# List sessions
tmux ls

# Attach to session
tmux attach -t claude

Check Pending File Status

# View pending file
cat ~/.claude/telegram_pending

# Manual cleanup (if stuck)
rm ~/.claude/telegram_pending

Port Conflict

If port 8091 is already in use, you'll see:

Error: Port 8091 is already in use
Please specify a different port: export PORT=<port> (current default: 8091)

Solution: Use a different port via environment variable:

PORT=9091 ./start-bridge.sh

Or check what's using the port and stop it:

lsof -i :8091
kill -9 <PID>

Common Issues

Issue Cause Solution
No response after sending message tmux session doesn't exist Run tmux new -s claude to start session
Hook not triggering settings.json not configured Verify Stop Hook in ~/.claude/settings.json
Response timeout Pending file expired (>10 min) Check system time, clean pending file
HTML format error Markdown conversion failed Hook falls back to plain text automatically
Address already in use Port 8091 occupied Use PORT=9091 ./start-bridge.sh

Error Handling

Pending File Timeout

If the pending file is older than 10 minutes, the Stop Hook will automatically delete it and skip sending the response.

Telegram API Error

If HTML format sending fails, the Hook automatically falls back to plain text format.

tmux Session Disconnected

If the tmux session doesn't exist, the Bridge Server returns a "tmux not found" error message to Telegram.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors