Telegram Bot UI
一个便携、与 SDK 无关的技能,用于 Telegram 机器人用户界面的完整生命周期:审计 → 屏幕/状态映射 → 文本、按钮和导航设计 → 实现 → 迁移 → 测试 → 文档。
Telegram 机器人没有 CSS,也没有布局引擎。它的整个界面由五件事组成:消息文本、格式化、键盘、聊天级别的界面元素(命令、菜单按钮、深度链接)以及状态之间的转换。 本技能将这五件事视为一个统一的设计面。
目的
帮助代理使机器人的界面清晰、一致且安全可修改:选择屏幕显示什么以及如何显示;标记、分组、排序、着色和布局按钮;设计屏幕与状态之间的导航;保持每个屏幕与机器人的其他部分一致;保持本地化完整;并使用最丰富的格式渲染消息体——跨越任何语言和任何 Telegram SDK,同时不破坏现有的处理器或业务逻辑。
何时使用
- 界面工作: "改善机器人的 UX/UI"、"重新设计此菜单"、"键盘过载"、"用户不理解此屏幕"、"添加返回按钮"、"对这些操作进行分组"、"使主操作突出"。
- 按钮和键盘: 内联键盘、回复键盘、按钮标签、按钮顺序和布局、
style颜色、icon_custom_emoji_id自定义表情符号、Web App / URL / 复制文本 / 切换内联按钮、ForceReply、键盘移除、分页和返回导航。 - 文本和微文案: 重写机器人消息、标题、说明文字、提示、确认、错误和空状态、语气和长度、表情符号的使用。
- 聊天界面元素:
/commands列表和作用域、菜单按钮、/start和深度链接、首次运行体验。 - 动态反馈: 流式 AI 答案(
sendMessageDraft、sendRichMessageDraft、<tg-thinking>)、进度条、"正在输入"状态、按钮加载器、"机器人在工作时感觉卡顿"。 - 个性化和链接: 安全地按名称问候用户、语言环境提示、URL 按钮与内联链接、链接预览、深度链接、提及。
- 一致性: 同一操作以三种不同方式命名、仅在某些屏幕上存在的返回按钮、编辑后状态不匹配。
- 消息渲染: HTML / MarkdownV2 /
MessageEntity、文本中的自定义表情符号、说明文字、表格和富消息、链接预览 / 静默 / 受保护选项、长消息拆分、流式草稿、编辑、频道帖子、本地化和 RTL、can't parse entities、损坏或超大的消息。
何时不使用
不涉及界面的机器人逻辑:Webhook 基础设施、支付处理、授权、数据库和迁移、群组管理和审核逻辑、爬虫、分析管道、小程序内部(其自身的 HTML/CSS UI 是普通的 Web 前端工作——本技能仅涵盖 Telegram 侧的界面:打开它的按钮或菜单)。也不适用于 Microsoft .rtf 文件。
术语——不要混淆
- 内联键盘 ≠ 回复键盘。
InlineKeyboardMarkup附加到特定消息,并发送callback_query/ 打开 URL。ReplyKeyboardMarkup替换用户的字母键盘,并将文本作为普通消息发送。不同的按钮类,不同的 UX。 style不是一个颜色值。 它只能是primary、success、danger之一。Telegram 没有 HEX/RGB/CSS 按钮颜色。icon_custom_emoji_id不是file_id, 不是表情符号包名称,不是链接,也不是 Unicode 表情符号。它是一个特定自定义表情符号的 ID。- Telegram 富文本不是 Microsoft RTF。 切勿将富消息称为 "RTF"。
- 富 Markdown ≠ MarkdownV2。 MarkdownV2 是用于常规消息的
parse_mode,具有严格的转义规则。富 Markdown 是用于富消息的文档语法。 - 富 HTML ≠ 任意浏览器 HTML。 仅限于 Telegram 支持的标签集。
- 编辑键盘 ≠ 重新发送屏幕。
editMessageReplyMarkup和editMessageText在原地更新;发送新消息会堆积屏幕。
真相源策略
按此顺序信任:
- 当前官方 Telegram 文档(Bot API、Bot 功能、格式化页面、官方博客)。
- 官方 Bot API 变更日志。
- 项目中实际安装的 SDK 的文档。
- SDK 源代码。
- SDK 问题追踪器。
- 第三方文章——仅作为补充背景。
在行动之前重新验证官方文档,当:任务涉及新 API;当前日期晚于 references/official-sources.md 中的 "最后验证" 日期;项目的 Bot API 版本未知;SDK 文档与 Bot API 冲突;遇到不熟悉的类型/字段;或用户询问 "最新功能"。
本技能并非冻结于 Bot API 10.2——如果 Telegram 发布了更新版本,请使用它。UI 相关版本门控:references/ui-changelog.md。
核心工作流程(在重新设计之前,先审计)
- 阅读项目的说明(
AGENTS.md/CLAUDE.md/ README / 文档)。 - 检测语言、框架、Telegram SDK 和确切版本。
- 确定 SDK 实际支持的 Bot API 版本——这决定了
style和icon_custom_emoji_id是否可用。 - 构建屏幕/状态映射:用户可以看到的每条消息、每个键盘、每个
callback_data、每个命令、每个转换(references/navigation-and-flows.md)。 - 对每个屏幕进行分类:入口 / 菜单 / 表单步骤 / 确认 / 结果 / 错误 / 空 / 通知。
- 识别真实的 UX 缺陷(不要凭空想象):模糊的标签、过载的键盘、没有返回路径的死胡同、不一致的命名、一键可触的破坏性操作、未本地化的字符串、不可读的消息体。
- 设计修复方案:先文本,后结构,再布局,最后是颜色/表情符号——按此顺序。颜色是最后一层,永远不能解决标签不佳的问题。
- 检查 SDK 是否支持你计划使用的每个字段(
references/sdk-compatibility.md)。 - 使用项目现有的样式和实用程序进行实现(不要重复其键盘构建器)。
- 保留
callback_data、URL、深度链接、处理器路由和本地化键,除非用户明确要求更改它们。 - 添加回退路径并保持旧客户端可用(
references/errors-and-fallbacks.md)。 - 使用项目现有的测试基础设施添加测试(
references/testing-playbook.md)。 - 运行项目的 lint / 类型检查 / 测试 / 适用的烟雾检查。
- 报告:屏幕映射、更改了什么以及为什么、故意保留了什么、限制和验证证据。
在步骤 1–6 完成之前,不要编写实现代码。
五个 UI 层(按此顺序设计)
| # | 层 | 它回答的问题 | 参考文档 |
|---|---|---|---|
| 1 | 文字 | 用户是否理解这是什么以及接下来会发生什么? | references/microcopy-and-labels.md |
| 2 | 结构 | 存在哪些操作,它们是如何分组和排序的? | references/inline-keyboards.md、references/reply-keyboards.md |
| 3 | 导航 | 我如何到达这里、返回以及退出?我处于哪个状态? | references/navigation-and-flows.md |
| 4 | 正文渲染 | 内容是否可读——表格、列表、标题、纯文本? | references/format-selection.md、references/tables.md |
| 5 | 强调 | 此处的主要操作是什么?什么是危险的? | references/buttons-and-styles.md、references/custom-emoji.md |
在层级 1 失败的屏幕,无法通过层级 4–5 来挽救。永远不要从颜色开始。
按钮要点(完整规则见 references/buttons-and-styles.md)
每个内联按钮一个操作。 根据 Bot API,InlineKeyboardButton 在 text、icon_custom_emoji_id 和 style 以外的字段中,要求恰好一个(url、callback_data、web_app、login_url、switch_inline_query*、copy_text、callback_game、pay)。KeyboardButton 允许其非 text/icon/style 字段中最多一个。
style(Bot API 9.4) — 可选,且必须是以下之一:
style | 颜色 | 含义 | 典型标签 |
|---|---|---|---|
primary | 蓝色 | *此屏幕的主要的前进操作 | 继续、开始、打开、下一步、选择 |
success | 绿色 | 正向提交/确认/完成 | 保存、确认、发布、提交、完成 |
danger | 红色 | 破坏性或不可逆的操作 | 删除、重置、退订、离开、取消计划 |
| 省略 | 应用默认值 | 其他所有操作 | 返回、设置、帮助、次要选项 |
如果省略 style,则使用应用特定的样式。每个屏幕最多一个 primary。danger 仅用于真正破坏性的操作,并应配以确认步骤。 诸如 "返回" 之类的次要操作通常保持无样式。
icon_custom_emoji_id(Bot API 9.4) — 在按钮文本前显示自定义表情符号。仅适用于在 Fragment 上购买了额外用户名的机器人,或者当机器人的所有者拥有 Telegram Premium 时,由机器人直接发送到私聊、群组和超级群组的消息中。切勿编造 ID——从(references/custom-emoji.md)获取,或向用户索要。
这两个字段都是在功能正常的按钮基础上的装饰:标签必须仍然在没有颜色和图标的情况下有意义。
消息体:最适合且最有帮助的格式
| 需求 | 使用 |
|---|---|
| 行/列或标签→值数据 | 表格 — references/tables.md |
| 结构化文档:报告、AI 答案、比较、清单 | 富 Markdown |
| 服务器模板化的内容,精确的标签控制 | 富 HTML |
| 从数据 / CMS / AST 进行类型化生成 | InputRichBlock 块 |
| 带键盘的屏幕:简短提示 + 选项 | 常规 HTML,简短 |
精确的偏移控制,无 parse_mode | MessageEntity |
| 真正不需要样式 | 纯文本 |
规则:结构化数据应变为真正的表格,而不是等宽网格——但菜单屏幕是简短的提示加按钮,而不是一篇论文。完整矩阵:references/format-selection.md。
机器人工作时的反馈
等待时没有信号是机器人中最常见的 UX 失败。根据操作的形态进行选择(完整规则:references/dynamic-feedback-and-streaming.md):
| 情况 | 机制 |
|---|---|
| 内联按钮被点击 | 首先调用 answerCallbackQuery,然后进行工作 |
| 2–5 秒的操作 | 调用 sendChatAction(typing、upload_photo、……)——最长 5 秒 |
| AI 文本正在生成(私聊) | 调用 sendMessageDraft——使用相同 draft_id,最后用 sendMessage 完成 |
| AI 回答带有结构 | 调用 sendRichMessageDraft + <tg-thinking> → sendRichMessage |
| 真实、可命名的阶段 | 调用 editMessageText,进行节流 |
| 无法测量的进度 | 使用命名阶段——切勿使用虚假的百分比 |
| 交互式过程 | 小程序(BottomButton.showProgress()、WebApp.ready()) |
切勿按 token 进行编辑:大约每 800–1500 毫秒、每 30–80 个新字符、每完成一个句子或每发生一个真实阶段的变化时更新——并尊重 retry_after。每个操作一个 draft_id / message_id / operation_id,并且恰好完成一次。
要阅读的参考文档(根据任务分发——不要全部阅读)
UI / UX
- 按钮标签、消息措辞、语气、文本中的表情符号 →
references/microcopy-and-labels.md style颜色、强调、按钮布局和分组 →references/buttons-and-styles.md- 内联键盘、
callback_data、分页、原地编辑 →references/inline-keyboards.md - 回复键盘、
ForceReply、键盘移除、占位符 →references/reply-keyboards.md - 屏幕、状态、返回/首页、命令、菜单按钮、深度链接 →
references/navigation-and-flows.md - 按钮和文本中的自定义表情符号、获取 ID、资格 →
references/custom-emoji.md - 流式答案、思考块、进度条、加载器、聊天动作 →
references/dynamic-feedback-and-streaming.md - 使用用户数据进行个性化、链接、预览、深度链接 →
references/personalization-and-links.md - 跨屏幕一致性 + 完成前检查清单 →
references/consistency-and-review.md - UI 相关 Bot API 历史和版本门控 →
references/ui-changelog.md - 已经过修改的前/后场景 →
references/examples-before-after.md
内容渲染
- 表格 →
references/tables.md - 富消息 / 块 / 能力矩阵 →
references/telegram-capabilities.md - HTML / MarkdownV2 / 实体 / 说明文字 / 预览 →
references/regular-formatting.md - 选择格式 →
references/format-selection.md - 媒体 →
references/rich-media.md - 限制与拆分 →
references/limits-and-splitting.md - 流式草稿与编辑 →
references/streaming-and-editing.md - 频道、通知、广播 →
references/channels-and-broadcasting.md
工程
- 调查未知项目 →
references/project-adaptation.md - 转义 / 注入 / 用户或 AI 内容 →
references/security-and-escaping.md - 本地化、RTL、按钮标签长度 →
references/localization-and-rtl.md - 错误、回退、旧客户端 →
references/errors-and-fallbacks.md - SDK 缺口 / 原始 Bot API 载荷 →
references/sdk-compatibility.md - 测试 →
references/testing-playbook.md - 来源与最后验证日期 →
references/official-sources.md
本地验证器:scripts/validate_skill.py、scripts/validate_references.py、scripts/validate_keyboard.py(键盘 JSON 规则——离线,无需 token)。
触发场景:evals/activation-evals.md。
不可协商的规则
- 保留行为。 保留现有的
callback_data、URL、深度链接、负载和处理器路由。视觉重新设计不得重写处理器。如果callback_data更改不可避免,请声明并在同一更改中更新每个处理器/路由。 - 文字优先于像素。 在添加颜色或表情符号之前,先修复标签。
- 无装饰性颜色。 根据操作的含义分配
style。不要给每个按钮着色;全彩色的键盘没有层次结构。 - **`styl
…
[为翻译而截断]