keepalive.sh
5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/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