Telegram Bot UI
Telegram 봇 사용자 인터페이스의 전체 수명 주기를 위한 이식 가능한 SDK 비종속 스킬입니다: 감사 → 화면/상태 맵 → 텍스트, 버튼 및 내비게이션 디자인 → 구현 → 마이그레이션 → 테스트 → 문서화.
Telegram 봇에는 CSS나 레이아웃 엔진이 없습니다. 봇의 전체 인터페이스는 다섯 가지 요소로 구성됩니다: 메시지 텍스트, 형식, 키보드, 채팅 수준 크롬(명령어, 메뉴 버튼, 딥 링크), 그리고 상태 간 전환. 이 스킬은 이 다섯 가지를 하나의 디자인 표면으로 취급합니다.
목적
에이전트가 봇의 인터페이스를 명확하고, 일관되며, 안전하게 변경할 수 있도록 돕습니다: 화면이 무엇을 말하고 어떻게 말할지 선택하고, 버튼에 레이블을 지정하고 그룹화, 정렬, 색상 지정 및 배치하며, 화면과 상태 간 내비게이션을 설계하고, 모든 화면을 봇의 나머지 부분과 일관성 있게 유지하며, 지역화를 유지하고, 모든 언어와 모든 Telegram SDK에서 기존 핸들러나 비즈니스 로직을 깨뜨리지 않고 가장 풍부한 형식으로 메시지 본문을 렌더링합니다.
사용 시기
- 인터페이스 작업: "봇의 UX/UI 개선", "이 메뉴 재설계", "키보드가 과부하됨", "사용자가 이 화면을 이해하지 못함", "뒤로 가기 버튼 추가", "이 액션들 그룹화", "주요 액션을 눈에 띄게 만들기".
- 버튼 및 키보드: 인라인 키보드, 응답 키보드, 버튼 레이블, 버튼 순서 및 레이아웃,
style색상,icon_custom_emoji_id사용자 정의 이모지, 웹 앱 / URL / 텍스트 복사 / 인라인 전환 버튼,ForceReply, 키보드 제거, 페이지 매김 및 뒤로 가기 내비게이션. - 텍스트 및 마이크로카피: 봇 메시지, 제목, 캡션, 프롬프트, 확인, 오류 및 빈 상태, 어조와 길이, 이모지 사용 재작성.
- 채팅 크롬:
/commands목록 및 범위, 메뉴 버튼,/start및 딥 링크, 첫 실행 경험. - 동적 피드백: AI 응답 스트리밍(
sendMessageDraft,sendRichMessageDraft,<tg-thinking>), 진행률 표시줄, "입력 중" 상태, 버튼 로더, "봇이 작업 중인 동안 멈춘 느낌". - 개인화 및 링크: 사용자 이름 안전하게 부르기, 로케일 힌트, URL 버튼 대 인라인 링크, 링크 미리보기, 딥 링크, 멘션.
- 일관성: 동일한 액션이 세 가지 다른 방식으로 명명됨, 일부 화면에만 존재하는 뒤로 가기 버튼, 편집 후 불일치 상태.
- 메시지 렌더링: HTML / MarkdownV2 /
MessageEntity, 텍스트 내 사용자 정의 이모지, 캡션, 테이블 및 리치 메시지, 링크 미리보기 / 무음 / 보호 옵션, 긴 메시지 분할, 스트리밍 초안, 편집, 채널 게시물, 지역화 및 RTL,can't parse entities, 깨지거나 너무 큰 메시지.
사용하지 말아야 할 경우
인터페이스에 표시되지 않는 봇 로직: 웹훅 인프라, 결제 처리, 인증, 데이터베이스 및 마이그레이션, 그룹 관리 및 중재 로직, 스크래핑, 분석 파이프라인, 미니 앱 내부(자체 HTML/CSS UI는 일반적인 웹 프론트엔드 작업입니다 — 이 스킬은 Telegram 측 표면, 즉 미니 앱을 여는 버튼이나 메뉴만 다룹니다). 또한 Microsoft .rtf 파일에는 해당하지 않습니다.
용어 — 혼동하지 마세요
- 인라인 키보드 ≠ 응답 키보드.
InlineKeyboardMarkup은 특정 메시지에 첨부되어callback_query를 보내거나 URL을 엽니다.ReplyKeyboardMarkup은 사용자의 문자 키보드를 대체하고 텍스트를 일반 메시지로 보냅니다. 서로 다른 버튼 클래스, 서로 다른 UX. style은 색상 값이 아닙니다. 정확히primary,success,danger중 하나입니다. Telegram에는 HEX/RGB/CSS 버튼 색상이 없습니다.icon_custom_emoji_id는file_id가 아닙니다. 이모지 팩 이름, 링크 또는 유니코드 이모지도 아닙니다. 특정 사용자 정의 이모지 하나의 ID입니다.- Telegram 리치 텍스트는 Microsoft RTF가 아닙니다. 리치 메시지를 "RTF"라고 부르지 마십시오.
- 리치 마크다운 ≠ MarkdownV2. MarkdownV2는 일반 메시지에 대한
parse_mode로 엄격한 이스케이프가 필요합니다. 리치 마크다운은 리치 메시지를 위한 문서 구문입니다. - 리치 HTML ≠ 임의의 브라우저 HTML. Telegram에서 지원하는 태그 집합만 허용됩니다.
- 키보드 편집 ≠ 화면 재전송.
editMessageReplyMarkup과editMessageText는 제자리에서 업데이트합니다. 새 메시지를 보내면 화면이 쌓입니다.
진리 기준 정책
다음 순서로 신뢰하세요:
- 현재 공식 Telegram 문서(Bot API, Bot Features, 형식 페이지, 공식 블로그).
- 공식 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 / docs)을 읽습니다. - 언어, 프레임워크, 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). - 프로젝트의 린트 / 타입 검사 / 테스트 / 해당 스모크 검사를 실행합니다.
- 보고합니다: 화면 맵, 변경된 내용과 이유, 의도적으로 건드리지 않은 내용, 한계 및 검증 증거.
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 답변, 비교, 체크리스트 | 리치 마크다운 |
| 서버 템플릿 콘텐츠, 정확한 태그 제어 | 리치 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()) |
토큰당 편집하지 마세요: 약 8001500ms, 약 3080개의 새 문자, 완성된 문장 또는 실제 단계 변경 시 업데이트 — 그리고 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 규칙 — 오프라인, 토큰 불필요). 트리거 시나리오: evals/activation-evals.md.
불가침 규칙
- 동작을 보존하세요. 기존
callback_data, URL, 딥 링크, 페이로드 및 핸들러 라우팅을 유지하세요. 시각적 재설계는 핸들러를 다시 작성해서는 안 됩니다.callback_data변경이 불가피한 경우, 그 사실을 명시하고 동일한 변경에서 모든 핸들러/경로를 업데이트하세요. - 픽셀보다 단어를 먼저. 색상이나 이모지를 추가하기 전에 레이블을 수정하세요.
- 장식용 색상 금지.
style을 액션의 의미에 따라 할당하세요. 모든 버튼에 색상을 지정하지 마세요. 모든 색상의 키보드는 계층 구조가 없습니다. style은 색상 값이 아닙니다. 정확히primary,success,danger중 하나입니다. Telegram에는 HEX/RGB/CSS 버튼 색상이 없습니다.