#!/data/data/com.termux/files/usr/bin/bash # keepalive.sh — Pixel 微信自动回复保活脚本 # # 守护以下进程,挂了就重启: # 1. termux wake-lock — 防 Doze 冻结 Termux:API(通知监听依赖它) # 2. HermesAccessibilityService — A11y 易被系统/更新关掉,发现 enabled_accessibility_services=null 就重启 # 3. hermes-agent gateway — :8642,LLM 网关 # 4. auto-reply.js — 微信回复主程序 # # 用法(在 Termux 用户 shell 里运行;不要在 root shell 起,wake-lock 拿不住 Termux 进程): # nohup bash ~/hermes-wechat/keepalive.sh > ~/hermes-wechat/keepalive.log 2>&1 & # # 前置条件(一次性设置): # 1. Android 设置 → 应用 → Termux / Termux:API / 微信 → 电池优化 → 不优化 # 2. Termux:API 已安装,并已授予通知访问权限 # 3. lsposed-wechat-sendmsg APK 已安装(含 HermesAccessibilityService) # 4. ~/hermes-wechat/start-ar.sh 存在并已设置 MY_WXID / MY_NICKNAME export PATH="/data/data/com.termux/files/usr/bin:$PATH" 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 } is_wake_lock_held() { su -c "dumpsys power 2>/dev/null | grep -q 'termux:service-wakelock'" } # ── 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 } 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 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 } start_gateway() { log "Starting hermes gateway..." if [ -x "$GATEWAY_START" ]; then bash "$GATEWAY_START" >> "$HOME/.hermes/logs/gateway-start.log" 2>&1 else log "[ERROR] $GATEWAY_START not found" fi } # ── 4. auto-reply.js ───────────────────────────────────────────── is_auto_reply_running() { pgrep -f "node.*auto-reply.js" >/dev/null 2>&1 } start_auto_reply() { log "Starting auto-reply..." 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 } # ── 5. 主循环 ──────────────────────────────────────────────────── log "=== Keepalive started ===" log "HERMES_DIR=$HERMES_DIR GATEWAY_START=$GATEWAY_START AR_START=$AR_START" log "Check interval: ${CHECK_INTERVAL_SEC}s" # 首次进入:把所有依赖拉到位 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 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 if ! is_auto_reply_running; then log "auto-reply.js not running, restarting..." start_auto_reply fi done