feat(agent): add Projects + Compliance agents, webhook notifications
- Add AgentFAB to ProjectsPage and CompliancePage - Add AgentWebhookNotifier for agent events (activated, message, escalation, error) - Webhook URL configurable via AGENT_WEBHOOK_URL env var - Build fresh web-v2 dist
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// AgentWebhookEvent representerar en agent-händelse
|
||||
type AgentWebhookEvent struct {
|
||||
EventType string `json:"event_type"`
|
||||
AgentRum string `json:"agent_rum"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
UserID string `json:"user_id,omitempty"`
|
||||
Payload map[string]interface{} `json:"payload"`
|
||||
}
|
||||
|
||||
// AgentWebhookNotifier skickar agent-händelser till konfigurerade webhooks
|
||||
type AgentWebhookNotifier struct {
|
||||
webhookURL string
|
||||
client *http.Client
|
||||
enabled bool
|
||||
}
|
||||
|
||||
// NewAgentWebhookNotifier skapar en ny notifier
|
||||
func NewAgentWebhookNotifier(webhookURL string) *AgentWebhookNotifier {
|
||||
return &AgentWebhookNotifier{
|
||||
webhookURL: webhookURL,
|
||||
client: &http.Client{Timeout: 10 * time.Second},
|
||||
enabled: webhookURL != "",
|
||||
}
|
||||
}
|
||||
|
||||
// Notify skickar en händelse till webhook
|
||||
func (n *AgentWebhookNotifier) Notify(event AgentWebhookEvent) {
|
||||
if !n.enabled {
|
||||
return
|
||||
}
|
||||
|
||||
event.Timestamp = time.Now().Format(time.RFC3339)
|
||||
|
||||
jsonData, err := json.Marshal(event)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("event", event.EventType).Msg("Failed to marshal webhook event")
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
resp, err := n.client.Post(n.webhookURL, "application/json", bytes.NewBuffer(jsonData))
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("url", n.webhookURL).Msg("Webhook delivery failed")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 400 {
|
||||
log.Warn().Int("status", resp.StatusCode).Str("url", n.webhookURL).Msg("Webhook returned error")
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// NotifyAgentActivated skickas när en agent aktiveras
|
||||
func (n *AgentWebhookNotifier) NotifyAgentActivated(rum, userID string) {
|
||||
n.Notify(AgentWebhookEvent{
|
||||
EventType: "agent.activated",
|
||||
AgentRum: rum,
|
||||
UserID: userID,
|
||||
Payload: map[string]interface{}{
|
||||
"rum": rum,
|
||||
"user_id": userID,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// NotifyAgentMessage skickas när en agent skickar ett meddelande
|
||||
func (n *AgentWebhookNotifier) NotifyAgentMessage(rum, userID, messageType string) {
|
||||
n.Notify(AgentWebhookEvent{
|
||||
EventType: "agent.message",
|
||||
AgentRum: rum,
|
||||
UserID: userID,
|
||||
Payload: map[string]interface{}{
|
||||
"rum": rum,
|
||||
"user_id": userID,
|
||||
"message_type": messageType,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// NotifyAgentEscalation skickas när en agent eskalerar
|
||||
func (n *AgentWebhookNotifier) NotifyAgentEscalation(rum, userID, reason string) {
|
||||
n.Notify(AgentWebhookEvent{
|
||||
EventType: "agent.escalation",
|
||||
AgentRum: rum,
|
||||
UserID: userID,
|
||||
Payload: map[string]interface{}{
|
||||
"rum": rum,
|
||||
"user_id": userID,
|
||||
"reason": reason,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// NotifyAgentError skickas när en agent stöter på ett fel
|
||||
func (n *AgentWebhookNotifier) NotifyAgentError(rum, userID, errorMsg string) {
|
||||
n.Notify(AgentWebhookEvent{
|
||||
EventType: "agent.error",
|
||||
AgentRum: rum,
|
||||
UserID: userID,
|
||||
Payload: map[string]interface{}{
|
||||
"rum": rum,
|
||||
"user_id": userID,
|
||||
"error": errorMsg,
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user