package proto import ( "encoding/json" "time" ) // ---- WSS 消息类型(server 与 agent-core 共用,Schema 只写一次)---- const ( TypeHello = "hello" TypeHelloAck = "hello.ack" TypeHeartbeat = "heartbeat" TypeHeartbeatAck = "heartbeat.ack" TypeTaskPush = "task.push" TypeTaskAck = "task.ack" TypeTaskResult = "task.result" TypeTaskCancel = "task.cancel" TypeChallenge = "challenge.new" TypeChallengeAck = "challenge.ack" TypeChallengeSolve = "challenge.solve" TypeAgentStatus = "agent.status" TypeError = "err" ) // Envelope WSS 统一信封:网关只透传小于1KB元数据,素材一律走签名直链 type Envelope struct { ID string `json:"id"` Type string `json:"type"` Payload json.RawMessage `json:"payload"` TS int64 `json:"ts"` } // NewEnvelope 构造信封 func NewEnvelope(id string, typ string, payload interface{}) *Envelope { raw, err := json.Marshal(payload) if err != nil { raw = []byte("{}") } return &Envelope{ID: id, Type: typ, Payload: raw, TS: time.Now().UnixMilli()} } // DeviceHello Agent 上线:设备ID + Ed25519 签名(nonce||ts)防伪造 type DeviceHello struct { DeviceID string `json:"deviceId"` Nonce string `json:"nonce"` TS int64 `json:"ts"` Sig string `json:"sig"` Version string `json:"version"` } // HelloAck 服务器应答(携带服务端 nonce 供会话内签名) type HelloAck struct { ServerNonce string `json:"serverNonce"` SessionID string `json:"sessionId"` ServerTS int64 `json:"serverTs"` Sig string `json:"sig"` } // Heartbeat 心跳(30s) type Heartbeat struct { DeviceID string `json:"deviceId"` TS int64 `json:"ts"` } // HeartbeatAck 心跳应答 type HeartbeatAck struct { ServerTS int64 `json:"serverTs"` } // TaskPush 任务下发(仅元数据;素材 URL 为签名直链) type TaskPush struct { TaskID string `json:"taskId"` Platform string `json:"platform"` AccountID string `json:"accountId"` AccountName string `json:"accountName"` Title string `json:"title"` Content string `json:"content"` Tags []string `json:"tags"` MaterialURLs []string `json:"materialUrls"` ScheduleAt int64 `json:"scheduleAt"` Priority int `json:"priority"` } // TaskAck Agent 确认接收 type TaskAck struct { TaskID string `json:"taskId"` Accept bool `json:"accept"` Reason string `json:"reason,omitempty"` } // TaskResult 执行结果回传 type TaskResult struct { TaskID string `json:"taskId"` Status string `json:"status"` PublishedURL string `json:"publishedUrl,omitempty"` Receipts []string `json:"receipts,omitempty"` Error string `json:"error,omitempty"` FinishedAt int64 `json:"finishedAt"` } // TaskCancel 取消任务 type TaskCancel struct { TaskID string `json:"taskId"` Reason string `json:"reason,omitempty"` } // Challenge 二次验证挑战(扫码/验证码/APP确认/人工兜底) type Challenge struct { ChallengeID string `json:"challengeId"` AccountID string `json:"accountId"` Platform string `json:"platform"` Kind string `json:"kind"` QRToken string `json:"qrToken,omitempty"` QRURL string `json:"qrUrl,omitempty"` Prompt string `json:"prompt"` ExpiresAt int64 `json:"expiresAt"` } // ChallengeAck 挑战应答 type ChallengeAck struct { ChallengeID string `json:"challengeId"` Action string `json:"action"` } // ChallengeSolve 网页端人工完成挑战 type ChallengeSolve struct { ChallengeID string `json:"challengeId"` Value string `json:"value,omitempty"` } // AgentStatus Agent 状态上报 type AgentStatus struct { DeviceID string `json:"deviceId"` Online bool `json:"online"` Busy bool `json:"busy"` Version string `json:"version"` TS int64 `json:"ts"` }