morz-infoboard/player/agent/internal/statusreporter/reporter.go
Jesko Anschütz f8a57b3e6b Bereinige signalstarke Linter-Funde
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-22 17:56:56 +01:00

105 lines
2.6 KiB
Go

package statusreporter
import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
)
type Snapshot struct {
Status string
ScreenID string
ServerBaseURL string
MQTTBroker string
HeartbeatEverySeconds int
StartedAt time.Time
LastHeartbeatAt time.Time
}
type statusPayload struct {
ScreenID string `json:"screen_id"`
Timestamp string `json:"ts"`
Status string `json:"status"`
ServerURL string `json:"server_url"`
MQTTBroker string `json:"mqtt_broker"`
HeartbeatEverySeconds int `json:"heartbeat_every_seconds"`
StartedAt string `json:"started_at,omitempty"`
LastHeartbeatAt string `json:"last_heartbeat_at,omitempty"`
}
type Reporter struct {
baseURL string
client *http.Client
now func() time.Time
}
func New(baseURL string, client *http.Client, now func() time.Time) *Reporter {
if client == nil {
client = &http.Client{Timeout: 5 * time.Second}
}
if now == nil {
now = time.Now
}
return &Reporter{
baseURL: strings.TrimRight(baseURL, "/"),
client: client,
now: now,
}
}
func (r *Reporter) Send(ctx context.Context, snapshot Snapshot) error {
payload := buildPayload(snapshot, r.now())
body, err := json.Marshal(payload)
if err != nil {
return fmt.Errorf("marshal status payload: %w", err)
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, r.baseURL+"/api/v1/player/status", bytes.NewReader(body))
if err != nil {
return fmt.Errorf("build status request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := r.client.Do(req)
if err != nil {
return fmt.Errorf("send status request: %w", err)
}
statusCode := resp.StatusCode
statusText := resp.Status
if err := resp.Body.Close(); err != nil {
return fmt.Errorf("close status response body: %w", err)
}
if statusCode != http.StatusOK {
return fmt.Errorf("unexpected status response: %s", statusText)
}
return nil
}
func buildPayload(snapshot Snapshot, now time.Time) statusPayload {
payload := statusPayload{
ScreenID: snapshot.ScreenID,
Timestamp: now.Format(time.RFC3339),
Status: snapshot.Status,
ServerURL: snapshot.ServerBaseURL,
MQTTBroker: snapshot.MQTTBroker,
HeartbeatEverySeconds: snapshot.HeartbeatEverySeconds,
}
if !snapshot.StartedAt.IsZero() {
payload.StartedAt = snapshot.StartedAt.Format(time.RFC3339)
}
if !snapshot.LastHeartbeatAt.IsZero() {
payload.LastHeartbeatAt = snapshot.LastHeartbeatAt.Format(time.RFC3339)
}
return payload
}