mirror of
https://github.com/fankes/beszel.git
synced 2025-10-20 02:09:28 +08:00
shoutrrr alerts / settings page
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
"log"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"github.com/containrrr/shoutrrr"
|
||||
"github.com/labstack/echo/v5"
|
||||
@@ -18,16 +17,21 @@ import (
|
||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||
)
|
||||
|
||||
type AlertManager struct {
|
||||
app *pocketbase.PocketBase
|
||||
}
|
||||
|
||||
type AlertData struct {
|
||||
User *models.Record
|
||||
UserID string
|
||||
Title string
|
||||
Message string
|
||||
Link string
|
||||
LinkText string
|
||||
}
|
||||
|
||||
type AlertManager struct {
|
||||
app *pocketbase.PocketBase
|
||||
type UserAlertSettings struct {
|
||||
Emails []string `json:"emails"`
|
||||
Webhooks []string `json:"webhooks"`
|
||||
}
|
||||
|
||||
func NewAlertManager(app *pocketbase.PocketBase) *AlertManager {
|
||||
@@ -107,7 +111,7 @@ func (am *AlertManager) handleSlidingValueAlert(newRecord *models.Record, alertR
|
||||
}
|
||||
if user := alertRecord.ExpandedOne("user"); user != nil {
|
||||
am.sendAlert(AlertData{
|
||||
User: user,
|
||||
UserID: user.GetId(),
|
||||
Title: subject,
|
||||
Message: body,
|
||||
Link: am.app.Settings().Meta.AppUrl + "/system/" + url.QueryEscape(systemName),
|
||||
@@ -146,7 +150,7 @@ func (am *AlertManager) handleStatusAlerts(newStatus string, oldRecord *models.R
|
||||
// send alert
|
||||
systemName := oldRecord.GetString("name")
|
||||
am.sendAlert(AlertData{
|
||||
User: user,
|
||||
UserID: user.GetId(),
|
||||
Title: fmt.Sprintf("Connection to %s is %s %v", systemName, alertStatus, emoji),
|
||||
Message: fmt.Sprintf("Connection to %s is %s", systemName, alertStatus),
|
||||
Link: am.app.Settings().Meta.AppUrl + "/system/" + url.QueryEscape(systemName),
|
||||
@@ -156,18 +160,42 @@ func (am *AlertManager) handleStatusAlerts(newStatus string, oldRecord *models.R
|
||||
}
|
||||
|
||||
func (am *AlertManager) sendAlert(data AlertData) {
|
||||
shoutrrrUrl := os.Getenv("SHOUTRRR_URL")
|
||||
if shoutrrrUrl != "" {
|
||||
err := am.SendShoutrrrAlert(shoutrrrUrl, data.Title, data.Message, data.Link, data.LinkText)
|
||||
if err == nil {
|
||||
log.Println("Sent shoutrrr alert")
|
||||
return
|
||||
}
|
||||
log.Println("Failed to send alert via shoutrrr, falling back to email notification. ", "err", err.Error())
|
||||
// get user settings
|
||||
record, err := am.app.Dao().FindFirstRecordByFilter(
|
||||
"user_settings", "user={:user}",
|
||||
dbx.Params{"user": data.UserID},
|
||||
)
|
||||
if err != nil {
|
||||
log.Println("Failed to get user settings", "err", err.Error())
|
||||
return
|
||||
}
|
||||
// unmarshal user settings
|
||||
userAlertSettings := UserAlertSettings{
|
||||
Emails: []string{},
|
||||
Webhooks: []string{},
|
||||
}
|
||||
if err := record.UnmarshalJSONField("settings", &userAlertSettings); err != nil {
|
||||
log.Println("Failed to unmarshal user settings", "err", err.Error())
|
||||
}
|
||||
// send alerts via webhooks
|
||||
for _, webhook := range userAlertSettings.Webhooks {
|
||||
err := am.SendShoutrrrAlert(webhook, data.Title, data.Message, data.Link, data.LinkText)
|
||||
if err != nil {
|
||||
am.app.Logger().Error("Failed to send shoutrrr alert", "err", err.Error())
|
||||
}
|
||||
}
|
||||
// send alerts via email
|
||||
if len(userAlertSettings.Emails) == 0 {
|
||||
log.Println("No email addresses found")
|
||||
return
|
||||
}
|
||||
addresses := []mail.Address{}
|
||||
for _, email := range userAlertSettings.Emails {
|
||||
addresses = append(addresses, mail.Address{Address: email})
|
||||
log.Println("Sending alert via email to", email)
|
||||
}
|
||||
// todo: email enable / disable and testing
|
||||
message := mailer.Message{
|
||||
To: []mail.Address{{Address: data.User.GetString("email")}},
|
||||
To: addresses,
|
||||
Subject: data.Title,
|
||||
Text: data.Message + fmt.Sprintf("\n\n%s", data.Link),
|
||||
From: mail.Address{
|
||||
|
8
beszel/internal/entities/user/user.go
Normal file
8
beszel/internal/entities/user/user.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package user
|
||||
|
||||
type UserSettings struct {
|
||||
// Language string `json:"lang"`
|
||||
ChartTime string `json:"chartTime"`
|
||||
NotificationEmails []string `json:"emails"`
|
||||
NotificationWebhooks []string `json:"webhooks"`
|
||||
}
|
@@ -4,6 +4,7 @@ import (
|
||||
"beszel"
|
||||
"beszel/internal/alerts"
|
||||
"beszel/internal/entities/system"
|
||||
"beszel/internal/entities/user"
|
||||
"beszel/internal/records"
|
||||
"beszel/site"
|
||||
"context"
|
||||
@@ -167,6 +168,36 @@ func (h *Hub) Run() {
|
||||
go h.updateSystem(e.Model.(*models.Record))
|
||||
return nil
|
||||
})
|
||||
// default user settings
|
||||
h.app.OnModelBeforeCreate("user_settings").Add(func(e *core.ModelEvent) error {
|
||||
record := e.Model.(*models.Record)
|
||||
// intialize settings with defaults
|
||||
settings := user.UserSettings{
|
||||
// Language: "en",
|
||||
ChartTime: "1h",
|
||||
NotificationEmails: []string{},
|
||||
NotificationWebhooks: []string{},
|
||||
}
|
||||
record.UnmarshalJSONField("settings", &settings)
|
||||
if len(settings.NotificationEmails) == 0 {
|
||||
// get user email from auth record
|
||||
if errs := h.app.Dao().ExpandRecord(record, []string{"user"}, nil); len(errs) == 0 {
|
||||
// app.Logger().Error("failed to expand user relation", "errs", errs)
|
||||
if user := record.ExpandedOne("user"); user != nil {
|
||||
settings.NotificationEmails = []string{user.GetString("email")}
|
||||
} else {
|
||||
log.Println("Failed to get user email from auth record")
|
||||
}
|
||||
} else {
|
||||
log.Println("failed to expand user relation", "errs", errs)
|
||||
}
|
||||
}
|
||||
// if len(settings.NotificationWebhooks) == 0 {
|
||||
// settings.NotificationWebhooks = []string{""}
|
||||
// }
|
||||
record.Set("settings", settings)
|
||||
return nil
|
||||
})
|
||||
|
||||
// do things after a systems record is updated
|
||||
h.app.OnModelAfterUpdate("systems").Add(func(e *core.ModelEvent) error {
|
||||
|
Reference in New Issue
Block a user