99 lines
4.9 KiB
Bash
Executable File
99 lines
4.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 真机微信全功能 + 截图 一键验收
|
||
# 目的:设备回线后,一条命令完成「读/发/转发 + 真机截图」并落盘证据(含 PNG 图片)。
|
||
# 真机铁律:只认 SDK :8899 上 WS Agent 在线的真机;离线直接 exit 2,不伪造。
|
||
#
|
||
# 用法:
|
||
# WORKPHONE_SDK_URL=http://127.0.0.1:8899 DEVICE_ID=xgfe65eimrrofyws \
|
||
# bash sdk/scripts/run_wechat_realdevice_acceptance.sh
|
||
#
|
||
# 可选:TO_ID=filehelper(发/转发目标) INCLUDE_FORWARD=1 EVIDENCE_DIR=...
|
||
set -uo pipefail
|
||
|
||
SDK="${WORKPHONE_SDK_URL:-http://127.0.0.1:8899}"
|
||
DEVICE_ID="${DEVICE_ID:-xgfe65eimrrofyws}"
|
||
TO_ID="${TO_ID:-filehelper}"
|
||
INCLUDE_FORWARD="${INCLUDE_FORWARD:-1}"
|
||
TS="$(date +%Y%m%d_%H%M%S)"
|
||
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||
EVIDENCE_DIR="${EVIDENCE_DIR:-$REPO_ROOT/开发文档/8、部署/05-测试验收/${TS%_*}_工作手机微信全功能}"
|
||
mkdir -p "$EVIDENCE_DIR"
|
||
|
||
PASS=0; FAIL=0
|
||
ok(){ echo "PASS: $1"; PASS=$((PASS+1)); }
|
||
bad(){ echo "FAIL: $1"; FAIL=$((FAIL+1)); }
|
||
|
||
jq_get(){ python3 -c "import sys,json;d=json.load(sys.stdin);print(eval('d'+sys.argv[1]) if d else '')" "$1" 2>/dev/null; }
|
||
|
||
echo "==> 真机门禁:$SDK device=$DEVICE_ID"
|
||
HEALTH="$(curl -sS -m 10 "$SDK/health" 2>/dev/null)"
|
||
ONLINE="$(printf '%s' "$HEALTH" | python3 -c "import sys,json;d=json.load(sys.stdin);print(d.get('devices_online',0))" 2>/dev/null || echo 0)"
|
||
if [[ "${ONLINE:-0}" -lt 1 ]]; then
|
||
echo "ABORT: SDK devices_online=$ONLINE,设备未在线(请解锁屏幕/确保 Termux Agent 连 ws://<sdk>/ws/device/$DEVICE_ID)。真机铁律:不伪造验收。"
|
||
echo "$HEALTH" > "$EVIDENCE_DIR/health_offline_$TS.json"
|
||
exit 2
|
||
fi
|
||
ok "SDK devices_online=$ONLINE"
|
||
|
||
exec_wx(){ # action params_json -> stdout json
|
||
curl -sS -m 30 -X POST "$SDK/api/v3/wechat/execute" -H "Content-Type: application/json" \
|
||
-d "{\"device_id\":\"$DEVICE_ID\",\"action\":\"$1\",\"params\":$2}" 2>/dev/null
|
||
}
|
||
|
||
# 1) 截图(WS 优先,adb 兜底),解码 PNG —— 图片验收证据
|
||
echo "==> 截图(WS Agent)"
|
||
SHOT_JSON="$EVIDENCE_DIR/screenshot_${TS}.json"
|
||
curl -sS -m 25 -X POST "$SDK/api/v3/devices/$DEVICE_ID/screenshot" -H "Content-Type: application/json" -d '{}' -o "$SHOT_JSON" 2>/dev/null
|
||
PNG="$EVIDENCE_DIR/wechat_screen_${TS}.png"
|
||
if python3 - "$SHOT_JSON" "$PNG" <<'PY'
|
||
import sys,json,base64,os
|
||
src,out=sys.argv[1],sys.argv[2]
|
||
try: d=json.load(open(src))
|
||
except Exception: sys.exit(1)
|
||
b=((d.get('data') or {}).get('base64') or '')
|
||
if not b: sys.exit(1)
|
||
open(out,'wb').write(base64.b64decode(b.split(',')[-1]))
|
||
print(os.path.getsize(out))
|
||
PY
|
||
then ok "截图 PNG -> $PNG"; else
|
||
# adb 兜底
|
||
if command -v adb >/dev/null && adb -s "$DEVICE_ID" get-state >/dev/null 2>&1; then
|
||
adb -s "$DEVICE_ID" exec-out screencap -p > "$PNG" 2>/dev/null && [[ -s "$PNG" ]] && ok "截图 PNG(adb) -> $PNG" || bad "截图失败(adb)"
|
||
else
|
||
bad "截图失败(WS 超时 + 无 adb 连接)"
|
||
fi
|
||
fi
|
||
|
||
# 2) 读类
|
||
echo "==> 读类"
|
||
exec_wx get_profile '{}' > "$EVIDENCE_DIR/profile_${TS}.json"
|
||
[[ "$(jq_get "['data']['success']" < "$EVIDENCE_DIR/profile_${TS}.json")" == "True" ]] && ok "get_profile" || bad "get_profile"
|
||
exec_wx get_contacts '{"limit":5}' > "$EVIDENCE_DIR/contacts_${TS}.json"
|
||
[[ "$(jq_get "['data']['success']" < "$EVIDENCE_DIR/contacts_${TS}.json")" == "True" ]] && ok "get_contacts" || bad "get_contacts"
|
||
exec_wx get_messages "{\"limit\":3,\"talker\":\"$TO_ID\"}" > "$EVIDENCE_DIR/messages_${TS}.json"
|
||
[[ "$(jq_get "['data']['success']" < "$EVIDENCE_DIR/messages_${TS}.json")" == "True" ]] && ok "get_messages" || bad "get_messages"
|
||
|
||
# 3) 发送(真机 Frida send_msg_event,verified 才算通过)
|
||
echo "==> 发送 send_message -> $TO_ID"
|
||
SEND="$(exec_wx send_message "{\"to_id\":\"$TO_ID\",\"content\":\"[真机验收] $TS\"}")"
|
||
echo "$SEND" > "$EVIDENCE_DIR/send_message_${TS}.json"
|
||
MID="$(printf '%s' "$SEND" | python3 -c "import sys,json;d=json.load(sys.stdin);print((d.get('data') or {}).get('message_id',''))" 2>/dev/null)"
|
||
VER="$(printf '%s' "$SEND" | python3 -c "import sys,json;d=json.load(sys.stdin);print((d.get('data') or {}).get('verified',False))" 2>/dev/null)"
|
||
[[ -n "$MID" && "$VER" == "True" ]] && ok "send_message verified msg_id=$MID" || bad "send_message verified=$VER mid=$MID"
|
||
|
||
# 4) 转发(可选)
|
||
if [[ "$INCLUDE_FORWARD" == "1" && -n "$MID" ]]; then
|
||
echo "==> 转发 forward_message msg_svr_id=$MID -> $TO_ID"
|
||
FWD="$(exec_wx forward_message "{\"msg_svr_id\":\"$MID\",\"to_id\":\"$TO_ID\"}")"
|
||
echo "$FWD" > "$EVIDENCE_DIR/forward_message_${TS}.json"
|
||
FVER="$(printf '%s' "$FWD" | python3 -c "import sys,json;d=json.load(sys.stdin);print((d.get('data') or {}).get('verified',False))" 2>/dev/null)"
|
||
[[ "$FVER" == "True" ]] && ok "forward_message verified" || bad "forward_message verified=$FVER"
|
||
fi
|
||
|
||
echo
|
||
echo "==> 证据目录:$EVIDENCE_DIR"
|
||
echo "==> 结果:PASS=$PASS FAIL=$FAIL"
|
||
[[ "$FAIL" -gt 0 ]] && exit 1
|
||
echo "==> 真机微信全功能验收通过"
|
||
exit 0
|