Files
workphone-sdk/sdk/agent/wechat_accept_friend_cli.sh
2026-07-23 23:40:57 +08:00

142 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
BASE="${SDK_BASE_URL:-http://127.0.0.1:8899}"
DEVICE="${SDK_DEVICE_ID:-xgfe65eimrrofyws}"
WAIT_SECONDS="${SDK_ACCEPT_WAIT_SECONDS:-0}"
POLL_SECONDS="${SDK_ACCEPT_POLL_SECONDS:-5}"
OUT="${SDK_ACCEPT_OUT:-sdk/agent/logs/wechat_accept_friend_$(date +%Y%m%d_%H%M%S)}"
mkdir -p "$OUT"
query_requests() {
curl -sS --max-time 45 -X POST "$BASE/api/v3/hook/execute" \
-H 'Content-Type: application/json' \
-d "{\"device_id\":\"$DEVICE\",\"platform\":\"wechat\",\"action\":\"get_friend_requests\",\"params\":{\"limit\":50},\"hook_only\":true}" \
> "$OUT/get_friend_requests.json"
}
extract_request() {
python3 - "$OUT/get_friend_requests.json" "$OUT" <<'PY'
import json
import pathlib
import sys
body = json.loads(pathlib.Path(sys.argv[1]).read_text())
data = body.get("data") if isinstance(body.get("data"), dict) else body
requests = data.get("requests") or []
selected = next(
(
item for item in requests
if item.get("encrypt_username") and item.get("ticket")
),
None,
)
out = pathlib.Path(sys.argv[2])
if not selected:
for name in ("encrypt_username", "ticket", "from_id"):
(out / f"{name}.txt").write_text("", encoding="utf-8")
raise SystemExit(1)
for name in ("encrypt_username", "ticket", "from_id"):
(out / f"{name}.txt").write_text(str(selected.get(name, "")), encoding="utf-8")
(out / "selected_request.json").write_text(
json.dumps(selected, ensure_ascii=False, indent=2),
encoding="utf-8",
)
PY
}
deadline=$(( $(date +%s) + WAIT_SECONDS ))
while true; do
query_requests
if extract_request; then
break
fi
if (( $(date +%s) >= deadline )); then
python3 - "$OUT" "$WAIT_SECONDS" <<'PY'
import json
import pathlib
import sys
out = pathlib.Path(sys.argv[1])
receipt = {
"success": False,
"status": "no_pending_friend_request",
"error_code": "friend_request_not_found",
"error_message": "当前没有携带有效票据的待通过好友请求",
"retryable": True,
"retry_after_seconds": 5,
"feedback": {
"level": "error",
"title": "暂无待通过好友请求",
"message": "收到新的好友请求后再次执行本命令。",
"action": "retry",
},
"waited_seconds": int(sys.argv[2]),
}
(out / "summary.json").write_text(
json.dumps(receipt, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(json.dumps(receipt, ensure_ascii=False, indent=2))
PY
exit 0
fi
sleep "$POLL_SECONDS"
done
ENCRYPT_USERNAME="$(cat "$OUT/encrypt_username.txt")"
TICKET="$(cat "$OUT/ticket.txt")"
FROM_ID="$(cat "$OUT/from_id.txt")"
python3 - "$DEVICE" "$ENCRYPT_USERNAME" "$TICKET" > "$OUT/accept_body.json" <<'PY'
import json
import sys
print(json.dumps({
"device_id": sys.argv[1],
"platform": "wechat",
"user_id": "",
"encrypt_username": sys.argv[2],
"ticket": sys.argv[3],
}, ensure_ascii=False))
PY
curl -sS --max-time 90 -X POST "$BASE/api/v3/friend/accept" \
-H 'Content-Type: application/json' \
--data-binary "@$OUT/accept_body.json" \
> "$OUT/accept.json"
if [[ -n "$FROM_ID" ]]; then
curl -sS --max-time 45 --get "$BASE/api/v3/friend/info" \
--data-urlencode "device_id=$DEVICE" \
--data-urlencode "platform=wechat" \
--data-urlencode "user_id=$FROM_ID" \
> "$OUT/readback.json"
fi
python3 - "$OUT" <<'PY'
import json
import pathlib
import sys
out = pathlib.Path(sys.argv[1])
accept = json.loads((out / "accept.json").read_text())
data = accept.get("data") if isinstance(accept.get("data"), dict) else accept
success = bool(data.get("success", accept.get("success", False)))
readback = None
if (out / "readback.json").exists():
readback = json.loads((out / "readback.json").read_text())
receipt = {
"success": success,
"status": "request_accepted" if success else "accept_failed",
"channel_used": accept.get("channel_used") or data.get("_channel_used", ""),
"accept": accept,
"readback": readback,
"evidence_dir": str(out.resolve()),
}
(out / "summary.json").write_text(
json.dumps(receipt, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(json.dumps(receipt, ensure_ascii=False, indent=2))
PY