vibe-coding-cn/assets/skills/telegram-dev/references/Telegram_Bot_按钮和键盘实现模板.md

405 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Telegram Bot 按钮与键盘实现指南
> 完整的 Telegram Bot 交互式功能开发参考
---
## 📋 目录
1. [按钮和键盘类型](#按钮和键盘类型)
2. [实现方式对比](#实现方式对比)
3. [核心代码示例](#核心代码示例)
4. [最佳实践](#最佳实践)
---
## 按钮和键盘类型
### 1. Inline Keyboard内联键盘
**特点**
- 显示在消息下方
- 点击后触发回调,不发送消息
- 支持回调数据、URL、切换查询等
**应用场景**:确认/取消、菜单导航、分页控制、设置选项
### 2. Reply Keyboard底部虚拟键盘
**特点**
- 显示在输入框上方
- 点击后发送文本消息
- 可设置持久化或一次性
**应用场景**:快捷命令、常用操作、表单输入、主菜单
### 3. Bot Command Menu命令菜单
**特点**
- 显示在输入框左侧 "/" 按钮
- 通过 BotFather 或 API 设置
- 提供命令列表和描述
**应用场景**:功能索引、新用户引导、快速命令访问
### 4. 类型对比
| 特性 | Inline | Reply | Command Menu |
|------|--------|-------|--------------|
| 位置 | 消息下方 | 输入框上方 | "/" 菜单 |
| 触发 | 回调查询 | 文本消息 | 命令 |
| 持久化 | 随消息 | 可配置 | 始终存在 |
| 场景 | 临时交互 | 常驻功能 | 命令索引 |
---
## 实现方式对比
### python-telegram-bot推荐 Bot 开发)
**优点**
- 官方推荐,完整的 Handler 系统
- 丰富的按钮和键盘支持
- 异步版本性能优异
**安装**
```bash
pip install python-telegram-bot==20.7
```
### Telethon适合用户账号自动化
**优点**
- 完整的 MTProto API 访问
- 可使用用户账号和 Bot
- 强大的消息监听能力
**安装**
```bash
pip install telethon cryptg
```
---
## 核心代码示例
### 1. Inline Keyboard 实现
**python-telegram-bot**
```python
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""显示内联键盘"""
keyboard = [
[
InlineKeyboardButton("📊 查看数据", callback_data="view_data"),
InlineKeyboardButton("⚙️ 设置", callback_data="settings"),
],
[
InlineKeyboardButton("🔗 访问网站", url="https://example.com"),
],
]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text("请选择:", reply_markup=reply_markup)
async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""处理按钮点击"""
query = update.callback_query
await query.answer() # 必须调用
if query.data == "view_data":
await query.edit_message_text("显示数据...")
elif query.data == "settings":
await query.edit_message_text("设置选项...")
# 注册处理器
app = Application.builder().token("TOKEN").build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CallbackQueryHandler(button_callback))
app.run_polling()
```
**Telethon**
```python
from telethon import TelegramClient, events, Button
client = TelegramClient('bot', api_id, api_hash).start(bot_token=BOT_TOKEN)
@client.on(events.NewMessage(pattern='/start'))
async def start(event):
buttons = [
[Button.inline("📊 查看数据", b"view_data"), Button.inline("⚙️ 设置", b"settings")],
[Button.url("🔗 访问网站", "https://example.com")]
]
await event.respond("请选择:", buttons=buttons)
@client.on(events.CallbackQuery)
async def callback(event):
if event.data == b"view_data":
await event.edit("显示数据...")
elif event.data == b"settings":
await event.edit("设置选项...")
client.run_until_disconnected()
```
### 2. Reply Keyboard 实现
**python-telegram-bot**
```python
from telegram import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
async def menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""显示底部键盘"""
keyboard = [
[KeyboardButton("📊 查看数据"), KeyboardButton("⚙️ 设置")],
[KeyboardButton("📚 帮助"), KeyboardButton("❌ 隐藏键盘")],
]
reply_markup = ReplyKeyboardMarkup(
keyboard,
resize_keyboard=True,
one_time_keyboard=False
)
await update.message.reply_text("菜单已激活", reply_markup=reply_markup)
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""处理文本消息"""
text = update.message.text
if text == "📊 查看数据":
await update.message.reply_text("显示数据...")
elif text == "❌ 隐藏键盘":
await update.message.reply_text("已隐藏", reply_markup=ReplyKeyboardRemove())
```
**Telethon**
```python
@client.on(events.NewMessage(pattern='/menu'))
async def menu(event):
buttons = [
[Button.text("📊 查看数据"), Button.text("⚙️ 设置")],
[Button.text("📚 帮助"), Button.text("❌ 隐藏键盘")]
]
await event.respond("菜单已激活", buttons=buttons)
@client.on(events.NewMessage)
async def handle_text(event):
if event.text == "📊 查看数据":
await event.respond("显示数据...")
```
### 3. Bot Command Menu 设置
**通过 BotFather**
```
1. 发送 /setcommands 到 @BotFather
2. 选择你的 Bot
3. 输入命令列表每行格式command - description
start - 启动机器人
help - 获取帮助
menu - 显示主菜单
settings - 配置设置
```
**通过 APIpython-telegram-bot**
```python
from telegram import BotCommand
async def set_commands(app: Application):
"""设置命令菜单"""
commands = [
BotCommand("start", "启动机器人"),
BotCommand("help", "获取帮助"),
BotCommand("menu", "显示主菜单"),
BotCommand("settings", "配置设置"),
]
await app.bot.set_my_commands(commands)
# 在启动时调用
app.post_init = set_commands
```
### 4. 项目结构示例
```
telegram_bot/
├── bot.py # 主程序
├── config.py # 配置管理
├── requirements.txt
├── .env
├── handlers/
│ ├── command_handlers.py # 命令处理器
│ ├── callback_handlers.py # 回调处理器
│ └── message_handlers.py # 消息处理器
├── keyboards/
│ ├── inline_keyboards.py # 内联键盘布局
│ └── reply_keyboards.py # 回复键盘布局
└── utils/
├── logger.py # 日志
└── database.py # 数据库
```
**模块化示例keyboards/inline_keyboards.py**
```python
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
def get_main_menu():
"""主菜单键盘"""
return InlineKeyboardMarkup([
[
InlineKeyboardButton("📊 数据", callback_data="data"),
InlineKeyboardButton("⚙️ 设置", callback_data="settings"),
],
[InlineKeyboardButton("📚 帮助", callback_data="help")],
])
def get_data_menu():
"""数据菜单键盘"""
return InlineKeyboardMarkup([
[
InlineKeyboardButton("📈 实时", callback_data="data_realtime"),
InlineKeyboardButton("📊 历史", callback_data="data_history"),
],
[InlineKeyboardButton("⬅️ 返回", callback_data="back")],
])
```
---
## 最佳实践
### 1. Handler 优先级
```python
# 先注册先匹配,按从特殊到通用的顺序
app.add_handler(CommandHandler("start", start)) # 1. 特定命令
app.add_handler(CallbackQueryHandler(callback)) # 2. 回调查询
app.add_handler(ConversationHandler(...)) # 3. 对话流程
app.add_handler(MessageHandler(filters.TEXT, text_msg)) # 4. 通用消息(最后)
```
### 2. 错误处理
```python
async def error_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""全局错误处理"""
logger.error(f"更新 {update} 引起错误", exc_info=context.error)
# 通知用户
if update and update.effective_message:
await update.effective_message.reply_text("操作失败,请重试")
app.add_error_handler(error_handler)
```
### 3. 回调数据管理
```python
# 使用结构化的 callback_data
callback_data = "action:page:item" # 例如 "view:1:product_123"
# 解析回调数据
async def callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.callback_query
parts = query.data.split(":")
action, page, item = parts
if action == "view":
await show_item(query, page, item)
```
### 4. 键盘设计原则
- **简洁**:每行最多 2-3 个按钮
- **清晰**:使用 emoji 增强识别度
- **一致**:保持统一的布局风格
- **响应**:及时反馈用户操作
### 5. 安全考虑
```python
# 验证用户权限
ADMIN_IDS = [123456789]
async def admin_only(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
if user_id not in ADMIN_IDS:
await update.message.reply_text("无权限")
return
# 执行管理员操作
```
### 6. 部署方案
**Webhook推荐生产环境**
```python
from flask import Flask, request
app_flask = Flask(__name__)
@app_flask.route('/webhook', methods=['POST'])
def webhook():
update = Update.de_json(request.get_json(), bot)
application.update_queue.put(update)
return "OK"
# 设置 webhook
bot.set_webhook(f"https://yourdomain.com/webhook")
```
**Systemd ServiceLinux**
```ini
[Unit]
Description=Telegram Bot
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/bot
ExecStart=/path/to/venv/bin/python bot.py
Restart=always
[Install]
WantedBy=multi-user.target
```
### 7. 常用库版本
```txt
# requirements.txt
python-telegram-bot==20.7
python-dotenv==1.0.0
aiosqlite==0.19.0
httpx==0.25.2
```
---
## 快速参考
### Inline Keyboard 按钮类型
```python
InlineKeyboardButton("文本", callback_data="data") # 回调按钮
InlineKeyboardButton("链接", url="https://...") # URL按钮
InlineKeyboardButton("切换", switch_inline_query="") # 内联查询
InlineKeyboardButton("登录", login_url=...) # 登录按钮
InlineKeyboardButton("支付", pay=True) # 支付按钮
InlineKeyboardButton("应用", web_app=WebAppInfo(...)) # Mini App
```
### 常用事件类型
- `events.NewMessage` - 新消息
- `events.CallbackQuery` - 回调查询
- `events.InlineQuery` - 内联查询
- `events.ChatAction` - 群组动作
---
**这份指南涵盖了 Telegram Bot 按钮和键盘的所有核心实现!**