mirror of
https://github.com/fankes/beszel.git
synced 2025-10-20 02:09:28 +08:00
Add support for alerts via shoutrrr (#145)
* Add support for alerts via shoutrrr This provides users the ability to use a wide variety of notification platforms instead of just email. If there's a problem sending a notification via shoutrrr, an error is logged and email is attempted as a fallback. Since this uses Viper, users can set a notification type and URL via either a config file or environment variable. In the beszel_data folder (where the sqlite dbs reside), create an alerts.env file to set values that way. Values: * NOTIFICATION_TYPE * If this is `shoutrrr`, then the shoutrrr library is used. Any other value, including not being set, uses the fallback email behavior. * NOTIFICATION_URL * If NOTIFICATION_TYPE is shoutrrr, this is the URL given to shoutrrr to send the alert. See list of supported services: https://containrrr.dev/shoutrrr/services/overview/ Note: there's currently a bug in viper v1.18.2+ where environment variable overrides aren't functioning when no config file exists, so this library should remain pinned to 1.18.1 until that's fixed. See: https://github.com/spf13/viper/issues/1895 * Update documentation * Log shoutrrr URL instead of unused "to" var
This commit is contained in:
@@ -6,20 +6,53 @@ import (
|
||||
"fmt"
|
||||
"net/mail"
|
||||
|
||||
"github.com/containrrr/shoutrrr"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase"
|
||||
"github.com/pocketbase/pocketbase/models"
|
||||
"github.com/pocketbase/pocketbase/tools/mailer"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type AlertManager struct {
|
||||
app *pocketbase.PocketBase
|
||||
app *pocketbase.PocketBase
|
||||
config AlertConfig
|
||||
}
|
||||
|
||||
type AlertConfig struct {
|
||||
NotificationType string `mapstructure:"NOTIFICATION_TYPE"`
|
||||
NotificationURL string `mapstructure:"NOTIFICATION_URL"`
|
||||
}
|
||||
|
||||
func NewAlertManager(app *pocketbase.PocketBase) *AlertManager {
|
||||
return &AlertManager{
|
||||
app: app,
|
||||
config, configErr := loadConfig("beszel_data")
|
||||
if configErr != nil {
|
||||
app.Logger().Error("Error loading config from beszel_data: ", "err", configErr.Error())
|
||||
}
|
||||
|
||||
return &AlertManager{
|
||||
app: app,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func loadConfig(path string) (AlertConfig, error) {
|
||||
viper.AddConfigPath(path)
|
||||
viper.SetConfigName("alerts")
|
||||
viper.SetConfigType("env")
|
||||
|
||||
viper.AutomaticEnv()
|
||||
|
||||
config := AlertConfig{}
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); !ok {
|
||||
return config, err
|
||||
}
|
||||
}
|
||||
|
||||
err = viper.Unmarshal(&config)
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (am *AlertManager) HandleSystemAlerts(newStatus string, newRecord *models.Record, oldRecord *models.Record) {
|
||||
@@ -139,6 +172,17 @@ func (am *AlertManager) handleStatusAlerts(newStatus string, oldRecord *models.R
|
||||
|
||||
func (am *AlertManager) sendAlert(message *mailer.Message) {
|
||||
// fmt.Println("sending alert", "to", message.To, "subj", message.Subject, "body", message.Text)
|
||||
|
||||
if am.config.NotificationType == "shoutrrr" {
|
||||
err := shoutrrr.Send(am.config.NotificationURL, fmt.Sprintf("%s\n\n%s", message.Subject, message.Text))
|
||||
if err == nil {
|
||||
am.app.Logger().Info("Sent shoutrrr alert", "to", am.config.NotificationURL, "subj", message.Subject)
|
||||
return
|
||||
}
|
||||
|
||||
am.app.Logger().Error("Failed to send alert via shoutrrr, falling back to email notification. ", "err", err.Error())
|
||||
}
|
||||
|
||||
message.From = mail.Address{
|
||||
Address: am.app.Settings().Meta.SenderAddress,
|
||||
Name: am.app.Settings().Meta.SenderName,
|
||||
@@ -146,6 +190,6 @@ func (am *AlertManager) sendAlert(message *mailer.Message) {
|
||||
if err := am.app.NewMailClient().Send(message); err != nil {
|
||||
am.app.Logger().Error("Failed to send alert: ", "err", err.Error())
|
||||
} else {
|
||||
am.app.Logger().Info("Sent alert", "to", message.To, "subj", message.Subject)
|
||||
am.app.Logger().Info("Sent email alert", "to", message.To, "subj", message.Subject)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user