Cline CLI Telegram Connector:把 Cline 编码代理接入 Telegram 机器人的完整实战指南
Cline CLI 的 Telegram Connector 让你通过一个 Telegram Bot 远程驱动 Cline 编码代理会话:无需公网 webhook,只需本地常驻一个轮询进程,就能在手机上提问、下达编码任务、审批工具调用,甚至接收定时任务的执行结果。本篇基于仓库文档 telegram.md 与对应源码 telegram.ts、telegram-format.ts 展开,覆盖启动配置、聊天命令、访问控制与消息投递的全部细节。
一、架构定位:一个纯轮询的本地桥接进程
Telegram Connector 是 Cline CLI 内置的多个聊天平台连接器之一(与 Slack、Discord、Google Chat、WhatsApp、Linear 并列,见 adapters 目录)。它的核心特征是:
- 轮询(polling)而非 webhook:底层通过
@chat-adapter/telegram适配器以mode: "polling"方式运行(见 telegram.ts 中createTelegramAdapter的调用),因此不需要公网可达的回调地址,适合直接跑在开发机或内网服务器上。 - RPC 会话桥接:每个 Telegram 线程(thread)对应一个 Cline RPC-backed 会话,由
HubSessionClient连接到本地 Hub 服务器,会话与线程状态通过线程绑定文件持久化,实现"聊天历史和工作目录状态按线程隔离"(见 thread-bindings.ts)。 - 进程即服务:连接器进程必须保持运行,进程停机后 Telegram 侧所有能力(收消息、审批、定时投递)全部不可用。
启动成功后,终端会打印连接信息,形如:
[telegram] connected as @my_bot mode=polling rpc=127.0.0.1:PORT provider=... model=... tools=on
[telegram] send /clear in a chat to start a fresh RPC session
[telegram] send /whereami in a chat to get its delivery thread id
[telegram] use /tools, /yolo, or /cwd <path> to update runtime settings
[telegram] send /exit in a chat or press Ctrl+C to stop
(对应源码 telegram.ts。)
二、快速开始:从 BotFather 到启动连接器
1. 创建 Bot
- 打开 Telegram,与
@BotFather开始对话。 - 发送
/newbot,按提示完成命名。 - 复制 Bot token。它等同于密码,务必妥善保管(建议放入环境变量,不要提交进仓库)。
2. 启动连接器
cline connect telegram -k "$TELEGRAM_BOT_TOKEN"
Connector 会用 token 调用 Telegram 的 getMe 接口自动发现 bot 用户名(实现见 telegram.ts 的 fetchTelegramBotUsername),只有在需要覆盖时(例如离线场景无法调用 API)才需传 --bot-username。
启动后在 Telegram 里给 bot 发 /help 或 /start 即可验证连通。
3. 常用变体命令
# 调试时把日志留在当前终端(前台运行)
cline connect telegram -i -k "$TELEGRAM_BOT_TOKEN"
# 从环境变量读取凭据
TELEGRAM_BOT_TOKEN=123456:ABCDEF... cline connect telegram
# 覆盖 Telegram 会话使用的工作区与模型
cline connect telegram -k "$TELEGRAM_BOT_TOKEN" --cwd /path/to/repo --provider cline --model openai/gpt-5.3-codex
# 不可信的 Telegram 入口禁用工具
cline connect telegram -k "$TELEGRAM_BOT_TOKEN" --no-tools
# 停止所有 Telegram connector 进程与会话
cline connect --stop telegram
三、完整命令行参数与环境变量
以下参数表基于源码 telegram.ts 中 createCommand() 的 Commander 定义整理,并补充了 readOptions 中的解析逻辑:
| 参数 | 说明 | 备注 |
|---|---|---|
-k, --bot-token <token> |
Telegram bot token | 缺省时回退读取环境变量 TELEGRAM_BOT_TOKEN;两者都没有则报错 |
-m, --bot-username <name> |
Bot 用户名 | 省略时通过 getMe 从 token 发现;也支持环境变量 TELEGRAM_BOT_USERNAME |
--cwd <path> |
运行时工作区/工作目录 | 默认 process.cwd() |
--provider <id> |
Provider 覆盖 | 默认沿用 CLI 最近使用的 provider 设置 |
--model <id> |
模型覆盖 | 同上 |
--api-key <key> |
Provider API Key 覆盖 | 可选 |
--system <prompt> |
系统提示词覆盖 | 可选 |
--mode <act|plan> |
Agent 模式 | 默认 act |
-i, --interactive |
前台运行连接器 | 不加则后台启动 |
--no-tools |
禁用该 Telegram 会话的全部工具 | 工具默认开启(enableTools: opts.tools !== false) |
--allowed-user-id <id> |
仅允许指定数字 Telegram 用户 ID 使用 bot | 只允许纯数字;与 --hook-command 互斥 |
--hook-command <command> |
对连接器事件执行自定义 shell 命令 | 也支持环境变量 CLINE_CONNECT_HOOK_COMMAND |
--rpc-address <host:port> |
RPC 地址 | 默认取 CLINE_RPC_ADDRESS 或解析的默认地址 |
类型定义上,Telegram 连接器的选项被声明为 ConnectTelegramOptions,运行状态持久化为 TelegramConnectorState(含 botUsername、botId、pid、rpcAddress、startedAt)。状态文件按 bot 用户名命名(<bot>.json 与 <bot>.threads.json),这也是 cline connect --stop telegram 能精确停掉进程并清理该 bot 会话的原因(见 stopTelegramConnectorInstance)。
源码中还有一处值得注意的健壮性设计:token 格式为 <botId>:<secret>,连接器会从 token 前半段解析出数字 botId(readTelegramBotId),用于在只给 token、没给 bot 用户名时检测"同一 bot 的连接器是否已在运行",避免重复启动(runWithOptions 中的 findRunningConnectorStateByBotId 检查)。
四、Telegram 聊天命令
Telegram 连接器复用共享的连接器命令解析器(connector command host),支持的命令如下:
| 命令 | 作用 |
|---|---|
/help 或 /start |
显示连接器帮助 |
/new 或 /clear |
为当前线程开启全新会话 |
/whereami |
显示线程 ID、cwd、工具开关、yolo 状态 |
/tools [on|off|toggle] |
允许或禁用仓库/文件/Shell 工具 |
/yolo [on|off|toggle] |
自动批准工具调用 |
/cwd <path> |
切换工作目录 |
/schedule create/list/trigger/delete |
管理定时工作流 |
/abort |
停止当前任务 |
/exit |
停止连接器 |
群组里的 bot 定向命令(如 /help@my_bot)只在后缀与配置的 bot 用户名匹配时才被规范化处理;发给其他 bot 的命令会被忽略。
从源码结构看,斜杠命令的处理链路比较特殊:Telegram 的 chat 适配器会把首个实体为 bot_command 的消息拦截下来,如果连接器不注册处理器,这些命令会被直接吞掉、永远到不了聊天命令主机。因此 createTelegramSlashCommandHandler 会重建原始聊天线程,把原始消息文本(保留群组中 @bot 定向写法)转发回与普通消息相同的 turn 流水线。普通消息则分别走 bot.onNewMention(@bot 提及)与 bot.onSubscribedMessage(已订阅线程)两个入口(telegram.ts)。
五、工具权限与访问控制
工具默认开启意味着:任何能成功给 bot 发消息的人,都可能要求它检查或修改你配置的工作区。对不受信任的入口,应使用 --no-tools:
cline connect telegram -k "$TELEGRAM_BOT_TOKEN" --no-tools
关键行为:一旦以 --no-tools 启动,/tools on、/yolo on 等聊天命令无法在该次运行中重新开启工具——源码中通过 forceDisableTools: !options.enableTools 传入 turn 处理逻辑(telegram.ts),聊天命令只能收窄、不能突破启动时的上限。
用户白名单
有三种方式限制可访问 bot 的用户:
-
交互式向导:运行
cline connect,Telegram 向导会询问是否限制访问,并指引你通过@userinfobot查询自己的数字用户 ID。 -
直接传参:
cline connect telegram -k "$TELEGRAM_BOT_TOKEN" --allowed-user-id 12345源码实现上,
--allowed-user-id并不是一个独立的过滤层,而是在 buildTelegramAllowedUserHookCommand 中自动合成为一条--hook-command:jq -r ".payload.actor.participantKey" | grep -qx "telegram:id:12345" && echo '{"action":"allow"}' || echo '{"action":"deny","message":"unauthorized","reason":"not_on_allowlist"}'即:对授权事件取
participantKey,精确匹配telegram:id:<userId>才放行。参与者键的生成规则见 resolveTelegramParticipant——优先使用数字 ID(telegram:id:<id>),回退到用户名(telegram:user:<username>),同时从message/edited_message/channel_post多种事件载体中提取from信息。 -
手动
--hook-command:自行编写返回{"action":"deny"}的 shell 命令来拒绝未授权事件。注意--allowed-user-id与--hook-command不可同时使用,源码会显式抛出错误(telegram.ts)。
如果两者都没配置,消息默认放行——这是把 bot 暴露到群组前必须注意的一点。
工具审批
需要授权的工具调用会推送到 Telegram,用户直接回复 Y(允许)或 N(拒绝)即可。源码中每个消息入口在进入 turn 之前都会先经过 maybeHandleConnectorApprovalReply(telegram.ts),命中待审批记录时优先消费 Y/N 回复,拒绝原因记录为 "Denied by Telegram user"。
六、消息投递机制:Markdown 实体、分块与降级
Telegram 的最终助手回复不经过普通 chat 适配器的流式通道,而是在运行时 turn 完成后直接走 Telegram sendMessage 接口发送(postFinalReply 回调,见 telegram.ts)。实现位于 telegram-format.ts,核心设计:
- Markdown 转 entities:用
markdownToFormattable把模型输出中的 Markdown 片段转成 Telegram 的message entities(加粗、代码、链接等),避免直接发送 Markdown 文本触发 Telegram 的 parse 错误。 - 4096 字符分块:
TELEGRAM_MESSAGE_LIMIT = 4096,超长回复被切成多段;切割时 entity 的 offset/length 会按每段重新计算并裁剪,保证跨块 entity 不错位(chunkFormattedMessage)。 - thread 定位:线程 ID 支持
telegram:<chatId>或telegram:<chatId>:<messageThreadId>两种格式,后者用于论坛超话题(parseTelegramThreadId),发送载荷中相应携带message_thread_id。 - 降级路径:entity 发送失败时,连接器回退为原始纯文本,按 4096 字符分片经适配器的普通
thread.post路径发出(postTelegramFormattedReply 的 catch 分支),已发出的分片之后的剩余文本会被拼接回退,避免内容丢失。 - 工具/状态更新和定时投递消息则统一走适配器的原始线程投递路径,不做 Markdown 实体处理。
作为对比,Google Chat 与 WhatsApp 连接器使用的是共享运行时流式通道做增量文本推送,而 Telegram 选择"turn 完成后再整体格式化发送"的模型。
七、定时任务结果投递到 Telegram
当定时任务的执行结果需要回推到 Telegram 时,推荐直接在 Telegram 聊天中创建 schedule:
- 启动 Telegram 连接器;
- 在 Telegram 中发送:
/schedule create "Daily summary" --cron "0 9 * * *" --prompt "Summarize yesterday's activity in this workspace."
这样创建的 schedule 会自动把当前 Telegram 线程设为投递目标。也可以在 Telegram 里使用 /schedule list、/schedule trigger <schedule-id>、/schedule delete <schedule-id> 管理。
若在 Telegram 之外用 CLI 创建 schedule,先在该线程里发 /whereami 拿到 thread id,再给 CLI 传递投递元数据:
cline schedule create "Daily summary" \
--cron "0 9 * * *" \
--prompt "Summarize yesterday's activity in this workspace." \
--workspace /path/to/repo \
--delivery-adapter telegram \
--delivery-bot my_bot \
--delivery-thread telegram:123456789
这些投递参数对应 schedule 命令的共享选项(--delivery-adapter、--delivery-bot、--delivery-channel、--delivery-thread)。其中 --delivery-bot 在仅凭 token 启动连接器的场景下仍然有效:把 /whereami 显示的 bot 用户名作为投递目标,可以精确指向某一个 Telegram 连接器;若 schedule 不需要限定到特定 bot,可省略该参数。
投递在连接器侧的落地逻辑见 deliverScheduledResult:连接器通过 client.streamEvents 监听 schedule.execution.completed / schedule.execution.failed 事件,校验投递元数据(adapter 必须为 telegram,若指定了 bot 则须匹配),按 binding 找回目标线程,把会话回复文本(失败时为错误信息)发送回去,并依次派发 schedule.delivery.started / sent / failed 三个 hook 事件。
前置条件:投递发生时连接器必须在运行,且目标线程必须已有线程绑定(binding),否则投递会被跳过并记录 Scheduled Telegram delivery skipped: missing thread binding 警告日志。
八、已知限制
- 连接器不是 Telegram 托管的服务,它是本地 CLI 进程在轮询 Telegram——机器或进程离线即完全失效,规划部署时建议配合进程守护(systemd/pm2 等)。
- 当前文档化的交互面是文本提示与命令回复,媒体类(图片、文件等)Telegram 工作流不在该连接器契约内。
- 群组消息投递仍依赖 Telegram 的 bot 设置以及 Bot API 实际投递给适配器的消息事件范围(例如 bot 在群组中的隐私模式会决定能否收到普通消息)。
九、延伸阅读
- 连接器基础与共享运行时:base.ts、connector-host.ts、chat-runtime.ts
- 线程绑定与状态持久化:thread-bindings.ts
- 连接器选项与状态类型定义:options.ts
- 消息格式化测试与行为验证:telegram-format.test.ts、telegram.test.ts
- 交互式连接器向导的平台字段定义(Telegram 的 "Bot token" 字段、安全字段校验):platforms.ts、platforms.test.ts
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00