mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-08-26 09:08:29 +00:00
docs: 更新文档和技能
This commit is contained in:
+404
@@ -0,0 +1,404 @@
|
||||
# Telegram Bot Button and Keyboard Implementation Guide
|
||||
|
||||
> A complete reference for developing interactive features for Telegram Bots
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
1. [Button and Keyboard Types](#button-and-keyboard-types)
|
||||
2. [Implementation Comparison](#implementation-comparison)
|
||||
3. [Core Code Examples](#core-code-examples)
|
||||
4. [Best Practices](#best-practices)
|
||||
|
||||
---
|
||||
|
||||
## Button and Keyboard Types
|
||||
|
||||
### 1. Inline Keyboard
|
||||
|
||||
**Features**:
|
||||
- Displayed below a message
|
||||
- Triggers a callback when clicked, without sending a message
|
||||
- Supports callback data, URLs, switch queries, etc.
|
||||
|
||||
**Use Cases**: Confirmation/cancellation, menu navigation, pagination control, setting options
|
||||
|
||||
### 2. Reply Keyboard
|
||||
|
||||
**Features**:
|
||||
- Displayed above the input field
|
||||
- Sends a text message when a button is clicked
|
||||
- Can be set as persistent or one-time
|
||||
|
||||
**Use Cases**: Quick commands, common actions, form input, main menu
|
||||
|
||||
### 3. Bot Command Menu
|
||||
|
||||
**Features**:
|
||||
- Displayed in the "/" button to the left of the input field
|
||||
- Set via BotFather or the API
|
||||
- Provides a list of commands and their descriptions
|
||||
|
||||
**Use Cases**: Function index, new user guidance, quick command access
|
||||
|
||||
### 4. Type Comparison
|
||||
|
||||
| Feature | Inline | Reply | Command Menu |
|
||||
|---|---|---|---|
|
||||
| Position | Below message | Above input field | "/" menu |
|
||||
| Trigger | Callback query | Text message | Command |
|
||||
| Persistence | With message | Configurable | Always present |
|
||||
| Scenario | Temporary interaction | Resident function | Command index |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Comparison
|
||||
|
||||
### python-telegram-bot (Recommended for Bot development)
|
||||
|
||||
**Advantages**:
|
||||
- Officially recommended, with a complete Handler system
|
||||
- Rich support for buttons and keyboards
|
||||
- Excellent performance with the asynchronous version
|
||||
|
||||
**Installation**:
|
||||
```bash
|
||||
pip install python-telegram-bot==20.7
|
||||
```
|
||||
|
||||
### Telethon (Suitable for user account automation)
|
||||
|
||||
**Advantages**:
|
||||
- Full access to the MTProto API
|
||||
- Can be used with user accounts and Bots
|
||||
- Powerful message listening capabilities
|
||||
|
||||
**Installation**:
|
||||
```bash
|
||||
pip install telethon cryptg
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Core Code Examples
|
||||
|
||||
### 1. Inline Keyboard Implementation
|
||||
|
||||
**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):
|
||||
"""Display an inline keyboard"""
|
||||
keyboard = [
|
||||
[
|
||||
InlineKeyboardButton("📊 View Data", callback_data="view_data"),
|
||||
InlineKeyboardButton("⚙️ Settings", callback_data="settings"),
|
||||
],
|
||||
[
|
||||
InlineKeyboardButton("🔗 Visit Website", url="https://example.com"),
|
||||
],
|
||||
]
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
await update.message.reply_text("Please choose:", reply_markup=reply_markup)
|
||||
|
||||
async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Handle button clicks"""
|
||||
query = update.callback_query
|
||||
await query.answer() # Must be called
|
||||
|
||||
if query.data == "view_data":
|
||||
await query.edit_message_text("Displaying data...")
|
||||
elif query.data == "settings":
|
||||
await query.edit_message_text("Settings options...")
|
||||
|
||||
# Register handlers
|
||||
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("📊 View Data", b"view_data"), Button.inline("⚙️ Settings", b"settings")],
|
||||
[Button.url("🔗 Visit Website", "https://example.com")]
|
||||
]
|
||||
await event.respond("Please choose:", buttons=buttons)
|
||||
|
||||
@client.on(events.CallbackQuery)
|
||||
async def callback(event):
|
||||
if event.data == b"view_data":
|
||||
await event.edit("Displaying data...")
|
||||
elif event.data == b"settings":
|
||||
await event.edit("Settings options...")
|
||||
|
||||
client.run_until_disconnected()
|
||||
```
|
||||
|
||||
### 2. Reply Keyboard Implementation
|
||||
|
||||
**python-telegram-bot:**
|
||||
```python
|
||||
from telegram import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove
|
||||
|
||||
async def menu(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Display a reply keyboard"""
|
||||
keyboard = [
|
||||
[KeyboardButton("📊 View Data"), KeyboardButton("⚙️ Settings")],
|
||||
[KeyboardButton("📚 Help"), KeyboardButton("❌ Hide Keyboard")],
|
||||
]
|
||||
reply_markup = ReplyKeyboardMarkup(
|
||||
keyboard,
|
||||
resize_keyboard=True,
|
||||
one_time_keyboard=False
|
||||
)
|
||||
await update.message.reply_text("Menu activated", reply_markup=reply_markup)
|
||||
|
||||
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Handle text messages"""
|
||||
text = update.message.text
|
||||
if text == "📊 View Data":
|
||||
await update.message.reply_text("Displaying data...")
|
||||
elif text == "❌ Hide Keyboard":
|
||||
await update.message.reply_text("Keyboard hidden", reply_markup=ReplyKeyboardRemove())
|
||||
```
|
||||
|
||||
**Telethon:**
|
||||
```python
|
||||
@client.on(events.NewMessage(pattern='/menu'))
|
||||
async def menu(event):
|
||||
buttons = [
|
||||
[Button.text("📊 View Data"), Button.text("⚙️ Settings")],
|
||||
[Button.text("📚 Help"), Button.text("❌ Hide Keyboard")]
|
||||
]
|
||||
await event.respond("Menu activated", buttons=buttons)
|
||||
|
||||
@client.on(events.NewMessage)
|
||||
async def handle_text(event):
|
||||
if event.text == "📊 View Data":
|
||||
await event.respond("Displaying data...")
|
||||
```
|
||||
|
||||
### 3. Bot Command Menu Setup
|
||||
|
||||
**Via BotFather:**
|
||||
```
|
||||
1. Send /setcommands to @BotFather
|
||||
2. Choose your Bot
|
||||
3. Enter the list of commands (format per line: command - description)
|
||||
|
||||
start - Start the bot
|
||||
help - Get help
|
||||
menu - Display the main menu
|
||||
settings - Configure settings
|
||||
```
|
||||
|
||||
**Via API (python-telegram-bot):**
|
||||
```python
|
||||
from telegram import BotCommand
|
||||
|
||||
async def set_commands(app: Application):
|
||||
"""Set the command menu"""
|
||||
commands = [
|
||||
BotCommand("start", "Start the bot"),
|
||||
BotCommand("help", "Get help"),
|
||||
BotCommand("menu", "Display the main menu"),
|
||||
BotCommand("settings", "Configure settings"),
|
||||
]
|
||||
await app.bot.set_my_commands(commands)
|
||||
|
||||
# Call on startup
|
||||
app.post_init = set_commands
|
||||
```
|
||||
|
||||
### 4. Project Structure Example
|
||||
|
||||
```
|
||||
telegram_bot/
|
||||
├── bot.py # Main program
|
||||
├── config.py # Configuration management
|
||||
├── requirements.txt
|
||||
├── .env
|
||||
├── handlers/
|
||||
│ ├── command_handlers.py # Command handlers
|
||||
│ ├── callback_handlers.py # Callback handlers
|
||||
│ └── message_handlers.py # Message handlers
|
||||
├── keyboards/
|
||||
│ ├── inline_keyboards.py # Inline keyboard layouts
|
||||
│ └── reply_keyboards.py # Reply keyboard layouts
|
||||
└── utils/
|
||||
├── logger.py # Logger
|
||||
└── database.py # Database
|
||||
```
|
||||
|
||||
**Modular Example (keyboards/inline_keyboards.py):**
|
||||
```python
|
||||
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
|
||||
def get_main_menu():
|
||||
"""Main menu keyboard"""
|
||||
return InlineKeyboardMarkup([
|
||||
[
|
||||
InlineKeyboardButton("📊 Data", callback_data="data"),
|
||||
InlineKeyboardButton("⚙️ Settings", callback_data="settings"),
|
||||
],
|
||||
[InlineKeyboardButton("📚 Help", callback_data="help")],
|
||||
])
|
||||
|
||||
def get_data_menu():
|
||||
"""Data menu keyboard"""
|
||||
return InlineKeyboardMarkup([
|
||||
[
|
||||
InlineKeyboardButton("📈 Real-time", callback_data="data_realtime"),
|
||||
InlineKeyboardButton("📊 History", callback_data="data_history"),
|
||||
],
|
||||
[InlineKeyboardButton("⬅️ Back", callback_data="back")],
|
||||
])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Handler Priority
|
||||
|
||||
```python
|
||||
# Match in order of registration, from most specific to most general
|
||||
app.add_handler(CommandHandler("start", start)) # 1. Specific command
|
||||
app.add_handler(CallbackQueryHandler(callback)) # 2. Callback query
|
||||
app.add_handler(ConversationHandler(...)) # 3. Conversation flow
|
||||
app.add_handler(MessageHandler(filters.TEXT, text_msg)) # 4. General message (last)
|
||||
```
|
||||
|
||||
### 2. Error Handling
|
||||
|
||||
```python
|
||||
async def error_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
"""Global error handler"""
|
||||
logger.error(f"Update {update} caused error", exc_info=context.error)
|
||||
|
||||
# Notify the user
|
||||
if update and update.effective_message:
|
||||
await update.effective_message.reply_text("Operation failed, please try again")
|
||||
|
||||
app.add_error_handler(error_handler)
|
||||
```
|
||||
|
||||
### 3. Callback Data Management
|
||||
|
||||
```python
|
||||
# Use structured callback_data
|
||||
callback_data = "action:page:item" # e.g., "view:1:product_123"
|
||||
|
||||
# Parse callback data
|
||||
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. Keyboard Design Principles
|
||||
|
||||
- **Concise**: 2-3 buttons per row at most
|
||||
- **Clear**: Use emojis to enhance recognition
|
||||
- **Consistent**: Maintain a uniform layout style
|
||||
- **Responsive**: Provide timely feedback to user actions
|
||||
|
||||
### 5. Security Considerations
|
||||
|
||||
```python
|
||||
# Verify user permissions
|
||||
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("Permission denied")
|
||||
return
|
||||
|
||||
# Execute admin operations
|
||||
```
|
||||
|
||||
### 6. Deployment Solutions
|
||||
|
||||
**Webhook (Recommended for production):**
|
||||
```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"
|
||||
|
||||
# Set webhook
|
||||
bot.set_webhook(f"https://yourdomain.com/webhook")
|
||||
```
|
||||
|
||||
**Systemd Service (Linux):**
|
||||
```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. Common Library Versions
|
||||
|
||||
```txt
|
||||
# requirements.txt
|
||||
python-telegram-bot==20.7
|
||||
python-dotenv==1.0.0
|
||||
aiosqlite==0.19.0
|
||||
httpx==0.25.2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Inline Keyboard Button Types
|
||||
|
||||
```python
|
||||
InlineKeyboardButton("Text", callback_data="data") # Callback button
|
||||
InlineKeyboardButton("Link", url="https://...") # URL button
|
||||
InlineKeyboardButton("Switch", switch_inline_query="") # Inline query
|
||||
InlineKeyboardButton("Login", login_url=...) # Login button
|
||||
InlineKeyboardButton("Pay", pay=True) # Payment button
|
||||
InlineKeyboardButton("App", web_app=WebAppInfo(...)) # Mini App
|
||||
```
|
||||
|
||||
### Common Event Types
|
||||
|
||||
- `events.NewMessage` - New message
|
||||
- `events.CallbackQuery` - Callback query
|
||||
- `events.InlineQuery` - Inline query
|
||||
- `events.ChatAction` - Group action
|
||||
|
||||
---
|
||||
|
||||
**This guide covers all the core implementations of Telegram Bot buttons and keyboards!**
|
||||
Reference in New Issue
Block a user