package main import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time" ) // BarkPushPayload 定义 Bark 推送的请求 JSON 结构(单 device_key) type BarkPushPayload struct { Title string `json:"title"` Body string `json:"body"` Group string `json:"group,omitempty"` DeviceKey string `json:"device_key"` IsArchive string `json:"isArchive,omitempty"` TTL int `json:"ttl,omitempty"` } // SendNotification 依次对每个 device_key 发送 Bark 通知,遇错即返回 func SendNotification(pushURL string, deviceKeys []string, title, body string) error { for _, key := range deviceKeys { if err := sendOne(pushURL, key, title, body); err != nil { return err } } return nil } // sendOne 向单个 device_key 发送推送 func sendOne(pushURL, deviceKey, title, body string) error { payload := BarkPushPayload{ Title: title, Body: body, Group: "Model Development Platform", DeviceKey: deviceKey, IsArchive: "1", TTL: 3600, } jsonBytes, err := json.Marshal(payload) if err != nil { return fmt.Errorf("JSON 序列化失败: %w", err) } req, err := http.NewRequest("POST", pushURL, bytes.NewBuffer(jsonBytes)) if err != nil { return fmt.Errorf("创建请求失败: %w", err) } req.Header.Set("Content-Type", "application/json; charset=utf-8") client := &http.Client{Timeout: 5 * time.Second} resp, err := client.Do(req) if err != nil { return fmt.Errorf("发送推送请求失败: %w", err) } defer resp.Body.Close() if resp.StatusCode >= 400 { bodyBytes, _ := io.ReadAll(io.LimitReader(resp.Body, 512)) bodyText := string(bytes.TrimSpace(bodyBytes)) if bodyText != "" { return fmt.Errorf("推送服务器返回异常状态码: %d, 响应: %s", resp.StatusCode, bodyText) } return fmt.Errorf("推送服务器返回异常状态码: %d", resp.StatusCode) } return nil }