keepalive.sh 4.4 KB
#!/bin/bash
# keepalive.sh — Termux 保活 + 进程守护脚本
#
# 功能:
#   1. 获取 wake-lock,防止息屏后 CPU 被冻结
#   2. 检查并启动 hermes server
#   3. 检查并启动 wechat auto-reply plugin
#   4. 进程死了自动重启
#
# 用法:
#   chmod +x keepalive.sh
#   nohup ./keepalive.sh > keepalive.log 2>&1 &
#
# 前置条件(必须手动设置):
#   1. Android 设置 → 应用 → Termux → 电池优化 → 不优化
#   2. Android 设置 → 应用 → Termux:API → 电池优化 → 不优化
#   3. Android 设置 → 应用 → 微信 → 电池优化 → 不优化
#   4. Android 设置 → 应用 → Termux → 允许自启动
#   5. Termux:API 已安装,并已授予通知访问权限

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
    fi

    if [ ! -d "$HERMES_DIR" ]; then
        log "[WARN] HERMES_DIR not found: $HERMES_DIR"
        _ok=1
    fi

    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

    return $_ok
}

# ── 3. 检查 hermes server 是否运行 ───────────────────────────────
is_hermes_running() {
    curl -s "http://${HERMES_HOST}:${HERMES_PORT}/api/health" >/dev/null 2>&1
}

# ── 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=$!"
    else
        log "[WARN] Hermes server may have failed to start, check hermes-server.log"
    fi
}

# ── 5. 检查 auto-reply 是否运行 ──────────────────────────────────
is_auto_reply_running() {
    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=$!"
}

# ── 7. 主循环 ────────────────────────────────────────────────────
log "=== Keepalive started ==="
log "HERMES_DIR=$HERMES_DIR"
log "MY_WXID=${MY_WXID:-not-set}"
log "MY_NICKNAME=${MY_NICKNAME:-not-set}"

if ! check_prerequisites; then
    log "[ERROR] Prerequisites check failed, exiting"
    exit 1
fi

while true; do
    # 检查 hermes
    if ! is_hermes_running; then
        log "Hermes server not responding, restarting..."
        start_hermes
    fi

    # 检查 auto-reply
    if ! is_auto_reply_running; then
        log "Auto-reply not running, restarting..."
        start_auto_reply
    fi

    sleep "$CHECK_INTERVAL_SEC"
done