mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-08-13 10:58:05 +00:00
refactor: 重构目录结构以支持 i18n
创建 'i18n' 目录以存放多语言内容。将所有现有的中文内容(文档、提示词、技能、README)移动到 'i18n/zh/' 中。添加了新的根 README 作为语言入口,并为英文('en')翻译创建了占位符结构。
This commit is contained in:
@@ -1,760 +0,0 @@
|
||||
---
|
||||
name: telegram-dev
|
||||
description: Telegram 生态开发全栈指南 - 涵盖 Bot API、Mini Apps (Web Apps)、MTProto 客户端开发。包括消息处理、支付、内联模式、Webhook、认证、存储、传感器 API 等完整开发资源。
|
||||
---
|
||||
|
||||
# Telegram 生态开发技能
|
||||
|
||||
全面的 Telegram 开发指南,涵盖 Bot 开发、Mini Apps (Web Apps)、客户端开发的完整技术栈。
|
||||
|
||||
## 何时使用此技能
|
||||
|
||||
当需要以下帮助时使用此技能:
|
||||
- 开发 Telegram Bot(消息机器人)
|
||||
- 创建 Telegram Mini Apps(小程序)
|
||||
- 构建自定义 Telegram 客户端
|
||||
- 集成 Telegram 支付和业务功能
|
||||
- 实现 Webhook 和长轮询
|
||||
- 使用 Telegram 认证和存储
|
||||
- 处理消息、媒体和文件
|
||||
- 实现内联模式和键盘
|
||||
|
||||
## Telegram 开发生态概览
|
||||
|
||||
### 三大核心 API
|
||||
|
||||
1. **Bot API** - 创建机器人程序
|
||||
- HTTP 接口,简单易用
|
||||
- 自动处理加密和通信
|
||||
- 适合:聊天机器人、自动化工具
|
||||
|
||||
2. **Mini Apps API** (Web Apps) - 创建 Web 应用
|
||||
- JavaScript 接口
|
||||
- 在 Telegram 内运行
|
||||
- 适合:小程序、游戏、电商
|
||||
|
||||
3. **Telegram API & TDLib** - 创建客户端
|
||||
- 完整的 Telegram 协议实现
|
||||
- 支持所有平台
|
||||
- 适合:自定义客户端、企业应用
|
||||
|
||||
## Bot API 开发
|
||||
|
||||
### 快速开始
|
||||
|
||||
**API 端点:**
|
||||
```
|
||||
https://api.telegram.org/bot<TOKEN>/METHOD_NAME
|
||||
```
|
||||
|
||||
**获取 Bot Token:**
|
||||
1. 与 @BotFather 对话
|
||||
2. 发送 `/newbot`
|
||||
3. 按提示设置名称
|
||||
4. 获取 token
|
||||
|
||||
**第一个 Bot (Python):**
|
||||
```python
|
||||
import requests
|
||||
|
||||
BOT_TOKEN = "your_bot_token_here"
|
||||
API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}"
|
||||
|
||||
# 发送消息
|
||||
def send_message(chat_id, text):
|
||||
url = f"{API_URL}/sendMessage"
|
||||
data = {"chat_id": chat_id, "text": text}
|
||||
return requests.post(url, json=data)
|
||||
|
||||
# 获取更新(长轮询)
|
||||
def get_updates(offset=None):
|
||||
url = f"{API_URL}/getUpdates"
|
||||
params = {"offset": offset, "timeout": 30}
|
||||
return requests.get(url, params=params).json()
|
||||
|
||||
# 主循环
|
||||
offset = None
|
||||
while True:
|
||||
updates = get_updates(offset)
|
||||
for update in updates.get("result", []):
|
||||
chat_id = update["message"]["chat"]["id"]
|
||||
text = update["message"]["text"]
|
||||
|
||||
# 回复消息
|
||||
send_message(chat_id, f"你说了:{text}")
|
||||
|
||||
offset = update["update_id"] + 1
|
||||
```
|
||||
|
||||
### 核心 API 方法
|
||||
|
||||
**更新管理:**
|
||||
- `getUpdates` - 长轮询获取更新
|
||||
- `setWebhook` - 设置 Webhook
|
||||
- `deleteWebhook` - 删除 Webhook
|
||||
- `getWebhookInfo` - 查询 Webhook 状态
|
||||
|
||||
**消息操作:**
|
||||
- `sendMessage` - 发送文本消息
|
||||
- `sendPhoto` / `sendVideo` / `sendDocument` - 发送媒体
|
||||
- `sendAudio` / `sendVoice` - 发送音频
|
||||
- `sendLocation` / `sendVenue` - 发送位置
|
||||
- `editMessageText` - 编辑消息
|
||||
- `deleteMessage` - 删除消息
|
||||
- `forwardMessage` / `copyMessage` - 转发/复制消息
|
||||
|
||||
**交互元素:**
|
||||
- `sendPoll` - 发送投票(最多 12 个选项)
|
||||
- 内联键盘 (InlineKeyboardMarkup)
|
||||
- 回复键盘 (ReplyKeyboardMarkup)
|
||||
- `answerCallbackQuery` - 响应回调查询
|
||||
|
||||
**文件操作:**
|
||||
- `getFile` - 获取文件信息
|
||||
- `downloadFile` - 下载文件
|
||||
- 支持最大 2GB 文件(本地 Bot API 模式)
|
||||
|
||||
**支付功能:**
|
||||
- `sendInvoice` - 发送发票
|
||||
- `answerPreCheckoutQuery` - 处理支付
|
||||
- Telegram Stars 支付(最高 10,000 Stars)
|
||||
|
||||
### Webhook 配置
|
||||
|
||||
**设置 Webhook:**
|
||||
```python
|
||||
import requests
|
||||
|
||||
BOT_TOKEN = "your_token"
|
||||
WEBHOOK_URL = "https://yourdomain.com/webhook"
|
||||
|
||||
requests.post(
|
||||
f"https://api.telegram.org/bot{BOT_TOKEN}/setWebhook",
|
||||
json={"url": WEBHOOK_URL}
|
||||
)
|
||||
```
|
||||
|
||||
**Flask Webhook 示例:**
|
||||
```python
|
||||
from flask import Flask, request
|
||||
import requests
|
||||
|
||||
app = Flask(__name__)
|
||||
BOT_TOKEN = "your_token"
|
||||
|
||||
@app.route('/webhook', methods=['POST'])
|
||||
def webhook():
|
||||
update = request.get_json()
|
||||
|
||||
chat_id = update["message"]["chat"]["id"]
|
||||
text = update["message"]["text"]
|
||||
|
||||
# 发送回复
|
||||
requests.post(
|
||||
f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
|
||||
json={"chat_id": chat_id, "text": f"收到: {text}"}
|
||||
)
|
||||
|
||||
return "OK"
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(port=5000)
|
||||
```
|
||||
|
||||
**Webhook 要求:**
|
||||
- 必须使用 HTTPS
|
||||
- 支持 TLS 1.2+
|
||||
- 端口:443, 80, 88, 8443
|
||||
- 公共可访问的 URL
|
||||
|
||||
### 内联键盘
|
||||
|
||||
**创建内联键盘:**
|
||||
```python
|
||||
def send_inline_keyboard(chat_id):
|
||||
keyboard = {
|
||||
"inline_keyboard": [
|
||||
[
|
||||
{"text": "按钮 1", "callback_data": "btn1"},
|
||||
{"text": "按钮 2", "callback_data": "btn2"}
|
||||
],
|
||||
[
|
||||
{"text": "打开链接", "url": "https://example.com"}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
requests.post(
|
||||
f"{API_URL}/sendMessage",
|
||||
json={
|
||||
"chat_id": chat_id,
|
||||
"text": "选择一个选项:",
|
||||
"reply_markup": keyboard
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**处理回调:**
|
||||
```python
|
||||
def handle_callback_query(callback_query):
|
||||
query_id = callback_query["id"]
|
||||
data = callback_query["data"]
|
||||
chat_id = callback_query["message"]["chat"]["id"]
|
||||
|
||||
# 响应回调
|
||||
requests.post(
|
||||
f"{API_URL}/answerCallbackQuery",
|
||||
json={"callback_query_id": query_id, "text": f"你点击了 {data}"}
|
||||
)
|
||||
|
||||
# 更新消息
|
||||
requests.post(
|
||||
f"{API_URL}/editMessageText",
|
||||
json={
|
||||
"chat_id": chat_id,
|
||||
"message_id": callback_query["message"]["message_id"],
|
||||
"text": f"你选择了:{data}"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 内联模式
|
||||
|
||||
**配置内联模式:**
|
||||
与 @BotFather 对话,发送 `/setinline`
|
||||
|
||||
**处理内联查询:**
|
||||
```python
|
||||
def handle_inline_query(inline_query):
|
||||
query_id = inline_query["id"]
|
||||
query_text = inline_query["query"]
|
||||
|
||||
# 创建结果
|
||||
results = [
|
||||
{
|
||||
"type": "article",
|
||||
"id": "1",
|
||||
"title": "结果 1",
|
||||
"input_message_content": {
|
||||
"message_text": f"你搜索了:{query_text}"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
requests.post(
|
||||
f"{API_URL}/answerInlineQuery",
|
||||
json={"inline_query_id": query_id, "results": results}
|
||||
)
|
||||
```
|
||||
|
||||
## Mini Apps (Web Apps) 开发
|
||||
|
||||
### 初始化 Mini App
|
||||
|
||||
**HTML 模板:**
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://telegram.org/js/telegram-web-app.js"></script>
|
||||
<title>My Mini App</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Telegram Mini App</h1>
|
||||
<button id="mainBtn">主按钮</button>
|
||||
|
||||
<script>
|
||||
// 获取 Telegram WebApp 对象
|
||||
const tg = window.Telegram.WebApp;
|
||||
|
||||
// 通知 Telegram 应用已准备好
|
||||
tg.ready();
|
||||
|
||||
// 展开到全屏
|
||||
tg.expand();
|
||||
|
||||
// 显示用户信息
|
||||
const user = tg.initDataUnsafe?.user;
|
||||
if (user) {
|
||||
console.log("用户名:", user.first_name);
|
||||
console.log("用户ID:", user.id);
|
||||
}
|
||||
|
||||
// 配置主按钮
|
||||
tg.MainButton.text = "提交";
|
||||
tg.MainButton.show();
|
||||
tg.MainButton.onClick(() => {
|
||||
// 发送数据到 Bot
|
||||
tg.sendData(JSON.stringify({action: "submit"}));
|
||||
});
|
||||
|
||||
// 添加返回按钮
|
||||
tg.BackButton.show();
|
||||
tg.BackButton.onClick(() => {
|
||||
tg.close();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Mini App 核心 API
|
||||
|
||||
**WebApp 对象主要属性:**
|
||||
```javascript
|
||||
// 初始化数据
|
||||
tg.initData // 原始初始化字符串
|
||||
tg.initDataUnsafe // 解析后的对象
|
||||
|
||||
// 用户和主题
|
||||
tg.initDataUnsafe.user // 用户信息
|
||||
tg.themeParams // 主题颜色
|
||||
tg.colorScheme // 'light' 或 'dark'
|
||||
|
||||
// 状态
|
||||
tg.isExpanded // 是否全屏
|
||||
tg.isFullscreen // 是否全屏
|
||||
tg.viewportHeight // 视口高度
|
||||
tg.platform // 平台类型
|
||||
|
||||
// 版本
|
||||
tg.version // WebApp 版本
|
||||
```
|
||||
|
||||
**主要方法:**
|
||||
```javascript
|
||||
// 窗口控制
|
||||
tg.ready() // 标记应用准备就绪
|
||||
tg.expand() // 展开到全高度
|
||||
tg.close() // 关闭 Mini App
|
||||
tg.requestFullscreen() // 请求全屏
|
||||
|
||||
// 数据发送
|
||||
tg.sendData(data) // 发送数据到 Bot
|
||||
|
||||
// 导航
|
||||
tg.openLink(url) // 打开外部链接
|
||||
tg.openTelegramLink(url) // 打开 Telegram 链接
|
||||
|
||||
// 对话框
|
||||
tg.showPopup(params, callback) // 显示弹窗
|
||||
tg.showAlert(message) // 显示警告
|
||||
tg.showConfirm(message) // 显示确认
|
||||
|
||||
// 分享
|
||||
tg.shareMessage(message) // 分享消息
|
||||
tg.shareUrl(url) // 分享链接
|
||||
```
|
||||
|
||||
### UI 控件
|
||||
|
||||
**主按钮 (MainButton):**
|
||||
```javascript
|
||||
tg.MainButton.setText("点击我");
|
||||
tg.MainButton.show();
|
||||
tg.MainButton.enable();
|
||||
tg.MainButton.showProgress(); // 显示加载
|
||||
tg.MainButton.hideProgress();
|
||||
|
||||
tg.MainButton.onClick(() => {
|
||||
console.log("主按钮被点击");
|
||||
});
|
||||
```
|
||||
|
||||
**次要按钮 (SecondaryButton):**
|
||||
```javascript
|
||||
tg.SecondaryButton.setText("取消");
|
||||
tg.SecondaryButton.show();
|
||||
tg.SecondaryButton.onClick(() => {
|
||||
tg.close();
|
||||
});
|
||||
```
|
||||
|
||||
**返回按钮 (BackButton):**
|
||||
```javascript
|
||||
tg.BackButton.show();
|
||||
tg.BackButton.onClick(() => {
|
||||
// 返回逻辑
|
||||
});
|
||||
```
|
||||
|
||||
**触觉反馈:**
|
||||
```javascript
|
||||
tg.HapticFeedback.impactOccurred('light'); // light, medium, heavy
|
||||
tg.HapticFeedback.notificationOccurred('success'); // success, warning, error
|
||||
tg.HapticFeedback.selectionChanged();
|
||||
```
|
||||
|
||||
### 存储 API
|
||||
|
||||
**云存储:**
|
||||
```javascript
|
||||
// 保存数据
|
||||
tg.CloudStorage.setItem('key', 'value', (error, success) => {
|
||||
if (success) console.log('保存成功');
|
||||
});
|
||||
|
||||
// 获取数据
|
||||
tg.CloudStorage.getItem('key', (error, value) => {
|
||||
console.log('值:', value);
|
||||
});
|
||||
|
||||
// 删除数据
|
||||
tg.CloudStorage.removeItem('key');
|
||||
|
||||
// 获取所有键
|
||||
tg.CloudStorage.getKeys((error, keys) => {
|
||||
console.log('所有键:', keys);
|
||||
});
|
||||
```
|
||||
|
||||
**本地存储:**
|
||||
```javascript
|
||||
// 普通本地存储
|
||||
localStorage.setItem('key', 'value');
|
||||
const value = localStorage.getItem('key');
|
||||
|
||||
// 安全存储(需要生物识别)
|
||||
tg.SecureStorage.setItem('secret', 'value', callback);
|
||||
tg.SecureStorage.getItem('secret', callback);
|
||||
```
|
||||
|
||||
### 生物识别认证
|
||||
|
||||
```javascript
|
||||
const bioManager = tg.BiometricManager;
|
||||
|
||||
// 初始化
|
||||
bioManager.init(() => {
|
||||
if (bioManager.isInited) {
|
||||
console.log('支持的类型:', bioManager.biometricType);
|
||||
// 'finger', 'face', 'unknown'
|
||||
|
||||
if (bioManager.isAccessGranted) {
|
||||
// 已授权,可以使用
|
||||
} else {
|
||||
// 请求授权
|
||||
bioManager.requestAccess({reason: '需要验证身份'}, (success) => {
|
||||
if (success) {
|
||||
console.log('授权成功');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 执行认证
|
||||
bioManager.authenticate({reason: '确认操作'}, (success, token) => {
|
||||
if (success) {
|
||||
console.log('认证成功,token:', token);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 位置和传感器
|
||||
|
||||
**获取位置:**
|
||||
```javascript
|
||||
tg.LocationManager.init(() => {
|
||||
if (tg.LocationManager.isInited) {
|
||||
tg.LocationManager.getLocation((location) => {
|
||||
console.log('纬度:', location.latitude);
|
||||
console.log('经度:', location.longitude);
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**加速度计:**
|
||||
```javascript
|
||||
tg.Accelerometer.start({refresh_rate: 100}, (started) => {
|
||||
if (started) {
|
||||
tg.Accelerometer.onEvent((event) => {
|
||||
console.log('加速度:', event.x, event.y, event.z);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 停止
|
||||
tg.Accelerometer.stop();
|
||||
```
|
||||
|
||||
**陀螺仪:**
|
||||
```javascript
|
||||
tg.Gyroscope.start({refresh_rate: 100}, callback);
|
||||
tg.Gyroscope.onEvent((event) => {
|
||||
console.log('旋转速度:', event.x, event.y, event.z);
|
||||
});
|
||||
```
|
||||
|
||||
**设备方向:**
|
||||
```javascript
|
||||
tg.DeviceOrientation.start({refresh_rate: 100}, callback);
|
||||
tg.DeviceOrientation.onEvent((event) => {
|
||||
console.log('方向:', event.absolute, event.alpha, event.beta, event.gamma);
|
||||
});
|
||||
```
|
||||
|
||||
### 支付集成
|
||||
|
||||
**发起支付 (Telegram Stars):**
|
||||
```javascript
|
||||
tg.openInvoice('https://t.me/$invoice_link', (status) => {
|
||||
if (status === 'paid') {
|
||||
console.log('支付成功');
|
||||
} else if (status === 'cancelled') {
|
||||
console.log('支付取消');
|
||||
} else if (status === 'failed') {
|
||||
console.log('支付失败');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 数据验证
|
||||
|
||||
**服务器端验证 initData (Python):**
|
||||
```python
|
||||
import hmac
|
||||
import hashlib
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
def validate_init_data(init_data, bot_token):
|
||||
# 解析数据
|
||||
parsed = parse_qs(init_data)
|
||||
received_hash = parsed.get('hash', [''])[0]
|
||||
|
||||
# 移除 hash
|
||||
data_check_arr = []
|
||||
for key, value in parsed.items():
|
||||
if key != 'hash':
|
||||
data_check_arr.append(f"{key}={value[0]}")
|
||||
|
||||
# 排序
|
||||
data_check_arr.sort()
|
||||
data_check_string = '\n'.join(data_check_arr)
|
||||
|
||||
# 计算密钥
|
||||
secret_key = hmac.new(
|
||||
b"WebAppData",
|
||||
bot_token.encode(),
|
||||
hashlib.sha256
|
||||
).digest()
|
||||
|
||||
# 计算哈希
|
||||
calculated_hash = hmac.new(
|
||||
secret_key,
|
||||
data_check_string.encode(),
|
||||
hashlib.sha256
|
||||
).hexdigest()
|
||||
|
||||
return calculated_hash == received_hash
|
||||
```
|
||||
|
||||
### 启动 Mini App
|
||||
|
||||
**从键盘按钮:**
|
||||
```python
|
||||
keyboard = {
|
||||
"keyboard": [[
|
||||
{
|
||||
"text": "打开应用",
|
||||
"web_app": {"url": "https://yourdomain.com/app"}
|
||||
}
|
||||
]],
|
||||
"resize_keyboard": True
|
||||
}
|
||||
|
||||
requests.post(
|
||||
f"{API_URL}/sendMessage",
|
||||
json={
|
||||
"chat_id": chat_id,
|
||||
"text": "点击按钮打开应用",
|
||||
"reply_markup": keyboard
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**从内联按钮:**
|
||||
```python
|
||||
keyboard = {
|
||||
"inline_keyboard": [[
|
||||
{
|
||||
"text": "启动应用",
|
||||
"web_app": {"url": "https://yourdomain.com/app"}
|
||||
}
|
||||
]]
|
||||
}
|
||||
```
|
||||
|
||||
**从菜单按钮:**
|
||||
与 @BotFather 对话:
|
||||
```
|
||||
/setmenubutton
|
||||
→ 选择你的 Bot
|
||||
→ 提供 URL: https://yourdomain.com/app
|
||||
```
|
||||
|
||||
## 客户端开发 (TDLib)
|
||||
|
||||
### 使用 TDLib
|
||||
|
||||
**Python 示例 (python-telegram):**
|
||||
```python
|
||||
from telegram.client import Telegram
|
||||
|
||||
tg = Telegram(
|
||||
api_id='your_api_id',
|
||||
api_hash='your_api_hash',
|
||||
phone='+1234567890',
|
||||
database_encryption_key='changeme1234',
|
||||
)
|
||||
|
||||
tg.login()
|
||||
|
||||
# 发送消息
|
||||
result = tg.send_message(
|
||||
chat_id=123456789,
|
||||
text='Hello from TDLib!'
|
||||
)
|
||||
|
||||
# 获取聊天列表
|
||||
result = tg.get_chats()
|
||||
result.wait()
|
||||
chats = result.update
|
||||
|
||||
print(chats)
|
||||
|
||||
tg.stop()
|
||||
```
|
||||
|
||||
### MTProto 协议
|
||||
|
||||
**特点:**
|
||||
- 端到端加密
|
||||
- 高性能
|
||||
- 支持所有 Telegram 功能
|
||||
- 需要 API ID/Hash(从 https://my.telegram.org 获取)
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### Bot 开发
|
||||
|
||||
1. **错误处理**
|
||||
```python
|
||||
try:
|
||||
response = requests.post(url, json=data, timeout=10)
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"请求失败: {e}")
|
||||
```
|
||||
|
||||
2. **速率限制**
|
||||
- 群组消息:最多 20 条/分钟
|
||||
- 私聊消息:最多 30 条/秒
|
||||
- 全局限制:避免过于频繁
|
||||
|
||||
3. **使用 Webhook 而非长轮询**
|
||||
- 更高效
|
||||
- 更低延迟
|
||||
- 更好的可扩展性
|
||||
|
||||
4. **数据验证**
|
||||
- 始终验证 initData
|
||||
- 不要信任客户端数据
|
||||
- 服务器端验证所有操作
|
||||
|
||||
### Mini Apps 开发
|
||||
|
||||
1. **响应式设计**
|
||||
```javascript
|
||||
// 监听主题变化
|
||||
tg.onEvent('themeChanged', () => {
|
||||
document.body.style.backgroundColor = tg.themeParams.bg_color;
|
||||
});
|
||||
|
||||
// 监听视口变化
|
||||
tg.onEvent('viewportChanged', () => {
|
||||
console.log('新高度:', tg.viewportHeight);
|
||||
});
|
||||
```
|
||||
|
||||
2. **性能优化**
|
||||
- 最小化 JavaScript 包大小
|
||||
- 使用懒加载
|
||||
- 优化图片和资源
|
||||
|
||||
3. **用户体验**
|
||||
- 适配深色/浅色主题
|
||||
- 使用原生 UI 控件(MainButton 等)
|
||||
- 提供触觉反馈
|
||||
- 快速响应用户操作
|
||||
|
||||
4. **安全考虑**
|
||||
- HTTPS 强制
|
||||
- 验证 initData
|
||||
- 不在客户端存储敏感信息
|
||||
- 使用 SecureStorage 存储密钥
|
||||
|
||||
## 常用库和工具
|
||||
|
||||
### Python
|
||||
- `python-telegram-bot` - 功能强大的 Bot 框架
|
||||
- `aiogram` - 异步 Bot 框架
|
||||
- `telethon` / `pyrogram` - MTProto 客户端
|
||||
|
||||
### Node.js
|
||||
- `node-telegram-bot-api` - Bot API 包装器
|
||||
- `telegraf` - 现代 Bot 框架
|
||||
- `grammy` - 轻量级框架
|
||||
|
||||
### 其他语言
|
||||
- PHP: `telegram-bot-sdk`
|
||||
- Go: `telegram-bot-api`
|
||||
- Java: `TelegramBots`
|
||||
- C#: `Telegram.Bot`
|
||||
|
||||
## 参考资源
|
||||
|
||||
### 官方文档
|
||||
- Bot API: https://core.telegram.org/bots/api
|
||||
- Mini Apps: https://core.telegram.org/bots/webapps
|
||||
- Mini Apps Platform: https://docs.telegram-mini-apps.com
|
||||
- Telegram API: https://core.telegram.org
|
||||
|
||||
### GitHub 仓库
|
||||
- Bot API 服务器: https://github.com/tdlib/telegram-bot-api
|
||||
- Android 客户端: https://github.com/DrKLO/Telegram
|
||||
- Desktop 客户端: https://github.com/telegramdesktop/tdesktop
|
||||
- 官方组织: https://github.com/orgs/TelegramOfficial/repositories
|
||||
|
||||
### 工具
|
||||
- @BotFather - 创建和管理 Bot
|
||||
- https://my.telegram.org - 获取 API ID/Hash
|
||||
- Telegram Web App 测试环境
|
||||
|
||||
## 参考文件
|
||||
|
||||
此技能包含详细的 Telegram 开发资源索引和完整实现模板:
|
||||
|
||||
- **index.md** - 完整的资源链接和快速导航
|
||||
- **Telegram_Bot_按钮和键盘实现模板.md** - 交互式按钮和键盘实现指南(404 行,12 KB)
|
||||
- 三种按钮类型详解(Inline/Reply/Command Menu)
|
||||
- python-telegram-bot 和 Telethon 双实现对比
|
||||
- 完整的即用代码示例和项目结构
|
||||
- Handler 系统、错误处理和部署方案
|
||||
- **动态视图对齐实现文档.md** - Telegram 数据展示指南(407 行,12 KB)
|
||||
- 智能动态对齐算法(三步法,O(n×m) 复杂度)
|
||||
- 等宽字体环境的完美对齐方案
|
||||
- 智能数值格式化系统(B/M/K 自动缩写)
|
||||
- 排行榜和数据表格专业展示
|
||||
|
||||
这些精简指南提供了核心的 Telegram Bot 开发解决方案:
|
||||
- 按钮和键盘交互的所有实现方式
|
||||
- 消息和数据的专业格式化展示
|
||||
- 实用的最佳实践和快速参考
|
||||
|
||||
---
|
||||
|
||||
**使用此技能掌握 Telegram 生态的全栈开发!**
|
||||
@@ -1,404 +0,0 @@
|
||||
# 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 按钮和键盘的所有核心实现!**
|
||||
@@ -1,470 +0,0 @@
|
||||
# Telegram 生态开发资源索引
|
||||
|
||||
## 官方文档
|
||||
|
||||
### Bot API
|
||||
**主文档:** https://core.telegram.org/bots/api
|
||||
**描述:** Telegram Bot API 完整参考文档
|
||||
|
||||
**核心功能:**
|
||||
- 消息发送和接收
|
||||
- 媒体文件处理
|
||||
- 内联模式
|
||||
- 支付集成
|
||||
- Webhook 配置
|
||||
- 游戏和投票
|
||||
|
||||
### Mini Apps (Web Apps)
|
||||
**主文档:** https://core.telegram.org/bots/webapps
|
||||
**完整平台:** https://docs.telegram-mini-apps.com
|
||||
**描述:** Telegram 小程序开发文档
|
||||
|
||||
**核心功能:**
|
||||
- WebApp API
|
||||
- 主题和 UI 控件
|
||||
- 存储(Cloud/Device/Secure)
|
||||
- 生物识别认证
|
||||
- 位置和传感器
|
||||
- 支付集成
|
||||
|
||||
### Telegram API & MTProto
|
||||
**主文档:** https://core.telegram.org
|
||||
**描述:** 完整的 Telegram 协议和客户端开发
|
||||
|
||||
**核心功能:**
|
||||
- MTProto 协议
|
||||
- TDLib 客户端库
|
||||
- 认证和加密
|
||||
- 文件操作
|
||||
- Secret Chats
|
||||
|
||||
## 官方 GitHub 仓库
|
||||
|
||||
### Bot API 服务器
|
||||
**仓库:** https://github.com/tdlib/telegram-bot-api
|
||||
**描述:** Telegram Bot API 服务器实现
|
||||
**特点:**
|
||||
- 本地模式部署
|
||||
- 支持大文件(最高 2000 MB)
|
||||
- C++ 实现
|
||||
- TDLib 基础
|
||||
|
||||
### Android 客户端
|
||||
**仓库:** https://github.com/DrKLO/Telegram
|
||||
**描述:** 官方 Android 客户端源代码
|
||||
**特点:**
|
||||
- 完整的 Android 实现
|
||||
- Material Design
|
||||
- 可自定义编译
|
||||
|
||||
### Desktop 客户端
|
||||
**仓库:** https://github.com/telegramdesktop/tdesktop
|
||||
**描述:** 官方桌面客户端 (Windows, macOS, Linux)
|
||||
**特点:**
|
||||
- Qt/C++ 实现
|
||||
- 跨平台支持
|
||||
- 完整功能
|
||||
|
||||
### 官方组织
|
||||
**组织页面:** https://github.com/orgs/TelegramOfficial/repositories
|
||||
**包含:**
|
||||
- Beta 版本
|
||||
- 支持工具
|
||||
- 示例代码
|
||||
|
||||
## API 方法分类
|
||||
|
||||
### 更新管理
|
||||
- `getUpdates` - 长轮询
|
||||
- `setWebhook` - 设置 Webhook
|
||||
- `deleteWebhook` - 删除 Webhook
|
||||
- `getWebhookInfo` - Webhook 信息
|
||||
|
||||
### 消息操作
|
||||
**发送消息:**
|
||||
- `sendMessage` - 文本消息
|
||||
- `sendPhoto` - 图片
|
||||
- `sendVideo` - 视频
|
||||
- `sendDocument` - 文档
|
||||
- `sendAudio` - 音频
|
||||
- `sendVoice` - 语音
|
||||
- `sendLocation` - 位置
|
||||
- `sendVenue` - 地点
|
||||
- `sendContact` - 联系人
|
||||
- `sendPoll` - 投票
|
||||
- `sendDice` - 骰子/飞镖
|
||||
|
||||
**编辑消息:**
|
||||
- `editMessageText` - 编辑文本
|
||||
- `editMessageCaption` - 编辑标题
|
||||
- `editMessageMedia` - 编辑媒体
|
||||
- `editMessageReplyMarkup` - 编辑键盘
|
||||
- `deleteMessage` - 删除消息
|
||||
|
||||
**其他操作:**
|
||||
- `forwardMessage` - 转发消息
|
||||
- `copyMessage` - 复制消息
|
||||
- `sendChatAction` - 发送动作(输入中...)
|
||||
|
||||
### 文件操作
|
||||
- `getFile` - 获取文件信息
|
||||
- 文件下载 URL: `https://api.telegram.org/file/bot<token>/<file_path>`
|
||||
- 文件上传:支持 multipart/form-data
|
||||
- 最大文件:50 MB (标准), 2000 MB (本地 Bot API)
|
||||
|
||||
### 内联模式
|
||||
- `answerInlineQuery` - 响应内联查询
|
||||
- 结果类型:article, photo, gif, video, audio, voice, document, location, venue, contact, game, sticker
|
||||
|
||||
### 回调查询
|
||||
- `answerCallbackQuery` - 响应按钮点击
|
||||
- 可显示通知或警告
|
||||
|
||||
### 支付
|
||||
- `sendInvoice` - 发送发票
|
||||
- `answerPreCheckoutQuery` - 预结账
|
||||
- `answerShippingQuery` - 配送查询
|
||||
- 支持提供商:Stripe, Yandex.Money, Telegram Stars
|
||||
|
||||
### 游戏
|
||||
- `sendGame` - 发送游戏
|
||||
- `setGameScore` - 设置分数
|
||||
- `getGameHighScores` - 获取排行榜
|
||||
|
||||
### 群组管理
|
||||
- `kickChatMember` / `unbanChatMember` - 封禁/解封
|
||||
- `restrictChatMember` - 限制权限
|
||||
- `promoteChatMember` - 提升管理员
|
||||
- `setChatTitle` / `setChatDescription` - 设置信息
|
||||
- `setChatPhoto` - 设置头像
|
||||
- `pinChatMessage` / `unpinChatMessage` - 置顶消息
|
||||
|
||||
## Mini Apps API 详解
|
||||
|
||||
### 初始化
|
||||
```javascript
|
||||
const tg = window.Telegram.WebApp;
|
||||
tg.ready();
|
||||
tg.expand();
|
||||
```
|
||||
|
||||
### 主要对象
|
||||
- **WebApp** - 主接口
|
||||
- **MainButton** - 主按钮
|
||||
- **SecondaryButton** - 次要按钮
|
||||
- **BackButton** - 返回按钮
|
||||
- **SettingsButton** - 设置按钮
|
||||
- **HapticFeedback** - 触觉反馈
|
||||
- **CloudStorage** - 云存储
|
||||
- **BiometricManager** - 生物识别
|
||||
- **LocationManager** - 位置服务
|
||||
- **Accelerometer** - 加速度计
|
||||
- **Gyroscope** - 陀螺仪
|
||||
- **DeviceOrientation** - 设备方向
|
||||
|
||||
### 事件系统
|
||||
40+ 事件包括:
|
||||
- `themeChanged` - 主题改变
|
||||
- `viewportChanged` - 视口改变
|
||||
- `mainButtonClicked` - 主按钮点击
|
||||
- `backButtonClicked` - 返回按钮点击
|
||||
- `settingsButtonClicked` - 设置按钮点击
|
||||
- `invoiceClosed` - 支付完成
|
||||
- `popupClosed` - 弹窗关闭
|
||||
- `qrTextReceived` - 扫码结果
|
||||
- `clipboardTextReceived` - 剪贴板文本
|
||||
- `writeAccessRequested` - 写入权限请求
|
||||
- `contactRequested` - 联系人请求
|
||||
|
||||
### 主题参数
|
||||
```javascript
|
||||
tg.themeParams = {
|
||||
bg_color, // 背景色
|
||||
text_color, // 文本色
|
||||
hint_color, // 提示色
|
||||
link_color, // 链接色
|
||||
button_color, // 按钮色
|
||||
button_text_color, // 按钮文本色
|
||||
secondary_bg_color, // 次要背景色
|
||||
header_bg_color, // 头部背景色
|
||||
accent_text_color, // 强调文本色
|
||||
section_bg_color, // 区块背景色
|
||||
section_header_text_color, // 区块头文本色
|
||||
subtitle_text_color, // 副标题色
|
||||
destructive_text_color // 危险操作色
|
||||
}
|
||||
```
|
||||
|
||||
## 开发工具
|
||||
|
||||
### @BotFather 命令
|
||||
创建和管理 Bot 的核心工具:
|
||||
|
||||
**Bot 管理:**
|
||||
- `/newbot` - 创建新 Bot
|
||||
- `/mybots` - 管理我的 Bots
|
||||
- `/deletebot` - 删除 Bot
|
||||
- `/token` - 重新生成 token
|
||||
|
||||
**设置命令:**
|
||||
- `/setname` - 设置名称
|
||||
- `/setdescription` - 设置描述
|
||||
- `/setabouttext` - 设置关于文本
|
||||
- `/setuserpic` - 设置头像
|
||||
|
||||
**功能配置:**
|
||||
- `/setcommands` - 设置命令列表
|
||||
- `/setinline` - 启用内联模式
|
||||
- `/setinlinefeedback` - 内联反馈
|
||||
- `/setjoingroups` - 允许加入群组
|
||||
- `/setprivacy` - 隐私模式
|
||||
|
||||
**支付和游戏:**
|
||||
- `/setgamescores` - 游戏分数
|
||||
- `/setpayments` - 配置支付
|
||||
|
||||
**Mini Apps:**
|
||||
- `/newapp` - 创建 Mini App
|
||||
- `/myapps` - 管理 Mini Apps
|
||||
- `/setmenubutton` - 设置菜单按钮
|
||||
|
||||
### API ID 获取
|
||||
访问 https://my.telegram.org
|
||||
1. 登录账号
|
||||
2. 进入 API development tools
|
||||
3. 创建应用
|
||||
4. 获取 API ID 和 API Hash
|
||||
|
||||
## 常用 Python 库
|
||||
|
||||
### python-telegram-bot
|
||||
```bash
|
||||
pip install python-telegram-bot
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 完整的 Bot API 包装
|
||||
- 异步和同步支持
|
||||
- 丰富的扩展
|
||||
- 活跃维护
|
||||
|
||||
**基础示例:**
|
||||
```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('你好!')
|
||||
|
||||
app = Application.builder().token("TOKEN").build()
|
||||
app.add_handler(CommandHandler("start", start))
|
||||
app.run_polling()
|
||||
```
|
||||
|
||||
### aiogram
|
||||
```bash
|
||||
pip install aiogram
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 纯异步
|
||||
- 高性能
|
||||
- FSM 状态机
|
||||
- 中间件系统
|
||||
|
||||
### Telethon / Pyrogram
|
||||
MTProto 客户端库:
|
||||
```bash
|
||||
pip install telethon
|
||||
pip install pyrogram
|
||||
```
|
||||
|
||||
**用途:**
|
||||
- 自定义客户端
|
||||
- 用户账号自动化
|
||||
- 完整 Telegram 功能
|
||||
|
||||
## 常用 Node.js 库
|
||||
|
||||
### node-telegram-bot-api
|
||||
```bash
|
||||
npm install node-telegram-bot-api
|
||||
```
|
||||
|
||||
### Telegraf
|
||||
```bash
|
||||
npm install telegraf
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 现代化
|
||||
- 中间件架构
|
||||
- TypeScript 支持
|
||||
|
||||
### grammY
|
||||
```bash
|
||||
npm install grammy
|
||||
```
|
||||
|
||||
**特点:**
|
||||
- 轻量级
|
||||
- 类型安全
|
||||
- 插件生态
|
||||
|
||||
## 部署选项
|
||||
|
||||
### Webhook 托管
|
||||
**推荐平台:**
|
||||
- Heroku
|
||||
- AWS Lambda
|
||||
- Google Cloud Functions
|
||||
- Azure Functions
|
||||
- Vercel
|
||||
- Railway
|
||||
- Render
|
||||
|
||||
**要求:**
|
||||
- HTTPS 支持
|
||||
- 公网可访问
|
||||
- 支持的端口:443, 80, 88, 8443
|
||||
|
||||
### 长轮询托管
|
||||
**推荐平台:**
|
||||
- VPS (Vultr, DigitalOcean, Linode)
|
||||
- Raspberry Pi
|
||||
- 本地服务器
|
||||
|
||||
**优点:**
|
||||
- 无需 HTTPS
|
||||
- 简单配置
|
||||
- 适合开发测试
|
||||
|
||||
## 安全最佳实践
|
||||
|
||||
1. **Token 安全**
|
||||
- 不要提交到 Git
|
||||
- 使用环境变量
|
||||
- 定期轮换
|
||||
|
||||
2. **数据验证**
|
||||
- 验证 initData
|
||||
- 服务器端验证
|
||||
- 不信任客户端
|
||||
|
||||
3. **权限控制**
|
||||
- 检查用户权限
|
||||
- 管理员验证
|
||||
- 群组权限
|
||||
|
||||
4. **速率限制**
|
||||
- 实现请求限制
|
||||
- 防止滥用
|
||||
- 监控异常
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### Bot 调试
|
||||
```python
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
```
|
||||
|
||||
### Mini App 调试
|
||||
```javascript
|
||||
// 开启调试模式
|
||||
tg.showAlert(JSON.stringify(tg.initDataUnsafe, null, 2));
|
||||
|
||||
// 控制台日志
|
||||
console.log('WebApp version:', tg.version);
|
||||
console.log('Platform:', tg.platform);
|
||||
console.log('Theme:', tg.colorScheme);
|
||||
```
|
||||
|
||||
### Webhook 测试
|
||||
使用 ngrok 本地测试:
|
||||
```bash
|
||||
ngrok http 5000
|
||||
# 将生成的 https URL 设置为 webhook
|
||||
```
|
||||
|
||||
## 社区资源
|
||||
|
||||
- **Telegram 开发者群组**: @BotDevelopers
|
||||
- **Telegram API 讨论**: @TelegramBots
|
||||
- **Mini Apps 讨论**: @WebAppChat
|
||||
|
||||
## 更新日志
|
||||
|
||||
**最新功能:**
|
||||
- Paid Media (付费媒体)
|
||||
- Checklist Tasks (检查列表任务)
|
||||
- Gift Conversion (礼物转换)
|
||||
- Business Features (商业功能)
|
||||
- Poll 选项增加到 12 个
|
||||
- Story 发布和编辑
|
||||
|
||||
---
|
||||
|
||||
## 完整实现模板 (新增)
|
||||
|
||||
### Telegram Bot 按钮和键盘实现指南
|
||||
**文件:** `Telegram_Bot_按钮和键盘实现模板.md`
|
||||
**行数:** 404 行
|
||||
**大小:** 12 KB
|
||||
**语言:** 中文
|
||||
|
||||
精简实用的 Telegram Bot 交互式功能实现指南:
|
||||
|
||||
**核心内容:**
|
||||
- 三种按钮类型详解(Inline/Reply/Command Menu)
|
||||
- python-telegram-bot 和 Telethon 双实现对比
|
||||
- 完整的代码示例(即拿即用)
|
||||
- 项目结构和模块化设计
|
||||
- Handler 优先级和事件处理
|
||||
- 生产环境部署方案
|
||||
- 安全和错误处理最佳实践
|
||||
|
||||
**特色:**
|
||||
- 核心代码精简,去除冗余示例
|
||||
- 聚焦常用场景和实用技巧
|
||||
- 完整的快速参考表
|
||||
|
||||
---
|
||||
|
||||
### 动态视图对齐 - 数据展示指南
|
||||
**文件:** `动态视图对齐实现文档.md`
|
||||
**行数:** 407 行
|
||||
**大小:** 12 KB
|
||||
**语言:** 中文
|
||||
|
||||
专业的等宽字体数据对齐和格式化方案:
|
||||
|
||||
**核心功能:**
|
||||
- 智能动态视图对齐算法(三步法)
|
||||
- 自动计算列宽,无需硬编码
|
||||
- 智能对齐规则(文本左,数字右)
|
||||
- 完整的格式化系统:
|
||||
- 交易量智能缩写(B/M/K)
|
||||
- 价格智能精度(自适应小数位)
|
||||
- 涨跌幅格式化(+/- 符号)
|
||||
- 资金流向智能显示
|
||||
|
||||
**应用场景:**
|
||||
- 排行榜、数据表格、实时行情
|
||||
- 任何需要专业数据展示的 Telegram Bot
|
||||
|
||||
**技术特点:**
|
||||
- O(n×m) 线性复杂度,高效实用
|
||||
- 1000 行数据处理仅需 5-10ms
|
||||
- 支持中文字符宽度扩展
|
||||
|
||||
**视觉效果示例:**
|
||||
```
|
||||
1. BTC $1.23B $45,000 +5.23%
|
||||
2. ETH $890.5M $2,500 +3.12%
|
||||
3. SOL $567.8M $101 +8.45%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**这些模板提供了从基础到生产级别的完整 Telegram Bot 开发解决方案!**
|
||||
@@ -1,407 +0,0 @@
|
||||
# 📊 动态视图对齐 - 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 专业数据展示的完整解决方案!**
|
||||
Reference in New Issue
Block a user