首页
/ Cline CLI Telegram Connector:把 Cline 编码代理接入 Telegram 机器人的完整实战指南

Cline CLI Telegram Connector:把 Cline 编码代理接入 Telegram 机器人的完整实战指南

2026-09-06 13:15:09作者:范靓好Udolf

Cline CLI 的 Telegram Connector 让你通过一个 Telegram Bot 远程驱动 Cline 编码代理会话:无需公网 webhook,只需本地常驻一个轮询进程,就能在手机上提问、下达编码任务、审批工具调用,甚至接收定时任务的执行结果。本篇基于仓库文档 telegram.md 与对应源码 telegram.tstelegram-format.ts 展开,覆盖启动配置、聊天命令、访问控制与消息投递的全部细节。

一、架构定位:一个纯轮询的本地桥接进程

Telegram Connector 是 Cline CLI 内置的多个聊天平台连接器之一(与 Slack、Discord、Google Chat、WhatsApp、Linear 并列,见 adapters 目录)。它的核心特征是:

  • 轮询(polling)而非 webhook:底层通过 @chat-adapter/telegram 适配器以 mode: "polling" 方式运行(见 telegram.tscreateTelegramAdapter 的调用),因此不需要公网可达的回调地址,适合直接跑在开发机或内网服务器上。
  • 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

  1. 打开 Telegram,与 @BotFather 开始对话。
  2. 发送 /newbot,按提示完成命名。
  3. 复制 Bot token。它等同于密码,务必妥善保管(建议放入环境变量,不要提交进仓库)。

2. 启动连接器

cline connect telegram -k "$TELEGRAM_BOT_TOKEN"

Connector 会用 token 调用 Telegram 的 getMe 接口自动发现 bot 用户名(实现见 telegram.tsfetchTelegramBotUsername),只有在需要覆盖时(例如离线场景无法调用 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.tscreateCommand() 的 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(含 botUsernamebotIdpidrpcAddressstartedAt)。状态文件按 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 的用户:

  1. 交互式向导:运行 cline connect,Telegram 向导会询问是否限制访问,并指引你通过 @userinfobot 查询自己的数字用户 ID。

  2. 直接传参

    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 信息。

  3. 手动 --hook-command:自行编写返回 {"action":"deny"} 的 shell 命令来拒绝未授权事件。注意 --allowed-user-id--hook-command 不可同时使用,源码会显式抛出错误(telegram.ts)。

如果两者都没配置,消息默认放行——这是把 bot 暴露到群组前必须注意的一点。

工具审批

需要授权的工具调用会推送到 Telegram,用户直接回复 Y(允许)或 N(拒绝)即可。源码中每个消息入口在进入 turn 之前都会先经过 maybeHandleConnectorApprovalReplytelegram.ts),命中待审批记录时优先消费 Y/N 回复,拒绝原因记录为 "Denied by Telegram user"。

六、消息投递机制:Markdown 实体、分块与降级

Telegram 的最终助手回复不经过普通 chat 适配器的流式通道,而是在运行时 turn 完成后直接走 Telegram sendMessage 接口发送(postFinalReply 回调,见 telegram.ts)。实现位于 telegram-format.ts,核心设计:

  1. Markdown 转 entities:用 markdownToFormattable 把模型输出中的 Markdown 片段转成 Telegram 的 message entities(加粗、代码、链接等),避免直接发送 Markdown 文本触发 Telegram 的 parse 错误。
  2. 4096 字符分块TELEGRAM_MESSAGE_LIMIT = 4096,超长回复被切成多段;切割时 entity 的 offset/length 会按每段重新计算并裁剪,保证跨块 entity 不错位(chunkFormattedMessage)。
  3. thread 定位:线程 ID 支持 telegram:<chatId>telegram:<chatId>:<messageThreadId> 两种格式,后者用于论坛超话题(parseTelegramThreadId),发送载荷中相应携带 message_thread_id
  4. 降级路径:entity 发送失败时,连接器回退为原始纯文本,按 4096 字符分片经适配器的普通 thread.post 路径发出(postTelegramFormattedReply 的 catch 分支),已发出的分片之后的剩余文本会被拼接回退,避免内容丢失。
  5. 工具/状态更新和定时投递消息则统一走适配器的原始线程投递路径,不做 Markdown 实体处理。

作为对比,Google Chat 与 WhatsApp 连接器使用的是共享运行时流式通道做增量文本推送,而 Telegram 选择"turn 完成后再整体格式化发送"的模型。

七、定时任务结果投递到 Telegram

当定时任务的执行结果需要回推到 Telegram 时,推荐直接在 Telegram 聊天中创建 schedule

  1. 启动 Telegram 连接器;
  2. 在 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 在群组中的隐私模式会决定能否收到普通消息)。

九、延伸阅读

登录后查看全文
热门项目推荐
相关项目推荐