Telegram Bot 中转项目(TG 收发 + Codex 实时流式回传 + 文件上传直读/下载 + 备份迁移)。
运行与部署请优先看:
- Webhook 接收 Telegram 消息(实时)
- 调用
codex app-server处理消息 - 流式输出到 Telegram(
sendMessageDraft+item/agentMessage/delta) - 按 chat 持久化多个 Codex 对话(
/new命名当前后新建、/switch切换、/clear删除) /new触发命名“当前对话”流程(命名后新建并切换,保留旧对话)- 文件上传后自动保存,并可直接交给 Codex 读取/分析
/get <路径|文件名|id>下载服务器文件或已上传文件(仅白名单)/export导出会话文本- 支持自动清理计划(周期清理历史文件与导出)
- 可选访问白名单(限定 user_id / chat_id)
- 可选人格文件注入(仅新会话首次注入)
- 本地 SQLite 持久化(便于备份/迁移)
- 可选自建
telegram-bot-api(支持大文件)
.
├── app/
│ ├── main.py
│ ├── config.py
│ ├── db.py
│ ├── llm.py
│ └── bot_api.py
├── persona/
│ └── SOUL.md
├── scripts/
│ ├── init_bot.sh
│ ├── deploy.sh
│ ├── backup.sh
│ ├── restore.sh
│ ├── switch_to.sh
│ └── switch_to_local_bot_api.sh
├── storage/
│ ├── app/ # bot.db + files
│ ├── tg-bot-api/ # 本地 Bot API 数据目录
│ └── backups/ # 备份包
├── Dockerfile
├── docker-compose.yml
└── .env.example
- 一台 Linux VPS(建议 1C1G 起)
- 域名(Webhook 推荐 HTTPS)
- Telegram Bot Token
- 可用的 Codex 配置(宿主机路径通过
CODEX_HOST_DIR指定,常见为$HOME/.codex) - 环境安装方法(Docker / Docker Compose)见
RUN_DEPLOY.md的「1. 前置条件」与「2. 环境安装」
cd "$HOME/tg-bot-stack"
cp .env.example .env
# 编辑 .env: BOT_TOKEN、CODEX_HOST_DIR
# 如有域名,保留 TELEGRAM_RUN_MODE=webhook 并设置 WEBHOOK_URL/PUBLIC_DOMAIN
# 如暂时无域名,改为 TELEGRAM_RUN_MODE=polling
docker compose --profile edge up -d --build
./scripts/init_bot.sh或直接一键:
cd "$HOME/tg-bot-stack"
./scripts/deploy.sh说明:deploy.sh 现在会先进入交互式配置(默认中文,可选英文),已填写项可直接回车保留。
所选语言会同步写入 TELEGRAM_MENU_LANGUAGE,用于 Telegram / 菜单描述;命令关键字本身仍保留英文(Telegram 限制)。
多数交互项支持输入 back 返回上一步(例如运行模式选错可直接回退)。
可选配置访问白名单(仅允许指定用户或群)。
可选启用/关闭人格文件注入(仅新会话首次生效)。
如果选择启用本地 telegram-bot-api profile,会继续提示填写 TELEGRAM_API_ID 与 TELEGRAM_API_HASH,并可选择自动切换本地 BOT_API_BASE_URL。
支持选择部署后端:docker(默认)或 host(宿主机进程)。
若检测到环境缺失,docker 与 host 两种模式都会提示是否自动安装依赖。
无域名推荐(轮询):
cd "$HOME/tg-bot-stack"
cp .env.example .env
# 填 BOT_TOKEN
sed -i 's#^TELEGRAM_RUN_MODE=.*#TELEGRAM_RUN_MODE=polling#' .env
sed -i 's#^ENABLE_EDGE_PROFILE=.*#ENABLE_EDGE_PROFILE=0#' .env
./scripts/deploy.sh健康检查:
curl -fsS http://127.0.0.1:9000/healthz/new触发命名“当前对话”流程(命名后新建并切换,保留旧对话)/cancel取消进行中的/new命名流程/switch [n]列出/切换 Codex 对话映射/clear [n|all]列出/删除 Codex 对话映射(all删除全部)/get <路径|文件名|id>下载文件(仅白名单)- 直接发送图片/文件给机器人即可读取;可附带 caption 说明需求
/export导出当前会话记录/cleanup [n]清理历史文件/导出(默认保留最近 10 个文件)/doctor健康诊断(队列、进程、存储、自动清理状态)/cost查看本月估算消耗与剩余额度/model查看模型/sh <cmd>在 VPS 执行 shell 命令(仅私聊,需启用)/ping连通性测试/whoami查看当前user_id/chat_id/help帮助
可在 .env 配置:
TELEGRAM_ALLOWED_USER_IDS=123456789,987654321
TELEGRAM_ALLOWED_CHAT_IDS=-1001234567890规则:
- 两项都为空:允许所有人(默认)
- 配置后:仅允许命中的
user_id或chat_id - 可发送
/whoami获取当前会话 ID - 只允许指定几个人:仅填
TELEGRAM_ALLOWED_USER_IDS - 允许整个群所有人:把群
chat_id填到TELEGRAM_ALLOWED_CHAT_IDS
默认文件:
persona/SOUL.md
配置项:
ENABLE_PERSONA_FILE=true
PERSONA_FILE_PATH=/app/persona/SOUL.md注入规则:
- 仅新会话首次消息注入
- 旧会话不重复注入
/new创建并切换的新对话会注入一次- 关闭
ENABLE_PERSONA_FILE后不注入
- 直接在 TG 给机器人发文件,机器人会下载到服务器并返回文件 ID
- 使用
/get <路径|文件名|id>可下载服务器文件或已上传文件 - 如果按文件名匹配到多个结果,机器人会列出路径并等待你回复序号选择
- 默认受
MAX_FILE_MB限制
ENABLE_AUTO_CLEANUP=true
AUTO_CLEANUP_INTERVAL_SEC=21600
AUTO_CLEANUP_KEEP_FILES=10
AUTO_CLEANUP_EXPORT_KEEP_COUNT=20
AUTO_CLEANUP_EXPORT_KEEP_DAYS=30
AUTO_CLEANUP_SCAN_LIMIT=5000说明:
- 自动清理后台任务会按
AUTO_CLEANUP_INTERVAL_SEC周期执行。 - 每个会话保留最近
AUTO_CLEANUP_KEEP_FILES个文件记录,其余文件会尝试删除磁盘与数据库记录。 - 导出文件(
exports/*.txt)按“保留最近 N 份 + 保留最近 N 天”双规则清理。 - 可随时使用
/doctor查看自动清理最近一次执行时间与结果摘要。
COST_TOKEN_PER_CHAR=0.28
COST_INPUT_USD_PER_1M_TOKENS=0
COST_OUTPUT_USD_PER_1M_TOKENS=0
COST_MONTHLY_BUDGET_USD=0说明:
- 使用
/cost查看“当前会话 + 全局”本月估算消耗。 - 估算方式:按消息字符数换算 token,再按每百万 token 单价换算费用。
COST_MONTHLY_BUDGET_USD大于 0 时,会显示本月剩余额度。- 这是估算值,不等同 provider 实际账单。
- 私聊下启用实时增量展示:官方 Telegram Bot API 默认使用
sendMessage+editMessageText - 若上游兼容
sendMessageDraft,会继续使用 draft 方式;不可用时自动回退为消息编辑预览 - 长任务会额外显示阶段状态与心跳时间,例如“思考中 / 执行命令 / 调用工具 / 整理回复”
- 回答较短时会直接把预览消息收敛为最终回复;较长时删除预览消息后分段发送完整内容
- 若任务长时间无任何事件返回,仍会受到空闲超时约束;在已经收到真实进度后,会自动切换到更长的活跃超时窗口
可选参数:
STREAM_PROGRESS_HEARTBEAT_SEC=5STREAM_PROGRESS_HEARTBEAT_SEC:长任务预览的心跳刷新周期(秒),默认 5 秒。
TELEGRAM_RUN_MODE=webhook:需要公网 HTTPS 地址(推荐生产)TELEGRAM_RUN_MODE=polling:无需域名,机器人主动拉消息(适合先跑通)- 可使用
./scripts/switch_to.sh交互式一键切换(支持中文/英文显示)
CODEX_APP_SERVER_CMD="codex app-server --listen stdio://"
CODEX_SANDBOX_MODE=workspace-write
CODEX_THREAD_CWD=/app
CODEX_REQUEST_TIMEOUT_SEC=180
CODEX_TURN_STREAM_IDLE_TIMEOUT_SEC=300
CODEX_TURN_ACTIVE_STREAM_IDLE_TIMEOUT_SEC=600说明:
CODEX_APP_SERVER_CMD:固定标准启动命令(codex app-server --listen stdio://),由脚本统一维护。CODEX_SANDBOX_MODE:Codex 线程沙箱模式,可选workspace-write/danger-full-access。CODEX_THREAD_CWD:Codex 新会话工作目录(docker/host切换时可自动同步默认值)。CODEX_REQUEST_TIMEOUT_SEC:RPC 请求超时(如turn/start),默认 180 秒。CODEX_TURN_STREAM_IDLE_TIMEOUT_SEC:流式阶段在“尚未收到任何真实进度”时的无事件超时,默认 300 秒。CODEX_TURN_ACTIVE_STREAM_IDLE_TIMEOUT_SEC:一旦已经收到真实进度,后续静默等待的活跃超时,默认 600 秒,适合长任务整理最终结果。./scripts/deploy.sh交互里仅保留两种权限模式:标准模式(workspace-write)和全权限模式(danger-full-access)。
ENABLE_TELEGRAM_SHELL=false
SHELL_COMMAND_TIMEOUT_SEC=120
SHELL_OUTPUT_MAX_CHARS=12000说明:
ENABLE_TELEGRAM_SHELL=true后可在 TG 私聊使用/sh <cmd>(/exec <cmd>也可)。- 命令执行目录默认使用
CODEX_THREAD_CWD,建议你在高权限模式下明确设置。 - 强烈建议同时配置
TELEGRAM_ALLOWED_USER_IDS,只放你自己的 user_id。
DEPLOY_RUNTIME_MODE=docker
AUTO_SWITCH_RUNTIME_PATHS=1
DOCKER_AUTO_INSTALL_DEPS=1
HOST_AUTO_INSTALL_DEPS=1
HOST_AUTO_CONFIG_NGINX_WEBHOOK=1
HOST_AUTO_ISSUE_CERTBOT_CERT=1
CERTBOT_ACCOUNT_EMAIL=you@example.com
HOST_SERVICE_MODE=systemd
HOST_SYSTEMD_SERVICE_NAME=tg-bot-stack.service
TG_BOT_UPSTREAM=bot:9000说明:
DEPLOY_RUNTIME_MODE:docker或host(宿主机进程)。AUTO_SWITCH_RUNTIME_PATHS=1:切换docker/host时自动改DATABASE_PATH、FILE_STORAGE_PATH、PERSONA_FILE_PATH、CODEX_THREAD_CWD,免手工改路径。DOCKER_AUTO_INSTALL_DEPS=1:Docker 模式检测到缺失环境(docker/ compose 插件)时可自动安装。HOST_AUTO_INSTALL_DEPS=1:宿主机模式检测到缺失环境时可自动安装。HOST_AUTO_CONFIG_NGINX_WEBHOOK=1:host + webhook时,如检测到nginx且存在对应域名证书,会自动生成并启用server_name=<PUBLIC_DOMAIN>的反代站点,避免 webhook 404。HOST_AUTO_ISSUE_CERTBOT_CERT=1:host + webhook且缺证书时,尝试使用certbot --nginx自动申请/续期证书(需 root、域名已解析到本机)。CERTBOT_ACCOUNT_EMAIL:Let's Encrypt 账户通知邮箱。建议填写,便于接收到期/失败提醒;留空则回退为无邮箱模式。HOST_SERVICE_MODE:systemd(守护+开机启动)或nohup(后台运行)。HOST_SYSTEMD_SERVICE_NAME:宿主机模式下的 systemd 服务名。TG_BOT_UPSTREAM:反向代理上游地址;deploy.sh会按后端模式自动设置(docker=bot:9000,host=127.0.0.1:9000)。
CONTAINER_RESTART_POLICY=unless-stopped
ENABLE_DOCKER_BOOT_AUTOSTART=0说明:
CONTAINER_RESTART_POLICY:容器守护/重启策略,推荐unless-stopped(no表示不自动重启)。ENABLE_DOCKER_BOOT_AUTOSTART=1:部署时尝试执行systemctl enable --now docker(要求宿主机使用 systemd 且具备 root 权限)。
用途:提高文件能力(例如更大上传)。
- 在
my.telegram.org申请TELEGRAM_API_ID/TELEGRAM_API_HASH - 写入
.env - 执行:
cd "$HOME/tg-bot-stack"
./scripts/switch_to_local_bot_api.sh该脚本会自动:
- 调用云端
logOut - 启动本地
telegram-bot-api - 修改
.env的BOT_API_BASE_URL/BOT_API_FILE_BASE_URL - 设置
ENABLE_LOCAL_BOT_API_PROFILE=1 - 重启应用并重新注册 webhook
费用说明:
TELEGRAM_API_ID/HASH申请免费- Telegram 不按 Bot API 请求收费
- 本地
telegram-bot-api运行成本来自你自己的服务器资源
如果你同时使用 HTTPS 入口与本地 Bot API,启动命令可以是:
docker compose --profile edge --profile localbotapi up -d --buildcd "$HOME/tg-bot-stack"
./scripts/backup.sh产物在 storage/backups/:
tg-bot-stack-<host>-<timestamp>.tar.gz- 对应
sha256文件
# 新机
mkdir -p "$HOME/tg-bot-stack"
# 将备份包拷贝到新机后执行
"$HOME/tg-bot-stack"/scripts/restore.sh /path/to/backup.tar.gz "$HOME/tg-bot-stack"
cd "$HOME/tg-bot-stack"
# 校验 .env(域名、密钥、IP 如有变化请更新)
docker compose up -d --build
./scripts/init_bot.sh- TG 仅做中转,计费由 Codex provider 决定
- 流式展示本身通常不会显著增加 token
- 会话越长成本越高,建议定期
/new
TELEGRAM_WEBHOOK_SECRET必填BOT_TOKEN、TELEGRAM_API_HASH、Codex provider 密钥(如有)不要提交到 git- 反向代理层启用 HTTPS
- 定时备份并做恢复演练
MIT