From 423e2229b5b66ef52fd095d9ab4702461d45b270 Mon Sep 17 00:00:00 2001 From: yibo Date: Sun, 24 May 2026 01:46:00 +0800 Subject: [PATCH] chore: 清理收尾 — 群昵称查询 + wake-lock 保活 + Frida 残留 --- server/services/wechat/android-wechat-tracker-sqlcipher.js | 6 +----- wechat_plain/scripts/local-testkit/keepalive.sh | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------- 2 files changed, 102 insertions(+), 96 deletions(-) diff --git a/server/services/wechat/android-wechat-tracker-sqlcipher.js b/server/services/wechat/android-wechat-tracker-sqlcipher.js index 789077e..00dbe26 100644 --- a/server/services/wechat/android-wechat-tracker-sqlcipher.js +++ b/server/services/wechat/android-wechat-tracker-sqlcipher.js @@ -144,11 +144,7 @@ class AndroidWechatTrackerSQLCipher extends EventEmitter { }; if (builtin[wxid]) return builtin[wxid]; - // 群聊 ID 走另一个表(chatroom),先简单返回 wxid 让上层处理 - if (wxid.endsWith('@chatroom')) { - return wxid; - } - + // 群(xxxx@chatroom)和私聊都用 rcontact 表 — nickname 就是群名 / 个人昵称 const safeWxid = String(wxid).replace(/'/g, "''"); const sql = `SELECT conRemark, nickname FROM rcontact WHERE username='${safeWxid}' LIMIT 1;`; try { diff --git a/wechat_plain/scripts/local-testkit/keepalive.sh b/wechat_plain/scripts/local-testkit/keepalive.sh index 270a59b..a459b30 100755 --- a/wechat_plain/scripts/local-testkit/keepalive.sh +++ b/wechat_plain/scripts/local-testkit/keepalive.sh @@ -1,125 +1,135 @@ -#!/bin/bash -# keepalive.sh — Termux 保活 + 进程守护脚本 +#!/data/data/com.termux/files/usr/bin/bash +# keepalive.sh — Pixel 微信自动回复保活脚本 # -# 功能: -# 1. 获取 wake-lock,防止息屏后 CPU 被冻结 -# 2. 检查并启动 hermes server -# 3. 检查并启动 wechat auto-reply plugin -# 4. 进程死了自动重启 +# 守护以下进程,挂了就重启: +# 1. termux wake-lock — 防 Doze 冻结 Termux:API(通知监听依赖它) +# 2. HermesAccessibilityService — A11y 易被系统/更新关掉,发现 enabled_accessibility_services=null 就重启 +# 3. hermes-agent gateway — :8642,LLM 网关 +# 4. auto-reply.js — 微信回复主程序 # -# 用法: -# chmod +x keepalive.sh -# nohup ./keepalive.sh > keepalive.log 2>&1 & +# 用法(在 Termux 用户 shell 里运行;不要在 root shell 起,wake-lock 拿不住 Termux 进程): +# nohup bash ~/hermes-wechat/keepalive.sh > ~/hermes-wechat/keepalive.log 2>&1 & # -# 前置条件(必须手动设置): -# 1. Android 设置 → 应用 → Termux → 电池优化 → 不优化 -# 2. Android 设置 → 应用 → Termux:API → 电池优化 → 不优化 -# 3. Android 设置 → 应用 → 微信 → 电池优化 → 不优化 -# 4. Android 设置 → 应用 → Termux → 允许自启动 -# 5. Termux:API 已安装,并已授予通知访问权限 +# 前置条件(一次性设置): +# 1. Android 设置 → 应用 → Termux / Termux:API / 微信 → 电池优化 → 不优化 +# 2. Termux:API 已安装,并已授予通知访问权限 +# 3. lsposed-wechat-sendmsg APK 已安装(含 HermesAccessibilityService) +# 4. ~/hermes-wechat/start-ar.sh 存在并已设置 MY_WXID / MY_NICKNAME -set -e - -# 确保 Termux 工具在 PATH 中(su 环境下可能缺失) export PATH="/data/data/com.termux/files/usr/bin:$PATH" - -HERMES_DIR="${HERMES_DIR:-/data/data/com.termux/files/home/hermes-wechat}" -HERMES_HOST="${HERMES_HOST:-localhost}" -HERMES_PORT="${HERMES_PORT:-3010}" -MY_WXID="${MY_WXID:-}" -MY_NICKNAME="${MY_NICKNAME:-}" -CHECK_INTERVAL_SEC="${CHECK_INTERVAL_SEC:-10}" - -log() { - echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" -} - -# ── 1. Wake lock ───────────────────────────────────────────────── -termux-wake-lock 2>/dev/null || true -log "Wake lock acquired" - -# ── 2. 检查前置条件 ────────────────────────────────────────────── -check_prerequisites() { - _ok=0 - - if ! command -v termux-notification-list >/dev/null 2>&1; then - log "[WARN] termux-notification-list not found. Install: pkg install termux-api" - _ok=1 +export HOME="/data/data/com.termux/files/home" + +HERMES_DIR="${HERMES_DIR:-$HOME/hermes-wechat}" +HERMES_PORT="${HERMES_PORT:-8642}" +GATEWAY_START="${GATEWAY_START:-$HOME/.hermes/scripts/start-gateway.sh}" +AR_START="${AR_START:-$HERMES_DIR/start-ar.sh}" +A11Y_SVC="com.hermes.wechat.xposed/com.hermes.wechat.xposed.accessibility.HermesAccessibilityService" +CHECK_INTERVAL_SEC="${CHECK_INTERVAL_SEC:-15}" + +log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; } + +# ── 1. Termux wake-lock ────────────────────────────────────────── +ensure_wake_lock() { + # 用命令行 termux-wake-lock(依赖 Termux:API app);am startservice 是备用 + if command -v termux-wake-lock >/dev/null 2>&1; then + termux-wake-lock 2>/dev/null + else + # 后备:用 su 调系统 ServiceManager + su -c "am startservice --user 0 -a com.termux.service_wake_lock com.termux/.app.TermuxService" 2>/dev/null || true fi +} - if [ ! -d "$HERMES_DIR" ]; then - log "[WARN] HERMES_DIR not found: $HERMES_DIR" - _ok=1 - fi +is_wake_lock_held() { + su -c "dumpsys power 2>/dev/null | grep -q 'termux:service-wakelock'" +} - if [ -z "$MY_WXID" ] || [ -z "$MY_NICKNAME" ]; then - log "[WARN] MY_WXID or MY_NICKNAME not set" - log " export MY_WXID=wxid_xxxxxx" - log " export MY_NICKNAME=你的昵称" - _ok=1 - fi +# ── 2. A11y service ────────────────────────────────────────────── +is_a11y_enabled() { + out=$(su -c "settings get secure enabled_accessibility_services" 2>/dev/null) + case "$out" in + *com.hermes.wechat.xposed*HermesAccessibilityService*) return 0 ;; + *) return 1 ;; + esac +} - return $_ok +enable_a11y() { + log "Enabling HermesAccessibilityService..." + su -c "settings put secure enabled_accessibility_services $A11Y_SVC; settings put secure accessibility_enabled 1" 2>/dev/null } -# ── 3. 检查 hermes server 是否运行 ─────────────────────────────── -is_hermes_running() { - curl -s "http://${HERMES_HOST}:${HERMES_PORT}/api/health" >/dev/null 2>&1 +# ── 3. hermes gateway ──────────────────────────────────────────── +is_gateway_running() { + # 用 /sys/class/net 风格的端口探测:通过 nc 或 curl,二选一 + if command -v curl >/dev/null 2>&1; then + # gateway 在 termux 用户下需要 Clash 代理(与本机回环无关); + # 但 127.0.0.1:8642 走本机,不用代理 + env -u HTTPS_PROXY -u HTTP_PROXY \ + curl -s --max-time 3 "http://127.0.0.1:${HERMES_PORT}/v1/models" >/dev/null 2>&1 + else + # nc fallback + echo > /dev/tcp/127.0.0.1/$HERMES_PORT 2>/dev/null + fi } -# ── 4. 启动 hermes server ──────────────────────────────────────── -# 必须在 proot Ubuntu 内以 ubuntu 用户运行(Claude CLI 拒绝 root + --dangerously-skip-permissions) -start_hermes() { - log "Starting hermes server in proot Ubuntu user=ubuntu..." - cd "$HERMES_DIR" - nohup proot-distro login ubuntu --user ubuntu -- bash -c \ - "cd $HERMES_DIR && . .env && node server/index.js" \ - > hermes-server.log 2>&1 & - sleep 5 - if is_hermes_running; then - log "Hermes server started PID=$!" +start_gateway() { + log "Starting hermes gateway..." + if [ -x "$GATEWAY_START" ]; then + bash "$GATEWAY_START" >> "$HOME/.hermes/logs/gateway-start.log" 2>&1 else - log "[WARN] Hermes server may have failed to start, check hermes-server.log" + log "[ERROR] $GATEWAY_START not found" fi } -# ── 5. 检查 auto-reply 是否运行 ────────────────────────────────── +# ── 4. auto-reply.js ───────────────────────────────────────────── is_auto_reply_running() { - pgrep -f "node auto-reply.js" >/dev/null 2>&1 + pgrep -f "node.*auto-reply.js" >/dev/null 2>&1 } -# ── 6. 启动 auto-reply ─────────────────────────────────────────── start_auto_reply() { log "Starting auto-reply..." - cd "$HERMES_DIR/server/services/wechat" - env MY_WXID="$MY_WXID" MY_NICKNAME="$MY_NICKNAME" \ - nohup node auto-reply.js > auto-reply.log 2>&1 & - log "Auto-reply started PID=$!" + if [ -x "$AR_START" ]; then + # auto-reply 走 root 才能 input keyevent / am broadcast / 读微信 DB + su -c "nohup bash $AR_START > /dev/null 2>&1 &" + else + log "[ERROR] $AR_START not found" + fi } -# ── 7. 主循环 ──────────────────────────────────────────────────── +# ── 5. 主循环 ──────────────────────────────────────────────────── log "=== Keepalive started ===" -log "HERMES_DIR=$HERMES_DIR" -log "MY_WXID=${MY_WXID:-not-set}" -log "MY_NICKNAME=${MY_NICKNAME:-not-set}" +log "HERMES_DIR=$HERMES_DIR GATEWAY_START=$GATEWAY_START AR_START=$AR_START" +log "Check interval: ${CHECK_INTERVAL_SEC}s" -if ! check_prerequisites; then - log "[ERROR] Prerequisites check failed, exiting" - exit 1 -fi +# 首次进入:把所有依赖拉到位 +ensure_wake_lock +is_a11y_enabled || enable_a11y +is_gateway_running || start_gateway +sleep 5 +is_auto_reply_running || start_auto_reply while true; do - # 检查 hermes - if ! is_hermes_running; then - log "Hermes server not responding, restarting..." - start_hermes + sleep "$CHECK_INTERVAL_SEC" + + # wake-lock 偶尔会因 Termux 重启 / 系统重启而丢,保险起见周期性 re-acquire + if ! is_wake_lock_held; then + log "Wake lock lost, re-acquiring..." + ensure_wake_lock + fi + + # A11y 易被系统升级 / 用户在设置中关掉 + if ! is_a11y_enabled; then + log "A11y service disabled, re-enabling..." + enable_a11y + fi + + if ! is_gateway_running; then + log "Gateway not responding on :$HERMES_PORT, restarting..." + start_gateway + sleep 6 fi - # 检查 auto-reply if ! is_auto_reply_running; then - log "Auto-reply not running, restarting..." + log "auto-reply.js not running, restarting..." start_auto_reply fi - - sleep "$CHECK_INTERVAL_SEC" done -- libgit2 0.21.4