mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-08-22 15:28: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:
@@ -0,0 +1,292 @@
|
||||
TRANSLATED CONTENT:
|
||||
---
|
||||
name: proxychains
|
||||
description: Auto-detect network issues and force proxy usage with proxychains4. Use this skill when encountering connection timeouts, DNS failures, or blocked network access. Default proxy is http://127.0.0.1:9910
|
||||
---
|
||||
|
||||
# Proxychains Network Proxy Skill
|
||||
|
||||
**自动使用代理解决网络问题** - 当遇到网络连接失败、超时或访问受限时,自动使用 proxychains4 强制走代理。
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
**触发条件(自动应用):**
|
||||
- ❌ Connection timeout errors
|
||||
- ❌ DNS resolution failures
|
||||
- ❌ "Connection refused" errors
|
||||
- ❌ HTTP 403/451 blocked access
|
||||
- ❌ GitHub/PyPI/npm 等国外资源访问失败
|
||||
- ❌ curl/wget/git/pip 等命令失败
|
||||
|
||||
**Claude 应该:**
|
||||
1. 检测到网络错误后,自动在命令前添加 `proxychains4`
|
||||
2. 使用默认代理配置:`http://127.0.0.1:9910`
|
||||
3. 如果代理失败,提示用户检查代理服务状态
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### 基本用法模式
|
||||
|
||||
```bash
|
||||
# ❌ 原命令失败
|
||||
curl https://github.com/user/repo
|
||||
|
||||
# ✅ 使用代理重试
|
||||
proxychains4 curl https://github.com/user/repo
|
||||
```
|
||||
|
||||
### 常见场景自动应用
|
||||
|
||||
**场景 1: Git 操作失败**
|
||||
```bash
|
||||
# 原命令
|
||||
git clone https://github.com/user/repo.git
|
||||
|
||||
# 自动改为
|
||||
proxychains4 git clone https://github.com/user/repo.git
|
||||
```
|
||||
|
||||
**场景 2: Python pip 安装失败**
|
||||
```bash
|
||||
# 原命令
|
||||
pip install requests
|
||||
|
||||
# 自动改为
|
||||
proxychains4 pip install requests
|
||||
```
|
||||
|
||||
**场景 3: npm/yarn 安装失败**
|
||||
```bash
|
||||
# 原命令
|
||||
npm install package-name
|
||||
|
||||
# 自动改为
|
||||
proxychains4 npm install package-name
|
||||
```
|
||||
|
||||
**场景 4: wget/curl 下载失败**
|
||||
```bash
|
||||
# 原命令
|
||||
wget https://example.com/file.tar.gz
|
||||
|
||||
# 自动改为
|
||||
proxychains4 wget https://example.com/file.tar.gz
|
||||
```
|
||||
|
||||
**场景 5: Docker 拉取镜像失败**
|
||||
```bash
|
||||
# 原命令
|
||||
docker pull image:tag
|
||||
|
||||
# 自动改为
|
||||
proxychains4 docker pull image:tag
|
||||
```
|
||||
|
||||
**场景 6: SSH 连接失败**
|
||||
```bash
|
||||
# 原命令
|
||||
ssh user@remote-host
|
||||
|
||||
# 自动改为
|
||||
proxychains4 ssh user@remote-host
|
||||
```
|
||||
|
||||
## 配置详情
|
||||
|
||||
### 默认代理配置
|
||||
|
||||
**本地代理地址:** `http://127.0.0.1:9910`
|
||||
|
||||
**配置文件位置:**
|
||||
- `~/.proxychains/proxychains.conf` (推荐)
|
||||
- `/etc/proxychains.conf` (系统级)
|
||||
|
||||
### 快速配置脚本
|
||||
|
||||
创建用户级配置(自动使用 127.0.0.1:9910):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.proxychains
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
# Proxychains configuration
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
```
|
||||
|
||||
### 环境变量方式(临时使用)
|
||||
|
||||
```bash
|
||||
# 设置代理环境变量
|
||||
export PROXYCHAINS_SOCKS5_HOST=127.0.0.1
|
||||
export PROXYCHAINS_SOCKS5_PORT=9910
|
||||
|
||||
# 使用
|
||||
proxychains4 curl https://github.com
|
||||
```
|
||||
|
||||
## 工作原理
|
||||
|
||||
Proxychains 通过 LD_PRELOAD 机制拦截程序的网络调用:
|
||||
|
||||
1. **拦截系统调用**:Hook socket 相关的 libc 函数
|
||||
2. **重定向连接**:将所有 TCP 连接重定向到代理服务器
|
||||
3. **DNS 代理**:通过代理服务器解析域名
|
||||
4. **透明代理**:应用程序无需修改
|
||||
|
||||
**重要限制:**
|
||||
- 只支持动态链接的程序(statically linked 程序不支持)
|
||||
- 只支持 TCP 连接(UDP 不支持)
|
||||
- 部分使用特殊网络库的程序可能不兼容
|
||||
|
||||
## Claude 自动化规则
|
||||
|
||||
### 规则 1: 网络错误自动重试
|
||||
|
||||
```
|
||||
IF 命令返回网络相关错误(timeout, connection refused, DNS failure)
|
||||
THEN 自动使用 proxychains4 重试该命令
|
||||
```
|
||||
|
||||
### 规则 2: 已知慢速源强制代理
|
||||
|
||||
```
|
||||
IF 访问以下域名/服务:
|
||||
- github.com
|
||||
- raw.githubusercontent.com
|
||||
- pypi.org
|
||||
- npmjs.org
|
||||
- registry.npmjs.org
|
||||
- docker.io
|
||||
- gcr.io
|
||||
THEN 直接使用 proxychains4(不等待失败)
|
||||
```
|
||||
|
||||
### 规则 3: 失败提示
|
||||
|
||||
```
|
||||
IF proxychains4 命令也失败
|
||||
THEN 提示用户:
|
||||
1. 检查代理服务是否运行(127.0.0.1:9910)
|
||||
2. 检查 proxychains 配置文件
|
||||
3. 尝试其他代理地址
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 检查代理服务状态
|
||||
|
||||
```bash
|
||||
# 测试代理是否可用
|
||||
curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
|
||||
# 检查端口是否监听
|
||||
netstat -tunlp | grep 9910
|
||||
# 或
|
||||
ss -tunlp | grep 9910
|
||||
```
|
||||
|
||||
### 验证 proxychains 配置
|
||||
|
||||
```bash
|
||||
# 测试配置是否正确
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
# 应该显示代理服务器的 IP,而不是本机 IP
|
||||
```
|
||||
|
||||
### 常见错误处理
|
||||
|
||||
**错误 1: "proxychains: command not found"**
|
||||
```bash
|
||||
# 安装 proxychains4
|
||||
sudo apt install proxychains4 # Debian/Ubuntu
|
||||
sudo yum install proxychains-ng # CentOS/RHEL
|
||||
```
|
||||
|
||||
**错误 2: "timeout"**
|
||||
```bash
|
||||
# 检查代理地址配置是否正确
|
||||
cat ~/.proxychains/proxychains.conf | grep -A 2 "\[ProxyList\]"
|
||||
|
||||
# 修改超时时间(在配置文件中)
|
||||
tcp_connect_time_out 15000
|
||||
tcp_read_time_out 30000
|
||||
```
|
||||
|
||||
**错误 3: "can't read configuration file"**
|
||||
```bash
|
||||
# 创建配置文件
|
||||
mkdir -p ~/.proxychains
|
||||
cp /etc/proxychains.conf ~/.proxychains/proxychains.conf
|
||||
# 然后编辑配置
|
||||
```
|
||||
|
||||
## 高级用法
|
||||
|
||||
### 多代理链
|
||||
|
||||
```conf
|
||||
# ~/.proxychains/proxychains.conf
|
||||
strict_chain # 按顺序使用所有代理
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
socks5 127.0.0.1 1080
|
||||
```
|
||||
|
||||
### 动态代理链
|
||||
|
||||
```conf
|
||||
dynamic_chain # 自动跳过死代理
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
http 127.0.0.1 8080
|
||||
socks5 127.0.0.1 1080
|
||||
```
|
||||
|
||||
### 随机代理链
|
||||
|
||||
```conf
|
||||
random_chain
|
||||
chain_len = 2 # 随机选择 2 个代理
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
socks5 127.0.0.1 1080
|
||||
socks5 127.0.0.1 1081
|
||||
```
|
||||
|
||||
### 自定义 DNS 服务器
|
||||
|
||||
```bash
|
||||
# 使用自定义 DNS 通过代理解析
|
||||
export PROXY_DNS_SERVER=8.8.8.8
|
||||
proxychains4 curl https://example.com
|
||||
```
|
||||
|
||||
## 参考资源
|
||||
|
||||
- **官方仓库**: https://github.com/haad/proxychains
|
||||
- **配置文件**: `references/proxychains.conf` (完整示例)
|
||||
- **故障排除**: `references/troubleshooting.md`
|
||||
- **命令速查**: `references/quick-reference.md`
|
||||
|
||||
## 总结
|
||||
|
||||
**记住这些原则:**
|
||||
1. ❌ **遇到网络错误** → ✅ 自动加上 `proxychains4`
|
||||
2. 🌐 **访问国外资源** → ✅ 主动使用 `proxychains4`
|
||||
3. 🔧 **代理也失败** → ✅ 提示用户检查代理服务
|
||||
|
||||
**默认代理:** `http://127.0.0.1:9910`
|
||||
|
||||
---
|
||||
|
||||
**这个技能让 Claude 在遇到网络问题时自动使用代理,无需用户手动干预!**
|
||||
@@ -0,0 +1,102 @@
|
||||
TRANSLATED CONTENT:
|
||||
# Proxychains 参考文档索引
|
||||
|
||||
## 核心文档
|
||||
|
||||
- **proxychains.conf** - 完整配置文件示例(针对 127.0.0.1:9910 优化)
|
||||
- **quick-reference.md** - 快速命令参考和常见场景
|
||||
- **troubleshooting.md** - 故障排除指南
|
||||
- **setup-guide.md** - 安装和初始配置指南
|
||||
|
||||
## 使用场景
|
||||
|
||||
本技能包专为以下场景设计:
|
||||
|
||||
1. **自动代理重试** - Claude 检测到网络错误时自动使用代理
|
||||
2. **已知慢速源** - 访问 GitHub、PyPI、npm 等自动走代理
|
||||
3. **一键配置** - 快速配置代理指向 127.0.0.1:9910
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 安装 proxychains4
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt install proxychains4
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo yum install proxychains-ng
|
||||
|
||||
# macOS
|
||||
brew install proxychains-ng
|
||||
```
|
||||
|
||||
### 2. 配置代理(127.0.0.1:9910)
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.proxychains
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
```
|
||||
|
||||
### 3. 测试代理
|
||||
|
||||
```bash
|
||||
# 测试配置
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
|
||||
# 应该显示代理服务器的 IP 地址
|
||||
```
|
||||
|
||||
## 核心概念
|
||||
|
||||
**Proxychains 工作原理:**
|
||||
- 通过 LD_PRELOAD 拦截程序的 socket 调用
|
||||
- 将所有 TCP 连接重定向到代理服务器
|
||||
- 支持 HTTP、SOCKS4、SOCKS5 代理协议
|
||||
- 透明代理,应用程序无需修改
|
||||
|
||||
**适用范围:**
|
||||
- ✅ 动态链接的程序
|
||||
- ✅ TCP 连接
|
||||
- ✅ HTTP/HTTPS 请求
|
||||
- ❌ 静态链接程序
|
||||
- ❌ UDP 连接
|
||||
|
||||
## 参考文档说明
|
||||
|
||||
### proxychains.conf
|
||||
完整的配置文件模板,已针对 127.0.0.1:9910 优化,包含:
|
||||
- 超时时间设置
|
||||
- DNS 代理配置
|
||||
- 代理链模式选择
|
||||
|
||||
### quick-reference.md
|
||||
快速命令参考,包含:
|
||||
- 常用命令模式
|
||||
- 不同工具的代理使用方法
|
||||
- 环境变量配置
|
||||
|
||||
### troubleshooting.md
|
||||
故障排除指南,包含:
|
||||
- 常见错误和解决方案
|
||||
- 代理服务检查方法
|
||||
- 配置验证步骤
|
||||
|
||||
### setup-guide.md
|
||||
详细的安装和配置指南,包含:
|
||||
- 不同系统的安装方法
|
||||
- 配置文件详解
|
||||
- 高级配置选项
|
||||
|
||||
---
|
||||
|
||||
**使用提示:** Claude 会自动使用这些参考文档中的信息来帮助解决网络问题。
|
||||
@@ -0,0 +1,80 @@
|
||||
TRANSLATED CONTENT:
|
||||
# Proxychains 配置文件
|
||||
# 针对本地代理 127.0.0.1:9910 优化
|
||||
|
||||
# 代理链模式(三选一)
|
||||
# ===========================
|
||||
|
||||
# strict_chain - 严格按顺序使用所有代理(推荐)
|
||||
# 所有代理必须在线,任何一个失败则整个链失败
|
||||
strict_chain
|
||||
|
||||
# dynamic_chain - 动态代理链
|
||||
# 自动跳过离线代理,至少需要一个可用
|
||||
#dynamic_chain
|
||||
|
||||
# random_chain - 随机代理链
|
||||
# 从列表中随机选择代理
|
||||
#random_chain
|
||||
#chain_len = 2 # 随机链长度
|
||||
|
||||
# 代理 DNS 请求
|
||||
# ===========================
|
||||
# 通过代理服务器解析 DNS,避免 DNS 泄漏
|
||||
proxy_dns
|
||||
|
||||
# DNS 解析设置
|
||||
# ===========================
|
||||
# remote_dns_subnet - 用于代理 DNS 的虚拟子网
|
||||
# 默认 224,范围 1-255
|
||||
remote_dns_subnet 224
|
||||
|
||||
# 超时设置(毫秒)
|
||||
# ===========================
|
||||
# tcp_read_time_out - 读取超时
|
||||
tcp_read_time_out 15000
|
||||
|
||||
# tcp_connect_time_out - 连接超时
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
# 日志设置
|
||||
# ===========================
|
||||
# 安静模式(不输出代理链信息)
|
||||
# quiet_mode
|
||||
|
||||
# 代理列表
|
||||
# ===========================
|
||||
# 格式:type host port [username password]
|
||||
# 支持类型:http, socks4, socks5
|
||||
#
|
||||
# 示例:
|
||||
# http 127.0.0.1 8080 username password
|
||||
# socks4 127.0.0.1 1080
|
||||
# socks5 127.0.0.1 1080 username password
|
||||
|
||||
[ProxyList]
|
||||
# 默认本地代理:127.0.0.1:9910
|
||||
http 127.0.0.1 9910
|
||||
|
||||
# 备用代理(取消注释以启用)
|
||||
# ===========================
|
||||
# http 127.0.0.1 8080
|
||||
# socks5 127.0.0.1 1080
|
||||
|
||||
# 使用说明
|
||||
# ===========================
|
||||
# 1. 将此文件保存为:
|
||||
# ~/.proxychains/proxychains.conf (用户级,推荐)
|
||||
# /etc/proxychains.conf (系统级)
|
||||
#
|
||||
# 2. 测试配置:
|
||||
# proxychains4 curl https://ipinfo.io/json
|
||||
#
|
||||
# 3. 使用示例:
|
||||
# proxychains4 git clone https://github.com/user/repo.git
|
||||
# proxychains4 pip install package-name
|
||||
# proxychains4 npm install package-name
|
||||
#
|
||||
# 4. 检查代理服务:
|
||||
# netstat -tunlp | grep 9910
|
||||
# curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
@@ -0,0 +1,380 @@
|
||||
TRANSLATED CONTENT:
|
||||
# Proxychains 快速参考
|
||||
|
||||
## 基本语法
|
||||
|
||||
```bash
|
||||
proxychains4 [command] [arguments]
|
||||
```
|
||||
|
||||
## 常用命令模式
|
||||
|
||||
### Git 操作
|
||||
|
||||
```bash
|
||||
# 克隆仓库
|
||||
proxychains4 git clone https://github.com/user/repo.git
|
||||
|
||||
# 拉取更新
|
||||
proxychains4 git pull
|
||||
|
||||
# 推送代码
|
||||
proxychains4 git push origin main
|
||||
|
||||
# 添加子模块
|
||||
proxychains4 git submodule update --init --recursive
|
||||
```
|
||||
|
||||
### Python/pip
|
||||
|
||||
```bash
|
||||
# 安装包
|
||||
proxychains4 pip install requests
|
||||
proxychains4 pip install -r requirements.txt
|
||||
|
||||
# 升级包
|
||||
proxychains4 pip install --upgrade package-name
|
||||
|
||||
# 搜索包
|
||||
proxychains4 pip search package-name
|
||||
|
||||
# 使用国内镜像 + 代理(双保险)
|
||||
proxychains4 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple package-name
|
||||
```
|
||||
|
||||
### Node.js/npm/yarn
|
||||
|
||||
```bash
|
||||
# npm 安装
|
||||
proxychains4 npm install package-name
|
||||
proxychains4 npm install -g package-name
|
||||
proxychains4 npm install
|
||||
|
||||
# yarn 安装
|
||||
proxychains4 yarn add package-name
|
||||
proxychains4 yarn install
|
||||
|
||||
# 清理缓存后安装
|
||||
proxychains4 npm cache clean --force
|
||||
proxychains4 npm install
|
||||
```
|
||||
|
||||
### curl/wget
|
||||
|
||||
```bash
|
||||
# curl 下载
|
||||
proxychains4 curl -O https://example.com/file.tar.gz
|
||||
proxychains4 curl -L https://example.com/redirect
|
||||
|
||||
# wget 下载
|
||||
proxychains4 wget https://example.com/file.tar.gz
|
||||
proxychains4 wget -c https://example.com/large-file.iso
|
||||
|
||||
# API 请求
|
||||
proxychains4 curl -X POST https://api.example.com/endpoint
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# 拉取镜像
|
||||
proxychains4 docker pull ubuntu:latest
|
||||
proxychains4 docker pull nginx:alpine
|
||||
|
||||
# 构建镜像(如果需要下载基础镜像)
|
||||
proxychains4 docker build -t myapp:latest .
|
||||
|
||||
# 推送镜像
|
||||
proxychains4 docker push myregistry.com/myapp:latest
|
||||
```
|
||||
|
||||
### SSH/SCP
|
||||
|
||||
```bash
|
||||
# SSH 连接
|
||||
proxychains4 ssh user@remote-host
|
||||
|
||||
# SCP 文件传输
|
||||
proxychains4 scp file.txt user@remote-host:/path/
|
||||
proxychains4 scp -r folder/ user@remote-host:/path/
|
||||
|
||||
# rsync 同步
|
||||
proxychains4 rsync -avz folder/ user@remote-host:/path/
|
||||
```
|
||||
|
||||
### 其他工具
|
||||
|
||||
```bash
|
||||
# telnet
|
||||
proxychains4 telnet example.com 80
|
||||
|
||||
# nc (netcat)
|
||||
proxychains4 nc example.com 80
|
||||
|
||||
# ftp
|
||||
proxychains4 ftp ftp.example.com
|
||||
|
||||
# svn
|
||||
proxychains4 svn checkout https://example.com/svn/repo
|
||||
|
||||
# mercurial (hg)
|
||||
proxychains4 hg clone https://example.com/hg/repo
|
||||
```
|
||||
|
||||
## 配置文件选项
|
||||
|
||||
### 指定配置文件
|
||||
|
||||
```bash
|
||||
# 使用自定义配置文件
|
||||
proxychains4 -f /path/to/proxychains.conf curl https://example.com
|
||||
|
||||
# 使用当前目录配置
|
||||
proxychains4 -f ./proxychains.conf command
|
||||
```
|
||||
|
||||
### 环境变量方式
|
||||
|
||||
```bash
|
||||
# 设置代理主机和端口(SOCKS5)
|
||||
export PROXYCHAINS_SOCKS5_HOST=127.0.0.1
|
||||
export PROXYCHAINS_SOCKS5_PORT=9910
|
||||
proxychains4 curl https://example.com
|
||||
|
||||
# 指定配置文件路径
|
||||
export PROXYCHAINS_CONF_FILE=~/.proxychains/custom.conf
|
||||
proxychains4 command
|
||||
|
||||
# 自定义 DNS 服务器
|
||||
export PROXY_DNS_SERVER=8.8.8.8
|
||||
proxychains4 curl https://example.com
|
||||
```
|
||||
|
||||
### 启动代理会话
|
||||
|
||||
```bash
|
||||
# 在代理环境中启动 shell
|
||||
proxychains4 bash
|
||||
# 或
|
||||
proxychains4 zsh
|
||||
|
||||
# 然后所有命令都会通过代理
|
||||
git clone https://github.com/user/repo.git
|
||||
pip install requests
|
||||
npm install package-name
|
||||
|
||||
# 退出代理会话
|
||||
exit
|
||||
```
|
||||
|
||||
## 诊断和测试
|
||||
|
||||
### 测试代理连接
|
||||
|
||||
```bash
|
||||
# 测试 HTTP 代理
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
proxychains4 curl https://ifconfig.me
|
||||
|
||||
# 测试特定网站
|
||||
proxychains4 curl -I https://github.com
|
||||
proxychains4 curl -I https://google.com
|
||||
|
||||
# 详细输出(调试)
|
||||
proxychains4 -q curl -v https://example.com
|
||||
```
|
||||
|
||||
### 检查代理服务
|
||||
|
||||
```bash
|
||||
# 检查端口是否监听
|
||||
netstat -tunlp | grep 9910
|
||||
ss -tunlp | grep 9910
|
||||
lsof -i :9910
|
||||
|
||||
# 测试代理直接连接(不用 proxychains)
|
||||
curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
curl -x socks5://127.0.0.1:1080 https://www.google.com
|
||||
|
||||
# 测试代理认证
|
||||
curl -x http://username:password@127.0.0.1:9910 https://www.google.com
|
||||
```
|
||||
|
||||
### DNS 解析测试
|
||||
|
||||
```bash
|
||||
# 通过代理解析 DNS
|
||||
proxychains4 nslookup google.com
|
||||
proxychains4 dig google.com
|
||||
|
||||
# 使用 proxyresolv 工具(proxychains 自带)
|
||||
proxyresolv google.com
|
||||
proxyresolv github.com
|
||||
```
|
||||
|
||||
## 快速配置生成
|
||||
|
||||
### 单行命令创建配置
|
||||
|
||||
```bash
|
||||
# 创建用户级配置(HTTP 代理 127.0.0.1:9910)
|
||||
mkdir -p ~/.proxychains && cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# 创建 SOCKS5 配置
|
||||
mkdir -p ~/.proxychains && cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
socks5 127.0.0.1 1080
|
||||
EOF
|
||||
```
|
||||
|
||||
### 临时配置(当前目录)
|
||||
|
||||
```bash
|
||||
# 在当前目录创建临时配置
|
||||
cat > proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# 使用临时配置
|
||||
proxychains4 -f ./proxychains.conf curl https://github.com
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 减少延迟
|
||||
|
||||
```bash
|
||||
# 配置文件中调整超时
|
||||
tcp_connect_time_out 5000 # 5秒
|
||||
tcp_read_time_out 10000 # 10秒
|
||||
|
||||
# 使用 quiet_mode 减少输出
|
||||
quiet_mode
|
||||
```
|
||||
|
||||
### 并行下载
|
||||
|
||||
```bash
|
||||
# aria2 多线程下载
|
||||
proxychains4 aria2c -x 16 https://example.com/large-file.iso
|
||||
|
||||
# wget 多连接下载
|
||||
proxychains4 wget --limit-rate=10m https://example.com/file.tar.gz
|
||||
```
|
||||
|
||||
## 常见组合场景
|
||||
|
||||
### 场景 1: Python 项目依赖安装
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
proxychains4 git clone https://github.com/user/project.git
|
||||
cd project
|
||||
|
||||
# 创建虚拟环境
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
proxychains4 pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 场景 2: Node.js 项目初始化
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
proxychains4 git clone https://github.com/user/project.git
|
||||
cd project
|
||||
|
||||
# 安装依赖
|
||||
proxychains4 npm install
|
||||
# 或
|
||||
proxychains4 yarn install
|
||||
|
||||
# 运行项目(如果需要下载额外资源)
|
||||
proxychains4 npm start
|
||||
```
|
||||
|
||||
### 场景 3: Docker 镜像构建
|
||||
|
||||
```bash
|
||||
# 拉取基础镜像
|
||||
proxychains4 docker pull node:18-alpine
|
||||
|
||||
# 构建镜像(Dockerfile 中有 FROM 远程镜像)
|
||||
proxychains4 docker build -t myapp:latest .
|
||||
|
||||
# 推送到仓库
|
||||
proxychains4 docker push myregistry.com/myapp:latest
|
||||
```
|
||||
|
||||
### 场景 4: 系统软件更新
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
proxychains4 sudo apt update
|
||||
proxychains4 sudo apt upgrade
|
||||
|
||||
# CentOS/RHEL
|
||||
proxychains4 sudo yum update
|
||||
|
||||
# Arch Linux
|
||||
proxychains4 sudo pacman -Syu
|
||||
```
|
||||
|
||||
## 别名设置(可选)
|
||||
|
||||
```bash
|
||||
# 添加到 ~/.bashrc 或 ~/.zshrc
|
||||
alias pc='proxychains4'
|
||||
alias pcgit='proxychains4 git'
|
||||
alias pcpip='proxychains4 pip'
|
||||
alias pcnpm='proxychains4 npm'
|
||||
alias pccurl='proxychains4 curl'
|
||||
alias pcwget='proxychains4 wget'
|
||||
|
||||
# 使用别名
|
||||
pc curl https://github.com
|
||||
pcgit clone https://github.com/user/repo.git
|
||||
pcpip install requests
|
||||
```
|
||||
|
||||
## 故障排除快速检查清单
|
||||
|
||||
```bash
|
||||
# 1. 检查 proxychains 是否安装
|
||||
which proxychains4
|
||||
|
||||
# 2. 检查配置文件是否存在
|
||||
ls -la ~/.proxychains/proxychains.conf
|
||||
cat ~/.proxychains/proxychains.conf
|
||||
|
||||
# 3. 检查代理服务是否运行
|
||||
netstat -tunlp | grep 9910
|
||||
|
||||
# 4. 测试代理直接连接
|
||||
curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
|
||||
# 5. 测试 proxychains 连接
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
|
||||
# 6. 查看详细错误信息
|
||||
proxychains4 curl -v https://example.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**提示:** 将常用命令保存为 shell 脚本或别名,可以提高效率。
|
||||
@@ -0,0 +1,641 @@
|
||||
TRANSLATED CONTENT:
|
||||
# Proxychains 安装和配置指南
|
||||
|
||||
## 安装 Proxychains
|
||||
|
||||
### Linux 系统
|
||||
|
||||
#### Ubuntu/Debian
|
||||
|
||||
```bash
|
||||
# 更新包列表
|
||||
sudo apt update
|
||||
|
||||
# 安装 proxychains4
|
||||
sudo apt install proxychains4
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
#### CentOS/RHEL 7/8
|
||||
|
||||
```bash
|
||||
# 安装 EPEL 仓库
|
||||
sudo yum install epel-release
|
||||
|
||||
# 安装 proxychains-ng
|
||||
sudo yum install proxychains-ng
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
#### Fedora
|
||||
|
||||
```bash
|
||||
# 安装 proxychains-ng
|
||||
sudo dnf install proxychains-ng
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
#### Arch Linux
|
||||
|
||||
```bash
|
||||
# 安装 proxychains-ng
|
||||
sudo pacman -S proxychains-ng
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
#### 从源码编译(通用方法)
|
||||
|
||||
```bash
|
||||
# 安装依赖
|
||||
sudo apt install build-essential git # Debian/Ubuntu
|
||||
# 或
|
||||
sudo yum install gcc git make # CentOS/RHEL
|
||||
|
||||
# 克隆仓库
|
||||
git clone https://github.com/haad/proxychains.git
|
||||
cd proxychains
|
||||
|
||||
# 编译安装
|
||||
./configure --prefix=/usr --sysconfdir=/etc
|
||||
make
|
||||
sudo make install
|
||||
sudo make install-config # 安装默认配置文件
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
### macOS
|
||||
|
||||
```bash
|
||||
# 使用 Homebrew 安装
|
||||
brew install proxychains-ng
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
### WSL (Windows Subsystem for Linux)
|
||||
|
||||
```bash
|
||||
# 在 WSL 中安装(使用 Ubuntu 示例)
|
||||
sudo apt update
|
||||
sudo apt install proxychains4
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 基础配置
|
||||
|
||||
### 配置文件位置
|
||||
|
||||
Proxychains 按以下顺序查找配置文件:
|
||||
|
||||
1. `${PROXYCHAINS_CONF_FILE}` 环境变量指定的路径
|
||||
2. 命令行 `-f` 参数指定的路径
|
||||
3. `./proxychains.conf` (当前目录)
|
||||
4. `~/.proxychains/proxychains.conf` (用户主目录) **推荐**
|
||||
5. `/etc/proxychains.conf` (系统级)
|
||||
|
||||
### 创建用户级配置(推荐)
|
||||
|
||||
```bash
|
||||
# 创建配置目录
|
||||
mkdir -p ~/.proxychains
|
||||
|
||||
# 创建配置文件(针对 127.0.0.1:9910)
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
# Proxychains 配置文件
|
||||
# 代理地址:127.0.0.1:9910
|
||||
|
||||
# 代理链模式
|
||||
strict_chain
|
||||
|
||||
# 代理 DNS 请求
|
||||
proxy_dns
|
||||
|
||||
# DNS 设置
|
||||
remote_dns_subnet 224
|
||||
|
||||
# 超时设置(毫秒)
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
# 代理列表
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# 设置权限
|
||||
chmod 644 ~/.proxychains/proxychains.conf
|
||||
```
|
||||
|
||||
### 创建系统级配置(可选)
|
||||
|
||||
```bash
|
||||
# 需要 root 权限
|
||||
sudo cat > /etc/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# 设置权限
|
||||
sudo chmod 644 /etc/proxychains.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置详解
|
||||
|
||||
### 代理链模式
|
||||
|
||||
在配置文件中只能选择一种模式:
|
||||
|
||||
#### strict_chain(严格链,推荐)
|
||||
|
||||
```conf
|
||||
# 严格按顺序使用所有代理
|
||||
# 所有代理必须在线,任何一个失败则整个链失败
|
||||
strict_chain
|
||||
```
|
||||
|
||||
**适用场景:**
|
||||
- 只有一个代理服务器
|
||||
- 需要确保所有代理都被使用
|
||||
- 对安全性要求高
|
||||
|
||||
#### dynamic_chain(动态链)
|
||||
|
||||
```conf
|
||||
# 自动跳过离线代理
|
||||
# 至少需要一个可用代理
|
||||
dynamic_chain
|
||||
```
|
||||
|
||||
**适用场景:**
|
||||
- 有多个代理服务器
|
||||
- 某些代理可能不稳定
|
||||
- 需要自动故障转移
|
||||
|
||||
#### random_chain(随机链)
|
||||
|
||||
```conf
|
||||
# 从列表中随机选择代理
|
||||
random_chain
|
||||
chain_len = 2 # 随机链长度(可选)
|
||||
```
|
||||
|
||||
**适用场景:**
|
||||
- 需要隐藏流量模式
|
||||
- 有多个代理可用
|
||||
- 对匿名性要求高
|
||||
|
||||
### DNS 设置
|
||||
|
||||
```conf
|
||||
# 通过代理服务器解析 DNS
|
||||
proxy_dns
|
||||
|
||||
# DNS 解析使用的虚拟子网(1-255)
|
||||
remote_dns_subnet 224
|
||||
|
||||
# 可选:自定义 DNS 服务器(通过环境变量)
|
||||
# export PROXY_DNS_SERVER=8.8.8.8
|
||||
```
|
||||
|
||||
### 超时设置
|
||||
|
||||
```conf
|
||||
# TCP 读取超时(毫秒)
|
||||
tcp_read_time_out 15000 # 15秒
|
||||
|
||||
# TCP 连接超时(毫秒)
|
||||
tcp_connect_time_out 8000 # 8秒
|
||||
```
|
||||
|
||||
**调优建议:**
|
||||
- 慢速网络:增加到 30000 和 15000
|
||||
- 快速网络:减少到 10000 和 5000
|
||||
- 本地代理:可以设置为 5000 和 3000
|
||||
|
||||
### 日志设置
|
||||
|
||||
```conf
|
||||
# 静默模式(不输出代理链信息)
|
||||
quiet_mode
|
||||
```
|
||||
|
||||
**注意:** 调试时应注释掉此选项以查看详细输出。
|
||||
|
||||
---
|
||||
|
||||
## 代理列表配置
|
||||
|
||||
### 基本格式
|
||||
|
||||
```conf
|
||||
[ProxyList]
|
||||
# 格式:type host port [username password]
|
||||
```
|
||||
|
||||
### HTTP 代理
|
||||
|
||||
```conf
|
||||
# 不需要认证
|
||||
http 127.0.0.1 9910
|
||||
|
||||
# 需要认证
|
||||
http 127.0.0.1 8080 username password
|
||||
```
|
||||
|
||||
### SOCKS4 代理
|
||||
|
||||
```conf
|
||||
# 不需要认证
|
||||
socks4 127.0.0.1 1080
|
||||
|
||||
# SOCKS4 不支持用户认证
|
||||
```
|
||||
|
||||
### SOCKS5 代理
|
||||
|
||||
```conf
|
||||
# 不需要认证
|
||||
socks5 127.0.0.1 1080
|
||||
|
||||
# 需要认证
|
||||
socks5 127.0.0.1 1080 username password
|
||||
```
|
||||
|
||||
### 多代理配置
|
||||
|
||||
```conf
|
||||
[ProxyList]
|
||||
# 主代理
|
||||
http 127.0.0.1 9910
|
||||
|
||||
# 备用代理(strict_chain 模式下会按顺序使用)
|
||||
# 取消注释以启用
|
||||
#http 127.0.0.1 8080
|
||||
#socks5 127.0.0.1 1080
|
||||
```
|
||||
|
||||
### 代理链示例
|
||||
|
||||
```conf
|
||||
# 多级代理(流量经过多个代理)
|
||||
strict_chain
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
socks5 proxy2.example.com 1080
|
||||
http proxy3.example.com 8080
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 高级配置
|
||||
|
||||
### 使用环境变量
|
||||
|
||||
```bash
|
||||
# SOCKS5 代理(简化配置)
|
||||
export PROXYCHAINS_SOCKS5_HOST=127.0.0.1
|
||||
export PROXYCHAINS_SOCKS5_PORT=9910
|
||||
proxychains4 curl https://github.com
|
||||
|
||||
# 指定配置文件
|
||||
export PROXYCHAINS_CONF_FILE=~/.proxychains/custom.conf
|
||||
proxychains4 command
|
||||
|
||||
# 自定义 DNS 服务器
|
||||
export PROXY_DNS_SERVER=8.8.8.8
|
||||
proxychains4 curl https://example.com
|
||||
```
|
||||
|
||||
### 多配置文件管理
|
||||
|
||||
```bash
|
||||
# 为不同场景创建不同配置文件
|
||||
mkdir -p ~/.proxychains
|
||||
|
||||
# 国内代理配置
|
||||
cat > ~/.proxychains/cn.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# 国外代理配置
|
||||
cat > ~/.proxychains/intl.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
socks5 proxy.example.com 1080
|
||||
EOF
|
||||
|
||||
# 使用特定配置
|
||||
proxychains4 -f ~/.proxychains/cn.conf curl https://github.com
|
||||
proxychains4 -f ~/.proxychains/intl.conf curl https://google.com
|
||||
```
|
||||
|
||||
### 创建 Shell 别名
|
||||
|
||||
```bash
|
||||
# 添加到 ~/.bashrc 或 ~/.zshrc
|
||||
cat >> ~/.bashrc << 'EOF'
|
||||
|
||||
# Proxychains 别名
|
||||
alias pc='proxychains4'
|
||||
alias pccn='proxychains4 -f ~/.proxychains/cn.conf'
|
||||
alias pcintl='proxychains4 -f ~/.proxychains/intl.conf'
|
||||
|
||||
# 常用命令别名
|
||||
alias pcgit='proxychains4 git'
|
||||
alias pcpip='proxychains4 pip'
|
||||
alias pcnpm='proxychains4 npm'
|
||||
alias pccurl='proxychains4 curl'
|
||||
alias pcwget='proxychains4 wget'
|
||||
alias pcssh='proxychains4 ssh'
|
||||
|
||||
EOF
|
||||
|
||||
# 重新加载配置
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 测试配置
|
||||
|
||||
### 基本连接测试
|
||||
|
||||
```bash
|
||||
# 测试 proxychains 是否工作
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
|
||||
# 应该显示代理服务器的 IP 地址,而不是本机 IP
|
||||
```
|
||||
|
||||
### 对比测试
|
||||
|
||||
```bash
|
||||
# 不使用代理的 IP
|
||||
curl https://ipinfo.io/json
|
||||
|
||||
# 使用代理的 IP(应该不同)
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
```
|
||||
|
||||
### DNS 测试
|
||||
|
||||
```bash
|
||||
# 测试 DNS 解析
|
||||
proxychains4 nslookup google.com
|
||||
proxychains4 dig github.com
|
||||
|
||||
# 使用 proxyresolv 工具
|
||||
proxyresolv google.com
|
||||
```
|
||||
|
||||
### 完整功能测试
|
||||
|
||||
```bash
|
||||
# HTTP 请求
|
||||
proxychains4 curl -I https://github.com
|
||||
|
||||
# HTTPS 请求
|
||||
proxychains4 curl https://www.google.com
|
||||
|
||||
# SSH 连接(如果有测试服务器)
|
||||
proxychains4 ssh user@example.com
|
||||
|
||||
# Git 克隆
|
||||
proxychains4 git clone https://github.com/haad/proxychains.git /tmp/test-repo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 与代理软件集成
|
||||
|
||||
### V2Ray
|
||||
|
||||
```bash
|
||||
# 假设 V2Ray HTTP 代理端口是 10809
|
||||
# 更新 proxychains 配置
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
http 127.0.0.1 10809
|
||||
EOF
|
||||
```
|
||||
|
||||
### Clash
|
||||
|
||||
```bash
|
||||
# 假设 Clash HTTP 代理端口是 7890
|
||||
# 更新 proxychains 配置
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
http 127.0.0.1 7890
|
||||
EOF
|
||||
```
|
||||
|
||||
### Shadowsocks
|
||||
|
||||
```bash
|
||||
# 假设 Shadowsocks SOCKS5 端口是 1080
|
||||
# 更新 proxychains 配置
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
socks5 127.0.0.1 1080
|
||||
EOF
|
||||
```
|
||||
|
||||
### SSH 动态端口转发
|
||||
|
||||
```bash
|
||||
# 创建 SSH 动态端口转发(SOCKS5)
|
||||
ssh -fN -D 1080 user@remote-server
|
||||
|
||||
# 配置 proxychains 使用 SSH 隧道
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
socks5 127.0.0.1 1080
|
||||
EOF
|
||||
|
||||
# 使用
|
||||
proxychains4 curl https://example.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 常见配置模板
|
||||
|
||||
### 模板 1: 单个 HTTP 代理(默认)
|
||||
|
||||
```conf
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
```
|
||||
|
||||
### 模板 2: 单个 SOCKS5 代理
|
||||
|
||||
```conf
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
[ProxyList]
|
||||
socks5 127.0.0.1 1080
|
||||
```
|
||||
|
||||
### 模板 3: 多代理动态链(自动故障转移)
|
||||
|
||||
```conf
|
||||
dynamic_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
http 127.0.0.1 8080
|
||||
socks5 127.0.0.1 1080
|
||||
```
|
||||
|
||||
### 模板 4: 低延迟优化
|
||||
|
||||
```conf
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 10000
|
||||
tcp_connect_time_out 5000
|
||||
quiet_mode
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 持久化配置
|
||||
|
||||
### 系统启动时自动使用代理
|
||||
|
||||
**不推荐全局使用,仅对特定用户/命令使用**
|
||||
|
||||
```bash
|
||||
# 创建启动脚本(示例)
|
||||
cat > ~/start-with-proxy.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
proxychains4 bash
|
||||
EOF
|
||||
|
||||
chmod +x ~/start-with-proxy.sh
|
||||
```
|
||||
|
||||
### 为特定应用创建包装脚本
|
||||
|
||||
```bash
|
||||
# Git 包装脚本
|
||||
cat > ~/bin/git-proxy << 'EOF'
|
||||
#!/bin/bash
|
||||
proxychains4 git "$@"
|
||||
EOF
|
||||
|
||||
chmod +x ~/bin/git-proxy
|
||||
|
||||
# 使用
|
||||
git-proxy clone https://github.com/user/repo.git
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 故障排除配置
|
||||
|
||||
如果遇到问题,使用此配置进行调试:
|
||||
|
||||
```conf
|
||||
# 调试配置
|
||||
strict_chain
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
tcp_read_time_out 30000
|
||||
tcp_connect_time_out 15000
|
||||
# 注释掉 quiet_mode 以查看详细输出
|
||||
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. **配置文件权限**
|
||||
```bash
|
||||
chmod 644 ~/.proxychains/proxychains.conf
|
||||
```
|
||||
|
||||
2. **不要在配置文件中明文存储密码**
|
||||
- 如果必须使用认证,确保配置文件权限正确
|
||||
- 考虑使用环境变量
|
||||
|
||||
3. **定期更新 proxychains**
|
||||
```bash
|
||||
sudo apt update && sudo apt upgrade proxychains4
|
||||
```
|
||||
|
||||
4. **验证代理服务器可信度**
|
||||
- 只使用信任的代理服务器
|
||||
- 避免使用公共免费代理
|
||||
|
||||
---
|
||||
|
||||
## 下一步
|
||||
|
||||
配置完成后:
|
||||
|
||||
1. 阅读 `quick-reference.md` 了解常用命令
|
||||
2. 阅读 `troubleshooting.md` 了解问题解决
|
||||
3. 开始使用 proxychains4!
|
||||
|
||||
---
|
||||
|
||||
**提示:** 配置文件修改后立即生效,无需重启服务。
|
||||
@@ -0,0 +1,476 @@
|
||||
TRANSLATED CONTENT:
|
||||
# Proxychains 故障排除指南
|
||||
|
||||
## 常见错误及解决方案
|
||||
|
||||
### 错误 1: "proxychains: command not found"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
bash: proxychains4: command not found
|
||||
```
|
||||
|
||||
**原因:** proxychains 未安装
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt update
|
||||
sudo apt install proxychains4
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo yum install epel-release
|
||||
sudo yum install proxychains-ng
|
||||
|
||||
# Fedora
|
||||
sudo dnf install proxychains-ng
|
||||
|
||||
# macOS
|
||||
brew install proxychains-ng
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S proxychains-ng
|
||||
|
||||
# 验证安装
|
||||
proxychains4 --version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 2: "can't read configuration file"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
[proxychains] can't read configuration file /etc/proxychains.conf
|
||||
```
|
||||
|
||||
**原因:** 配置文件不存在或路径错误
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 方法 1: 创建用户级配置文件
|
||||
mkdir -p ~/.proxychains
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
strict_chain
|
||||
proxy_dns
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# 方法 2: 复制系统配置模板
|
||||
sudo cp /usr/share/doc/proxychains*/proxychains.conf /etc/
|
||||
# 或
|
||||
sudo cp /usr/local/etc/proxychains.conf /etc/
|
||||
|
||||
# 方法 3: 指定配置文件路径
|
||||
proxychains4 -f /path/to/proxychains.conf curl https://github.com
|
||||
|
||||
# 验证配置文件
|
||||
cat ~/.proxychains/proxychains.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 3: "timeout"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
[proxychains] Strict chain ... 127.0.0.1:9910 ... github.com:443 ... timeout
|
||||
curl: (28) Connection timed out after 10000 milliseconds
|
||||
```
|
||||
|
||||
**原因:** 代理服务未运行、端口错误或防火墙阻止
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 检查代理服务是否运行
|
||||
netstat -tunlp | grep 9910
|
||||
ss -tunlp | grep 9910
|
||||
lsof -i :9910
|
||||
|
||||
# 2. 测试代理服务直接连接
|
||||
curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
|
||||
# 3. 检查防火墙规则
|
||||
sudo iptables -L -n | grep 9910
|
||||
sudo ufw status
|
||||
|
||||
# 4. 确认代理配置正确
|
||||
cat ~/.proxychains/proxychains.conf | grep -A 2 "\[ProxyList\]"
|
||||
|
||||
# 5. 增加超时时间(编辑配置文件)
|
||||
tcp_connect_time_out 15000
|
||||
tcp_read_time_out 30000
|
||||
|
||||
# 6. 如果代理服务未运行,启动代理服务
|
||||
# (根据你的代理软件,例如:)
|
||||
# v2ray、clash、shadowsocks 等
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 4: "connection refused"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
[proxychains] Strict chain ... 127.0.0.1:9910 ... connect refused
|
||||
curl: (7) Failed to connect to 127.0.0.1 port 9910: Connection refused
|
||||
```
|
||||
|
||||
**原因:** 代理端口未监听或代理服务未启动
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 确认代理服务状态
|
||||
# 检查你的代理软件是否运行(v2ray、clash、shadowsocks 等)
|
||||
|
||||
# 2. 验证代理端口
|
||||
netstat -tunlp | grep 9910
|
||||
# 如果没有输出,说明端口未监听
|
||||
|
||||
# 3. 检查代理软件配置
|
||||
# 确认代理软件监听的端口是 9910
|
||||
|
||||
# 4. 尝试其他可能的代理端口
|
||||
# 常见端口:1080 (SOCKS), 7890 (HTTP), 8080 (HTTP)
|
||||
netstat -tunlp | grep -E '1080|7890|8080|9910'
|
||||
|
||||
# 5. 更新 proxychains 配置为正确端口
|
||||
nano ~/.proxychains/proxychains.conf
|
||||
# 修改 [ProxyList] 部分:
|
||||
# http 127.0.0.1 [正确的端口]
|
||||
|
||||
# 6. 重启代理服务
|
||||
# 根据你的代理软件执行相应命令
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 5: "DNS request timed out"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
[proxychains] DNS request timed out
|
||||
curl: (6) Could not resolve host: github.com
|
||||
```
|
||||
|
||||
**原因:** DNS 解析失败或 proxy_dns 配置问题
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 检查配置文件中的 proxy_dns 设置
|
||||
cat ~/.proxychains/proxychains.conf | grep proxy_dns
|
||||
# 应该有:proxy_dns
|
||||
|
||||
# 2. 如果没有,添加 proxy_dns
|
||||
nano ~/.proxychains/proxychains.conf
|
||||
# 添加:
|
||||
proxy_dns
|
||||
remote_dns_subnet 224
|
||||
|
||||
# 3. 测试 DNS 解析
|
||||
proxychains4 nslookup github.com
|
||||
proxychains4 dig github.com
|
||||
|
||||
# 4. 使用自定义 DNS 服务器
|
||||
export PROXY_DNS_SERVER=8.8.8.8
|
||||
proxychains4 curl https://github.com
|
||||
|
||||
# 5. 或者使用 IP 地址直接访问(跳过 DNS)
|
||||
proxychains4 curl https://140.82.114.4 # GitHub IP
|
||||
|
||||
# 6. 检查 /etc/resolv.conf
|
||||
cat /etc/resolv.conf
|
||||
# 确保有有效的 nameserver
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 6: "Program not supported"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 ./static-binary
|
||||
[proxychains] Program not supported
|
||||
```
|
||||
|
||||
**原因:** 程序是静态链接的,proxychains 只支持动态链接程序
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 检查程序是否静态链接
|
||||
ldd ./program
|
||||
# 如果输出 "not a dynamic executable",则为静态链接
|
||||
|
||||
# 2. 对于静态链接程序,需要其他方案:
|
||||
# - 使用系统级代理(iptables 转发)
|
||||
# - 使用 VPN
|
||||
# - 使用容器级代理
|
||||
|
||||
# 3. Go 程序示例(通常是静态链接)
|
||||
# 设置环境变量而不是用 proxychains
|
||||
export HTTP_PROXY=http://127.0.0.1:9910
|
||||
export HTTPS_PROXY=http://127.0.0.1:9910
|
||||
./go-program
|
||||
|
||||
# 4. 对于可重新编译的程序
|
||||
# 编译为动态链接版本
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 7: "strict chain ... all proxy servers are down"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
[proxychains] strict chain ... all proxy servers are down!
|
||||
curl: (97) Failure in receiving network data
|
||||
```
|
||||
|
||||
**原因:** strict_chain 模式下所有代理都不可用
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 测试代理列表中的每个代理
|
||||
cat ~/.proxychains/proxychains.conf | grep -A 10 "\[ProxyList\]"
|
||||
|
||||
# 逐个测试
|
||||
curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
curl -x http://127.0.0.1:8080 https://www.google.com
|
||||
|
||||
# 2. 切换到 dynamic_chain 模式(自动跳过死代理)
|
||||
nano ~/.proxychains/proxychains.conf
|
||||
# 注释掉:#strict_chain
|
||||
# 启用:dynamic_chain
|
||||
|
||||
# 3. 或者移除不可用的代理
|
||||
nano ~/.proxychains/proxychains.conf
|
||||
# 只保留可用的代理在 [ProxyList] 中
|
||||
|
||||
# 4. 重新测试
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 错误 8: "Permission denied"
|
||||
|
||||
**症状:**
|
||||
```bash
|
||||
$ proxychains4 curl https://github.com
|
||||
[proxychains] Permission denied
|
||||
```
|
||||
|
||||
**原因:** 配置文件或 proxychains 可执行文件权限问题
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 检查配置文件权限
|
||||
ls -la ~/.proxychains/proxychains.conf
|
||||
|
||||
# 2. 修复权限
|
||||
chmod 644 ~/.proxychains/proxychains.conf
|
||||
|
||||
# 3. 检查目录权限
|
||||
ls -la ~/.proxychains/
|
||||
|
||||
# 4. 修复目录权限
|
||||
chmod 755 ~/.proxychains/
|
||||
|
||||
# 5. 检查 proxychains 可执行文件权限
|
||||
ls -la $(which proxychains4)
|
||||
|
||||
# 6. 如果是系统级配置文件
|
||||
sudo chmod 644 /etc/proxychains.conf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 高级故障排除
|
||||
|
||||
### 调试模式
|
||||
|
||||
```bash
|
||||
# 启用详细输出
|
||||
# 编辑配置文件,注释掉 quiet_mode
|
||||
nano ~/.proxychains/proxychains.conf
|
||||
# 注释:#quiet_mode
|
||||
|
||||
# 使用 strace 跟踪系统调用
|
||||
strace -e trace=network proxychains4 curl https://github.com
|
||||
|
||||
# 查看环境变量
|
||||
env | grep -i proxy
|
||||
```
|
||||
|
||||
### 日志分析
|
||||
|
||||
```bash
|
||||
# proxychains 输出到文件
|
||||
proxychains4 curl https://github.com 2>&1 | tee proxychains.log
|
||||
|
||||
# 分析连接过程
|
||||
cat proxychains.log | grep -E 'chain|connect|timeout'
|
||||
```
|
||||
|
||||
### 网络连通性测试
|
||||
|
||||
```bash
|
||||
# 测试本地连接
|
||||
ping 127.0.0.1
|
||||
telnet 127.0.0.1 9910
|
||||
|
||||
# 测试外部连接(不通过代理)
|
||||
curl https://ipinfo.io/json
|
||||
|
||||
# 测试外部连接(通过代理)
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
|
||||
# 比较 IP 地址
|
||||
# 不通过代理的 IP 应该是本机 IP
|
||||
# 通过代理的 IP 应该是代理服务器 IP
|
||||
```
|
||||
|
||||
### 配置验证
|
||||
|
||||
```bash
|
||||
# 验证配置文件语法
|
||||
proxychains4 -f ~/.proxychains/proxychains.conf true
|
||||
|
||||
# 测试不同的代理类型
|
||||
# HTTP
|
||||
proxychains4 -f - curl https://github.com << 'EOF'
|
||||
strict_chain
|
||||
[ProxyList]
|
||||
http 127.0.0.1 9910
|
||||
EOF
|
||||
|
||||
# SOCKS5
|
||||
proxychains4 -f - curl https://github.com << 'EOF'
|
||||
strict_chain
|
||||
[ProxyList]
|
||||
socks5 127.0.0.1 1080
|
||||
EOF
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 性能问题
|
||||
|
||||
### 连接缓慢
|
||||
|
||||
**症状:** 命令执行很慢
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 减少超时时间
|
||||
nano ~/.proxychains/proxychains.conf
|
||||
tcp_connect_time_out 5000
|
||||
tcp_read_time_out 10000
|
||||
|
||||
# 2. 启用 quiet_mode 减少输出
|
||||
quiet_mode
|
||||
|
||||
# 3. 使用更快的代理服务器
|
||||
|
||||
# 4. 测试代理延迟
|
||||
time proxychains4 curl -I https://github.com
|
||||
|
||||
# 5. 使用 dynamic_chain 跳过慢速代理
|
||||
dynamic_chain
|
||||
```
|
||||
|
||||
### 频繁断开
|
||||
|
||||
**症状:** 连接经常中断
|
||||
|
||||
**解决方案:**
|
||||
|
||||
```bash
|
||||
# 1. 增加超时时间
|
||||
tcp_read_time_out 30000
|
||||
|
||||
# 2. 检查代理服务器稳定性
|
||||
# 持续 ping 测试
|
||||
ping -c 100 127.0.0.1
|
||||
|
||||
# 3. 更换代理服务器
|
||||
|
||||
# 4. 检查网络稳定性
|
||||
mtr 8.8.8.8
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 检查清单
|
||||
|
||||
使用此清单快速诊断问题:
|
||||
|
||||
```bash
|
||||
# ✅ 检查 1: proxychains 已安装
|
||||
which proxychains4
|
||||
|
||||
# ✅ 检查 2: 配置文件存在
|
||||
ls -la ~/.proxychains/proxychains.conf
|
||||
|
||||
# ✅ 检查 3: 配置文件格式正确
|
||||
cat ~/.proxychains/proxychains.conf
|
||||
|
||||
# ✅ 检查 4: 代理服务运行中
|
||||
netstat -tunlp | grep 9910
|
||||
|
||||
# ✅ 检查 5: 代理可直接访问
|
||||
curl -x http://127.0.0.1:9910 https://www.google.com
|
||||
|
||||
# ✅ 检查 6: DNS 解析正常
|
||||
proxychains4 nslookup github.com
|
||||
|
||||
# ✅ 检查 7: proxychains 连接正常
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
|
||||
# ✅ 检查 8: IP 地址已变更
|
||||
# 对比直接访问和代理访问的 IP 应该不同
|
||||
curl https://ipinfo.io/json
|
||||
proxychains4 curl https://ipinfo.io/json
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 获取帮助
|
||||
|
||||
如果以上方法都无法解决问题:
|
||||
|
||||
```bash
|
||||
# 查看帮助文档
|
||||
man proxychains4
|
||||
proxychains4 --help
|
||||
|
||||
# 查看系统日志
|
||||
sudo journalctl -xe | grep proxy
|
||||
dmesg | grep -i proxy
|
||||
|
||||
# 检查 proxychains 版本
|
||||
proxychains4 --version
|
||||
|
||||
# GitHub Issues
|
||||
# https://github.com/haad/proxychains/issues
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**提示:** 大多数问题都是由于代理服务未运行或端口配置错误造成的。首先确保代理服务正常运行。
|
||||
@@ -0,0 +1,123 @@
|
||||
TRANSLATED CONTENT:
|
||||
#!/bin/bash
|
||||
# Proxychains 快速配置脚本
|
||||
# 自动配置代理指向 127.0.0.1:9910
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "Proxychains 快速配置脚本"
|
||||
echo "=========================================="
|
||||
echo
|
||||
|
||||
# 检查 proxychains4 是否安装
|
||||
if ! command -v proxychains4 &> /dev/null; then
|
||||
echo "❌ proxychains4 未安装"
|
||||
echo
|
||||
echo "请先安装 proxychains4:"
|
||||
echo
|
||||
echo " Ubuntu/Debian:"
|
||||
echo " sudo apt install proxychains4"
|
||||
echo
|
||||
echo " CentOS/RHEL:"
|
||||
echo " sudo yum install epel-release"
|
||||
echo " sudo yum install proxychains-ng"
|
||||
echo
|
||||
echo " macOS:"
|
||||
echo " brew install proxychains-ng"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ proxychains4 已安装"
|
||||
echo
|
||||
|
||||
# 创建配置目录
|
||||
echo "📁 创建配置目录..."
|
||||
mkdir -p ~/.proxychains
|
||||
|
||||
# 创建配置文件
|
||||
echo "📝 创建配置文件..."
|
||||
cat > ~/.proxychains/proxychains.conf << 'EOF'
|
||||
# Proxychains 配置文件
|
||||
# 代理地址:127.0.0.1:9910
|
||||
|
||||
# 代理链模式(严格按顺序使用所有代理)
|
||||
strict_chain
|
||||
|
||||
# 代理 DNS 请求(避免 DNS 泄漏)
|
||||
proxy_dns
|
||||
|
||||
# DNS 设置
|
||||
remote_dns_subnet 224
|
||||
|
||||
# 超时设置(毫秒)
|
||||
tcp_read_time_out 15000
|
||||
tcp_connect_time_out 8000
|
||||
|
||||
# 代理列表
|
||||
[ProxyList]
|
||||
# HTTP 代理:127.0.0.1:9910
|
||||
http 127.0.0.1 9910
|
||||
|
||||
# 备用代理(取消注释以启用)
|
||||
#http 127.0.0.1 8080
|
||||
#socks5 127.0.0.1 1080
|
||||
EOF
|
||||
|
||||
# 设置权限
|
||||
chmod 644 ~/.proxychains/proxychains.conf
|
||||
|
||||
echo "✅ 配置文件已创建: ~/.proxychains/proxychains.conf"
|
||||
echo
|
||||
|
||||
# 测试代理服务
|
||||
echo "🔍 检查代理服务..."
|
||||
if curl -s -x http://127.0.0.1:9910 --connect-timeout 3 https://www.google.com > /dev/null 2>&1; then
|
||||
echo "✅ 代理服务 127.0.0.1:9910 可用"
|
||||
echo
|
||||
|
||||
# 测试 proxychains
|
||||
echo "🧪 测试 proxychains..."
|
||||
if proxychains4 curl -s --connect-timeout 5 https://ipinfo.io/json > /dev/null 2>&1; then
|
||||
echo "✅ Proxychains 配置成功!"
|
||||
echo
|
||||
echo "🎉 配置完成!可以开始使用了。"
|
||||
else
|
||||
echo "⚠️ Proxychains 测试失败"
|
||||
echo " 但配置文件已创建,请检查代理服务是否正常"
|
||||
fi
|
||||
else
|
||||
echo "⚠️ 代理服务 127.0.0.1:9910 无法连接"
|
||||
echo
|
||||
echo "请检查:"
|
||||
echo " 1. 代理服务是否运行"
|
||||
echo " 2. 代理端口是否正确(127.0.0.1:9910)"
|
||||
echo " 3. 防火墙设置"
|
||||
echo
|
||||
echo "检查代理端口:"
|
||||
echo " netstat -tunlp | grep 9910"
|
||||
echo " ss -tunlp | grep 9910"
|
||||
echo
|
||||
echo "配置文件已创建,代理服务就绪后即可使用。"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "=========================================="
|
||||
echo "使用方法:"
|
||||
echo "=========================================="
|
||||
echo
|
||||
echo " proxychains4 curl https://github.com"
|
||||
echo " proxychains4 git clone https://github.com/user/repo.git"
|
||||
echo " proxychains4 pip install package-name"
|
||||
echo " proxychains4 npm install package-name"
|
||||
echo
|
||||
echo "配置文件位置:"
|
||||
echo " ~/.proxychains/proxychains.conf"
|
||||
echo
|
||||
echo "查看配置:"
|
||||
echo " cat ~/.proxychains/proxychains.conf"
|
||||
echo
|
||||
echo "修改代理地址:"
|
||||
echo " nano ~/.proxychains/proxychains.conf"
|
||||
echo "=========================================="
|
||||
@@ -0,0 +1,274 @@
|
||||
---
|
||||
name: snapdom
|
||||
description: snapDOM is a fast, accurate DOM-to-image capture tool that converts HTML elements into scalable SVG images. Use for capturing HTML elements, converting DOM to images (SVG, PNG, JPG, WebP), preserving styles, fonts, and pseudo-elements.
|
||||
---
|
||||
|
||||
# SnapDOM Skill
|
||||
|
||||
Fast, dependency-free DOM-to-image capture library for converting HTML elements into scalable SVG or raster image formats.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use SnapDOM when you need to:
|
||||
- Convert HTML elements to images (SVG, PNG, JPG, WebP)
|
||||
- Capture styled DOM with pseudo-elements and shadows
|
||||
- Export elements with embedded fonts and icons
|
||||
- Create screenshots with custom dimensions or scaling
|
||||
- Handle CORS-blocked resources using proxy fallback
|
||||
- Implement custom rendering pipelines with plugins
|
||||
- Optimize performance on large or complex elements
|
||||
|
||||
## Key Features
|
||||
|
||||
### Universal Export Options
|
||||
- **SVG** - Scalable vector format, embeds all styles
|
||||
- **PNG, JPG, WebP** - Raster formats with configurable quality
|
||||
- **Canvas** - Get raw Canvas element for further processing
|
||||
- **Blob** - Raw binary data for custom handling
|
||||
|
||||
### Performance
|
||||
- Ultra-fast capture (1.6ms for small elements, ~171ms for 4000×2000)
|
||||
- **No dependencies** - Uses standard Web APIs only
|
||||
- Outperforms html2canvas by 10-40x on complex elements
|
||||
|
||||
### Style Support
|
||||
- Embedded fonts (including icon fonts)
|
||||
- CSS pseudo-elements (::before, ::after)
|
||||
- CSS counters
|
||||
- CSS line-clamp
|
||||
- Transform and shadow effects
|
||||
- Shadow DOM content
|
||||
|
||||
### Advanced Capabilities
|
||||
- Same-origin iframe support
|
||||
- CORS proxy fallback for blocked assets
|
||||
- Plugin system for custom transformations
|
||||
- Straighten transforms (remove rotate/translate)
|
||||
- Selective element exclusion
|
||||
- Tight bounding box calculation
|
||||
|
||||
## Installation
|
||||
|
||||
### NPM/Yarn
|
||||
```bash
|
||||
npm install @zumer/snapdom
|
||||
# or
|
||||
yarn add @zumer/snapdom
|
||||
```
|
||||
|
||||
### CDN (ES Module)
|
||||
```html
|
||||
<script type="module">
|
||||
import { snapdom } from "https://unpkg.com/@zumer/snapdom/dist/snapdom.mjs";
|
||||
</script>
|
||||
```
|
||||
|
||||
### CDN (UMD)
|
||||
```html
|
||||
<script src="https://unpkg.com/@zumer/snapdom/dist/snapdom.umd.js"></script>
|
||||
```
|
||||
|
||||
## Quick Start Examples
|
||||
|
||||
### Basic Reusable Capture
|
||||
```javascript
|
||||
// Create reusable capture object
|
||||
const result = await snapdom(document.querySelector('#target'));
|
||||
|
||||
// Export to different formats
|
||||
const png = await result.toPng();
|
||||
const jpg = await result.toJpg();
|
||||
const svg = await result.toSvg();
|
||||
const canvas = await result.toCanvas();
|
||||
const blob = await result.toBlob();
|
||||
|
||||
// Use the result
|
||||
document.body.appendChild(png);
|
||||
```
|
||||
|
||||
### One-Step Export
|
||||
```javascript
|
||||
// Direct export without intermediate object
|
||||
const png = await snapdom.toPng(document.querySelector('#target'));
|
||||
const svg = await snapdom.toSvg(element);
|
||||
```
|
||||
|
||||
### Download Element
|
||||
```javascript
|
||||
// Automatically download as file
|
||||
await snapdom.download(element, 'screenshot.png');
|
||||
await snapdom.download(element, 'image.svg');
|
||||
```
|
||||
|
||||
### With Options
|
||||
```javascript
|
||||
const result = await snapdom(element, {
|
||||
scale: 2, // 2x resolution
|
||||
width: 800, // Custom width
|
||||
height: 600, // Custom height
|
||||
embedFonts: true, // Include @font-face
|
||||
exclude: '.no-capture', // Hide elements
|
||||
useProxy: true, // Enable CORS proxy
|
||||
straighten: true, // Remove transforms
|
||||
noShadows: false // Keep shadows
|
||||
});
|
||||
|
||||
const png = await result.toPng({ quality: 0.95 });
|
||||
```
|
||||
|
||||
## Essential Options Reference
|
||||
|
||||
| Option | Type | Purpose |
|
||||
|--------|------|---------|
|
||||
| `scale` | Number | Scale output (e.g., 2 for 2x resolution) |
|
||||
| `width` | Number | Custom output width in pixels |
|
||||
| `height` | Number | Custom output height in pixels |
|
||||
| `embedFonts` | Boolean | Include non-icon @font-face rules |
|
||||
| `useProxy` | String\|Boolean | Enable CORS proxy (URL or true for default) |
|
||||
| `exclude` | String | CSS selector for elements to hide |
|
||||
| `straighten` | Boolean | Remove translate/rotate transforms |
|
||||
| `noShadows` | Boolean | Strip shadow effects |
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Responsive Screenshots
|
||||
```javascript
|
||||
// Capture at different scales
|
||||
const mobile = await snapdom.toPng(element, { scale: 1 });
|
||||
const tablet = await snapdom.toPng(element, { scale: 1.5 });
|
||||
const desktop = await snapdom.toPng(element, { scale: 2 });
|
||||
```
|
||||
|
||||
### Exclude Elements
|
||||
```javascript
|
||||
// Hide specific elements from capture
|
||||
const png = await snapdom.toPng(element, {
|
||||
exclude: '.controls, .watermark, [data-no-capture]'
|
||||
});
|
||||
```
|
||||
|
||||
### Fixed Dimensions
|
||||
```javascript
|
||||
// Capture with specific size
|
||||
const result = await snapdom(element, {
|
||||
width: 1200,
|
||||
height: 630 // Standard social media size
|
||||
});
|
||||
```
|
||||
|
||||
### CORS Handling
|
||||
```javascript
|
||||
// Fallback for CORS-blocked resources
|
||||
const png = await snapdom.toPng(element, {
|
||||
useProxy: 'https://cors.example.com/?' // Custom proxy
|
||||
});
|
||||
```
|
||||
|
||||
### Plugin System (Beta)
|
||||
```javascript
|
||||
// Extend with custom exporters
|
||||
snapdom.plugins([pluginFactory, { colorOverlay: true }]);
|
||||
|
||||
// Hook into lifecycle
|
||||
defineExports(context) {
|
||||
return {
|
||||
pdf: async (ctx, opts) => { /* generate PDF */ }
|
||||
};
|
||||
}
|
||||
|
||||
// Lifecycle hooks available:
|
||||
// beforeSnap → beforeClone → afterClone →
|
||||
// beforeRender → beforeExport → afterExport
|
||||
```
|
||||
|
||||
## Performance Comparison
|
||||
|
||||
SnapDOM significantly outperforms html2canvas:
|
||||
|
||||
| Scenario | SnapDOM | html2canvas | Improvement |
|
||||
|----------|---------|-------------|-------------|
|
||||
| Small (200×100) | 1.6ms | 68ms | 42x faster |
|
||||
| Medium (800×600) | 12ms | 280ms | 23x faster |
|
||||
| Large (4000×2000) | 171ms | 1,800ms | 10x faster |
|
||||
|
||||
## Development
|
||||
|
||||
### Setup
|
||||
```bash
|
||||
git clone https://github.com/zumerlab/snapdom.git
|
||||
cd snapdom
|
||||
npm install
|
||||
```
|
||||
|
||||
### Build
|
||||
```bash
|
||||
npm run compile
|
||||
```
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## Browser Support
|
||||
|
||||
- Chrome/Edge 90+
|
||||
- Firefox 88+
|
||||
- Safari 14+
|
||||
- Mobile browsers (iOS Safari 14+, Chrome Mobile)
|
||||
|
||||
## Resources
|
||||
|
||||
### Documentation
|
||||
- **Official Website:** https://snapdom.dev/
|
||||
- **GitHub Repository:** https://github.com/zumerlab/snapdom
|
||||
- **NPM Package:** https://www.npmjs.com/package/@zumer/snapdom
|
||||
- **License:** MIT
|
||||
|
||||
### scripts/
|
||||
Add helper scripts here for automation, e.g.:
|
||||
- `batch-screenshot.js` - Capture multiple elements
|
||||
- `pdf-export.js` - Convert snapshots to PDF
|
||||
- `compare-outputs.js` - Compare SVG vs PNG quality
|
||||
|
||||
### assets/
|
||||
Add templates and examples:
|
||||
- HTML templates for common capture scenarios
|
||||
- CSS frameworks pre-configured with snapdom
|
||||
- Boilerplate projects integrating snapdom
|
||||
|
||||
## Related Tools
|
||||
|
||||
- **html2canvas** - Alternative DOM capture (slower but more compatible)
|
||||
- **Orbit CSS Toolkit** - Companion toolkit by Zumerlab (https://github.com/zumerlab/orbit)
|
||||
|
||||
## Tips & Best Practices
|
||||
|
||||
1. **Performance**: Use `scale` instead of `width`/`height` for better performance
|
||||
2. **Fonts**: Set `embedFonts: true` to ensure custom fonts appear correctly
|
||||
3. **CORS Issues**: Use `useProxy: true` if images fail to load
|
||||
4. **Large Elements**: Break into smaller chunks for complex pages
|
||||
5. **Quality**: For PNG/JPG, use `quality: 0.95` for best quality
|
||||
6. **SVG Vectors**: Prefer SVG export for charts and graphics
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Elements Not Rendering
|
||||
- Check if element has sufficient height/width
|
||||
- Verify CSS is fully loaded before capture
|
||||
- Try `straighten: false` if transforms are causing issues
|
||||
|
||||
### Missing Fonts
|
||||
- Set `embedFonts: true`
|
||||
- Ensure fonts are loaded before calling snapdom
|
||||
- Check browser console for font loading errors
|
||||
|
||||
### CORS Issues
|
||||
- Enable `useProxy: true`
|
||||
- Use custom proxy URL if default fails
|
||||
- Check if resources are from same origin
|
||||
|
||||
### Performance Issues
|
||||
- Reduce `scale` value
|
||||
- Use `noShadows: true` to skip shadow rendering
|
||||
- Consider splitting large captures into smaller sections
|
||||
@@ -0,0 +1,7 @@
|
||||
# Snapdom Documentation Index
|
||||
|
||||
## Categories
|
||||
|
||||
### Other
|
||||
**File:** `other.md`
|
||||
**Pages:** 1
|
||||
@@ -0,0 +1,53 @@
|
||||
# Snapdom - Other
|
||||
|
||||
**Pages:** 1
|
||||
|
||||
---
|
||||
|
||||
## snapDOM – HTML to Image capture with superior accuracy and speed - Now with Plugins!
|
||||
|
||||
**URL:** https://snapdom.dev/
|
||||
|
||||
**Contents:**
|
||||
- 🏁 Benchmark: snapDOM vs html2canvas
|
||||
- 📦 Basic
|
||||
- Hello SnapDOM!
|
||||
- Transforms & Shadows
|
||||
- 🅰️ ASCII Plugin
|
||||
- 🕒 Timestamp Plugin
|
||||
- 🚀 Fun Transition
|
||||
- Orbit CSS toolkit - Go to repo
|
||||
- 🔤 Google Fonts
|
||||
- Unique Typography!
|
||||
|
||||
Each library will capture the same DOM element to canvas 5 times. We'll calculate average speed and show the winner.
|
||||
|
||||
Capture it just with outerTransforms / outerShadows.
|
||||
|
||||
I'm dancing and changing color!
|
||||
|
||||
Google Fonts with embedFonts: true.
|
||||
|
||||
**Examples:**
|
||||
|
||||
Example 1 (unknown):
|
||||
```unknown
|
||||
outerTransforms
|
||||
```
|
||||
|
||||
Example 2 (unknown):
|
||||
```unknown
|
||||
outerShadows
|
||||
```
|
||||
|
||||
Example 3 (unknown):
|
||||
```unknown
|
||||
outerTransforms
|
||||
```
|
||||
|
||||
Example 4 (unknown):
|
||||
```unknown
|
||||
outerShadows
|
||||
```
|
||||
|
||||
---
|
||||
@@ -0,0 +1,760 @@
|
||||
---
|
||||
name: telegram-dev
|
||||
description: A full-stack guide to Telegram ecosystem development - covering Bot API, Mini Apps (Web Apps), and MTProto client development. Includes complete development resources for message handling, payments, inline mode, webhooks, authentication, storage, sensor APIs, and more.
|
||||
---
|
||||
|
||||
# Telegram Ecosystem Development Skill
|
||||
|
||||
A comprehensive guide to Telegram development, covering the full technology stack for Bot development, Mini Apps (Web Apps), and client development.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need help with the following:
|
||||
- Developing a Telegram Bot (message bot)
|
||||
- Creating Telegram Mini Apps
|
||||
- Building a custom Telegram client
|
||||
- Integrating Telegram payments and business features
|
||||
- Implementing webhooks and long polling
|
||||
- Using Telegram authentication and storage
|
||||
- Handling messages, media, and files
|
||||
- Implementing inline mode and keyboards
|
||||
|
||||
## Overview of the Telegram Development Ecosystem
|
||||
|
||||
### Three Core APIs
|
||||
|
||||
1. **Bot API** - For creating bot programs
|
||||
- Simple to use HTTP interface
|
||||
- Automatically handles encryption and communication
|
||||
- Suitable for: chatbots, automation tools
|
||||
|
||||
2. **Mini Apps API** (Web Apps) - For creating web applications
|
||||
- JavaScript interface
|
||||
- Runs inside Telegram
|
||||
- Suitable for: mini-apps, games, e-commerce
|
||||
|
||||
3. **Telegram API & TDLib** - For creating clients
|
||||
- Full implementation of the Telegram protocol
|
||||
- Supports all platforms
|
||||
- Suitable for: custom clients, enterprise applications
|
||||
|
||||
## Bot API Development
|
||||
|
||||
### Quick Start
|
||||
|
||||
**API Endpoint:**
|
||||
```
|
||||
https://api.telegram.org/bot<TOKEN>/METHOD_NAME
|
||||
```
|
||||
|
||||
**Get a Bot Token:**
|
||||
1. Talk to @BotFather
|
||||
2. Send `/newbot`
|
||||
3. Follow the prompts to set a name
|
||||
4. Get the token
|
||||
|
||||
**First Bot (Python):**
|
||||
```python
|
||||
import requests
|
||||
|
||||
BOT_TOKEN = "your_bot_token_here"
|
||||
API_URL = f"https://api.telegram.org/bot{BOT_TOKEN}"
|
||||
|
||||
# Send a message
|
||||
def send_message(chat_id, text):
|
||||
url = f"{API_URL}/sendMessage"
|
||||
data = {"chat_id": chat_id, "text": text}
|
||||
return requests.post(url, json=data)
|
||||
|
||||
# Get updates (long polling)
|
||||
def get_updates(offset=None):
|
||||
url = f"{API_URL}/getUpdates"
|
||||
params = {"offset": offset, "timeout": 30}
|
||||
return requests.get(url, params=params).json()
|
||||
|
||||
# Main loop
|
||||
offset = None
|
||||
while True:
|
||||
updates = get_updates(offset)
|
||||
for update in updates.get("result", []):
|
||||
chat_id = update["message"]["chat"]["id"]
|
||||
text = update["message"]["text"]
|
||||
|
||||
# Reply to the message
|
||||
send_message(chat_id, f"You said: {text}")
|
||||
|
||||
offset = update["update_id"] + 1
|
||||
```
|
||||
|
||||
### Core API Methods
|
||||
|
||||
**Update Management:**
|
||||
- `getUpdates` - Get updates via long polling
|
||||
- `setWebhook` - Set a webhook
|
||||
- `deleteWebhook` - Delete a webhook
|
||||
- `getWebhookInfo` - Query webhook status
|
||||
|
||||
**Message Operations:**
|
||||
- `sendMessage` - Send a text message
|
||||
- `sendPhoto` / `sendVideo` / `sendDocument` - Send media
|
||||
- `sendAudio` / `sendVoice` - Send audio
|
||||
- `sendLocation` / `sendVenue` - Send a location
|
||||
- `editMessageText` - Edit a message
|
||||
- `deleteMessage` - Delete a message
|
||||
- `forwardMessage` / `copyMessage` - Forward/copy a message
|
||||
|
||||
**Interactive Elements:**
|
||||
- `sendPoll` - Send a poll (up to 12 options)
|
||||
- Inline Keyboard (InlineKeyboardMarkup)
|
||||
- Reply Keyboard (ReplyKeyboardMarkup)
|
||||
- `answerCallbackQuery` - Respond to a callback query
|
||||
|
||||
**File Operations:**
|
||||
- `getFile` - Get file information
|
||||
- `downloadFile` - Download a file
|
||||
- Supports files up to 2GB (in local Bot API mode)
|
||||
|
||||
**Payment Features:**
|
||||
- `sendInvoice` - Send an invoice
|
||||
- `answerPreCheckoutQuery` - Process a payment
|
||||
- Telegram Stars payment (up to 10,000 Stars)
|
||||
|
||||
### Webhook Configuration
|
||||
|
||||
**Set a 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 Example:**
|
||||
```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"]
|
||||
|
||||
# Send a reply
|
||||
requests.post(
|
||||
f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage",
|
||||
json={"chat_id": chat_id, "text": f"Received: {text}"}
|
||||
)
|
||||
|
||||
return "OK"
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(port=5000)
|
||||
```
|
||||
|
||||
**Webhook Requirements:**
|
||||
- Must use HTTPS
|
||||
- Supports TLS 1.2+
|
||||
- Ports: 443, 80, 88, 8443
|
||||
- Publicly accessible URL
|
||||
|
||||
### Inline Keyboard
|
||||
|
||||
**Create an Inline Keyboard:**
|
||||
```python
|
||||
def send_inline_keyboard(chat_id):
|
||||
keyboard = {
|
||||
"inline_keyboard": [
|
||||
[
|
||||
{"text": "Button 1", "callback_data": "btn1"},
|
||||
{"text": "Button 2", "callback_data": "btn2"}
|
||||
],
|
||||
[
|
||||
{"text": "Open Link", "url": "https://example.com"}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
requests.post(
|
||||
f"{API_URL}/sendMessage",
|
||||
json={
|
||||
"chat_id": chat_id,
|
||||
"text": "Choose an option:",
|
||||
"reply_markup": keyboard
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**Handle Callbacks:**
|
||||
```python
|
||||
def handle_callback_query(callback_query):
|
||||
query_id = callback_query["id"]
|
||||
data = callback_query["data"]
|
||||
chat_id = callback_query["message"]["chat"]["id"]
|
||||
|
||||
# Respond to the callback
|
||||
requests.post(
|
||||
f"{API_URL}/answerCallbackQuery",
|
||||
json={"callback_query_id": query_id, "text": f"You clicked {data}"}
|
||||
)
|
||||
|
||||
# Update the message
|
||||
requests.post(
|
||||
f"{API_URL}/editMessageText",
|
||||
json={
|
||||
"chat_id": chat_id,
|
||||
"message_id": callback_query["message"]["message_id"],
|
||||
"text": f"You chose: {data}"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Inline Mode
|
||||
|
||||
**Configure Inline Mode:**
|
||||
Talk to @BotFather and send `/setinline`
|
||||
|
||||
**Handle Inline Queries:**
|
||||
```python
|
||||
def handle_inline_query(inline_query):
|
||||
query_id = inline_query["id"]
|
||||
query_text = inline_query["query"]
|
||||
|
||||
# Create results
|
||||
results = [
|
||||
{
|
||||
"type": "article",
|
||||
"id": "1",
|
||||
"title": "Result 1",
|
||||
"input_message_content": {
|
||||
"message_text": f"You searched for: {query_text}"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
requests.post(
|
||||
f"{API_URL}/answerInlineQuery",
|
||||
json={"inline_query_id": query_id, "results": results}
|
||||
)
|
||||
```
|
||||
|
||||
## Mini Apps (Web Apps) Development
|
||||
|
||||
### Initialize a Mini App
|
||||
|
||||
**HTML Template:**
|
||||
```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">Main Button</button>
|
||||
|
||||
<script>
|
||||
// Get the Telegram WebApp object
|
||||
const tg = window.Telegram.WebApp;
|
||||
|
||||
// Notify Telegram that the app is ready
|
||||
tg.ready();
|
||||
|
||||
// Expand to full screen
|
||||
tg.expand();
|
||||
|
||||
// Display user information
|
||||
const user = tg.initDataUnsafe?.user;
|
||||
if (user) {
|
||||
console.log("Username:", user.first_name);
|
||||
console.log("User ID:", user.id);
|
||||
}
|
||||
|
||||
// Configure the main button
|
||||
tg.MainButton.text = "Submit";
|
||||
tg.MainButton.show();
|
||||
tg.MainButton.onClick(() => {
|
||||
// Send data to the Bot
|
||||
tg.sendData(JSON.stringify({action: "submit"}));
|
||||
});
|
||||
|
||||
// Add a back button
|
||||
tg.BackButton.show();
|
||||
tg.BackButton.onClick(() => {
|
||||
tg.close();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### Mini App Core API
|
||||
|
||||
**WebApp Object Main Properties:**
|
||||
```javascript
|
||||
// Initialization data
|
||||
tg.initData // Raw initialization string
|
||||
tg.initDataUnsafe // Parsed object
|
||||
|
||||
// User and theme
|
||||
tg.initDataUnsafe.user // User information
|
||||
tg.themeParams // Theme colors
|
||||
tg.colorScheme // 'light' or 'dark'
|
||||
|
||||
// Status
|
||||
tg.isExpanded // Whether it's full screen
|
||||
tg.isFullscreen // Whether it's full screen
|
||||
tg.viewportHeight // Viewport height
|
||||
tg.platform // Platform type
|
||||
|
||||
// Version
|
||||
tg.version // WebApp version
|
||||
```
|
||||
|
||||
**Main Methods:**
|
||||
```javascript
|
||||
// Window control
|
||||
tg.ready() // Mark the app as ready
|
||||
tg.expand() // Expand to full height
|
||||
tg.close() // Close the Mini App
|
||||
tg.requestFullscreen() // Request full screen
|
||||
|
||||
// Data sending
|
||||
tg.sendData(data) // Send data to the Bot
|
||||
|
||||
// Navigation
|
||||
tg.openLink(url) // Open an external link
|
||||
tg.openTelegramLink(url) // Open a Telegram link
|
||||
|
||||
// Dialogs
|
||||
tg.showPopup(params, callback) // Show a popup
|
||||
tg.showAlert(message) // Show an alert
|
||||
tg.showConfirm(message) // Show a confirmation
|
||||
|
||||
// Sharing
|
||||
tg.shareMessage(message) // Share a message
|
||||
tg.shareUrl(url) // Share a link
|
||||
```
|
||||
|
||||
### UI Controls
|
||||
|
||||
**Main Button (MainButton):**
|
||||
```javascript
|
||||
tg.MainButton.setText("Click Me");
|
||||
tg.MainButton.show();
|
||||
tg.MainButton.enable();
|
||||
tg.MainButton.showProgress(); // Show loading
|
||||
tg.MainButton.hideProgress();
|
||||
|
||||
tg.MainButton.onClick(() => {
|
||||
console.log("Main button clicked");
|
||||
});
|
||||
```
|
||||
|
||||
**Secondary Button (SecondaryButton):**
|
||||
```javascript
|
||||
tg.SecondaryButton.setText("Cancel");
|
||||
tg.SecondaryButton.show();
|
||||
tg.SecondaryButton.onClick(() => {
|
||||
tg.close();
|
||||
});
|
||||
```
|
||||
|
||||
**Back Button (BackButton):**
|
||||
```javascript
|
||||
tg.BackButton.show();
|
||||
tg.BackButton.onClick(() => {
|
||||
// Back logic
|
||||
});
|
||||
```
|
||||
|
||||
**Haptic Feedback:**
|
||||
```javascript
|
||||
tg.HapticFeedback.impactOccurred('light'); // light, medium, heavy
|
||||
tg.HapticFeedback.notificationOccurred('success'); // success, warning, error
|
||||
tg.HapticFeedback.selectionChanged();
|
||||
```
|
||||
|
||||
### Storage API
|
||||
|
||||
**Cloud Storage:**
|
||||
```javascript
|
||||
// Save data
|
||||
tg.CloudStorage.setItem('key', 'value', (error, success) => {
|
||||
if (success) console.log('Saved successfully');
|
||||
});
|
||||
|
||||
// Get data
|
||||
tg.CloudStorage.getItem('key', (error, value) => {
|
||||
console.log('Value:', value);
|
||||
});
|
||||
|
||||
// Delete data
|
||||
tg.CloudStorage.removeItem('key');
|
||||
|
||||
// Get all keys
|
||||
tg.CloudStorage.getKeys((error, keys) => {
|
||||
console.log('All keys:', keys);
|
||||
});
|
||||
```
|
||||
|
||||
**Local Storage:**
|
||||
```javascript
|
||||
// Normal local storage
|
||||
localStorage.setItem('key', 'value');
|
||||
const value = localStorage.getItem('key');
|
||||
|
||||
// Secure storage (requires biometrics)
|
||||
tg.SecureStorage.setItem('secret', 'value', callback);
|
||||
tg.SecureStorage.getItem('secret', callback);
|
||||
```
|
||||
|
||||
### Biometric Authentication
|
||||
|
||||
```javascript
|
||||
const bioManager = tg.BiometricManager;
|
||||
|
||||
// Initialize
|
||||
bioManager.init(() => {
|
||||
if (bioManager.isInited) {
|
||||
console.log('Supported type:', bioManager.biometricType);
|
||||
// 'finger', 'face', 'unknown'
|
||||
|
||||
if (bioManager.isAccessGranted) {
|
||||
// Already authorized, can be used
|
||||
} else {
|
||||
// Request authorization
|
||||
bioManager.requestAccess({reason: 'Need to verify identity'}, (success) => {
|
||||
if (success) {
|
||||
console.log('Authorization successful');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Perform authentication
|
||||
bioManager.authenticate({reason: 'Confirm action'}, (success, token) => {
|
||||
if (success) {
|
||||
console.log('Authentication successful, token:', token);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Location and Sensors
|
||||
|
||||
**Get Location:**
|
||||
```javascript
|
||||
tg.LocationManager.init(() => {
|
||||
if (tg.LocationManager.isInited) {
|
||||
tg.LocationManager.getLocation((location) => {
|
||||
console.log('Latitude:', location.latitude);
|
||||
console.log('Longitude:', location.longitude);
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**Accelerometer:**
|
||||
```javascript
|
||||
tg.Accelerometer.start({refresh_rate: 100}, (started) => {
|
||||
if (started) {
|
||||
tg.Accelerometer.onEvent((event) => {
|
||||
console.log('Acceleration:', event.x, event.y, event.z);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Stop
|
||||
tg.Accelerometer.stop();
|
||||
```
|
||||
|
||||
**Gyroscope:**
|
||||
```javascript
|
||||
tg.Gyroscope.start({refresh_rate: 100}, callback);
|
||||
tg.Gyroscope.onEvent((event) => {
|
||||
console.log('Rotation speed:', event.x, event.y, event.z);
|
||||
});
|
||||
```
|
||||
|
||||
**Device Orientation:**
|
||||
```javascript
|
||||
tg.DeviceOrientation.start({refresh_rate: 100}, callback);
|
||||
tg.DeviceOrientation.onEvent((event) => {
|
||||
console.log('Orientation:', event.absolute, event.alpha, event.beta, event.gamma);
|
||||
});
|
||||
```
|
||||
|
||||
### Payment Integration
|
||||
|
||||
**Initiate a Payment (Telegram Stars):**
|
||||
```javascript
|
||||
tg.openInvoice('https://t.me/$invoice_link', (status) => {
|
||||
if (status === 'paid') {
|
||||
console.log('Payment successful');
|
||||
} else if (status === 'cancelled') {
|
||||
console.log('Payment cancelled');
|
||||
} else if (status === 'failed') {
|
||||
console.log('Payment failed');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Data Validation
|
||||
|
||||
**Server-side Validation of initData (Python):**
|
||||
```python
|
||||
import hmac
|
||||
import hashlib
|
||||
from urllib.parse import parse_qs
|
||||
|
||||
def validate_init_data(init_data, bot_token):
|
||||
# Parse the data
|
||||
parsed = parse_qs(init_data)
|
||||
received_hash = parsed.get('hash', [''])[0]
|
||||
|
||||
# Remove the hash
|
||||
data_check_arr = []
|
||||
for key, value in parsed.items():
|
||||
if key != 'hash':
|
||||
data_check_arr.append(f"{key}={value[0]}")
|
||||
|
||||
# Sort
|
||||
data_check_arr.sort()
|
||||
data_check_string = '\n'.join(data_check_arr)
|
||||
|
||||
# Calculate the secret key
|
||||
secret_key = hmac.new(
|
||||
b"WebAppData",
|
||||
bot_token.encode(),
|
||||
hashlib.sha256
|
||||
).digest()
|
||||
|
||||
# Calculate the hash
|
||||
calculated_hash = hmac.new(
|
||||
secret_key,
|
||||
data_check_string.encode(),
|
||||
hashlib.sha256
|
||||
).hexdigest()
|
||||
|
||||
return calculated_hash == received_hash
|
||||
```
|
||||
|
||||
### Launching a Mini App
|
||||
|
||||
**From a Keyboard Button:**
|
||||
```python
|
||||
keyboard = {
|
||||
"keyboard": [[
|
||||
{
|
||||
"text": "Open App",
|
||||
"web_app": {"url": "https://yourdomain.com/app"}
|
||||
}
|
||||
]],
|
||||
"resize_keyboard": True
|
||||
}
|
||||
|
||||
requests.post(
|
||||
f"{API_URL}/sendMessage",
|
||||
json={
|
||||
"chat_id": chat_id,
|
||||
"text": "Click the button to open the app",
|
||||
"reply_markup": keyboard
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**From an Inline Button:**
|
||||
```python
|
||||
keyboard = {
|
||||
"inline_keyboard": [[
|
||||
{
|
||||
"text": "Launch App",
|
||||
"web_app": {"url": "https://yourdomain.com/app"}
|
||||
}
|
||||
]]
|
||||
}
|
||||
```
|
||||
|
||||
**From the Menu Button:**
|
||||
Talk to @BotFather:
|
||||
```
|
||||
/setmenubutton
|
||||
→ Choose your Bot
|
||||
→ Provide URL: https://yourdomain.com/app
|
||||
```
|
||||
|
||||
## Client Development (TDLib)
|
||||
|
||||
### Using TDLib
|
||||
|
||||
**Python Example (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()
|
||||
|
||||
# Send a message
|
||||
result = tg.send_message(
|
||||
chat_id=123456789,
|
||||
text='Hello from TDLib!'
|
||||
)
|
||||
|
||||
# Get chat list
|
||||
result = tg.get_chats()
|
||||
result.wait()
|
||||
chats = result.update
|
||||
|
||||
print(chats)
|
||||
|
||||
tg.stop()
|
||||
```
|
||||
|
||||
### MTProto Protocol
|
||||
|
||||
**Features:**
|
||||
- End-to-end encryption
|
||||
- High performance
|
||||
- Supports all Telegram features
|
||||
- Requires API ID/Hash (from https://my.telegram.org)
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Bot Development
|
||||
|
||||
1. **Error Handling**
|
||||
```python
|
||||
try:
|
||||
response = requests.post(url, json=data, timeout=10)
|
||||
response.raise_for_status()
|
||||
except requests.exceptions.RequestException as e:
|
||||
print(f"Request failed: {e}")
|
||||
```
|
||||
|
||||
2. **Rate Limiting**
|
||||
- Group messages: max 20/minute
|
||||
- Private messages: max 30/second
|
||||
- Global limits: avoid being too frequent
|
||||
|
||||
3. **Use Webhooks instead of Long Polling**
|
||||
- More efficient
|
||||
- Lower latency
|
||||
- Better scalability
|
||||
|
||||
4. **Data Validation**
|
||||
- Always validate initData
|
||||
- Don't trust client-side data
|
||||
- Server-side validation for all operations
|
||||
|
||||
### Mini Apps Development
|
||||
|
||||
1. **Responsive Design**
|
||||
```javascript
|
||||
// Listen for theme changes
|
||||
tg.onEvent('themeChanged', () => {
|
||||
document.body.style.backgroundColor = tg.themeParams.bg_color;
|
||||
});
|
||||
|
||||
// Listen for viewport changes
|
||||
tg.onEvent('viewportChanged', () => {
|
||||
console.log('New height:', tg.viewportHeight);
|
||||
});
|
||||
```
|
||||
|
||||
2. **Performance Optimization**
|
||||
- Minimize JavaScript bundle size
|
||||
- Use lazy loading
|
||||
- Optimize images and resources
|
||||
|
||||
3. **User Experience**
|
||||
- Adapt to dark/light themes
|
||||
- Use native UI controls (MainButton, etc.)
|
||||
- Provide haptic feedback
|
||||
- Respond quickly to user actions
|
||||
|
||||
4. **Security Considerations**
|
||||
- HTTPS is mandatory
|
||||
- Validate initData
|
||||
- Don't store sensitive information on the client
|
||||
- Use SecureStorage for secrets
|
||||
|
||||
## Common Libraries and Tools
|
||||
|
||||
### Python
|
||||
- `python-telegram-bot` - A powerful Bot framework
|
||||
- `aiogram` - An asynchronous Bot framework
|
||||
- `telethon` / `pyrogram` - MTProto clients
|
||||
|
||||
### Node.js
|
||||
- `node-telegram-bot-api` - Bot API wrapper
|
||||
- `telegraf` - Modern Bot framework
|
||||
- `grammy` - Lightweight framework
|
||||
|
||||
### Other Languages
|
||||
- PHP: `telegram-bot-sdk`
|
||||
- Go: `telegram-bot-api`
|
||||
- Java: `TelegramBots`
|
||||
- C#: `Telegram.Bot`
|
||||
|
||||
## Reference Resources
|
||||
|
||||
### Official Documentation
|
||||
- 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 Repositories
|
||||
- Bot API Server: https://github.com/tdlib/telegram-bot-api
|
||||
- Android Client: https://github.com/DrKLO/Telegram
|
||||
- Desktop Client: https://github.com/telegramdesktop/tdesktop
|
||||
- Official Organization: https://github.com/orgs/TelegramOfficial/repositories
|
||||
|
||||
### Tools
|
||||
- @BotFather - Create and manage Bots
|
||||
- https://my.telegram.org - Get API ID/Hash
|
||||
- Telegram Web App test environment
|
||||
|
||||
## Reference Files
|
||||
|
||||
This skill includes a detailed index of Telegram development resources and complete implementation templates:
|
||||
|
||||
- **index.md** - A complete index of resources and quick navigation
|
||||
- **Telegram_Bot_按钮和键盘实现模板.md** - An implementation guide for interactive buttons and keyboards (404 lines, 12 KB)
|
||||
- Detailed explanation of three button types (Inline/Reply/Command Menu)
|
||||
- Comparison of implementations with python-telegram-bot and Telethon
|
||||
- Complete ready-to-use code examples and project structure
|
||||
- Handler system, error handling, and deployment方案
|
||||
- **动态视图对齐实现文档.md** - A guide to data display in Telegram (407 lines, 12 KB)
|
||||
- Intelligent dynamic alignment algorithm (three-step method, O(n×m) complexity)
|
||||
- Perfect alignment solution for monospaced font environments
|
||||
- Intelligent numerical formatting system (automatic B/M/K abbreviation)
|
||||
- Professional display for leaderboards and data tables
|
||||
|
||||
These concise guides provide core solutions for Telegram Bot development:
|
||||
- All implementation methods for button and keyboard interaction
|
||||
- Professional formatting and display of messages and data
|
||||
- Practical best practices and quick references
|
||||
|
||||
---
|
||||
|
||||
**Master full-stack development of the Telegram ecosystem with this skill!**
|
||||
+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!**
|
||||
@@ -0,0 +1,439 @@
|
||||
TRANSLATED CONTENT:
|
||||
# twscrape
|
||||
|
||||
Python library for scraping Twitter/X data using GraphQL API with account rotation and session management.
|
||||
|
||||
## When to use this skill
|
||||
|
||||
Use this skill when:
|
||||
- Working with Twitter/X data extraction and scraping
|
||||
- Need to bypass Twitter API limitations with account rotation
|
||||
- Building social media monitoring or analytics tools
|
||||
- Extracting tweets, user profiles, followers, trends from Twitter/X
|
||||
- Need async/parallel scraping operations for large-scale data collection
|
||||
- Looking for alternatives to official Twitter API
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install twscrape
|
||||
```
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from twscrape import API, gather
|
||||
|
||||
async def main():
|
||||
api = API() # Uses accounts.db by default
|
||||
|
||||
# Add accounts (with cookies - more stable)
|
||||
cookies = "abc=12; ct0=xyz"
|
||||
await api.pool.add_account("user1", "pass1", "email@example.com", "mail_pass", cookies=cookies)
|
||||
|
||||
# Or add accounts (with login/password - less stable)
|
||||
await api.pool.add_account("user2", "pass2", "email2@example.com", "mail_pass2")
|
||||
await api.pool.login_all()
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
### Common Operations
|
||||
|
||||
```python
|
||||
# Search tweets
|
||||
await gather(api.search("elon musk", limit=20))
|
||||
|
||||
# Get user info
|
||||
await api.user_by_login("xdevelopers")
|
||||
user = await api.user_by_id(2244994945)
|
||||
|
||||
# Get user tweets
|
||||
await gather(api.user_tweets(user_id, limit=20))
|
||||
await gather(api.user_tweets_and_replies(user_id, limit=20))
|
||||
await gather(api.user_media(user_id, limit=20))
|
||||
|
||||
# Get followers/following
|
||||
await gather(api.followers(user_id, limit=20))
|
||||
await gather(api.following(user_id, limit=20))
|
||||
|
||||
# Tweet operations
|
||||
await api.tweet_details(tweet_id)
|
||||
await gather(api.retweeters(tweet_id, limit=20))
|
||||
await gather(api.tweet_replies(tweet_id, limit=20))
|
||||
|
||||
# Trends
|
||||
await gather(api.trends("news"))
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Multiple API Support
|
||||
- **Search API**: Standard Twitter search functionality
|
||||
- **GraphQL API**: Advanced queries and data extraction
|
||||
- **Automatic switching**: Based on rate limits and availability
|
||||
|
||||
### 2. Async/Await Architecture
|
||||
```python
|
||||
# Parallel scraping
|
||||
async for tweet in api.search("elon musk"):
|
||||
print(tweet.id, tweet.user.username, tweet.rawContent)
|
||||
```
|
||||
|
||||
### 3. Account Management
|
||||
- Add multiple accounts for rotation
|
||||
- Automatic rate limit handling
|
||||
- Session persistence across runs
|
||||
- Email verification support (IMAP or manual)
|
||||
|
||||
### 4. Data Models
|
||||
- SNScrape-compatible models
|
||||
- Easy conversion to dict/JSON
|
||||
- Raw API response access available
|
||||
|
||||
## Core API Methods
|
||||
|
||||
### Search Operations
|
||||
|
||||
#### `search(query, limit, kv={})`
|
||||
Search tweets by query string.
|
||||
|
||||
**Parameters:**
|
||||
- `query` (str): Search query (supports Twitter search syntax)
|
||||
- `limit` (int): Maximum number of tweets to return
|
||||
- `kv` (dict): Additional parameters (e.g., `{"product": "Top"}` for Top tweets)
|
||||
|
||||
**Returns:** AsyncIterator of Tweet objects
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
# Latest tweets
|
||||
async for tweet in api.search("elon musk", limit=20):
|
||||
print(tweet.rawContent)
|
||||
|
||||
# Top tweets
|
||||
await gather(api.search("python", limit=20, kv={"product": "Top"}))
|
||||
```
|
||||
|
||||
### User Operations
|
||||
|
||||
#### `user_by_login(username)`
|
||||
Get user information by username.
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
user = await api.user_by_login("xdevelopers")
|
||||
print(user.id, user.displayname, user.followersCount)
|
||||
```
|
||||
|
||||
#### `user_by_id(user_id)`
|
||||
Get user information by user ID.
|
||||
|
||||
#### `followers(user_id, limit)`
|
||||
Get user's followers.
|
||||
|
||||
#### `following(user_id, limit)`
|
||||
Get users that the user follows.
|
||||
|
||||
#### `verified_followers(user_id, limit)`
|
||||
Get only verified followers.
|
||||
|
||||
#### `subscriptions(user_id, limit)`
|
||||
Get user's Twitter Blue subscriptions.
|
||||
|
||||
### Tweet Operations
|
||||
|
||||
#### `tweet_details(tweet_id)`
|
||||
Get detailed information about a specific tweet.
|
||||
|
||||
#### `tweet_replies(tweet_id, limit)`
|
||||
Get replies to a tweet.
|
||||
|
||||
#### `retweeters(tweet_id, limit)`
|
||||
Get users who retweeted a specific tweet.
|
||||
|
||||
#### `user_tweets(user_id, limit)`
|
||||
Get tweets from a user (excludes replies).
|
||||
|
||||
#### `user_tweets_and_replies(user_id, limit)`
|
||||
Get tweets and replies from a user.
|
||||
|
||||
#### `user_media(user_id, limit)`
|
||||
Get tweets with media from a user.
|
||||
|
||||
### Other Operations
|
||||
|
||||
#### `list_timeline(list_id)`
|
||||
Get tweets from a Twitter list.
|
||||
|
||||
#### `trends(category)`
|
||||
Get trending topics by category.
|
||||
|
||||
**Categories:** "news", "sport", "entertainment", etc.
|
||||
|
||||
## Account Management
|
||||
|
||||
### Adding Accounts
|
||||
|
||||
**With cookies (recommended):**
|
||||
```python
|
||||
cookies = "abc=12; ct0=xyz" # String or JSON format
|
||||
await api.pool.add_account("user", "pass", "email@example.com", "mail_pass", cookies=cookies)
|
||||
```
|
||||
|
||||
**With credentials:**
|
||||
```python
|
||||
await api.pool.add_account("user", "pass", "email@example.com", "mail_pass")
|
||||
await api.pool.login_all()
|
||||
```
|
||||
|
||||
### CLI Account Management
|
||||
|
||||
```bash
|
||||
# Add accounts from file
|
||||
twscrape add_accounts accounts.txt username:password:email:email_password
|
||||
|
||||
# Login all accounts
|
||||
twscrape login_accounts
|
||||
|
||||
# Manual email verification
|
||||
twscrape login_accounts --manual
|
||||
|
||||
# List accounts and status
|
||||
twscrape accounts
|
||||
|
||||
# Re-login specific accounts
|
||||
twscrape relogin user1 user2
|
||||
|
||||
# Retry failed logins
|
||||
twscrape relogin_failed
|
||||
```
|
||||
|
||||
## Proxy Configuration
|
||||
|
||||
### Per-Account Proxy
|
||||
```python
|
||||
proxy = "http://login:pass@example.com:8080"
|
||||
await api.pool.add_account("user", "pass", "email@example.com", "mail_pass", proxy=proxy)
|
||||
```
|
||||
|
||||
### Global Proxy
|
||||
```python
|
||||
api = API(proxy="http://login:pass@example.com:8080")
|
||||
```
|
||||
|
||||
### Environment Variable
|
||||
```bash
|
||||
export TWS_PROXY=socks5://user:pass@127.0.0.1:1080
|
||||
twscrape search "elon musk"
|
||||
```
|
||||
|
||||
### Dynamic Proxy Changes
|
||||
```python
|
||||
api.proxy = "socks5://user:pass@127.0.0.1:1080"
|
||||
doc = await api.user_by_login("elonmusk")
|
||||
api.proxy = None # Disable proxy
|
||||
```
|
||||
|
||||
**Priority:** `api.proxy` > `TWS_PROXY` env var > account-specific proxy
|
||||
|
||||
## CLI Usage
|
||||
|
||||
### Search Operations
|
||||
```bash
|
||||
twscrape search "QUERY" --limit=20
|
||||
twscrape search "elon musk lang:es" --limit=20 > data.txt
|
||||
twscrape search "python" --limit=20 --raw # Raw API responses
|
||||
```
|
||||
|
||||
### User Operations
|
||||
```bash
|
||||
twscrape user_by_login USERNAME
|
||||
twscrape user_by_id USER_ID
|
||||
twscrape followers USER_ID --limit=20
|
||||
twscrape following USER_ID --limit=20
|
||||
twscrape verified_followers USER_ID --limit=20
|
||||
twscrape user_tweets USER_ID --limit=20
|
||||
```
|
||||
|
||||
### Tweet Operations
|
||||
```bash
|
||||
twscrape tweet_details TWEET_ID
|
||||
twscrape tweet_replies TWEET_ID --limit=20
|
||||
twscrape retweeters TWEET_ID --limit=20
|
||||
```
|
||||
|
||||
### Trends
|
||||
```bash
|
||||
twscrape trends sport
|
||||
twscrape trends news
|
||||
```
|
||||
|
||||
### Custom Database
|
||||
```bash
|
||||
twscrape --db custom-accounts.db <command>
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Raw API Responses
|
||||
```python
|
||||
async for response in api.search_raw("elon musk"):
|
||||
print(response.status_code, response.json())
|
||||
```
|
||||
|
||||
### Stopping Iteration
|
||||
```python
|
||||
from contextlib import aclosing
|
||||
|
||||
async with aclosing(api.search("elon musk")) as gen:
|
||||
async for tweet in gen:
|
||||
if tweet.id < 200:
|
||||
break
|
||||
```
|
||||
|
||||
### Convert Models to Dict/JSON
|
||||
```python
|
||||
user = await api.user_by_id(user_id)
|
||||
user_dict = user.dict()
|
||||
user_json = user.json()
|
||||
```
|
||||
|
||||
### Enable Debug Logging
|
||||
```python
|
||||
from twscrape.logger import set_log_level
|
||||
set_log_level("DEBUG")
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
- **`TWS_PROXY`**: Global proxy for all accounts
|
||||
Example: `socks5://user:pass@127.0.0.1:1080`
|
||||
|
||||
- **`TWS_WAIT_EMAIL_CODE`**: Timeout for email verification (default: 30 seconds)
|
||||
|
||||
- **`TWS_RAISE_WHEN_NO_ACCOUNT`**: Raise exception when no accounts available instead of waiting
|
||||
Values: `false`, `0`, `true`, `1` (default: `false`)
|
||||
|
||||
## Rate Limits & Limitations
|
||||
|
||||
### Rate Limits
|
||||
- Rate limits reset **every 15 minutes** per endpoint
|
||||
- Each account has **separate limits** for different operations
|
||||
- Accounts automatically rotate when limits are reached
|
||||
|
||||
### Tweet Limits
|
||||
- `user_tweets` and `user_tweets_and_replies` return approximately **3,200 tweets maximum** per user
|
||||
- This is a Twitter/X platform limitation
|
||||
|
||||
### Account Status
|
||||
- Rate limits vary based on:
|
||||
- Account age
|
||||
- Account verification status
|
||||
- Account activity history
|
||||
|
||||
### Handling Rate Limits
|
||||
The library automatically:
|
||||
- Switches to next available account
|
||||
- Waits for rate limit reset if all accounts exhausted
|
||||
- Tracks rate limit status per endpoint
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Large-Scale Data Collection
|
||||
```python
|
||||
async def collect_user_data(username):
|
||||
user = await api.user_by_login(username)
|
||||
|
||||
# Collect tweets
|
||||
tweets = await gather(api.user_tweets(user.id, limit=100))
|
||||
|
||||
# Collect followers
|
||||
followers = await gather(api.followers(user.id, limit=100))
|
||||
|
||||
# Collect following
|
||||
following = await gather(api.following(user.id, limit=100))
|
||||
|
||||
return {
|
||||
'user': user,
|
||||
'tweets': tweets,
|
||||
'followers': followers,
|
||||
'following': following
|
||||
}
|
||||
```
|
||||
|
||||
### Search with Filters
|
||||
```python
|
||||
# Language filter
|
||||
await gather(api.search("python lang:en", limit=20))
|
||||
|
||||
# Date filter
|
||||
await gather(api.search("AI since:2024-01-01", limit=20))
|
||||
|
||||
# From specific user
|
||||
await gather(api.search("from:elonmusk", limit=20))
|
||||
|
||||
# With media
|
||||
await gather(api.search("cats filter:media", limit=20))
|
||||
```
|
||||
|
||||
### Batch Processing
|
||||
```python
|
||||
async def process_users(usernames):
|
||||
tasks = []
|
||||
for username in usernames:
|
||||
task = api.user_by_login(username)
|
||||
tasks.append(task)
|
||||
|
||||
users = await asyncio.gather(*tasks)
|
||||
return users
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Login Issues
|
||||
- **Use cookies instead of credentials** for more stable authentication
|
||||
- Enable **manual email verification** with `--manual` flag
|
||||
- Check **email password** is correct for IMAP access
|
||||
|
||||
### Rate Limit Problems
|
||||
- **Add more accounts** for better rotation
|
||||
- **Increase wait time** between requests
|
||||
- **Monitor account status** with `twscrape accounts`
|
||||
|
||||
### No Data Returned
|
||||
- **Check account status** - they may be suspended or rate limited
|
||||
- **Verify query syntax** - use Twitter search syntax
|
||||
- **Try different accounts** - some may have better access
|
||||
|
||||
### Connection Issues
|
||||
- **Configure proxy** if behind firewall
|
||||
- **Check network connectivity**
|
||||
- **Verify Twitter/X is accessible** from your location
|
||||
|
||||
## Resources
|
||||
|
||||
- **GitHub Repository**: https://github.com/vladkens/twscrape
|
||||
- **Installation**: `pip install twscrape`
|
||||
- **Development Version**: `pip install git+https://github.com/vladkens/twscrape.git`
|
||||
|
||||
## References
|
||||
|
||||
For detailed API documentation and examples, see the reference files in the `references/` directory:
|
||||
|
||||
- `references/installation.md` - Installation and setup
|
||||
- `references/api_methods.md` - Complete API method reference
|
||||
- `references/account_management.md` - Account configuration and management
|
||||
- `references/cli_usage.md` - Command-line interface guide
|
||||
- `references/proxy_config.md` - Proxy configuration options
|
||||
- `references/examples.md` - Code examples and patterns
|
||||
|
||||
---
|
||||
|
||||
**Repository**: https://github.com/vladkens/twscrape
|
||||
**Stars**: 1998+
|
||||
**Language**: Python
|
||||
**License**: MIT
|
||||
@@ -0,0 +1,328 @@
|
||||
TRANSLATED CONTENT:
|
||||
# twscrape Examples
|
||||
|
||||
## Basic Search Example
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from twscrape import API, gather
|
||||
|
||||
async def main():
|
||||
api = API()
|
||||
|
||||
# Search for tweets
|
||||
tweets = await gather(api.search("elon musk", limit=20))
|
||||
|
||||
for tweet in tweets:
|
||||
print(f"{tweet.user.username}: {tweet.rawContent}")
|
||||
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## User Profile Analysis
|
||||
|
||||
```python
|
||||
async def analyze_user(username):
|
||||
api = API()
|
||||
|
||||
# Get user info
|
||||
user = await api.user_by_login(username)
|
||||
print(f"User: {user.displayname}")
|
||||
print(f"Followers: {user.followersCount}")
|
||||
print(f"Following: {user.followingCount}")
|
||||
|
||||
# Get recent tweets
|
||||
tweets = await gather(api.user_tweets(user.id, limit=50))
|
||||
print(f"Recent tweets: {len(tweets)}")
|
||||
|
||||
return user, tweets
|
||||
```
|
||||
|
||||
## Follower Network Collection
|
||||
|
||||
```python
|
||||
async def collect_network(user_id):
|
||||
api = API()
|
||||
|
||||
# Collect followers
|
||||
followers = await gather(api.followers(user_id, limit=100))
|
||||
print(f"Collected {len(followers)} followers")
|
||||
|
||||
# Collect following
|
||||
following = await gather(api.following(user_id, limit=100))
|
||||
print(f"Collected {len(following)} following")
|
||||
|
||||
return followers, following
|
||||
```
|
||||
|
||||
## Advanced Search with Filters
|
||||
|
||||
```python
|
||||
async def advanced_search():
|
||||
api = API()
|
||||
|
||||
# Search with language filter
|
||||
en_tweets = await gather(api.search("python lang:en", limit=20))
|
||||
|
||||
# Search with date filter
|
||||
recent_tweets = await gather(api.search("AI since:2024-01-01", limit=20))
|
||||
|
||||
# Search from specific user
|
||||
user_tweets = await gather(api.search("from:elonmusk", limit=20))
|
||||
|
||||
# Search with media
|
||||
media_tweets = await gather(api.search("cats filter:media", limit=20))
|
||||
|
||||
return en_tweets, recent_tweets, user_tweets, media_tweets
|
||||
```
|
||||
|
||||
## Tweet Thread Analysis
|
||||
|
||||
```python
|
||||
async def analyze_thread(tweet_id):
|
||||
api = API()
|
||||
|
||||
# Get tweet details
|
||||
tweet = await api.tweet_details(tweet_id)
|
||||
print(f"Tweet: {tweet.rawContent}")
|
||||
|
||||
# Get replies
|
||||
replies = await gather(api.tweet_replies(tweet_id, limit=100))
|
||||
print(f"Replies: {len(replies)}")
|
||||
|
||||
# Get retweeters
|
||||
retweeters = await gather(api.retweeters(tweet_id, limit=100))
|
||||
print(f"Retweeters: {len(retweeters)}")
|
||||
|
||||
return tweet, replies, retweeters
|
||||
```
|
||||
|
||||
## Batch User Processing
|
||||
|
||||
```python
|
||||
async def process_multiple_users(usernames):
|
||||
api = API()
|
||||
results = []
|
||||
|
||||
tasks = []
|
||||
for username in usernames:
|
||||
task = api.user_by_login(username)
|
||||
tasks.append(task)
|
||||
|
||||
users = await asyncio.gather(*tasks)
|
||||
|
||||
for user in users:
|
||||
if user:
|
||||
print(f"Processed: {user.displayname}")
|
||||
results.append(user)
|
||||
|
||||
return results
|
||||
|
||||
# Usage
|
||||
usernames = ["elonmusk", "xdevelopers", "github"]
|
||||
users = await process_multiple_users(usernames)
|
||||
```
|
||||
|
||||
## Real-time Monitoring
|
||||
|
||||
```python
|
||||
async def monitor_keywords(keywords, limit=100):
|
||||
api = API()
|
||||
|
||||
for keyword in keywords:
|
||||
print(f"\\nMonitoring: {keyword}")
|
||||
|
||||
async for tweet in api.search(keyword, limit=limit):
|
||||
print(f"[{tweet.date}] @{tweet.user.username}: {tweet.rawContent[:100]}")
|
||||
|
||||
# Process tweet
|
||||
if tweet.likeCount > 1000:
|
||||
print(f" -> Popular tweet! {tweet.likeCount} likes")
|
||||
|
||||
# Usage
|
||||
await monitor_keywords(["python", "javascript", "ai"], limit=50)
|
||||
```
|
||||
|
||||
## Data Export to JSON
|
||||
|
||||
```python
|
||||
import json
|
||||
|
||||
async def export_user_data(username, output_file):
|
||||
api = API()
|
||||
|
||||
user = await api.user_by_login(username)
|
||||
tweets = await gather(api.user_tweets(user.id, limit=100))
|
||||
|
||||
data = {
|
||||
'user': user.dict(),
|
||||
'tweets': [tweet.dict() for tweet in tweets]
|
||||
}
|
||||
|
||||
with open(output_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"Exported to {output_file}")
|
||||
|
||||
# Usage
|
||||
await export_user_data("elonmusk", "elon_data.json")
|
||||
```
|
||||
|
||||
## Trends Analysis
|
||||
|
||||
```python
|
||||
async def analyze_trends():
|
||||
api = API()
|
||||
|
||||
# Get different trend categories
|
||||
news_trends = await gather(api.trends("news"))
|
||||
sport_trends = await gather(api.trends("sport"))
|
||||
|
||||
print("News Trends:")
|
||||
for trend in news_trends[:10]:
|
||||
print(f" - {trend}")
|
||||
|
||||
print("\\nSport Trends:")
|
||||
for trend in sport_trends[:10]:
|
||||
print(f" - {trend}")
|
||||
|
||||
return news_trends, sport_trends
|
||||
```
|
||||
|
||||
## Using Context Manager for Early Termination
|
||||
|
||||
```python
|
||||
from contextlib import aclosing
|
||||
|
||||
async def find_specific_tweet(query, target_id):
|
||||
api = API()
|
||||
|
||||
async with aclosing(api.search(query)) as gen:
|
||||
async for tweet in gen:
|
||||
if tweet.id == target_id:
|
||||
print(f"Found target tweet: {tweet.rawContent}")
|
||||
return tweet
|
||||
|
||||
if tweet.id < target_id:
|
||||
print("Target not found in results")
|
||||
break
|
||||
|
||||
return None
|
||||
```
|
||||
|
||||
## Account Setup Example
|
||||
|
||||
```python
|
||||
async def setup_accounts():
|
||||
api = API()
|
||||
|
||||
# Add accounts with cookies (more stable)
|
||||
cookies = "abc=12; ct0=xyz"
|
||||
await api.pool.add_account(
|
||||
"user1",
|
||||
"password1",
|
||||
"user1@example.com",
|
||||
"mail_password1",
|
||||
cookies=cookies
|
||||
)
|
||||
|
||||
# Add account with credentials
|
||||
await api.pool.add_account(
|
||||
"user2",
|
||||
"password2",
|
||||
"user2@example.com",
|
||||
"mail_password2"
|
||||
)
|
||||
|
||||
# Login all accounts
|
||||
await api.pool.login_all()
|
||||
|
||||
print("Accounts setup complete")
|
||||
```
|
||||
|
||||
## Proxy Configuration Example
|
||||
|
||||
```python
|
||||
async def use_proxy():
|
||||
# Global proxy
|
||||
proxy = "http://user:pass@proxy.example.com:8080"
|
||||
api = API(proxy=proxy)
|
||||
|
||||
# Make requests through proxy
|
||||
user = await api.user_by_login("elonmusk")
|
||||
print(f"User: {user.displayname}")
|
||||
|
||||
# Change proxy dynamically
|
||||
api.proxy = "socks5://user:pass@127.0.0.1:1080"
|
||||
tweets = await gather(api.search("python", limit=10))
|
||||
|
||||
# Disable proxy
|
||||
api.proxy = None
|
||||
more_tweets = await gather(api.search("javascript", limit=10))
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
async def safe_user_lookup(username):
|
||||
api = API()
|
||||
|
||||
try:
|
||||
user = await api.user_by_login(username)
|
||||
return user
|
||||
except Exception as e:
|
||||
print(f"Error fetching user {username}: {e}")
|
||||
return None
|
||||
|
||||
async def bulk_lookup_with_errors(usernames):
|
||||
results = []
|
||||
for username in usernames:
|
||||
user = await safe_user_lookup(username)
|
||||
if user:
|
||||
results.append(user)
|
||||
|
||||
return results
|
||||
```
|
||||
|
||||
## Complete Workflow Example
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import json
|
||||
from twscrape import API, gather
|
||||
from twscrape.logger import set_log_level
|
||||
|
||||
async def complete_workflow():
|
||||
# Setup
|
||||
api = API("my_data.db")
|
||||
set_log_level("INFO")
|
||||
|
||||
# Add accounts
|
||||
await api.pool.add_account(
|
||||
"user1", "pass1", "email1@example.com", "mail_pass1",
|
||||
cookies="cookie_string_here"
|
||||
)
|
||||
|
||||
# Search and analyze
|
||||
query = "python programming"
|
||||
tweets = await gather(api.search(query, limit=100))
|
||||
|
||||
# Extract user data
|
||||
users = {}
|
||||
for tweet in tweets:
|
||||
if tweet.user.username not in users:
|
||||
users[tweet.user.username] = {
|
||||
'user': tweet.user.dict(),
|
||||
'tweets': []
|
||||
}
|
||||
users[tweet.user.username]['tweets'].append(tweet.dict())
|
||||
|
||||
# Export results
|
||||
with open('results.json', 'w', encoding='utf-8') as f:
|
||||
json.dump(users, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"Processed {len(tweets)} tweets from {len(users)} users")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(complete_workflow())
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
TRANSLATED CONTENT:
|
||||
# twscrape Reference Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This directory contains detailed reference documentation for twscrape, a Python library for scraping Twitter/X data.
|
||||
|
||||
## Reference Files
|
||||
|
||||
### Core Documentation
|
||||
- **[installation.md](installation.md)** - Installation instructions and dependencies
|
||||
- **[api_methods.md](api_methods.md)** - Complete API method reference with parameters
|
||||
- **[account_management.md](account_management.md)** - Account setup, login, and rotation
|
||||
- **[cli_usage.md](cli_usage.md)** - Command-line interface guide
|
||||
- **[proxy_config.md](proxy_config.md)** - Proxy configuration and setup
|
||||
- **[examples.md](examples.md)** - Practical code examples and patterns
|
||||
|
||||
## Quick Navigation
|
||||
|
||||
### Getting Started
|
||||
1. Read [installation.md](installation.md) for setup
|
||||
2. Review [account_management.md](account_management.md) for adding accounts
|
||||
3. Check [examples.md](examples.md) for quick start code
|
||||
|
||||
### API Reference
|
||||
- For programmatic usage: [api_methods.md](api_methods.md)
|
||||
- For command-line usage: [cli_usage.md](cli_usage.md)
|
||||
|
||||
### Advanced Topics
|
||||
- Proxy configuration: [proxy_config.md](proxy_config.md)
|
||||
- Rate limit handling: See [api_methods.md](api_methods.md#rate-limits)
|
||||
|
||||
## Key Features
|
||||
|
||||
- ✅ Async/await support for parallel operations
|
||||
- ✅ Automatic account rotation
|
||||
- ✅ Session persistence
|
||||
- ✅ Multiple proxy support
|
||||
- ✅ SNScrape-compatible data models
|
||||
- ✅ Both CLI and Python API
|
||||
@@ -0,0 +1,67 @@
|
||||
TRANSLATED CONTENT:
|
||||
# Installation
|
||||
|
||||
## Standard Installation
|
||||
|
||||
```bash
|
||||
pip install twscrape
|
||||
```
|
||||
|
||||
## Development Version
|
||||
|
||||
Install the latest development version directly from GitHub:
|
||||
|
||||
```bash
|
||||
pip install git+https://github.com/vladkens/twscrape.git
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.7+
|
||||
- asyncio support
|
||||
- Internet connection for Twitter/X access
|
||||
|
||||
## Dependencies
|
||||
|
||||
The library automatically installs required dependencies:
|
||||
- `httpx` - Async HTTP client
|
||||
- `aiosqlite` - Async SQLite database
|
||||
- Additional dependencies as specified in setup.py
|
||||
|
||||
## Verification
|
||||
|
||||
Verify installation:
|
||||
|
||||
```bash
|
||||
# Check CLI is available
|
||||
twscrape --help
|
||||
|
||||
# Check Python import works
|
||||
python -c "from twscrape import API; print('OK')"
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
```bash
|
||||
pip install --upgrade twscrape
|
||||
```
|
||||
|
||||
## Uninstallation
|
||||
|
||||
```bash
|
||||
pip uninstall twscrape
|
||||
```
|
||||
|
||||
## Database Location
|
||||
|
||||
By default, twscrape creates `accounts.db` in your current working directory. You can specify a custom location:
|
||||
|
||||
```python
|
||||
api = API("path/to/custom.db")
|
||||
```
|
||||
|
||||
Or via CLI:
|
||||
|
||||
```bash
|
||||
twscrape --db path/to/custom.db <command>
|
||||
```
|
||||
Reference in New Issue
Block a user