WxAgent Control Plane
Go 1.23 控制面与 React 管理端。节点只主动出站连接,控制面不暴露节点端口。
本地启动
cd control-plane
npm --prefix web ci --no-audit --no-fund
npm --prefix web run build
go run ./cmd/wxagent-control-plane
启动前设置(单节点兼容写法):
export WXAGENT_NODE_ID=local-node
export WXAGENT_NODE_TOKEN='local-node-token'
export WXAGENT_WEB_USER=admin
export WXAGENT_WEB_PASSWORD='change-me'
多节点/多用户使用 JSON map:
export WXAGENT_NODE_TOKENS='{"node-a":"token-a","node-b":"token-b"}'
export WXAGENT_WEB_USERS='{"admin":"change-me","auditor":"read-only-password"}'
可选:WXAGENT_CONTROL_PLANE_ADDR(默认 127.0.0.1:8090)、WXAGENT_CONTROL_PLANE_DATA(默认 control-plane-data.json)。Token 只从环境变量读取,不写入控制面数据文件和日志。节点 service.json 可设置 remoteConfigurationFile 指向 CLI 管理的 remote.json;修改上报配置会在下一轮生效,修改远程地址/Token 后需重启 Agent。
浏览器访问 http://127.0.0.1:8090/,登录后管理节点、任务、白名单事件和审计记录。生产部署必须使用 HTTPS 和外部密钥管理;本地 HTTP 仅用于 loopback 集成测试。
远程只读查询使用同一持久化任务队列,返回 task_id 后通过 GET /v1/tasks/{task_id} 取结果:
POST /v1/reads/sessions { node_id, account_id, idempotency_key, limit?, offset? }
POST /v1/reads/contacts { node_id, account_id, idempotency_key, groups_only, contains?, limit?, offset? }
POST /v1/reads/messages { node_id, account_id, idempotency_key, chat_id, include_content?, limit?, offset? }
节点只返回本地已启用且 identityVerified 的白名单会话;未授权范围在节点读取前拒绝。chat_id 必须使用会话列表返回的稳定会话标识,消息结果是当前微信 UI 可见历史,不是数据库全量历史。联系人查询中的 chat_id 使用联系人数据库稳定 ID;所有响应仍受任务结果大小和分页上限约束。
验证
cd control-plane
go test ./...
go vet ./...
cd ../control-plane/web
npm run build
cd ../..
./scripts/remote-control-smoke.sh
remote-control-smoke.sh 会启动一次临时控制面,运行 .NET 节点协议客户端,验证注册、心跳、任务租约、幂等、结果回传和白名单拒绝;不会操作真实微信联系人。
Windows 手工验收
-
在已登录且未锁定的微信桌面会话中运行
WxAgent.Host doctor和WxAgent.Host inspect-ui --output artifacts/ui-tree.json,确认账号绑定使用稳定accountId,会话使用稳定AutomationId,不使用昵称/PID/窗口句柄猜测。 -
为节点配置
remote.json,例如先执行:WxAgent.Host remote auth set --config remote.json --address https://control.example --token $env:WXAGENT_NODE_TOKEN --node node-a --active-account <已确认的accountId> WxAgent.Host remote reporting enable --config remote.json WxAgent.Host remote reporting account-add --config remote.json --account <已确认的accountId> WxAgent.Host remote reporting account-enable --config remote.json --account <已确认的accountId> WxAgent.Host remote reporting allow --config remote.json --account <已确认的accountId> --type group --chat-id <已确认的稳定chatId> --identity-verified WxAgent.Host remote probe run --config remote.json -
在节点
service.json设置"remoteConfigurationFile": "<remote.json绝对路径>"后启动serve。控制面应显示节点Online、已验证账号和心跳版本。 -
仅使用文件传输助手、
Hao 豪、吉祥三宝、消息测试专用群组做发送/接收验证:先验证允许的群聊事件能到达控制面,再执行reporting deny,确认后续正文不再上传;创建send-text前确认目标账号、稳定 chat ID 和文本。 -
在控制面取消任务并验证节点不执行;断开网络后恢复,确认未完成副作用任务显示
ResultUnconfirmed,不会自动重放。
未解锁的 Session 0、昵称、PID、窗口句柄和未确认的运行时身份都应视为验收失败;手工验收不得改写微信数据库或绕过安全机制。
容器镜像
.gitea/workflows/build-web-image.yml 会构建并推送 git.ipao.vip/<owner>/<repo> 镜像:主分支额外更新 latest,v* 标签额外更新对应版本标签。请在 Gitea 账号级 Secrets 配置 REGISTRY_TOKEN;登录用户名使用仓库所有者。