trading skills: 文档同步 (单币上限规则/平仓盈亏字段/静默规则/推送模板)
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
# TG Forwarder Operations 2026-09-21
|
||||
|
||||
## 容器挂载配置 (v4.5.4 修复后)
|
||||
|
||||
`/home/openclaw/TelegramForwarder/docker-compose.yml` 必须挂载两个目录:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ./filters:/app/filters # 启用 is_original_time 修改生效
|
||||
- ./handlers:/app/handlers # 修改 user_handler.py 生效 (转发+时间戳)
|
||||
```
|
||||
|
||||
**背景**: 之前只挂了 `db`, `.env`, `logs`, `sessions`, `temp`, `config` 等, 没挂 `filters/` 和 `handlers/`。
|
||||
容器内的 Python 文件是镜像内置, 不挂载 = 改主机版本无效。
|
||||
|
||||
## SOCKS5 代理坑 (v4.5.4 修复)
|
||||
|
||||
Mihomo 在主机监听:
|
||||
- 7890 = **mixed-port** (HTTP/HTTPS only, 不接受 SOCKS5 握手)
|
||||
- 7891 = **socks-port** (SOCKS5 raw TCP)
|
||||
|
||||
**Forwarder `main.py` 解析逻辑**: `HTTP_PROXY=http://127.0.0.1:7890` → 正则提取 host=127.0.0.1, port=7890 → **用 SOCKS5 协议连 7890** → 失败 (mixed-port 不识别 SOCKS5 握手) → `GeneralProxyError: Socket error: timed out`。
|
||||
|
||||
**修复**: 把所有 `HTTP_PROXY` / `HTTPS_PROXY` 改为 `127.0.0.1:7891` (SOCKS5 端口)。
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- HTTP_PROXY=http://127.0.0.1:7891
|
||||
- HTTPS_PROXY=http://127.0.0.1:7891
|
||||
- http_proxy=http://127.0.0.1:7891
|
||||
- https_proxy=http://127.0.0.1:7891
|
||||
```
|
||||
|
||||
**诊断命令** (容器内):
|
||||
```bash
|
||||
docker exec telegram-forwarder python3 -c "
|
||||
import socks, socket
|
||||
s = socks.socksocket()
|
||||
s.set_proxy(socks.SOCKS5, '127.0.0.1', 7891)
|
||||
s.settimeout(10)
|
||||
try:
|
||||
s.connect(('91.108.56.137', 443))
|
||||
print('✅ SOCKS5 OK')
|
||||
except Exception as e:
|
||||
print(f'❌ {e}')
|
||||
"
|
||||
```
|
||||
|
||||
## 转发流程真相 (2026-09-21 验证)
|
||||
|
||||
**forwarder 实际不走 filter_chain**, 走 `handlers/user_handler.py:process_forward_rule()`:
|
||||
1. `await check_keywords(rule, check_message_text)` — 用 keywords 表
|
||||
2. `await client.forward_messages(target_chat_id, message_id, chat_id)` — **TG 原生转发**
|
||||
3. (v4.5.4 后) `await client.send_message(target_chat_id, '⏱信号时间: ...')` — **追加时间戳**
|
||||
|
||||
⚠️ **`/app/filters/` 下的所有 filter (InfoFilter, KeywordFilter, SenderFilter...) 都是死代码** — `filter_chain` 是空链 (0 filter), 没人调用。要改转发行为只能改 `user_handler.py`。
|
||||
|
||||
⚠️ **`forward_messages()` 不支持附加文本** — TG API 限制, 只能转发原消息。要加文本必须**在转发后另外 send_message** (这就是 v4.5.4 的做法)。
|
||||
|
||||
## 时间戳方案 (v4.5.4)
|
||||
|
||||
用户偏好: 转发群每条消息后**追加 `⏱信号时间: {接收时刻}`**, 用 forwarder 接收时刻不用原消息时间。
|
||||
|
||||
**实现** (`/home/openclaw/TelegramForwarder/handlers/user_handler.py`):
|
||||
|
||||
```python
|
||||
_TZ_SH = ZoneInfo("Asia/Shanghai")
|
||||
|
||||
def _build_time_stamp() -> str:
|
||||
return datetime.now(_TZ_SH).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
async def _send_time_stamp(client, target_chat_id, time_template):
|
||||
ts = _build_time_stamp()
|
||||
template = time_template or '⏱信号时间: {time}'
|
||||
msg = template.replace("{time}", ts)
|
||||
await client.send_message(target_chat_id, msg)
|
||||
```
|
||||
|
||||
在 `forward_messages()` 成功**之后**调用 (不是之前, 否则发不出):
|
||||
```python
|
||||
await client.forward_messages(target_chat_id, event.message.id, event.chat_id)
|
||||
if getattr(rule, 'is_original_time', False):
|
||||
time_template = getattr(rule, 'time_template', None)
|
||||
await _send_time_stamp(client, target_chat_id, time_template)
|
||||
```
|
||||
|
||||
## 硬编码黑名单 (v4.5.4)
|
||||
|
||||
规则 1 是 `WHITELIST + .*` (匹配所有), `keywords` 表的黑名单条目在 WHITELIST 模式下**被忽略** (代码逻辑反转)。
|
||||
要在不破坏现有规则下加广告过滤, 只能**硬编码**在 `user_handler.py`:
|
||||
|
||||
```python
|
||||
HARD_BLACKLIST_PATTERNS = [
|
||||
r'(?i)\bhttps?://(?!t\.me/)\S+', # 非 t.me 外链
|
||||
r'(?i)加我私聊', # 拉私
|
||||
r'(?i)进群(?!信号)', # 拉群
|
||||
r'(?i)联系(我|客服|助理)',
|
||||
r'(?i)带单|指导|喊单|牛牛老师',
|
||||
r'(?i)免费(送|领|试用)',
|
||||
r'(?i)代购|代充|充值优惠',
|
||||
r'(?i)usdt\|cny\|套现',
|
||||
r'(?i)\bVIP\b|\b老师\b',
|
||||
]
|
||||
|
||||
def _hard_blacklist_hit(text: str) -> bool:
|
||||
if not text: return False
|
||||
for pattern in HARD_BLACKLIST_PATTERNS:
|
||||
if re.search(pattern, text): return True
|
||||
return False
|
||||
```
|
||||
|
||||
**调用位置**: `check_keywords(rule, ...)` 通过后, 再 `_hard_blacklist_hit(message_text)` 二次过滤, 命中即跳过转发。
|
||||
|
||||
## 改完生效流程
|
||||
|
||||
```bash
|
||||
# 1. 改主机文件
|
||||
vim /home/openclaw/TelegramForwarder/handlers/user_handler.py
|
||||
|
||||
# 2. 重启容器 (自动用挂载的主机版)
|
||||
cd /home/openclaw/TelegramForwarder
|
||||
docker compose down && docker compose up -d
|
||||
# 或: docker compose restart
|
||||
|
||||
# 3. 验证生效
|
||||
docker exec telegram-forwarder grep "新代码关键字" /app/handlers/user_handler.py
|
||||
```
|
||||
|
||||
## 不要做的
|
||||
|
||||
- ❌ 改 `info_filter.py` 期望生效 — filter_chain 没装载它
|
||||
- ❌ 改 `keywords` 表加普通黑名单 — WHITELIST 模式忽略
|
||||
- ❌ 用 `forward_messages()` 时附加文本 — TG API 不支持, 必用 send_message 单独发
|
||||
- ❌ 把 SOCKS5 proxy 设为 7890 — mixed-port 不接 SOCKS5 握手, 必用 7891
|
||||
- ❌ 假设 `is_filter_user_info=True` 时 check_message_text 包含发送者信息 — 它会变, 但不影响主流程
|
||||
|
||||
## 已废弃的做法 (历史)
|
||||
|
||||
| 做法 | 状态 | 原因 |
|
||||
|------|------|------|
|
||||
| filter_chain.InfoFilter 加时间戳 | ❌ 死代码 | filter_chain 0 filter |
|
||||
| filter_chain.KeywordFilter 黑名单 | ❌ 死代码 | 同上 |
|
||||
| 改 keywords 表加黑名单 | ❌ 被忽略 | WHITELIST 模式 |
|
||||
| forward_messages 附加文本 | ❌ API 不支持 | 改用 send_message |
|
||||
| HTTP_PROXY=7890 让 forwarder 出网 | ❌ SOCKS5 握手失败 | 改用 7891 |
|
||||
Reference in New Issue
Block a user