139 lines
3.8 KiB
Go
139 lines
3.8 KiB
Go
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"`
|
||
}
|