mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-08-20 06:18:05 +00:00
docs: align en/ structure with main README
- Simplify language badges (zh, en, more languages) - Add X badge @123olp - Reorganize prompts: 00-meta, 01-system, 02-coding, 03-user - Reorganize skills: 00-meta, 01-ai-tools, 02-databases, 03-crypto, 04-dev-tools - Update all path references
This commit is contained in:
+408
@@ -0,0 +1,408 @@
|
||||
TRANSLATED CONTENT:
|
||||
# 📊 动态视图对齐 - Telegram 数据展示指南
|
||||
|
||||
> 专业的等宽字体数据对齐和格式化方案
|
||||
|
||||
---
|
||||
|
||||
## 📑 目录
|
||||
|
||||
- [核心原理](#核心原理)
|
||||
- [实现代码](#实现代码)
|
||||
- [格式化系统](#格式化系统)
|
||||
- [应用示例](#应用示例)
|
||||
- [最佳实践](#最佳实践)
|
||||
|
||||
---
|
||||
|
||||
## 核心原理
|
||||
|
||||
### 问题场景
|
||||
|
||||
在 Telegram Bot 中展示排行榜、数据表格时,需要在等宽字体环境(代码块)中实现完美对齐:
|
||||
|
||||
**❌ 未对齐:**
|
||||
```
|
||||
1. BTC $1.23B $45000 +5.23%
|
||||
10. DOGE $123.4M $0.0789 -1.45%
|
||||
```
|
||||
|
||||
**✅ 动态对齐:**
|
||||
```
|
||||
1. BTC $1.23B $45,000 +5.23%
|
||||
10. DOGE $123.4M $0.0789 -1.45%
|
||||
```
|
||||
|
||||
### 三步对齐算法
|
||||
|
||||
```
|
||||
步骤 1: 扫描数据,计算每列最大宽度
|
||||
步骤 2: 根据列类型应用对齐规则(文本左对齐,数字右对齐)
|
||||
步骤 3: 拼接成最终文本
|
||||
```
|
||||
|
||||
### 对齐规则
|
||||
|
||||
| 列索引 | 数据类型 | 对齐方式 | 示例 |
|
||||
|--------|----------|----------|------|
|
||||
| 列 0 | 序号 | 左对齐 | `1. `, `10. ` |
|
||||
| 列 1 | 符号 | 左对齐 | `BTC `, `DOGE ` |
|
||||
| 列 2+ | 数值 | 右对齐 | ` $1.23B`, `$123.4M` |
|
||||
|
||||
---
|
||||
|
||||
## 实现代码
|
||||
|
||||
### 核心函数
|
||||
|
||||
```python
|
||||
def dynamic_align_format(data_rows):
|
||||
"""
|
||||
动态视图对齐格式化
|
||||
|
||||
参数:
|
||||
data_rows: 二维列表 [["1.", "BTC", "$1.23B", ...], ...]
|
||||
|
||||
返回:
|
||||
对齐后的文本字符串
|
||||
"""
|
||||
if not data_rows:
|
||||
return "暂无数据"
|
||||
|
||||
# ========== 步骤 1: 计算每列最大宽度 ==========
|
||||
max_widths = []
|
||||
for row in data_rows:
|
||||
for i, cell in enumerate(row):
|
||||
# 动态扩展列表
|
||||
if i >= len(max_widths):
|
||||
max_widths.append(0)
|
||||
# 更新最大宽度
|
||||
max_widths[i] = max(max_widths[i], len(str(cell)))
|
||||
|
||||
# ========== 步骤 2: 格式化每一行 ==========
|
||||
formatted_rows = []
|
||||
for row in data_rows:
|
||||
formatted_cells = []
|
||||
for i, cell in enumerate(row):
|
||||
cell_str = str(cell)
|
||||
|
||||
if i == 0 or i == 1:
|
||||
# 序号列和符号列 - 左对齐
|
||||
formatted_cells.append(cell_str.ljust(max_widths[i]))
|
||||
else:
|
||||
# 数值列 - 右对齐
|
||||
formatted_cells.append(cell_str.rjust(max_widths[i]))
|
||||
|
||||
# 用空格连接所有单元格
|
||||
formatted_line = ' '.join(formatted_cells)
|
||||
formatted_rows.append(formatted_line)
|
||||
|
||||
# ========== 步骤 3: 拼接成最终文本 ==========
|
||||
return '\n'.join(formatted_rows)
|
||||
```
|
||||
|
||||
### 使用示例
|
||||
|
||||
```python
|
||||
# 准备数据
|
||||
data_rows = [
|
||||
["1.", "BTC", "$1.23B", "$45,000", "+5.23%"],
|
||||
["2.", "ETH", "$890.5M", "$2,500", "+3.12%"],
|
||||
["10.", "DOGE", "$123.4M", "$0.0789", "-1.45%"]
|
||||
]
|
||||
|
||||
# 调用对齐函数
|
||||
aligned_text = dynamic_align_format(data_rows)
|
||||
|
||||
# 输出到 Telegram
|
||||
text = f"""📊 排行榜
|
||||
```
|
||||
{aligned_text}
|
||||
```
|
||||
💡 说明文字"""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 格式化系统
|
||||
|
||||
### 1. 交易量智能缩写
|
||||
|
||||
```python
|
||||
def format_volume(volume: float) -> str:
|
||||
"""智能格式化交易量"""
|
||||
if volume >= 1e9:
|
||||
return f"${volume/1e9:.2f}B" # 十亿 → $1.23B
|
||||
elif volume >= 1e6:
|
||||
return f"${volume/1e6:.2f}M" # 百万 → $890.5M
|
||||
elif volume >= 1e3:
|
||||
return f"${volume/1e3:.2f}K" # 千 → $123.4K
|
||||
else:
|
||||
return f"${volume:.2f}" # 小数 → $45.67
|
||||
```
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
format_volume(1234567890) # → "$1.23B"
|
||||
format_volume(890500000) # → "$890.5M"
|
||||
format_volume(123400) # → "$123.4K"
|
||||
```
|
||||
|
||||
### 2. 价格智能精度
|
||||
|
||||
```python
|
||||
def format_price(price: float) -> str:
|
||||
"""智能格式化价格 - 根据大小自动调整小数位"""
|
||||
if price >= 1000:
|
||||
return f"${price:,.0f}" # 千元以上 → $45,000
|
||||
elif price >= 1:
|
||||
return f"${price:.3f}" # 1-1000 → $2.500
|
||||
elif price >= 0.01:
|
||||
return f"${price:.4f}" # 0.01-1 → $0.0789
|
||||
else:
|
||||
return f"${price:.6f}" # <0.01 → $0.000123
|
||||
```
|
||||
|
||||
### 3. 涨跌幅格式化
|
||||
|
||||
```python
|
||||
def format_change(change_percent: float) -> str:
|
||||
"""格式化涨跌幅 - 正数添加+号"""
|
||||
if change_percent >= 0:
|
||||
return f"+{change_percent:.2f}%"
|
||||
else:
|
||||
return f"{change_percent:.2f}%"
|
||||
```
|
||||
|
||||
**示例:**
|
||||
```python
|
||||
format_change(5.234) # → "+5.23%"
|
||||
format_change(-1.456) # → "-1.46%"
|
||||
format_change(0) # → "+0.00%"
|
||||
```
|
||||
|
||||
### 4. 资金流向智能显示
|
||||
|
||||
```python
|
||||
def format_flow(net_flow: float) -> str:
|
||||
"""格式化资金净流向"""
|
||||
sign = "+" if net_flow >= 0 else ""
|
||||
abs_flow = abs(net_flow)
|
||||
|
||||
if abs_flow >= 1e9:
|
||||
return f"{sign}{net_flow/1e9:.2f}B"
|
||||
elif abs_flow >= 1e6:
|
||||
return f"{sign}{net_flow/1e6:.2f}M"
|
||||
elif abs_flow >= 1e3:
|
||||
return f"{sign}{net_flow/1e3:.2f}K"
|
||||
else:
|
||||
return f"{sign}{net_flow:.0f}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 应用示例
|
||||
|
||||
### 完整排行榜实现
|
||||
|
||||
```python
|
||||
def get_volume_ranking(data, limit=10):
|
||||
"""获取交易量排行榜"""
|
||||
|
||||
# 1. 数据处理和排序
|
||||
sorted_data = sorted(data, key=lambda x: x['volume'], reverse=True)[:limit]
|
||||
|
||||
# 2. 准备数据行
|
||||
data_rows = []
|
||||
for i, item in enumerate(sorted_data, 1):
|
||||
symbol = item['symbol']
|
||||
volume = item['volume']
|
||||
price = item['price']
|
||||
change = item['change_percent']
|
||||
|
||||
# 格式化各列
|
||||
volume_str = format_volume(volume)
|
||||
price_str = format_price(price)
|
||||
change_str = format_change(change)
|
||||
|
||||
# 添加到数据行
|
||||
data_rows.append([
|
||||
f"{i}.", # 序号
|
||||
symbol, # 币种
|
||||
volume_str, # 交易量
|
||||
price_str, # 价格
|
||||
change_str # 涨跌幅
|
||||
])
|
||||
|
||||
# 3. 动态对齐格式化
|
||||
aligned_data = dynamic_align_format(data_rows)
|
||||
|
||||
# 4. 构建最终消息
|
||||
text = f"""🎪 热币排行 - 交易量榜 🎪
|
||||
⏰ 更新 {datetime.now().strftime('%Y-%m-%d %H:%M')}
|
||||
📊 排序 24小时交易量(USDT) / 降序
|
||||
排名/币种/24h交易量/价格/24h涨跌
|
||||
```
|
||||
{aligned_data}
|
||||
```
|
||||
💡 交易量反映市场活跃度和流动性"""
|
||||
|
||||
return text
|
||||
```
|
||||
|
||||
### 输出效果
|
||||
|
||||
```
|
||||
🎪 热币排行 - 交易量榜 🎪
|
||||
⏰ 更新 2025-10-29 14:30
|
||||
📊 排序 24小时交易量(USDT) / 降序
|
||||
排名/币种/24h交易量/价格/24h涨跌
|
||||
|
||||
1. BTC $1.23B $45,000 +5.23%
|
||||
2. ETH $890.5M $2,500 +3.12%
|
||||
3. SOL $567.8M $101 +8.45%
|
||||
4. BNB $432.1M $315 +2.67%
|
||||
5. XRP $345.6M $0.589 -1.23%
|
||||
|
||||
💡 交易量反映市场活跃度和流动性
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 数据准备规范
|
||||
|
||||
```python
|
||||
# ✅ 推荐:使用列表嵌套结构
|
||||
data_rows = [
|
||||
["1.", "BTC", "$1.23B", "$45,000", "+5.23%"],
|
||||
["2.", "ETH", "$890.5M", "$2,500", "+3.12%"]
|
||||
]
|
||||
|
||||
# ❌ 不推荐:使用字典(需要额外转换)
|
||||
data_rows = [
|
||||
{"rank": 1, "symbol": "BTC", ...},
|
||||
]
|
||||
```
|
||||
|
||||
### 2. 格式化顺序
|
||||
|
||||
```python
|
||||
# ✅ 推荐:先格式化,再对齐
|
||||
for i, item in enumerate(data, 1):
|
||||
volume_str = format_volume(item['volume']) # 格式化
|
||||
price_str = format_price(item['price']) # 格式化
|
||||
change_str = format_change(item['change']) # 格式化
|
||||
|
||||
data_rows.append([f"{i}.", symbol, volume_str, price_str, change_str])
|
||||
|
||||
aligned_data = dynamic_align_format(data_rows) # 对齐
|
||||
```
|
||||
|
||||
### 3. Telegram 消息嵌入
|
||||
|
||||
```python
|
||||
# ✅ 推荐:使用代码块包裹对齐数据
|
||||
text = f"""📊 排行榜标题
|
||||
⏰ 更新时间 {time}
|
||||
```
|
||||
{aligned_data}
|
||||
```
|
||||
💡 说明文字"""
|
||||
|
||||
# ❌ 不推荐:直接输出(Telegram会自动换行,破坏对齐)
|
||||
text = f"""📊 排行榜标题
|
||||
{aligned_data}
|
||||
💡 说明文字"""
|
||||
```
|
||||
|
||||
### 4. 空数据处理
|
||||
|
||||
```python
|
||||
# ✅ 推荐:在函数开头检查
|
||||
def dynamic_align_format(data_rows):
|
||||
if not data_rows:
|
||||
return "暂无数据"
|
||||
# ... 正常处理逻辑 ...
|
||||
```
|
||||
|
||||
### 5. 性能优化
|
||||
|
||||
```python
|
||||
# ✅ 推荐:限制数据量
|
||||
sorted_data = sorted(data, key=lambda x: x['volume'], reverse=True)[:limit]
|
||||
aligned_data = dynamic_align_format(data_rows)
|
||||
|
||||
# ❌ 不推荐:处理全量后截取(浪费资源)
|
||||
aligned_data = dynamic_align_format(all_data_rows)
|
||||
final_data = aligned_data.split('\n')[:limit]
|
||||
```
|
||||
|
||||
### 6. 中文字符支持(可选)
|
||||
|
||||
```python
|
||||
def get_display_width(text):
|
||||
"""计算文本显示宽度(中文=2,英文=1)"""
|
||||
width = 0
|
||||
for char in text:
|
||||
if ord(char) > 127: # 非ASCII字符
|
||||
width += 2
|
||||
else:
|
||||
width += 1
|
||||
return width
|
||||
|
||||
# 在 dynamic_align_format 中使用
|
||||
max_widths[i] = max(max_widths[i], get_display_width(str(cell)))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 设计优势
|
||||
|
||||
### 与硬编码方式对比
|
||||
|
||||
| 特性 | 传统硬编码 | 动态对齐 |
|
||||
|------|-----------|---------|
|
||||
| 列宽适配 | 手动指定 | 自动计算 |
|
||||
| 维护成本 | 高(需多处修改) | 低(一次编写) |
|
||||
| 对齐精度 | 易出偏差 | 字符级精确 |
|
||||
| 扩展性 | 需重构 | 自动支持任意列 |
|
||||
| 性能 | O(n) | O(n×m) |
|
||||
|
||||
### 技术亮点
|
||||
|
||||
- **自适应宽度**: 无论数据如何变化,始终完美对齐
|
||||
- **智能对齐规则**: 符合人类阅读习惯(文本左,数字右)
|
||||
- **等宽字体完美支持**: 空格填充确保对齐效果
|
||||
- **高复用性**: 一个函数适用所有排行榜场景
|
||||
|
||||
---
|
||||
|
||||
## 快速参考
|
||||
|
||||
### 函数签名
|
||||
|
||||
```python
|
||||
dynamic_align_format(data_rows: list[list]) -> str
|
||||
format_volume(volume: float) -> str
|
||||
format_price(price: float) -> str
|
||||
format_change(change_percent: float) -> str
|
||||
format_flow(net_flow: float) -> str
|
||||
```
|
||||
|
||||
### 时间复杂度
|
||||
|
||||
- 宽度计算: O(n × m)
|
||||
- 格式化输出: O(n × m)
|
||||
- 总复杂度: O(n × m) - 线性时间,高效实用
|
||||
|
||||
### 性能基准
|
||||
|
||||
- 处理 100 行 × 5 列: ~1ms
|
||||
- 处理 1000 行 × 5 列: ~5-10ms
|
||||
- 内存占用: 最小
|
||||
|
||||
---
|
||||
|
||||
**这份指南提供了 Telegram Bot 专业数据展示的完整解决方案!**
|
||||
+405
@@ -0,0 +1,405 @@
|
||||
TRANSLATED CONTENT:
|
||||
# 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 - 配置设置
|
||||
```
|
||||
|
||||
**通过 API(python-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 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. 常用库版本
|
||||
|
||||
```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 按钮和键盘的所有核心实现!**
|
||||
+413
@@ -0,0 +1,413 @@
|
||||
# 📊 Dynamic View Alignment - A Guide to Data Display in Telegram
|
||||
|
||||
> A professional solution for monospaced font data alignment and formatting
|
||||
|
||||
---
|
||||
|
||||
## 📑 Table of Contents
|
||||
|
||||
- [Core Principles](#core-principles)
|
||||
- [Implementation Code](#implementation-code)
|
||||
- [Formatting System](#formatting-system)
|
||||
- [Application Examples](#application-examples)
|
||||
- [Best Practices](#best-practices)
|
||||
|
||||
---
|
||||
|
||||
## Core Principles
|
||||
|
||||
### Problem Scenario
|
||||
|
||||
When displaying leaderboards or data tables in a Telegram Bot, perfect alignment is required in a monospaced font environment (code block):
|
||||
|
||||
**❌ Unaligned:**
|
||||
```
|
||||
1. BTC $1.23B $45000 +5.23%
|
||||
10. DOGE $123.4M $0.0789 -1.45%
|
||||
```
|
||||
|
||||
**✅ Dynamically Aligned:**
|
||||
```
|
||||
1. BTC $1.23B $45,000 +5.23%
|
||||
10. DOGE $123.4M $0.0789 -1.45%
|
||||
```
|
||||
|
||||
### Three-Step Alignment Algorithm
|
||||
|
||||
```
|
||||
Step 1: Scan the data to calculate the maximum width of each column
|
||||
Step 2: Apply alignment rules based on the column type (text left-aligned, numbers right-aligned)
|
||||
Step 3: Concatenate into the final text
|
||||
```
|
||||
|
||||
### Alignment Rules
|
||||
|
||||
| Column Index | Data Type | Alignment | Example |
|
||||
|---|---|---|---|
|
||||
| Column 0 | Sequence No. | Left-aligned | `1. `, `10. ` |
|
||||
| Column 1 | Symbol | Left-aligned | `BTC `, `DOGE ` |
|
||||
| Column 2+ | Numeric Value | Right-aligned | ` $1.23B`, `$123.4M` |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Code
|
||||
|
||||
### Core Function
|
||||
|
||||
```python
|
||||
def dynamic_align_format(data_rows):
|
||||
"""
|
||||
Dynamically aligns and formats the view.
|
||||
|
||||
Args:
|
||||
data_rows: A 2D list [["1.", "BTC", "$1.23B", ...], ...]
|
||||
|
||||
Returns:
|
||||
An aligned text string.
|
||||
"""
|
||||
if not data_rows:
|
||||
return "No data available"
|
||||
|
||||
# ========== Step 1: Calculate the maximum width of each column ==========
|
||||
max_widths = []
|
||||
for row in data_rows:
|
||||
for i, cell in enumerate(row):
|
||||
# Dynamically expand the list
|
||||
if i >= len(max_widths):
|
||||
max_widths.append(0)
|
||||
# Update the maximum width
|
||||
max_widths[i] = max(max_widths[i], len(str(cell)))
|
||||
|
||||
# ========== Step 2: Format each row ==========
|
||||
formatted_rows = []
|
||||
for row in data_rows:
|
||||
formatted_cells = []
|
||||
for i, cell in enumerate(row):
|
||||
cell_str = str(cell)
|
||||
|
||||
if i == 0 or i == 1:
|
||||
# Sequence number and symbol columns - left-aligned
|
||||
formatted_cells.append(cell_str.ljust(max_widths[i]))
|
||||
else:
|
||||
# Numeric columns - right-aligned
|
||||
formatted_cells.append(cell_str.rjust(max_widths[i]))
|
||||
|
||||
# Join all cells with a space
|
||||
formatted_line = ' '.join(formatted_cells)
|
||||
formatted_rows.append(formatted_line)
|
||||
|
||||
# ========== Step 3: Concatenate into the final text ==========
|
||||
return '\n'.join(formatted_rows)
|
||||
```
|
||||
|
||||
### Usage Example
|
||||
|
||||
```python
|
||||
# Prepare the data
|
||||
data_rows = [
|
||||
["1.", "BTC", "$1.23B", "$45,000", "+5.23%"],
|
||||
["2.", "ETH", "$890.5M", "$2,500", "+3.12%"],
|
||||
["10.", "DOGE", "$123.4M", "$0.0789", "-1.45%"]
|
||||
]
|
||||
|
||||
# Call the alignment function
|
||||
aligned_text = dynamic_align_format(data_rows)
|
||||
|
||||
# Output to Telegram
|
||||
text = f"""
|
||||
📊 Leaderboard
|
||||
```
|
||||
{aligned_text}
|
||||
```
|
||||
💡 Explanatory text"""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Formatting System
|
||||
|
||||
### 1. Smart Abbreviation for Trading Volume
|
||||
|
||||
```python
|
||||
def format_volume(volume: float) -> str:
|
||||
"""Intelligently formats trading volume."""
|
||||
if volume >= 1e9:
|
||||
return f"${volume/1e9:.2f}B" # Billions → $1.23B
|
||||
elif volume >= 1e6:
|
||||
return f"${volume/1e6:.2f}M" # Millions → $890.5M
|
||||
elif volume >= 1e3:
|
||||
return f"${volume/1e3:.2f}K" # Thousands → $123.4K
|
||||
else:
|
||||
return f"${volume:.2f}" # Decimals → $45.67
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
format_volume(1234567890) # → "$1.23B"
|
||||
format_volume(890500000) # → "$890.5M"
|
||||
format_volume(123400) # → "$123.4K"
|
||||
```
|
||||
|
||||
### 2. Smart Precision for Price
|
||||
|
||||
```python
|
||||
def format_price(price: float) -> str:
|
||||
"""Intelligently formats price - automatically adjusts decimal places based on value."""
|
||||
if price >= 1000:
|
||||
return f"${price:,.0f}" # Above 1000 → $45,000
|
||||
elif price >= 1:
|
||||
return f"${price:.3f}" # 1-1000 → $2.500
|
||||
elif price >= 0.01:
|
||||
return f"${price:.4f}" # 0.01-1 → $0.0789
|
||||
else:
|
||||
return f"${price:.6f}" # <0.01 → $0.000123
|
||||
```
|
||||
|
||||
### 3. Formatting for Price Change Percentage
|
||||
|
||||
```python
|
||||
def format_change(change_percent: float) -> str:
|
||||
"""Formats price change percentage - adds a '+' sign for positive numbers."""
|
||||
if change_percent >= 0:
|
||||
return f"+{change_percent:.2f}%"
|
||||
else:
|
||||
return f"{change_percent:.2f}%"
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
format_change(5.234) # → "+5.23%"
|
||||
format_change(-1.456) # → "-1.46%"
|
||||
format_change(0) # → "+0.00%"
|
||||
```
|
||||
|
||||
### 4. Smart Display for Fund Flow
|
||||
|
||||
```python
|
||||
def format_flow(net_flow: float) -> str:
|
||||
"""Formats net fund flow."""
|
||||
sign = "+" if net_flow >= 0 else ""
|
||||
abs_flow = abs(net_flow)
|
||||
|
||||
if abs_flow >= 1e9:
|
||||
return f"{sign}{net_flow/1e9:.2f}B"
|
||||
elif abs_flow >= 1e6:
|
||||
return f"{sign}{net_flow/1e6:.2f}M"
|
||||
elif abs_flow >= 1e3:
|
||||
return f"{sign}{net_flow/1e3:.2f}K"
|
||||
else:
|
||||
return f"{sign}{net_flow:.0f}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Application Examples
|
||||
|
||||
### Complete Leaderboard Implementation
|
||||
|
||||
```python
|
||||
def get_volume_ranking(data, limit=10):
|
||||
"""Gets the trading volume leaderboard."""
|
||||
|
||||
# 1. Data processing and sorting
|
||||
sorted_data = sorted(data, key=lambda x: x['volume'], reverse=True)[:limit]
|
||||
|
||||
# 2. Prepare data rows
|
||||
data_rows = []
|
||||
for i, item in enumerate(sorted_data, 1):
|
||||
symbol = item['symbol']
|
||||
volume = item['volume']
|
||||
price = item['price']
|
||||
change = item['change_percent']
|
||||
|
||||
# Format each column
|
||||
volume_str = format_volume(volume)
|
||||
price_str = format_price(price)
|
||||
change_str = format_change(change)
|
||||
|
||||
# Add to data rows
|
||||
data_rows.append([
|
||||
f"{i}.", # Sequence No.
|
||||
symbol, # Coin
|
||||
volume_str, # Volume
|
||||
price_str, # Price
|
||||
change_str # Change %
|
||||
])
|
||||
|
||||
# 3. Dynamic alignment and formatting
|
||||
aligned_data = dynamic_align_format(data_rows)
|
||||
|
||||
# 4. Build the final message
|
||||
text = f"""
|
||||
🎪 Hot Coins - Volume Ranking 🎪
|
||||
⏰ Updated {datetime.now().strftime('%Y-%m-%d %H:%M')}
|
||||
📊 Sorted by 24h Volume (USDT) / Descending
|
||||
Rank/Coin/24h Vol/Price/24h Change
|
||||
```
|
||||
{aligned_data}
|
||||
```
|
||||
💡 Volume reflects market activity and liquidity."""
|
||||
|
||||
return text
|
||||
```
|
||||
|
||||
### Output Effect
|
||||
|
||||
```
|
||||
🎪 Hot Coins - Volume Ranking 🎪
|
||||
⏰ Updated 2025-10-29 14:30
|
||||
📊 Sorted by 24h Volume (USDT) / Descending
|
||||
Rank/Coin/24h Vol/Price/24h Change
|
||||
|
||||
1. BTC $1.23B $45,000 +5.23%
|
||||
2. ETH $890.5M $2,500 +3.12%
|
||||
3. SOL $567.8M $101 +8.45%
|
||||
4. BNB $432.1M $315 +2.67%
|
||||
5. XRP $345.6M $0.589 -1.23%
|
||||
|
||||
💡 Volume reflects market activity and liquidity.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Data Preparation Standards
|
||||
|
||||
```python
|
||||
# ✅ Recommended: Use a nested list structure
|
||||
data_rows = [
|
||||
["1.", "BTC", "$1.23B", "$45,000", "+5.23%"],
|
||||
["2.", "ETH", "$890.5M", "$2,500", "+3.12%"]
|
||||
]
|
||||
|
||||
# ❌ Not recommended: Use a dictionary (requires extra conversion)
|
||||
data_rows = [
|
||||
{"rank": 1, "symbol": "BTC", ...},
|
||||
]
|
||||
```
|
||||
|
||||
### 2. Formatting Order
|
||||
|
||||
```python
|
||||
# ✅ Recommended: Format first, then align
|
||||
for i, item in enumerate(data, 1):
|
||||
volume_str = format_volume(item['volume']) # Format
|
||||
price_str = format_price(item['price']) # Format
|
||||
change_str = format_change(item['change']) # Format
|
||||
|
||||
data_rows.append([f"{i}.", symbol, volume_str, price_str, change_str])
|
||||
|
||||
aligned_data = dynamic_align_format(data_rows) # Align
|
||||
```
|
||||
|
||||
### 3. Embedding in Telegram Messages
|
||||
|
||||
```python
|
||||
# ✅ Recommended: Wrap aligned data in a code block
|
||||
text = f"""
|
||||
📊 Leaderboard Title
|
||||
⏰ Update Time {time}
|
||||
```
|
||||
{aligned_data}
|
||||
```
|
||||
💡 Explanatory text"""
|
||||
|
||||
# ❌ Not recommended: Direct output (Telegram's auto-wrapping will break alignment)
|
||||
text = f"""
|
||||
📊 Leaderboard Title
|
||||
{aligned_data}
|
||||
💡 Explanatory text"""
|
||||
```
|
||||
|
||||
### 4. Handling Empty Data
|
||||
|
||||
```python
|
||||
# ✅ Recommended: Check at the beginning of the function
|
||||
def dynamic_align_format(data_rows):
|
||||
if not data_rows:
|
||||
return "No data available"
|
||||
# ... Normal processing logic ...
|
||||
```
|
||||
|
||||
### 5. Performance Optimization
|
||||
|
||||
```python
|
||||
# ✅ Recommended: Limit the amount of data
|
||||
sorted_data = sorted(data, key=lambda x: x['volume'], reverse=True)[:limit]
|
||||
aligned_data = dynamic_align_format(data_rows)
|
||||
|
||||
# ❌ Not recommended: Process all data then truncate (wastes resources)
|
||||
aligned_data = dynamic_align_format(all_data_rows)
|
||||
final_data = aligned_data.split('\n')[:limit]
|
||||
```
|
||||
|
||||
### 6. Chinese Character Support (Optional)
|
||||
|
||||
```python
|
||||
def get_display_width(text):
|
||||
"""Calculates the display width of text (Chinese=2, English=1)."""
|
||||
width = 0
|
||||
for char in text:
|
||||
if ord(char) > 127: # Non-ASCII characters
|
||||
width += 2
|
||||
else:
|
||||
width += 1
|
||||
return width
|
||||
|
||||
# Use in dynamic_align_format
|
||||
max_widths[i] = max(max_widths[i], get_display_width(str(cell)))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Design Advantages
|
||||
|
||||
### Comparison with Hardcoding
|
||||
|
||||
| Feature | Traditional Hardcoding | Dynamic Alignment |
|
||||
|---|---|---|
|
||||
| Column Width Adaptation | Manual specification | Automatic calculation |
|
||||
| Maintenance Cost | High (requires multiple modifications) | Low (write once) |
|
||||
| Alignment Precision | Prone to deviation | Character-level precision |
|
||||
| Scalability | Requires refactoring | Supports any number of columns automatically |
|
||||
| Performance | O(n) | O(n×m) |
|
||||
|
||||
### Technical Highlights
|
||||
|
||||
- **Adaptive Width**: Perfect alignment regardless of data changes
|
||||
- **Smart Alignment Rules**: Conforms to human reading habits (text left, numbers right)
|
||||
- **Perfect Monospaced Font Support**: Space padding ensures alignment
|
||||
- **High Reusability**: One function for all leaderboard scenarios
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Function Signatures
|
||||
|
||||
```python
|
||||
dynamic_align_format(data_rows: list[list]) -> str
|
||||
format_volume(volume: float) -> str
|
||||
format_price(price: float) -> str
|
||||
format_change(change_percent: float) -> str
|
||||
format_flow(net_flow: float) -> str
|
||||
```
|
||||
|
||||
### Time Complexity
|
||||
|
||||
- Width Calculation: O(n × m)
|
||||
- Formatted Output: O(n × m)
|
||||
- Total Complexity: O(n × m) - Linear time, highly efficient
|
||||
|
||||
### Performance Benchmarks
|
||||
|
||||
- Processing 100 rows × 5 columns: ~1ms
|
||||
- Processing 1000 rows × 5 columns: ~5-10ms
|
||||
- Memory Usage: Minimal
|
||||
|
||||
---
|
||||
|
||||
**This guide provides a complete solution for professional data display in Telegram Bots!**
|
||||
|
||||
```
|
||||
@@ -0,0 +1,470 @@
|
||||
# Telegram Ecosystem Development Resource Index
|
||||
|
||||
## Official Documentation
|
||||
|
||||
### Bot API
|
||||
**Main Documentation:** https://core.telegram.org/bots/api
|
||||
**Description:** Complete reference documentation for the Telegram Bot API
|
||||
|
||||
**Core Features:**
|
||||
- Sending and receiving messages
|
||||
- Handling media files
|
||||
- Inline mode
|
||||
- Payment integration
|
||||
- Webhook configuration
|
||||
- Games and polls
|
||||
|
||||
### Mini Apps (Web Apps)
|
||||
**Main Documentation:** https://core.telegram.org/bots/webapps
|
||||
**Full Platform:** https://docs.telegram-mini-apps.com
|
||||
**Description:** Development documentation for Telegram Mini Apps
|
||||
|
||||
**Core Features:**
|
||||
- WebApp API
|
||||
- Themes and UI controls
|
||||
- Storage (Cloud/Device/Secure)
|
||||
- Biometric authentication
|
||||
- Location and sensors
|
||||
- Payment integration
|
||||
|
||||
### Telegram API & MTProto
|
||||
**Main Documentation:** https://core.telegram.org
|
||||
**Description:** Complete Telegram protocol and client development
|
||||
|
||||
**Core Features:**
|
||||
- MTProto protocol
|
||||
- TDLib client library
|
||||
- Authentication and encryption
|
||||
- File operations
|
||||
- Secret Chats
|
||||
|
||||
## Official GitHub Repositories
|
||||
|
||||
### Bot API Server
|
||||
**Repository:** https://github.com/tdlib/telegram-bot-api
|
||||
**Description:** Implementation of the Telegram Bot API server
|
||||
**Features:**
|
||||
- Local mode deployment
|
||||
- Support for large files (up to 2000 MB)
|
||||
- C++ implementation
|
||||
- Based on TDLib
|
||||
|
||||
### Android Client
|
||||
**Repository:** https://github.com/DrKLO/Telegram
|
||||
**Description:** Source code for the official Android client
|
||||
**Features:**
|
||||
- Complete Android implementation
|
||||
- Material Design
|
||||
- Customizable compilation
|
||||
|
||||
### Desktop Client
|
||||
**Repository:** https://github.com/telegramdesktop/tdesktop
|
||||
**Description:** Official desktop client (Windows, macOS, Linux)
|
||||
**Features:**
|
||||
- Qt/C++ implementation
|
||||
- Cross-platform support
|
||||
- Full functionality
|
||||
|
||||
### Official Organization
|
||||
**Organization Page:** https://github.com/orgs/TelegramOfficial/repositories
|
||||
**Includes:**
|
||||
- Beta versions
|
||||
- Support tools
|
||||
- Example code
|
||||
|
||||
## API Method Categories
|
||||
|
||||
### Update Management
|
||||
- `getUpdates` - Long polling
|
||||
- `setWebhook` - Set a webhook
|
||||
- `deleteWebhook` - Delete a webhook
|
||||
- `getWebhookInfo` - Webhook information
|
||||
|
||||
### Message Operations
|
||||
**Sending Messages:**
|
||||
- `sendMessage` - Text message
|
||||
- `sendPhoto` - Photo
|
||||
- `sendVideo` - Video
|
||||
- `sendDocument` - Document
|
||||
- `sendAudio` - Audio
|
||||
- `sendVoice` - Voice
|
||||
- `sendLocation` - Location
|
||||
- `sendVenue` - Venue
|
||||
- `sendContact` - Contact
|
||||
- `sendPoll` - Poll
|
||||
- `sendDice` - Dice/Darts
|
||||
|
||||
**Editing Messages:**
|
||||
- `editMessageText` - Edit text
|
||||
- `editMessageCaption` - Edit caption
|
||||
- `editMessageMedia` - Edit media
|
||||
- `editMessageReplyMarkup` - Edit keyboard
|
||||
- `deleteMessage` - Delete a message
|
||||
|
||||
**Other Operations:**
|
||||
- `forwardMessage` - Forward a message
|
||||
- `copyMessage` - Copy a message
|
||||
- `sendChatAction` - Send an action (typing...)
|
||||
|
||||
### File Operations
|
||||
- `getFile` - Get file information
|
||||
- File download URL: `https://api.telegram.org/file/bot<token>/<file_path>`
|
||||
- File upload: Supports multipart/form-data
|
||||
- Max file size: 50 MB (standard), 2000 MB (local Bot API)
|
||||
|
||||
### Inline Mode
|
||||
- `answerInlineQuery` - Respond to an inline query
|
||||
- Result types: article, photo, gif, video, audio, voice, document, location, venue, contact, game, sticker
|
||||
|
||||
### Callback Queries
|
||||
- `answerCallbackQuery` - Respond to a button click
|
||||
- Can display a notification or an alert
|
||||
|
||||
### Payments
|
||||
- `sendInvoice` - Send an invoice
|
||||
- `answerPreCheckoutQuery` - Pre-checkout
|
||||
- `answerShippingQuery` - Shipping query
|
||||
- Supported providers: Stripe, Yandex.Money, Telegram Stars
|
||||
|
||||
### Games
|
||||
- `sendGame` - Send a game
|
||||
- `setGameScore` - Set a score
|
||||
- `getGameHighScores` - Get high scores
|
||||
|
||||
### Group Management
|
||||
- `kickChatMember` / `unbanChatMember` - Ban/unban
|
||||
- `restrictChatMember` - Restrict permissions
|
||||
- `promoteChatMember` - Promote to admin
|
||||
- `setChatTitle` / `setChatDescription` - Set chat info
|
||||
- `setChatPhoto` - Set chat photo
|
||||
- `pinChatMessage` / `unpinChatMessage` - Pin/unpin a message
|
||||
|
||||
## Mini Apps API Details
|
||||
|
||||
### Initialization
|
||||
```javascript
|
||||
const tg = window.Telegram.WebApp;
|
||||
tg.ready();
|
||||
tg.expand();
|
||||
```
|
||||
|
||||
### Main Objects
|
||||
- **WebApp** - Main interface
|
||||
- **MainButton** - Main button
|
||||
- **SecondaryButton** - Secondary button
|
||||
- **BackButton** - Back button
|
||||
- **SettingsButton** - Settings button
|
||||
- **HapticFeedback** - Haptic feedback
|
||||
- **CloudStorage** - Cloud storage
|
||||
- **BiometricManager** - Biometrics
|
||||
- **LocationManager** - Location services
|
||||
- **Accelerometer** - Accelerometer
|
||||
- **Gyroscope** - Gyroscope
|
||||
- **DeviceOrientation** - Device orientation
|
||||
|
||||
### Event System
|
||||
40+ events including:
|
||||
- `themeChanged` - Theme changed
|
||||
- `viewportChanged` - Viewport changed
|
||||
- `mainButtonClicked` - Main button clicked
|
||||
- `backButtonClicked` - Back button clicked
|
||||
- `settingsButtonClicked` - Settings button clicked
|
||||
- `invoiceClosed` - Payment completed
|
||||
- `popupClosed` - Popup closed
|
||||
- `qrTextReceived` - QR code scan result
|
||||
- `clipboardTextReceived` - Clipboard text
|
||||
- `writeAccessRequested` - Write access requested
|
||||
- `contactRequested` - Contact requested
|
||||
|
||||
### Theme Parameters
|
||||
```javascript
|
||||
tg.themeParams = {
|
||||
bg_color, // Background color
|
||||
text_color, // Text color
|
||||
hint_color, // Hint color
|
||||
link_color, // Link color
|
||||
button_color, // Button color
|
||||
button_text_color, // Button text color
|
||||
secondary_bg_color, // Secondary background color
|
||||
header_bg_color, // Header background color
|
||||
accent_text_color, // Accent text color
|
||||
section_bg_color, // Section background color
|
||||
section_header_text_color, // Section header text color
|
||||
subtitle_text_color, // Subtitle color
|
||||
destructive_text_color // Destructive action color
|
||||
}
|
||||
```
|
||||
|
||||
## Development Tools
|
||||
|
||||
### @BotFather Commands
|
||||
The core tool for creating and managing Bots:
|
||||
|
||||
**Bot Management:**
|
||||
- `/newbot` - Create a new Bot
|
||||
- `/mybots` - Manage my Bots
|
||||
- `/deletebot` - Delete a Bot
|
||||
- `/token` - Regenerate a token
|
||||
|
||||
**Settings Commands:**
|
||||
- `/setname` - Set name
|
||||
- `/setdescription` - Set description
|
||||
- `/setabouttext` - Set about text
|
||||
- `/setuserpic` - Set user picture
|
||||
|
||||
**Feature Configuration:**
|
||||
- `/setcommands` - Set command list
|
||||
- `/setinline` - Enable inline mode
|
||||
- `/setinlinefeedback` - Inline feedback
|
||||
- `/setjoingroups` - Allow joining groups
|
||||
- `/setprivacy` - Privacy mode
|
||||
|
||||
**Payments and Games:**
|
||||
- `/setgamescores` - Game scores
|
||||
- `/setpayments` - Configure payments
|
||||
|
||||
**Mini Apps:**
|
||||
- `/newapp` - Create a Mini App
|
||||
- `/myapps` - Manage Mini Apps
|
||||
- `/setmenubutton` - Set menu button
|
||||
|
||||
### Getting an API ID
|
||||
Visit https://my.telegram.org
|
||||
1. Log in to your account
|
||||
2. Go to API development tools
|
||||
3. Create an application
|
||||
4. Get your API ID and API Hash
|
||||
|
||||
## Common Python Libraries
|
||||
|
||||
### python-telegram-bot
|
||||
```bash
|
||||
pip install python-telegram-bot
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Complete Bot API wrapper
|
||||
- Asynchronous and synchronous support
|
||||
- Rich extensions
|
||||
- Actively maintained
|
||||
|
||||
**Basic Example:**
|
||||
```python
|
||||
from telegram import Update
|
||||
from telegram.ext import Application, CommandHandler, ContextTypes
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Hello!')
|
||||
|
||||
app = Application.builder().token("TOKEN").build()
|
||||
app.add_handler(CommandHandler("start", start))
|
||||
app.run_polling()
|
||||
```
|
||||
|
||||
### aiogram
|
||||
```bash
|
||||
pip install aiogram
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Purely asynchronous
|
||||
- High performance
|
||||
- FSM state machine
|
||||
- Middleware system
|
||||
|
||||
### Telethon / Pyrogram
|
||||
MTProto client libraries:
|
||||
```bash
|
||||
pip install telethon
|
||||
pip install pyrogram
|
||||
```
|
||||
|
||||
**Uses:**
|
||||
- Custom clients
|
||||
- User account automation
|
||||
- Full Telegram functionality
|
||||
|
||||
## Common Node.js Libraries
|
||||
|
||||
### node-telegram-bot-api
|
||||
```bash
|
||||
npm install node-telegram-bot-api
|
||||
```
|
||||
|
||||
### Telegraf
|
||||
```bash
|
||||
npm install telegraf
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Modern
|
||||
- Middleware architecture
|
||||
- TypeScript support
|
||||
|
||||
### grammY
|
||||
```bash
|
||||
npm install grammy
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Lightweight
|
||||
- Type-safe
|
||||
- Plugin ecosystem
|
||||
|
||||
## Deployment Options
|
||||
|
||||
### Webhook Hosting
|
||||
**Recommended Platforms:**
|
||||
- Heroku
|
||||
- AWS Lambda
|
||||
- Google Cloud Functions
|
||||
- Azure Functions
|
||||
- Vercel
|
||||
- Railway
|
||||
- Render
|
||||
|
||||
**Requirements:**
|
||||
- HTTPS support
|
||||
- Publicly accessible
|
||||
- Supported ports: 443, 80, 88, 8443
|
||||
|
||||
### Long Polling Hosting
|
||||
**Recommended Platforms:**
|
||||
- VPS (Vultr, DigitalOcean, Linode)
|
||||
- Raspberry Pi
|
||||
- Local server
|
||||
|
||||
**Advantages:**
|
||||
- No HTTPS required
|
||||
- Simple configuration
|
||||
- Suitable for development and testing
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Token Security**
|
||||
- Do not commit to Git
|
||||
- Use environment variables
|
||||
- Rotate tokens regularly
|
||||
|
||||
2. **Data Validation**
|
||||
- Validate initData
|
||||
- Server-side validation
|
||||
- Do not trust the client
|
||||
|
||||
3. **Permission Control**
|
||||
- Check user permissions
|
||||
- Admin verification
|
||||
- Group permissions
|
||||
|
||||
4. **Rate Limiting**
|
||||
- Implement request limits
|
||||
- Prevent abuse
|
||||
- Monitor for anomalies
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### Bot Debugging
|
||||
```python
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
```
|
||||
|
||||
### Mini App Debugging
|
||||
```javascript
|
||||
// Enable debug mode
|
||||
tg.showAlert(JSON.stringify(tg.initDataUnsafe, null, 2));
|
||||
|
||||
// Console logs
|
||||
console.log('WebApp version:', tg.version);
|
||||
console.log('Platform:', tg.platform);
|
||||
console.log('Theme:', tg.colorScheme);
|
||||
```
|
||||
|
||||
### Webhook Testing
|
||||
Use ngrok for local testing:
|
||||
```bash
|
||||
ngrok http 5000
|
||||
# Set the generated https URL as the webhook
|
||||
```
|
||||
|
||||
## Community Resources
|
||||
|
||||
- **Telegram Developer Group**: @BotDevelopers
|
||||
- **Telegram API Discussion**: @TelegramBots
|
||||
- **Mini Apps Discussion**: @WebAppChat
|
||||
|
||||
## Changelog
|
||||
|
||||
**Latest Features:**
|
||||
- Paid Media
|
||||
- Checklist Tasks
|
||||
- Gift Conversion
|
||||
- Business Features
|
||||
- Poll options increased to 12
|
||||
- Story publishing and editing
|
||||
|
||||
---
|
||||
|
||||
## Complete Implementation Templates (New)
|
||||
|
||||
### Telegram Bot Button and Keyboard Implementation Guide
|
||||
**File:** `Telegram_Bot_button_and_keyboard_implementation_template.md`
|
||||
**Lines:** 404
|
||||
**Size:** 12 KB
|
||||
**Language:** Chinese
|
||||
|
||||
A concise and practical guide to implementing interactive features for Telegram Bots:
|
||||
|
||||
**Core Content:**
|
||||
- Detailed explanation of three button types (Inline/Reply/Command Menu)
|
||||
- Comparison of implementations with python-telegram-bot and Telethon
|
||||
- Complete code examples (ready to use)
|
||||
- Project structure and modular design
|
||||
- Handler priority and event handling
|
||||
- Production deployment solutions
|
||||
- Security and error handling best practices
|
||||
|
||||
**Features:**
|
||||
- Concise core code, removing redundant examples
|
||||
- Focus on common scenarios and practical tips
|
||||
- A complete quick reference table
|
||||
|
||||
---
|
||||
|
||||
### Dynamic View Alignment - Data Display Guide
|
||||
**File:** `dynamic-view-alignment-implementation-document.md`
|
||||
**Lines:** 407
|
||||
**Size:** 12 KB
|
||||
- **Language:** Chinese
|
||||
|
||||
A professional solution for monospaced font data alignment and formatting:
|
||||
|
||||
**Core Features:**
|
||||
- Intelligent dynamic view alignment algorithm (three-step method)
|
||||
- Automatic column width calculation, no hardcoding required
|
||||
- Smart alignment rules (text left, numbers right)
|
||||
- Complete formatting system:
|
||||
- Smart abbreviation for trading volume (B/M/K)
|
||||
- Smart precision for price (adaptive decimal places)
|
||||
- Formatting for price change percentage (+/- signs)
|
||||
- Smart display for fund flow
|
||||
|
||||
**Use Cases:**
|
||||
- Leaderboards, data tables, real-time tickers
|
||||
- Any Telegram Bot that needs professional data display
|
||||
|
||||
**Technical Features:**
|
||||
- O(n×m) linear complexity, highly efficient
|
||||
- Processes 1000 rows of data in just 5-10ms
|
||||
- Supports Chinese character width expansion
|
||||
|
||||
**Visual Effect Example:**
|
||||
```
|
||||
1. BTC $1.23B $45,000 +5.23%
|
||||
2. ETH $890.5M $2,500 +3.12%
|
||||
3. SOL $567.8M $101 +8.45%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**These templates provide a complete solution for Telegram Bot development, from basic to production level!**
|
||||
+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