Files
Hermes-Skills/okx-auto-position/references/tg-forwarder-ops-2026-09-21.md
T

5.5 KiB

TG Forwarder Operations 2026-09-21

容器挂载配置 (v4.5.4 修复后)

/home/openclaw/TelegramForwarder/docker-compose.yml 必须挂载两个目录:

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 端口)。

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

诊断命令 (容器内):

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):

_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() 成功之后调用 (不是之前, 否则发不出):

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:

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) 二次过滤, 命中即跳过转发。

改完生效流程

# 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