一日一撸(No.2):离开电脑就用不了 Claude?试试 Telegram Bot

起因:一个周末的小烦恼

上周末在咖啡馆坐着,突然想起有个 bug 没修。打开手机想用 Claude Code 看一眼,结果发现——它只能在终端里跑

回家开电脑?太麻烦了。用 OpenClaw?我试过,配置 Web 服务器、Nginx 反向代理、HTTPS 证书……折腾了一下午,最后发现我只是想改几行代码而已。

这时候我想:能不能直接在 Telegram 里跟 Claude 聊天?

Telegram 有现成的 Bot API,不需要自己搭服务器,消息推送也是长连接,安全性由 Telegram 保证。听起来很适合做这件事。

于是周末两天,撸了个 Telegram Bot 版本的 Claude Code 遥控器。

痛点:为什么不用 OpenClaw?

OpenClaw 是个很棒的项目,但它解决的是"把 Claude 搬到云端"的问题,适合团队协作或者需要完整 Web IDE 的场景。

我的需求更简单:

  • 只想在手机上偶尔操作一下,不需要完整的浏览器界面
  • 不想折腾服务器配置,端口暴露、防火墙、SSL 证书这些东西太重了
  • 已经在用 Claude Code CLI,只是想加个远程入口

所以我需要的是一个"轻量级的后门",而不是一个完整的 Web 应用。

开发过程:从 0 到 1

第一步:验证可行性

先写了个最简单的 Demo:

from telegram import Update
from telegram.ext import Application, MessageHandler

async def handle_message(update: Update, context):
    user_input = update.message.text
    # 调用 Claude CLI
    result = subprocess.run(['claude', user_input], capture_output=True)
    await update.message.reply_text(result.stdout)

跑起来发现——能用! 虽然很粗糙,但核心逻辑通了。

第二步:解决流式响应

Claude Code 的输出是流式的,直接用 subprocess.run 会卡住。改成异步读取:

process = await asyncio.create_subprocess_exec(
    'claude', user_input,
    stdout=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE
)

async for line in process.stdout:
    await update.message.reply_text(line.decode())

这样就能实时看到 Claude 的回复了。

第三步:处理交互式问题

Claude Code 有时会问问题(比如 AskUserQuestion),需要把选项转成 Telegram 的内联键盘。

这部分花了点时间,因为要解析 Claude 的输出格式,识别出哪些是问题、哪些是选项。最后用正则表达式 + JSON 解析搞定了。

第四步:会话管理

每个用户的对话需要独立的会话,不能互相干扰。写了个简单的 SessionManager

class SessionManager:
    def __init__(self):
        self.sessions = {}

    def get_session(self, user_id):
        if user_id not in self.sessions:
            self.sessions[user_id] = Session(user_id)
        return self.sessions[user_id]

支持三种存储方式:JSON 文件(默认)、Redis、SQLite。开发时用 JSON,生产环境可以换 Redis。

第五步:文件访问沙箱

Claude Code 可以读写文件,但我不想让它随便访问系统文件。加了个简单的沙箱机制:

  • 项目目录内的文件自动允许
  • 项目目录外的文件需要用户确认

这样既方便又安全。

第六步:后台守护进程

最后加了个启动脚本 start.sh,支持后台运行和自动重启:

#!/bin/bash
while true; do
    python -m telegram_bot
    echo "Bot crashed, restarting in 5 seconds..."
    sleep 5
done

macOS 还可以用 launchd 配置开机自启。

项目特点

1. 零基础设施

不需要 Web 服务器、不需要端口暴露、不需要配置 HTTPS。Telegram 自带长连接,消息推送由 Telegram 服务器处理。

2. 默认安全

  • 文件访问沙箱化
  • 支持用户白名单(ALLOWED_USER_IDS
  • 敏感操作需要确认

3. 轻量级

依赖少,代码简单,出问题了直接看源码就能改。核心逻辑就几百行。

4. 功能完整

  • 支持流式响应
  • 支持交互式问题(内联键盘)
  • 支持会话恢复
  • 支持模型切换(Sonnet/Opus/Haiku)
  • 支持斜杠命令(/commit/xhs-writer 等)

上手指南

1. 获取 Telegram Bot Token

@BotFather 创建一个 Bot,拿到 Token。

2. 克隆仓库

git clone https://github.com/terranc/claude-telegram-bot-bridge
cd claude-telegram-bot-bridge/telegram_bot

3. 配置环境变量

cp .env.example .env
# 编辑 .env,填入以下内容:
# TELEGRAM_BOT_TOKEN=你的Token
# PROJECT_ROOT=/path/to/your/project
# ALLOWED_USER_IDS=你的Telegram用户ID

4. 安装依赖

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

5. 启动

./start.sh

然后在 Telegram 里给你的 Bot 发消息就行了。

项目地址

GitHub: https://github.com/terranc/claude-telegram-bot-bridge

欢迎提 Issue 或 PR。如果你也觉得 OpenClaw 太重,可以试试这个方案。

后记

这个项目从想法到能用,大概花了一个周末。代码不复杂,但解决了我的实际问题。

有时候工具不需要很完美,够用就行。OpenClaw 是一辆卡车,我这个是一辆自行车——看你要运货还是通勤。

下一步可能会加个语音输入功能,这样在路上也能用语音跟 Claude 对话。不过这是后话了。

先这样,继续撸代码去了 🚀