| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #!/usr/bin/env bash
- # quick-start.sh - v1.2.1
- # 一键升级到 v1.2.0 auto-reply daemon 并启动,绕开 agent 的不稳定代码生成。
- #
- # 用法(在 Linux 服务器上):
- # unzip -o openclaw-wechat-skill-v1.2.x.zip -d openclaw-wechat-skill
- # cd openclaw-wechat-skill
- # bash quick-start.sh
- #
- # 可选环境变量:
- # WECHAT_API_BASE=http://your-host:port # 跳过自动探测
- # SKIP_DEPLOY=1 # 只启动 daemon,不重新部署
- set -uo pipefail
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
- OPENCLAW_DIR="$HOME/.openclaw"
- SKILLS_ROOT="$OPENCLAW_DIR/skills"
- DAEMON_DST="$OPENCLAW_DIR/auto-reply-daemon.js"
- CRED_FILE="$OPENCLAW_DIR/wechat-credentials.json"
- PID_FILE="$OPENCLAW_DIR/wechat-auto-reply.pid"
- LOG_FILE="$OPENCLAW_DIR/logs/auto-reply.log"
- GREEN=$'\e[32m'; YELLOW=$'\e[33m'; RED=$'\e[31m'; CYAN=$'\e[36m'; NC=$'\e[0m'
- section() { echo ""; echo "${CYAN}==== $* ====${NC}"; }
- ok() { echo " ${GREEN}[OK]${NC} $*"; }
- warn() { echo " ${YELLOW}[!]${NC} $*"; }
- err() { echo " ${RED}[ERR]${NC} $*"; }
- # ---------------- 1. Kill any running daemon (ours + agent's) ----------------
- section "1. 停止任何正在运行的 auto-reply daemon"
- # our daemon via pid file
- if [ -f "$PID_FILE" ]; then
- PID=$(cat "$PID_FILE" 2>/dev/null || echo "")
- if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
- kill "$PID" 2>/dev/null
- sleep 1
- kill -0 "$PID" 2>/dev/null && kill -9 "$PID" 2>/dev/null
- ok "已停止旧 daemon (PID=$PID)"
- fi
- rm -f "$PID_FILE"
- fi
- # agent's hallucinated daemon: kill any node process running *auto-reply*
- # (pattern-match to avoid killing unrelated node processes)
- STALE=$(pgrep -f 'node.*auto.reply' 2>/dev/null || true)
- if [ -n "$STALE" ]; then
- echo "$STALE" | xargs -r kill 2>/dev/null || true
- sleep 1
- STALE2=$(pgrep -f 'node.*auto.reply' 2>/dev/null || true)
- [ -n "$STALE2" ] && echo "$STALE2" | xargs -r kill -9 2>/dev/null || true
- ok "已停止 agent 遗留的 daemon 进程: $STALE"
- fi
- # ---------------- 2. Check prerequisites ----------------
- section "2. 检查依赖"
- if ! command -v node >/dev/null 2>&1; then
- err "未找到 node, 请先安装 Node.js (>=14)"
- exit 1
- fi
- ok "node $(node --version)"
- if ! command -v curl >/dev/null 2>&1; then
- err "未找到 curl"
- exit 1
- fi
- ok "curl OK"
- # ---------------- 3. Deploy skills + daemon (unless SKIP_DEPLOY=1) ----------------
- if [ "${SKIP_DEPLOY:-0}" != "1" ]; then
- section "3. 部署 skills 和 daemon"
- if [ -f "$SCRIPT_DIR/deploy-to-openclaw.js" ]; then
- node "$SCRIPT_DIR/deploy-to-openclaw.js" --source-root="$SCRIPT_DIR" || {
- err "部署脚本失败,请检查上面的输出"
- exit 1
- }
- else
- err "找不到 $SCRIPT_DIR/deploy-to-openclaw.js, 确认你在解压目录里运行本脚本"
- exit 1
- fi
- else
- warn "SKIP_DEPLOY=1, 跳过部署"
- fi
- # ---------------- 4. Probe / set wechatApiBase ----------------
- section "4. 探测可用的 wechatApiBase"
- probe() {
- local base="$1"
- local resp
- resp=$(curl -s --max-time 5 -X POST "$base/login/check-online" \
- -H "Content-Type: application/json" -d '{}' 2>/dev/null || echo "")
- if echo "$resp" | grep -q '"ret":200'; then
- local ONLINE="?"
- echo "$resp" | grep -q '"data":true' && ONLINE="true"
- echo "$resp" | grep -q '"data":false' && ONLINE="false"
- echo " probe $base -> ret=200 online=$ONLINE"
- return 0
- fi
- echo " probe $base -> NO (resp=${resp:0:80})"
- return 1
- }
- WORKING_BASE=""
- if [ -n "${WECHAT_API_BASE:-}" ]; then
- echo "使用环境变量 WECHAT_API_BASE=$WECHAT_API_BASE"
- if probe "$WECHAT_API_BASE"; then WORKING_BASE="$WECHAT_API_BASE"; fi
- else
- # Read current config first
- CURRENT=""
- if [ -f "$CRED_FILE" ]; then
- CURRENT=$(node -e "try{console.log(require('$CRED_FILE').wechatApiBase||'')}catch(e){}" 2>/dev/null || echo "")
- fi
- CANDIDATES=(
- "$CURRENT"
- "http://127.0.0.1:8138"
- "http://127.0.0.1"
- "http://localhost:8138"
- "http://localhost"
- "http://8.138.37.248"
- "http://8.138.37.248/api/wechat-agent"
- )
- # de-dup + drop empty
- for base in "${CANDIDATES[@]}"; do
- [ -z "$base" ] && continue
- [ "$base" = "$WORKING_BASE" ] && continue
- # skip duplicates
- seen=0
- for done_base in "${TRIED[@]:-}"; do [ "$done_base" = "$base" ] && seen=1; done
- [ "$seen" = "1" ] && continue
- TRIED+=("$base")
- if probe "$base"; then
- WORKING_BASE="$base"
- break
- fi
- done
- fi
- if [ -z "$WORKING_BASE" ]; then
- err "所有候选 URL 都不通, 请手动确认后端地址再运行: WECHAT_API_BASE=http://your-host bash quick-start.sh"
- exit 1
- fi
- ok "使用 wechatApiBase = $WORKING_BASE"
- # Write into credentials file
- mkdir -p "$OPENCLAW_DIR"
- node -e "
- const fs=require('fs'),p='$CRED_FILE';
- let c={}; try{c=JSON.parse(fs.readFileSync(p,'utf8'))}catch(e){};
- c.wechatApiBase='$WORKING_BASE';
- fs.writeFileSync(p,JSON.stringify(c,null,2));
- "
- ok "已写入 $CRED_FILE"
- # ---------------- 5. Start our daemon ----------------
- section "5. 启动 v1.2.0 daemon"
- if [ ! -f "$DAEMON_DST" ]; then
- err "daemon 未部署到 $DAEMON_DST, 请检查上一步"
- exit 1
- fi
- mkdir -p "$(dirname "$LOG_FILE")"
- # Append separator to log
- echo "" >> "$LOG_FILE"
- echo "=== quick-start $(date -Iseconds) ===" >> "$LOG_FILE"
- nohup node "$DAEMON_DST" >> "$LOG_FILE" 2>&1 &
- NEW_PID=$!
- echo "$NEW_PID" > "$PID_FILE"
- sleep 2
- if kill -0 "$NEW_PID" 2>/dev/null; then
- ok "daemon 已启动, PID=$NEW_PID"
- else
- err "daemon 启动后立即退出, 看日志排查:"
- tail -n 30 "$LOG_FILE"
- exit 1
- fi
- # ---------------- 6. Watch log for 15 seconds ----------------
- section "6. 观察日志 15 秒 (期望看到 '配置载入' + 至少一次 get-messages)"
- sleep 15
- echo ""
- tail -n 30 "$LOG_FILE"
- echo ""
- if grep -q 'daemon start' "$LOG_FILE" && ! grep -q 'fatal\|uncaughtException' "$LOG_FILE"; then
- section "完成"
- ok "daemon 健康运行中, PID=$NEW_PID"
- echo ""
- echo "下一步:"
- echo " 1) 让测试微信号给这台机器登录的微信发条消息"
- echo " 2) 持续观察: tail -f $LOG_FILE"
- echo " 3) 改规则: vim $OPENCLAW_DIR/wechat-auto-reply-config.json (热加载)"
- echo " 4) 停服务: kill \$(cat $PID_FILE)"
- echo ""
- echo "如果测试消息发了但日志里没有 'received' -> 看后端 /messages 接口是否正常"
- echo "如果有 'received' 但没有 'replied' -> 看 'skip' / 'cooldown' / 'no-reply-rule' 原因"
- else
- warn "daemon 启动但日志异常, 请把上面的日志贴出来排查"
- fi
|