diff --git a/config/validate.go b/config/validate.go
index 5fcff58..ac865e9 100644
--- a/config/validate.go
+++ b/config/validate.go
@@ -70,51 +70,64 @@ func (c *Config) Validate() []string {
}
// Validate Discord
- if c.Alerts.Discord.Enabled {
- if results := c.validateDiscord(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.Discord {
+ if profile.Enabled {
+ if results := c.validateDiscord(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
// Validate Gotify
- if c.Alerts.Gotify.Enabled {
- if results := c.validateGotify(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.Gotify {
+ if profile.Enabled {
+ if results := c.validateGotify(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
// Validate SMTP
- if c.Alerts.SMTP.Enabled {
- if results := c.validateSMTP(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.SMTP {
+ if profile.Enabled {
+ if results := c.validateSMTP(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
-
// Validate Telegram
- if c.Alerts.Telegram.Enabled {
- if results := c.validateTelegram(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.Telegram {
+ if profile.Enabled {
+ if results := c.validateTelegram(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
// Validate Pushover
- if c.Alerts.Pushover.Enabled {
- if results := c.validatePushover(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.Pushover {
+ if profile.Enabled {
+ if results := c.validatePushover(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
// Validate Ntfy
- if c.Alerts.Ntfy.Enabled {
- if results := c.validateNtfy(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.Ntfy {
+ if profile.Enabled {
+ if results := c.validateNtfy(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
// Validate Webhook
- if c.Alerts.Webhook.Enabled {
- if results := c.validateWebhook(); len(results) > 0 {
- validationErrors = append(validationErrors, results...)
+ for id, profile := range c.Alerts.Webhook {
+ if profile.Enabled {
+ if results := c.validateWebhook(id); len(results) > 0 {
+ validationErrors = append(validationErrors, results...)
+ }
}
}
@@ -410,160 +423,160 @@ func (c *Config) validateLabelFiltering() []string {
return labelErrors
}
-func (c *Config) validateDiscord() []string {
+func (c *Config) validateDiscord(id int) []string {
var discordErrors []string
- log.Debug().Msg("Discord alerting enabled.")
- discordStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for Discord profile ID %v", id)
+ discordStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.Discord = append(Internal.Status.Notifications.Discord, discordStatus)
- if c.Alerts.Discord.Webhook == "" {
- discordErrors = append(discordErrors, "No Discord webhook specified!")
+ if c.Alerts.Discord[id].Webhook == "" {
+ discordErrors = append(discordErrors, fmt.Sprintf("No Discord webhook specified! Profile ID %v", id))
}
// Check template syntax
- if msg := validateTemplate("Discord", c.Alerts.Discord.Template); msg != "" {
- discordErrors = append(discordErrors, msg)
+ if msg := validateTemplate("Discord", c.Alerts.Discord[id].Template); msg != "" {
+ discordErrors = append(discordErrors, msg+fmt.Sprintf(" Profile ID %v", id))
}
return discordErrors
}
-func (c *Config) validateGotify() []string {
+func (c *Config) validateGotify(id int) []string {
var gotifyErrors []string
- log.Debug().Msg("Gotify alerting enabled.")
- gotifyStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for Gotify profile ID %v", id)
+ gotifyStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.Gotify = append(Internal.Status.Notifications.Gotify, gotifyStatus)
- if c.Alerts.Gotify.Server == "" {
- gotifyErrors = append(gotifyErrors, "No Gotify server specified!")
+ if c.Alerts.Gotify[id].Server == "" {
+ gotifyErrors = append(gotifyErrors, fmt.Sprintf("No Gotify server specified! Profile ID %v", id))
}
- if c.Alerts.Gotify.Token == "" {
- gotifyErrors = append(gotifyErrors, "No Gotify token specified!")
+ if c.Alerts.Gotify[id].Token == "" {
+ gotifyErrors = append(gotifyErrors, fmt.Sprintf("No Gotify token specified! Profile ID %v", id))
}
// Check if Gotify server URL contains protocol, assume HTTP if not specified
- if !strings.Contains(c.Alerts.Gotify.Server, "http://") && !strings.Contains(c.Alerts.Gotify.Server, "https://") {
- log.Debug().Msg("No protocol specified on Gotify Server. Assuming http://. If this is incorrect, please adjust the config file.")
- c.Alerts.Gotify.Server = fmt.Sprintf("http://%s", c.Alerts.Gotify.Server)
+ if !strings.Contains(c.Alerts.Gotify[id].Server, "http://") && !strings.Contains(c.Alerts.Gotify[id].Server, "https://") {
+ log.Debug().Msgf("No protocol specified on Gotify Server. Assuming http://. If this is incorrect, please adjust the config file. Profile ID %v", id)
+ c.Alerts.Gotify[id].Server = fmt.Sprintf("http://%s", c.Alerts.Gotify[id].Server)
}
// Check template syntax
- if msg := validateTemplate("Gotify", c.Alerts.Gotify.Template); msg != "" {
- gotifyErrors = append(gotifyErrors, msg)
+ if msg := validateTemplate("Gotify", c.Alerts.Gotify[id].Template); msg != "" {
+ gotifyErrors = append(gotifyErrors, msg+fmt.Sprintf(" Profile ID %v", id))
}
return gotifyErrors
}
-func (c *Config) validateSMTP() []string {
+func (c *Config) validateSMTP(id int) []string {
var smtpErrors []string
- log.Debug().Msg("SMTP alerting enabled.")
- smtpStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for SMTP profile ID %v", id)
+ smtpStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.SMTP = append(Internal.Status.Notifications.SMTP, smtpStatus)
- if c.Alerts.SMTP.Server == "" {
- smtpErrors = append(smtpErrors, "No SMTP server specified!")
+ if c.Alerts.SMTP[id].Server == "" {
+ smtpErrors = append(smtpErrors, fmt.Sprintf("No SMTP server specified! Profile ID %v", id))
}
- if c.Alerts.SMTP.Recipient == "" {
- smtpErrors = append(smtpErrors, "No SMTP recipients specified!")
+ if c.Alerts.SMTP[id].Recipient == "" {
+ smtpErrors = append(smtpErrors, fmt.Sprintf("No SMTP recipients specified! Profile ID %v", id))
}
- if c.Alerts.SMTP.User != "" && c.Alerts.SMTP.Password == "" {
- smtpErrors = append(smtpErrors, "SMTP username in config, but no password provided!")
+ if c.Alerts.SMTP[id].User != "" && c.Alerts.SMTP[id].Password == "" {
+ smtpErrors = append(smtpErrors, fmt.Sprintf("SMTP username in config, but no password provided! Profile ID %v", id))
}
- if c.Alerts.SMTP.Port == 0 {
- c.Alerts.SMTP.Port = 25
+ if c.Alerts.SMTP[id].Port == 0 {
+ c.Alerts.SMTP[id].Port = 25
}
// Copy `user` to `from` if `from` not explicitly configured
- if c.Alerts.SMTP.From == "" && c.Alerts.SMTP.User != "" {
- c.Alerts.SMTP.From = c.Alerts.SMTP.User
+ if c.Alerts.SMTP[id].From == "" && c.Alerts.SMTP[id].User != "" {
+ c.Alerts.SMTP[id].From = c.Alerts.SMTP[id].User
}
// Check template syntax
- if msg := validateTemplate("SMTP", c.Alerts.SMTP.Template); msg != "" {
- smtpErrors = append(smtpErrors, msg)
+ if msg := validateTemplate("SMTP", c.Alerts.SMTP[id].Template); msg != "" {
+ smtpErrors = append(smtpErrors, msg+fmt.Sprintf(" Profile ID %v", id))
}
return smtpErrors
}
-func (c *Config) validateTelegram() []string {
+func (c *Config) validateTelegram(id int) []string {
var telegramErrors []string
- log.Debug().Msg("Telegram alerting enabled.")
- telegramStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for Telegram profile ID %v", id)
+ telegramStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.Telegram = append(Internal.Status.Notifications.Telegram, telegramStatus)
- if c.Alerts.Telegram.ChatID == 0 {
- telegramErrors = append(telegramErrors, "No Telegram Chat ID specified!")
+ if c.Alerts.Telegram[id].ChatID == 0 {
+ telegramErrors = append(telegramErrors, fmt.Sprintf("No Telegram Chat ID specified! Profile ID %v", id))
}
- if c.Alerts.Telegram.Token == "" {
- telegramErrors = append(telegramErrors, "No Telegram bot token specified!")
+ if c.Alerts.Telegram[id].Token == "" {
+ telegramErrors = append(telegramErrors, fmt.Sprintf("No Telegram bot token specified! Profile ID %v", id))
}
// Check template syntax
- if msg := validateTemplate("Telegram", c.Alerts.Telegram.Template); msg != "" {
- telegramErrors = append(telegramErrors, msg)
+ if msg := validateTemplate("Telegram", c.Alerts.Telegram[id].Template); msg != "" {
+ telegramErrors = append(telegramErrors, msg+fmt.Sprintf(" Profile ID %v", id))
}
return telegramErrors
}
-func (c *Config) validatePushover() []string {
+func (c *Config) validatePushover(id int) []string {
var pushoverErrors []string
- log.Debug().Msg("Pushover alerting enabled.")
- pushoverStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for Pushover profile ID %v", id)
+ pushoverStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.Pushover = append(Internal.Status.Notifications.Pushover, pushoverStatus)
- if c.Alerts.Pushover.Token == "" {
- pushoverErrors = append(pushoverErrors, "No Pushover API token specified!")
+ if c.Alerts.Pushover[id].Token == "" {
+ pushoverErrors = append(pushoverErrors, fmt.Sprintf("No Pushover API token specified! Profile ID %v", id))
}
- if c.Alerts.Pushover.Userkey == "" {
- pushoverErrors = append(pushoverErrors, "No Pushover user key specified!")
+ if c.Alerts.Pushover[id].Userkey == "" {
+ pushoverErrors = append(pushoverErrors, fmt.Sprintf("No Pushover user key specified! Profile ID %v", id))
}
- if c.Alerts.Pushover.Priority < -2 || c.Alerts.Pushover.Priority > 2 {
- pushoverErrors = append(pushoverErrors, "Pushover priority must be between -2 and 2!")
+ if c.Alerts.Pushover[id].Priority < -2 || c.Alerts.Pushover[id].Priority > 2 {
+ pushoverErrors = append(pushoverErrors, fmt.Sprintf("Pushover priority must be between -2 and 2! Profile ID %v", id))
}
// Priority 2 is emergency, needs a retry interval & expiration set
- if c.Alerts.Pushover.Priority == 2 {
- if c.Alerts.Pushover.Retry == 0 || c.Alerts.Pushover.Expire == 0 {
- pushoverErrors = append(pushoverErrors, "Pushover retry interval & expiration must be set with priority 2!")
+ if c.Alerts.Pushover[id].Priority == 2 {
+ if c.Alerts.Pushover[id].Retry == 0 || c.Alerts.Pushover[id].Expire == 0 {
+ pushoverErrors = append(pushoverErrors, fmt.Sprintf("Pushover retry interval & expiration must be set with priority 2! Profile ID %v", id))
}
- if c.Alerts.Pushover.Retry < 30 {
- pushoverErrors = append(pushoverErrors, "Pushover retry cannot be less than 30 seconds!")
+ if c.Alerts.Pushover[id].Retry < 30 {
+ pushoverErrors = append(pushoverErrors, fmt.Sprintf("Pushover retry cannot be less than 30 seconds! Profile ID %v", id))
}
}
- if c.Alerts.Pushover.TTL < 0 {
- pushoverErrors = append(pushoverErrors, "Pushover TTL cannot be negative!")
+ if c.Alerts.Pushover[id].TTL < 0 {
+ pushoverErrors = append(pushoverErrors, fmt.Sprintf("Pushover TTL cannot be negative! Profile ID %v", id))
}
// Check template syntax
- if msg := validateTemplate("Pushover", c.Alerts.Pushover.Template); msg != "" {
- pushoverErrors = append(pushoverErrors, msg)
+ if msg := validateTemplate("Pushover", c.Alerts.Pushover[id].Template); msg != "" {
+ pushoverErrors = append(pushoverErrors, msg+fmt.Sprintf("Profile ID %v", id))
}
return pushoverErrors
}
-func (c *Config) validateNtfy() []string {
+func (c *Config) validateNtfy(id int) []string {
var ntfyErrors []string
- log.Debug().Msg("Ntfy alerting enabled.")
- ntfyStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for Ntfy profile ID %v", id)
+ ntfyStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.Ntfy = append(Internal.Status.Notifications.Ntfy, ntfyStatus)
- if c.Alerts.Ntfy.Server == "" {
- ntfyErrors = append(ntfyErrors, "No Ntfy server specified!")
+ if c.Alerts.Ntfy[id].Server == "" {
+ ntfyErrors = append(ntfyErrors, fmt.Sprintf("No Ntfy server specified! Profile ID %v", id))
}
- if c.Alerts.Ntfy.Topic == "" {
- ntfyErrors = append(ntfyErrors, "No Ntfy topic specified!")
+ if c.Alerts.Ntfy[id].Topic == "" {
+ ntfyErrors = append(ntfyErrors, fmt.Sprintf("No Ntfy topic specified! Profile ID %v", id))
}
// Check template syntax
- if msg := validateTemplate("Ntfy", c.Alerts.Ntfy.Template); msg != "" {
- ntfyErrors = append(ntfyErrors, msg)
+ if msg := validateTemplate("Ntfy", c.Alerts.Ntfy[id].Template); msg != "" {
+ ntfyErrors = append(ntfyErrors, msg+fmt.Sprintf("Profile ID %v", id))
}
// Check HTTP header template syntax
if msg := validateTemplate("Ntfy HTTP Headers", c.Alerts.General.Title); msg != "" {
- ntfyErrors = append(ntfyErrors, msg)
+ ntfyErrors = append(ntfyErrors, msg+fmt.Sprintf("Profile ID %v", id))
}
return ntfyErrors
}
-func (c *Config) validateWebhook() []string {
+func (c *Config) validateWebhook(id int) []string {
var webhookErrors []string
- log.Debug().Msg("Webhook alerting enabled.")
- webhookStatus := models.NotifierStatus{Enabled: true, Status: "configured, not used yet"}
+ log.Debug().Msgf("Alerting enabled for Webhook profile ID %v", id)
+ webhookStatus := models.NotifierStatus{ID: id, Enabled: true, Status: "configured, not used yet"}
Internal.Status.Notifications.Webhook = append(Internal.Status.Notifications.Webhook, webhookStatus)
- if c.Alerts.Webhook.Server == "" {
- webhookErrors = append(webhookErrors, "No Webhook server specified!")
+ if c.Alerts.Webhook[id].Server == "" {
+ webhookErrors = append(webhookErrors, fmt.Sprintf("No Webhook server specified! Profile ID %v", id))
}
// Check HTTP header template syntax
if msg := validateTemplate("Webhook HTTP Headers", c.Alerts.General.Title); msg != "" {
- webhookErrors = append(webhookErrors, msg)
+ webhookErrors = append(webhookErrors, msg+fmt.Sprintf("Profile ID %v", id))
}
return webhookErrors
@@ -571,26 +584,40 @@ func (c *Config) validateWebhook() []string {
func (c *Config) validateAlertingEnabled() string {
// Check to ensure at least one alert provider is configured
- if c.Alerts.Discord.Enabled {
- return ""
+ for _, profile := range c.Alerts.Discord {
+ if profile.Enabled {
+ return ""
+ }
}
- if c.Alerts.Gotify.Enabled {
- return ""
+ for _, profile := range c.Alerts.Gotify {
+ if profile.Enabled {
+ return ""
+ }
}
- if c.Alerts.SMTP.Enabled {
- return ""
+ for _, profile := range c.Alerts.SMTP {
+ if profile.Enabled {
+ return ""
+ }
}
- if c.Alerts.Telegram.Enabled {
- return ""
+ for _, profile := range c.Alerts.Telegram {
+ if profile.Enabled {
+ return ""
+ }
}
- if c.Alerts.Pushover.Enabled {
- return ""
+ for _, profile := range c.Alerts.Pushover {
+ if profile.Enabled {
+ return ""
+ }
}
- if c.Alerts.Ntfy.Enabled {
- return ""
+ for _, profile := range c.Alerts.Ntfy {
+ if profile.Enabled {
+ return ""
+ }
}
- if c.Alerts.Webhook.Enabled {
- return ""
+ for _, profile := range c.Alerts.Webhook {
+ if profile.Enabled {
+ return ""
+ }
}
return "No alerting methods have been configured. Please check config file syntax!"
}
diff --git a/config/validate_test.go b/config/validate_test.go
index 20ee0f9..17777d8 100644
--- a/config/validate_test.go
+++ b/config/validate_test.go
@@ -176,18 +176,19 @@ func TestValidateAlertGeneral(t *testing.T) {
func TestValidateDiscord(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Discord = make([]models.Discord, 1)
// Test valid config
- config.Alerts.Discord.Webhook = "https://something.test"
- result := config.validateDiscord()
+ config.Alerts.Discord[0].Webhook = "https://something.test"
+ result := config.validateDiscord(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing webhook config
- config.Alerts.Discord.Webhook = ""
- result = config.validateDiscord()
+ config.Alerts.Discord[0].Webhook = ""
+ result = config.validateDiscord(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -196,27 +197,28 @@ func TestValidateDiscord(t *testing.T) {
func TestValidateGotify(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Gotify = make([]models.Gotify, 1)
// Test valid config
- config.Alerts.Gotify.Server = "https://something.test"
- config.Alerts.Gotify.Token = "abcdefg"
- result := config.validateGotify()
+ config.Alerts.Gotify[0].Server = "https://something.test"
+ config.Alerts.Gotify[0].Token = "abcdefg"
+ result := config.validateGotify(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing server config
- config.Alerts.Gotify.Server = ""
- result = config.validateGotify()
+ config.Alerts.Gotify[0].Server = ""
+ result = config.validateGotify(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing token config
- config.Alerts.Gotify.Token = ""
- result = config.validateGotify()
+ config.Alerts.Gotify[0].Token = ""
+ result = config.validateGotify(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -225,47 +227,48 @@ func TestValidateGotify(t *testing.T) {
func TestValidateSMTP(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.SMTP = make([]models.SMTP, 1)
// Test valid config
- config.Alerts.SMTP.Server = "192.0.2.10"
- config.Alerts.SMTP.Recipient = "someone@none.test"
- config.Alerts.SMTP.User = "someuser"
- config.Alerts.SMTP.Password = "abcd"
- result := config.validateSMTP()
+ config.Alerts.SMTP[0].Server = "192.0.2.10"
+ config.Alerts.SMTP[0].Recipient = "someone@none.test"
+ config.Alerts.SMTP[0].User = "someuser"
+ config.Alerts.SMTP[0].Password = "abcd"
+ result := config.validateSMTP(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Check Default port set
- if config.Alerts.SMTP.Port != 25 {
- t.Errorf("Expected: port 25 , Got: %v", config.Alerts.SMTP.Port)
+ if config.Alerts.SMTP[0].Port != 25 {
+ t.Errorf("Expected: port 25 , Got: %v", config.Alerts.SMTP[0].Port)
}
// Check SMTP From is copied
- if config.Alerts.SMTP.User != config.Alerts.SMTP.From {
- t.Errorf("Expected: %v, Got: %v", config.Alerts.SMTP.User, config.Alerts.SMTP.From)
+ if config.Alerts.SMTP[0].User != config.Alerts.SMTP[0].From {
+ t.Errorf("Expected: %v, Got: %v", config.Alerts.SMTP[0].User, config.Alerts.SMTP[0].From)
}
// Test missing server
- config.Alerts.SMTP.Server = ""
- result = config.validateSMTP()
+ config.Alerts.SMTP[0].Server = ""
+ result = config.validateSMTP(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing recipient
- config.Alerts.SMTP.Recipient = ""
- result = config.validateSMTP()
+ config.Alerts.SMTP[0].Recipient = ""
+ result = config.validateSMTP(0)
expected = 2
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test invalid auth config
- config.Alerts.SMTP.Password = ""
- result = config.validateSMTP()
+ config.Alerts.SMTP[0].Password = ""
+ result = config.validateSMTP(0)
expected = 3
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -274,27 +277,28 @@ func TestValidateSMTP(t *testing.T) {
func TestValidateTelegram(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Telegram = make([]models.Telegram, 1)
// Test valid config
- config.Alerts.Telegram.ChatID = 1234
- config.Alerts.Telegram.Token = "abcd"
- result := config.validateTelegram()
+ config.Alerts.Telegram[0].ChatID = 1234
+ config.Alerts.Telegram[0].Token = "abcd"
+ result := config.validateTelegram(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing Chat ID
- config.Alerts.Telegram.ChatID = 0
- result = config.validateTelegram()
+ config.Alerts.Telegram[0].ChatID = 0
+ result = config.validateTelegram(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing Token
- config.Alerts.Telegram.Token = ""
- result = config.validateTelegram()
+ config.Alerts.Telegram[0].Token = ""
+ result = config.validateTelegram(0)
expected = 2
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -303,53 +307,54 @@ func TestValidateTelegram(t *testing.T) {
func TestValidatePushover(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Pushover = make([]models.Pushover, 1)
// Test valid config
- config.Alerts.Pushover.Token = "abcd"
- config.Alerts.Pushover.Userkey = "abcd"
- config.Alerts.Pushover.Priority = 1
- result := config.validatePushover()
+ config.Alerts.Pushover[0].Token = "abcd"
+ config.Alerts.Pushover[0].Userkey = "abcd"
+ config.Alerts.Pushover[0].Priority = 1
+ result := config.validatePushover(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing token
- config.Alerts.Pushover.Token = ""
- result = config.validatePushover()
+ config.Alerts.Pushover[0].Token = ""
+ result = config.validatePushover(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing Userkey
- config.Alerts.Pushover.Userkey = ""
- result = config.validatePushover()
+ config.Alerts.Pushover[0].Userkey = ""
+ result = config.validatePushover(0)
expected = 2
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test priority 2 missing retry / expiration config
- config.Alerts.Pushover.Priority = 2
- result = config.validatePushover()
+ config.Alerts.Pushover[0].Priority = 2
+ result = config.validatePushover(0)
expected = 4
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test priority 2 with low retry interval
- config.Alerts.Pushover.Retry = 2
- config.Alerts.Pushover.Expire = 10
- result = config.validatePushover()
+ config.Alerts.Pushover[0].Retry = 2
+ config.Alerts.Pushover[0].Expire = 10
+ result = config.validatePushover(0)
expected = 3
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test negative TTL
- config.Alerts.Pushover.TTL = -2
- result = config.validatePushover()
+ config.Alerts.Pushover[0].TTL = -2
+ result = config.validatePushover(0)
expected = 4
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -358,27 +363,28 @@ func TestValidatePushover(t *testing.T) {
func TestValidateNtfy(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Ntfy = make([]models.Ntfy, 1)
// Test valid config
- config.Alerts.Ntfy.Server = "https://ntfy.test"
- config.Alerts.Ntfy.Topic = "frigate"
- result := config.validateNtfy()
+ config.Alerts.Ntfy[0].Server = "https://ntfy.test"
+ config.Alerts.Ntfy[0].Topic = "frigate"
+ result := config.validateNtfy(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing server config
- config.Alerts.Ntfy.Server = ""
- result = config.validateNtfy()
+ config.Alerts.Ntfy[0].Server = ""
+ result = config.validateNtfy(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing topic config
- config.Alerts.Ntfy.Topic = ""
- result = config.validateNtfy()
+ config.Alerts.Ntfy[0].Topic = ""
+ result = config.validateNtfy(0)
expected = 2
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -386,18 +392,19 @@ func TestValidateNtfy(t *testing.T) {
}
func TestValidateWebhook(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Webhook = make([]models.Webhook, 1)
// Test valid config
- config.Alerts.Webhook.Server = "https://webhook.test"
- result := config.validateWebhook()
+ config.Alerts.Webhook[0].Server = "https://webhook.test"
+ result := config.validateWebhook(0)
expected := 0
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
}
// Test missing server config
- config.Alerts.Webhook.Server = ""
- result = config.validateWebhook()
+ config.Alerts.Webhook[0].Server = ""
+ result = config.validateWebhook(0)
expected = 1
if len(result) != expected {
t.Errorf("Expected: %v error(s), Got: %v", expected, result)
@@ -407,9 +414,10 @@ func TestValidateWebhook(t *testing.T) {
func TestValidateAlertingEnabled(t *testing.T) {
config := Config{Alerts: &models.Alerts{}}
+ config.Alerts.Discord = make([]models.Discord, 1)
// Test valid config
- config.Alerts.Discord.Enabled = true
+ config.Alerts.Discord[0].Enabled = true
result := config.validateAlertingEnabled()
expected := ""
if result != expected {
@@ -417,7 +425,7 @@ func TestValidateAlertingEnabled(t *testing.T) {
}
// Test missing server config
- config.Alerts.Discord.Enabled = false
+ config.Alerts.Discord[0].Enabled = false
result = config.validateAlertingEnabled()
if result == "" {
t.Errorf("Expected: error message, Got: %v", result)
diff --git a/events/events.go b/events/events.go
index 7c1ef70..b885e05 100644
--- a/events/events.go
+++ b/events/events.go
@@ -32,7 +32,7 @@ func processEvent(event models.Event) {
Msgf("Event start time: %s", eventTime)
// Check that event passes configured filters
- if !checkFilters(event) {
+ if !checkEventFilters(event) {
return
}
diff --git a/events/filters.go b/events/filters.go
index 51cd3cb..411390f 100644
--- a/events/filters.go
+++ b/events/filters.go
@@ -11,8 +11,8 @@ import (
"github.com/0x2142/frigate-notify/models"
)
-// checkFilters processes incoming event through configured filters to determine if it should generate a notification
-func checkFilters(event models.Event) bool {
+// checkEventFilters processes incoming event through configured filters to determine if it should generate a notification
+func checkEventFilters(event models.Event) bool {
// Check if notifications are currently disabled
if !config.Internal.Status.Notifications.Enabled {
log.Info().Msg("Event dropped - Notifications currently disabled.")
diff --git a/events/reviews.go b/events/reviews.go
index 0029f85..36c7d2c 100644
--- a/events/reviews.go
+++ b/events/reviews.go
@@ -67,7 +67,7 @@ func processReview(review models.Review) {
// Check that event passes configured filters
detection.CurrentZones = detection.Zones
- if !checkFilters(detection) {
+ if !checkEventFilters(detection) {
reviewFiltered = true
break
}
diff --git a/models/config.go b/models/config.go
index da4ae7c..529b9ed 100644
--- a/models/config.go
+++ b/models/config.go
@@ -47,18 +47,18 @@ type Cameras struct {
}
type Alerts struct {
- General General `fig:"general" json:"general,omitempty" doc:"Common alert settings"`
- Quiet Quiet `fig:"quiet" json:"quiet,omitempty" doc:"Alert quiet periods"`
- Zones Zones `fig:"zones" json:"zones,omitempty" doc:"Allow/Block zones from alerting"`
- Labels Labels `fig:"labels" json:"labels,omitempty" doc:"Allow/Block labels from alerting"`
- SubLabels Labels `fig:"sublabels" json:"sublabels,omitempty" doc:"Allow/Block sublabels from alerting"`
- Discord Discord `fig:"discord" json:"discord,omitempty" doc:"Discord notification settings"`
- Gotify Gotify `fig:"gotify" json:"gotify,omitempty" doc:"Gotify notification settings"`
- SMTP SMTP `fig:"smtp" json:"smtp,omitempty" doc:"SMTP notification settings"`
- Telegram Telegram `fig:"telegram" json:"telegram,omitempty" doc:"Telegram notification settings"`
- Pushover Pushover `fig:"pushover" json:"pushover,omitempty" doc:"Pushover notification settings"`
- Ntfy Ntfy `fig:"ntfy" json:"ntfy,omitempty" doc:"Ntfy notification settings"`
- Webhook Webhook `fig:"webhook" json:"webhook,omitempty" doc:"Webhook notification settings"`
+ General General `fig:"general" json:"general,omitempty" doc:"Common alert settings"`
+ Quiet Quiet `fig:"quiet" json:"quiet,omitempty" doc:"Alert quiet periods"`
+ Zones Zones `fig:"zones" json:"zones,omitempty" doc:"Allow/Block zones from alerting"`
+ Labels Labels `fig:"labels" json:"labels,omitempty" doc:"Allow/Block labels from alerting"`
+ SubLabels Labels `fig:"sublabels" json:"sublabels,omitempty" doc:"Allow/Block sublabels from alerting"`
+ Discord []Discord `fig:"discord" json:"discord,omitempty" doc:"Discord notification settings"`
+ Gotify []Gotify `fig:"gotify" json:"gotify,omitempty" doc:"Gotify notification settings"`
+ SMTP []SMTP `fig:"smtp" json:"smtp,omitempty" doc:"SMTP notification settings"`
+ Telegram []Telegram `fig:"telegram" json:"telegram,omitempty" doc:"Telegram notification settings"`
+ Pushover []Pushover `fig:"pushover" json:"pushover,omitempty" doc:"Pushover notification settings"`
+ Ntfy []Ntfy `fig:"ntfy" json:"ntfy,omitempty" doc:"Ntfy notification settings"`
+ Webhook []Webhook `fig:"webhook" json:"webhook,omitempty" doc:"Webhook notification settings"`
}
type General struct {
@@ -89,51 +89,64 @@ type Labels struct {
Block []string `fig:"block" json:"block,omitempty" doc:"List of labels to always block" default:[]`
}
+type AlertFilter struct {
+ Cameras []string `fig:"cameras" json:"cameras,omitempty" doc:"List of cameras that will use this alert provider`
+ Zones []string `fig:"zones" json:"zones,omitempty" doc:"List of zones that will use this alert provider`
+ Quiet Quiet `fig:"quiet" json:"quiet,omitempty" doc:"Quiet period for this alert provider"`
+ Labels []string `fig:"labels" json:"labels,omitempty" doc:"List of labels that will use this alert provider"`
+ Sublabels []string `fig:"sublabels" json:"sublabels,omitempty" doc:"List of sublabels that will use this alert provider"`
+}
+
type Discord struct {
- Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Discord" default:false`
- Webhook string `fig:"webhook" json:"webhook,omitempty" doc:"Discord webhook URL to send alerts" default:""`
- Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Discord" default:false`
+ Webhook string `fig:"webhook" json:"webhook,omitempty" doc:"Discord webhook URL to send alerts" default:""`
+ Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type Gotify struct {
- Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Gotify" default:false`
- Server string `fig:"server" json:"server,omitempty" doc:"Gotify server URL" default:""`
- Token string `fig:"token" json:"token,omitempty" doc:"Gotify app token" default:""`
- Insecure bool `fig:"ignoressl" json:"ignoressl,omitempty" doc:"Ignore TLS/SSL errors" default:false`
- Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Gotify" default:false`
+ Server string `fig:"server" json:"server,omitempty" doc:"Gotify server URL" default:""`
+ Token string `fig:"token" json:"token,omitempty" doc:"Gotify app token" default:""`
+ Insecure bool `fig:"ignoressl" json:"ignoressl,omitempty" doc:"Ignore TLS/SSL errors" default:false`
+ Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type SMTP struct {
- Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via SMTP" default:false`
- Server string `fig:"server" json:"server,omitempty" doc:"SMTP server hostname or IP address" default:""`
- Port int `fig:"port" json:"port,omitempty" minimum:"1" maximum:"65535" doc:"SMTP server port" default:25`
- TLS bool `fig:"tls" json:"tls,omitempty" enum:"true,false" doc:"Enable/Disable TLS connection" default:false`
- User string `fig:"user" json:"user,omitempty" doc:"SMTP user for authentication" default:""`
- Password string `fig:"password" json:"password,omitempty" doc:"SMTP password for authentication" default:""`
- From string `fig:"from" json:"from,omitempty" format:"email" doc:"SMTP sender" default:""`
- Recipient string `fig:"recipient" json:"recipient,omitempty" format:"email" doc:"SMTP recipient" default:""`
- Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
- Insecure bool `fig:"ignoressl" enum:"true,false" json:"ignoressl,omitempty" default:false`
+ Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via SMTP" default:false`
+ Server string `fig:"server" json:"server,omitempty" doc:"SMTP server hostname or IP address" default:""`
+ Port int `fig:"port" json:"port,omitempty" minimum:"1" maximum:"65535" doc:"SMTP server port" default:25`
+ TLS bool `fig:"tls" json:"tls,omitempty" enum:"true,false" doc:"Enable/Disable TLS connection" default:false`
+ User string `fig:"user" json:"user,omitempty" doc:"SMTP user for authentication" default:""`
+ Password string `fig:"password" json:"password,omitempty" doc:"SMTP password for authentication" default:""`
+ From string `fig:"from" json:"from,omitempty" format:"email" doc:"SMTP sender" default:""`
+ Recipient string `fig:"recipient" json:"recipient,omitempty" format:"email" doc:"SMTP recipient" default:""`
+ Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Insecure bool `fig:"ignoressl" enum:"true,false" json:"ignoressl,omitempty" default:false`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type Telegram struct {
- Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Telegram" default:false`
- ChatID int64 `fig:"chatid" json:"chatid,omitempty" minimum:"1" doc:"Telegram chat ID" default:"0"`
- Token string `fig:"token" json:"token,omitempty" doc:"Telegram bot token" default:""`
- Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Telegram" default:false`
+ ChatID int64 `fig:"chatid" json:"chatid,omitempty" minimum:"1" doc:"Telegram chat ID" default:"0"`
+ Token string `fig:"token" json:"token,omitempty" doc:"Telegram bot token" default:""`
+ Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type Pushover struct {
- Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Pushover" default:false`
- Token string `fig:"token" json:"token,omitempty" doc:"Pushover app token" default:""`
- Userkey string `fig:"userkey" json:"userkey,omitempty" doc:"Pushover user key" default:""`
- Devices string `fig:"devices" json:"devices,omitempty" doc:"Pushover devices to target for notification" default:""`
- Sound string `fig:"sound" json:"sound,omitempty" doc:"Pushover notification sound" default:"pushover"`
- Priority int `fig:"priority" json:"priority,omitempty" minimum:"-2" maximum:"2" doc:"Pushover message priority" default:"0"`
- Retry int `fig:"retry" json:"retry,omitempty" doc:"Retry interval for emergency notifications (Priority 2)" default:"0"`
- Expire int `fig:"expire" json:"expire,omitempty" doc:"Expiration timer for emergency notifications (Priority 2)" default:"0"`
- TTL int `fig:"ttl" json:"ttl,omitempty" doc:"Time to Live for notification messages" default:"0"`
- Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Enabled bool `fig:"enabled" json:"enabled" enum:"true,false" doc:"Enable notifications via Pushover" default:false`
+ Token string `fig:"token" json:"token,omitempty" doc:"Pushover app token" default:""`
+ Userkey string `fig:"userkey" json:"userkey,omitempty" doc:"Pushover user key" default:""`
+ Devices string `fig:"devices" json:"devices,omitempty" doc:"Pushover devices to target for notification" default:""`
+ Sound string `fig:"sound" json:"sound,omitempty" doc:"Pushover notification sound" default:"pushover"`
+ Priority int `fig:"priority" json:"priority,omitempty" minimum:"-2" maximum:"2" doc:"Pushover message priority" default:"0"`
+ Retry int `fig:"retry" json:"retry,omitempty" doc:"Retry interval for emergency notifications (Priority 2)" default:"0"`
+ Expire int `fig:"expire" json:"expire,omitempty" doc:"Expiration timer for emergency notifications (Priority 2)" default:"0"`
+ TTL int `fig:"ttl" json:"ttl,omitempty" doc:"Time to Live for notification messages" default:"0"`
+ Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type Ntfy struct {
@@ -143,6 +156,7 @@ type Ntfy struct {
Insecure bool `fig:"ignoressl" json:"ignoressl,omitempty" doc:"Ignore TLS/SSL errors" default:false`
Headers []map[string]string `fig:"headers" json:"headers,omitempty" doc:"HTTP headers to include with Ntfy notifications" default:[]`
Template string `fig:"template" json:"template,omitempty" doc:"Custom message template" default:""`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type Webhook struct {
@@ -153,6 +167,7 @@ type Webhook struct {
Params []map[string]string `fix:"params" json:"params,omitempty" doc:"URL parameters for webhook notifications"`
Headers []map[string]string `fig:"headers" json:"headers,omitempty" doc:"HTTP headers for webhook notifications"`
Template interface{} `fig:"template" json:"template,omitempty" doc:"Custom message template"`
+ Filters AlertFilter `fig:"filters" json:"filters,omitempty" doc:"Filter notifications sent via this provider"`
}
type Monitor struct {
diff --git a/notifier/alerts.go b/notifier/alerts.go
index cafeedb..7f89024 100644
--- a/notifier/alerts.go
+++ b/notifier/alerts.go
@@ -21,6 +21,11 @@ import (
var TemplateFiles embed.FS
+type notifMeta struct {
+ name string
+ index int
+}
+
// SendAlert forwards alert information to all enabled alerting methods
func SendAlert(event models.Event) {
config.Internal.Status.LastNotification = time.Now()
@@ -43,26 +48,68 @@ func SendAlert(event models.Event) {
}
// Send Alerts
- if config.ConfigData.Alerts.Discord.Enabled {
- go SendDiscordMessage(event, bytes.NewReader(snap))
+ // Discord
+ for id, profile := range config.ConfigData.Alerts.Discord {
+ if profile.Enabled {
+ provider := notifMeta{name: "discord", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendDiscordMessage(event, bytes.NewReader(snap), provider)
+ }
+ }
}
- if config.ConfigData.Alerts.Gotify.Enabled {
- go SendGotifyPush(event)
+ // Gotify
+ for id, profile := range config.ConfigData.Alerts.Gotify {
+ if profile.Enabled {
+ provider := notifMeta{name: "gotify", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendGotifyPush(event, provider)
+ }
+ }
}
- if config.ConfigData.Alerts.SMTP.Enabled {
- go SendSMTP(event, bytes.NewReader(snap))
+ // SMTP
+ for id, profile := range config.ConfigData.Alerts.SMTP {
+ if profile.Enabled {
+ provider := notifMeta{name: "smtp", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendSMTP(event, bytes.NewReader(snap), provider)
+ }
+ }
}
- if config.ConfigData.Alerts.Telegram.Enabled {
- go SendTelegramMessage(event, bytes.NewReader(snap))
+ // Telegram
+ for id, profile := range config.ConfigData.Alerts.Telegram {
+ if profile.Enabled {
+ provider := notifMeta{name: "telegram", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendTelegramMessage(event, bytes.NewReader(snap), provider)
+ }
+ }
}
- if config.ConfigData.Alerts.Pushover.Enabled {
- go SendPushoverMessage(event, bytes.NewReader(snap))
+ // Pushover
+ for id, profile := range config.ConfigData.Alerts.Pushover {
+ if profile.Enabled {
+ provider := notifMeta{name: "pushover", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendPushoverMessage(event, bytes.NewReader(snap), provider)
+ }
+ }
}
- if config.ConfigData.Alerts.Ntfy.Enabled {
- go SendNtfyPush(event, bytes.NewReader(snap))
+ // Ntfy
+ for id, profile := range config.ConfigData.Alerts.Ntfy {
+ if profile.Enabled {
+ provider := notifMeta{name: "ntfy", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendNtfyPush(event, bytes.NewReader(snap), provider)
+ }
+ }
}
- if config.ConfigData.Alerts.Webhook.Enabled {
- go SendWebhook(event)
+ // Webhook
+ for id, profile := range config.ConfigData.Alerts.Webhook {
+ if profile.Enabled {
+ provider := notifMeta{name: "webhook", index: id}
+ if checkAlertFilters(event, profile.Filters, provider) {
+ go SendWebhook(event, provider)
+ }
+ }
}
}
diff --git a/notifier/discord.go b/notifier/discord.go
index ed70743..d2fa7dc 100644
--- a/notifier/discord.go
+++ b/notifier/discord.go
@@ -14,22 +14,25 @@ import (
)
// SendDiscordMessage pushes alert message to Discord via webhook
-func SendDiscordMessage(event models.Event, snapshot io.Reader) {
+func SendDiscordMessage(event models.Event, snapshot io.Reader, provider notifMeta) {
+ profile := config.ConfigData.Alerts.Discord[provider.index]
+
var err error
var message string
// Build notification
- if config.ConfigData.Alerts.Discord.Template != "" {
- message = renderMessage(config.ConfigData.Alerts.Discord.Template, event, "message", "Discord")
+ if profile.Template != "" {
+ message = renderMessage(profile.Template, event, "message", "Discord")
} else {
message = renderMessage("markdown", event, "message", "Discord")
}
// Connect to Discord
- client, err := webhook.NewWithURL(config.ConfigData.Alerts.Discord.Webhook)
+ client, err := webhook.NewWithURL(profile.Webhook)
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Discord").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Discord[0].NotifFailure(err.Error())
@@ -48,6 +51,7 @@ func SendDiscordMessage(event models.Event, snapshot io.Reader) {
msg, err = client.CreateMessage(discord.NewWebhookMessageCreateBuilder().SetEmbeds(embed).SetFiles(image).Build())
log.Trace().
Str("event_id", event.ID).
+ Int("provider_id", provider.index).
Interface("payload", msg).
Msg("Send Discord Alert")
@@ -56,6 +60,7 @@ func SendDiscordMessage(event models.Event, snapshot io.Reader) {
msg, err = client.CreateMessage(discord.NewWebhookMessageCreateBuilder().SetEmbeds(embed).Build())
log.Trace().
Str("event_id", event.ID).
+ Int("provider_id", provider.index).
Interface("payload", msg).
Msg("Send Discord Alert")
}
@@ -63,6 +68,7 @@ func SendDiscordMessage(event models.Event, snapshot io.Reader) {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Discord").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Discord[0].NotifFailure(err.Error())
@@ -70,6 +76,7 @@ func SendDiscordMessage(event models.Event, snapshot io.Reader) {
log.Info().
Str("event_id", event.ID).
Str("provider", "Discord").
+ Int("provider_id", provider.index).
Msg("Alert sent")
config.Internal.Status.Notifications.Discord[0].NotifSuccess()
}
diff --git a/notifier/filters.go b/notifier/filters.go
new file mode 100644
index 0000000..86982ee
--- /dev/null
+++ b/notifier/filters.go
@@ -0,0 +1,134 @@
+package notifier
+
+import (
+ "slices"
+ "time"
+
+ "github.com/0x2142/frigate-notify/models"
+ "github.com/rs/zerolog/log"
+)
+
+// checkAlertFilters will determine which notification provider is able to send this alert
+func checkAlertFilters(event models.Event, filters models.AlertFilter, provider notifMeta) bool {
+ log.Trace().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Checking alert filters")
+
+ // Check against quiet hours
+ currentTime, _ := time.Parse("15:04:05", time.Now().Format("15:04:05"))
+ start, _ := time.Parse("15:04", filters.Quiet.Start)
+ end, _ := time.Parse("15:04", filters.Quiet.End)
+ log.Trace().
+ Time("current_time", currentTime).
+ Time("quiet_start", start).
+ Time("quiet_end", end).
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Check quiet hours")
+ // Check if quiet period is overnight
+ if end.Before(start) {
+ if currentTime.After(start) || currentTime.Before(end) {
+ log.Debug().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Notification droppped - Quiet hours")
+ return false
+ }
+ }
+ // Otherwise check if between start & end times
+ if currentTime.After(start) && currentTime.Before(end) {
+ log.Debug().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Notification droppped - Quiet hours")
+ return false
+ }
+
+ // Check filtered cameras
+ log.Trace().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Str("camera", event.Camera).
+ Strs("allowed", filters.Cameras).
+ Msg("Check allowed cameras")
+ if len(filters.Cameras) >= 1 {
+ if !slices.Contains(filters.Cameras, event.Camera) {
+ log.Debug().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Notification droppped - Camera not on filter list")
+ return false
+ }
+ }
+
+ // Check filtered zones
+ log.Trace().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Strs("zones", event.CurrentZones).
+ Strs("allowed", filters.Zones).
+ Msg("Check allowed zone")
+ if len(filters.Zones) >= 1 {
+ matchzone := false
+ for _, zone := range event.CurrentZones {
+ if slices.Contains(filters.Zones, zone) {
+ matchzone = true
+ }
+ }
+ if !matchzone {
+ log.Debug().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Notification droppped - Zone not on filter list")
+ return false
+ }
+ }
+
+ // Check filtered Labels
+ log.Trace().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Str("label", event.Label).
+ Strs("allowed", filters.Labels).
+ Msg("Check allowed label")
+ if len(filters.Labels) >= 1 {
+ if !slices.Contains(filters.Labels, event.Label) {
+ log.Debug().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Notification droppped - Label not on filter list")
+ return false
+ }
+ }
+
+ // Check filtered Sublabels
+ log.Trace().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Strs("label", event.SubLabel).
+ Strs("allowed", filters.Sublabels).
+ Msg("Check allowed sublabel")
+ if len(filters.Sublabels) >= 1 {
+ matchsublabel := false
+ for _, sublabel := range event.SubLabel {
+ if slices.Contains(filters.Sublabels, sublabel) {
+ matchsublabel = true
+ }
+ }
+ if !matchsublabel {
+ log.Debug().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Notification droppped - Sublabel not on filter list")
+ return false
+ }
+ }
+
+ // Alert permitted if all conditions pass
+ log.Trace().
+ Str("provider", provider.name).
+ Int("provider_id", provider.index).
+ Msg("Alert filters passed!")
+ return true
+}
diff --git a/notifier/gotify.go b/notifier/gotify.go
index bb57106..8205420 100644
--- a/notifier/gotify.go
+++ b/notifier/gotify.go
@@ -35,7 +35,9 @@ type gotifyPayload struct {
}
// SendGotifyPush forwards alert messages to Gotify push notification server
-func SendGotifyPush(event models.Event) {
+func SendGotifyPush(event models.Event, provider notifMeta) {
+ profile := config.ConfigData.Alerts.Gotify[provider.index]
+
var snapshotURL string
if config.ConfigData.Frigate.PublicURL != "" {
snapshotURL = config.ConfigData.Frigate.PublicURL + "/api/events/" + event.ID + "/snapshot.jpg"
@@ -44,8 +46,8 @@ func SendGotifyPush(event models.Event) {
}
// Build notification
var message string
- if config.ConfigData.Alerts.Gotify.Template != "" {
- message = renderMessage(config.ConfigData.Alerts.Gotify.Template, event, "message", "Gotify")
+ if profile.Template != "" {
+ message = renderMessage(profile.Template, event, "message", "Gotify")
} else {
message = renderMessage("markdown", event, "message", "Gotify")
}
@@ -68,20 +70,22 @@ func SendGotifyPush(event models.Event) {
Str("event_id", event.ID).
Str("provider", "Gotify").
Err(err).
+ Int("provider_id", provider.index).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Gotify[0].NotifFailure(err.Error())
return
}
- gotifyURL := fmt.Sprintf("%s/message?token=%s&", config.ConfigData.Alerts.Gotify.Server, config.ConfigData.Alerts.Gotify.Token)
+ gotifyURL := fmt.Sprintf("%s/message?token=%s&", profile.Server, profile.Token)
header := map[string]string{"Content-Type": "application/json"}
- response, err := util.HTTPPost(gotifyURL, config.ConfigData.Alerts.Gotify.Insecure, data, "", header)
+ response, err := util.HTTPPost(gotifyURL, profile.Insecure, data, "", header)
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Gotify").
Err(err).
+ Int("provider_id", provider.index).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Gotify[0].NotifFailure(err.Error())
return
@@ -93,6 +97,7 @@ func SendGotifyPush(event models.Event) {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Gotify").
+ Int("provider_id", provider.index).
Msgf("Unable to send alert: %v - %v", errorMessage.Error, errorMessage.ErrorDescription)
config.Internal.Status.Notifications.Gotify[0].NotifFailure(errorMessage.ErrorDescription)
return
@@ -100,6 +105,7 @@ func SendGotifyPush(event models.Event) {
log.Info().
Str("event_id", event.ID).
Str("provider", "Gotify").
+ Int("provider_id", provider.index).
Msg("Alert sent")
config.Internal.Status.Notifications.Gotify[0].NotifSuccess()
}
diff --git a/notifier/nfty.go b/notifier/nfty.go
index 94896f6..4c58e81 100644
--- a/notifier/nfty.go
+++ b/notifier/nfty.go
@@ -13,23 +13,25 @@ import (
)
// SendNtfyPush forwards alert messages to Ntfy server
-func SendNtfyPush(event models.Event, snapshot io.Reader) {
+func SendNtfyPush(event models.Event, snapshot io.Reader, provider notifMeta) {
+ profile := config.ConfigData.Alerts.Ntfy[provider.index]
+
// Build notification
var message string
- if config.ConfigData.Alerts.Ntfy.Template != "" {
- message = renderMessage(config.ConfigData.Alerts.Ntfy.Template, event, "message", "Ntfy")
+ if profile.Template != "" {
+ message = renderMessage(profile.Template, event, "message", "Ntfy")
} else {
message = renderMessage("plaintext", event, "message", "Ntfy")
}
- NtfyURL := fmt.Sprintf("%s/%s", config.ConfigData.Alerts.Ntfy.Server, config.ConfigData.Alerts.Ntfy.Topic)
+ NtfyURL := fmt.Sprintf("%s/%s", profile.Server, profile.Topic)
// Set headers
title := renderMessage(config.ConfigData.Alerts.General.Title, event, "title", "Ntfy")
var headers []map[string]string
headers = append(headers, map[string]string{"Content-Type": "text/markdown"})
headers = append(headers, map[string]string{"X-Title": title})
- headers = append(headers, config.ConfigData.Alerts.Ntfy.Headers...)
+ headers = append(headers, profile.Headers...)
var attachment []byte
if event.HasSnapshot {
@@ -59,11 +61,12 @@ func SendNtfyPush(event models.Event, snapshot io.Reader) {
headers = renderHTTPKV(headers, event, "headers", "Ntfy")
- resp, err := util.HTTPPost(NtfyURL, config.ConfigData.Alerts.Ntfy.Insecure, attachment, "", headers...)
+ resp, err := util.HTTPPost(NtfyURL, profile.Insecure, attachment, "", headers...)
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Ntfy").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Ntfy[0].NotifFailure(err.Error())
@@ -75,6 +78,7 @@ func SendNtfyPush(event models.Event, snapshot io.Reader) {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Ntfy").
+ Int("provider_id", provider.index).
Str("error", string(resp)).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Ntfy[0].NotifFailure(string(resp))
@@ -83,6 +87,7 @@ func SendNtfyPush(event models.Event, snapshot io.Reader) {
log.Info().
Str("event_id", event.ID).
+ Int("provider_id", provider.index).
Str("provider", "Ntfy").
Msg("Alert sent")
config.Internal.Status.Notifications.Ntfy[0].NotifSuccess()
diff --git a/notifier/pushover.go b/notifier/pushover.go
index 4db924e..38ec335 100644
--- a/notifier/pushover.go
+++ b/notifier/pushover.go
@@ -13,45 +13,48 @@ import (
)
// SendPushoverMessage sends alert message through Pushover service
-func SendPushoverMessage(event models.Event, snapshot io.Reader) {
+func SendPushoverMessage(event models.Event, snapshot io.Reader, provider notifMeta) {
+ profile := config.ConfigData.Alerts.Pushover[provider.index]
+
// Build notification
var message string
- if config.ConfigData.Alerts.Pushover.Template != "" {
- message = renderMessage(config.ConfigData.Alerts.Pushover.Template, event, "message", "Pushover")
+ if profile.Template != "" {
+ message = renderMessage(profile.Template, event, "message", "Pushover")
} else {
message = renderMessage("html", event, "message", "Pushover")
message = strings.ReplaceAll(message, "
", "")
}
- push := pushover.New(config.ConfigData.Alerts.Pushover.Token)
- recipient := pushover.NewRecipient(config.ConfigData.Alerts.Pushover.Userkey)
+ push := pushover.New(profile.Token)
+ recipient := pushover.NewRecipient(profile.Userkey)
// Create new message
title := renderMessage(config.ConfigData.Alerts.General.Title, event, "title", "Pushover")
notif := &pushover.Message{
Message: message,
Title: title,
- Priority: config.ConfigData.Alerts.Pushover.Priority,
- Sound: config.ConfigData.Alerts.Pushover.Sound,
+ Priority: profile.Priority,
+ Sound: profile.Sound,
HTML: true,
- TTL: time.Duration(config.ConfigData.Alerts.Pushover.TTL) * time.Second,
+ TTL: time.Duration(profile.TTL) * time.Second,
}
// If emergency priority, set retry / expiration
if notif.Priority == 2 {
- notif.Retry = time.Duration(config.ConfigData.Alerts.Pushover.Retry) * time.Second
- notif.Expire = time.Duration(config.ConfigData.Alerts.Pushover.Expire) * time.Second
+ notif.Retry = time.Duration(profile.Retry) * time.Second
+ notif.Expire = time.Duration(profile.Expire) * time.Second
}
// Add target devices if specified
- if config.ConfigData.Alerts.Pushover.Devices != "" {
- devices := strings.ReplaceAll(config.ConfigData.Alerts.Pushover.Devices, " ", "")
+ if profile.Devices != "" {
+ devices := strings.ReplaceAll(profile.Devices, " ", "")
notif.DeviceName = devices
}
log.Trace().
Interface("payload", notif).
Interface("recipient", "--secret removed--").
+ Int("provider_id", provider.index).
Msg("Send Pushover alert")
// Send notification
@@ -60,11 +63,13 @@ func SendPushoverMessage(event models.Event, snapshot io.Reader) {
response, err := push.SendMessage(notif, recipient)
log.Trace().
Interface("payload", response).
+ Int("provider_id", provider.index).
Msg("Pushover response")
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Pushover").
+ Int("provider_id", provider.index).
Msgf("Unable to send alert: %v", err)
config.Internal.Status.Notifications.Pushover[0].NotifFailure(err.Error())
return
@@ -73,11 +78,13 @@ func SendPushoverMessage(event models.Event, snapshot io.Reader) {
response, err := push.SendMessage(notif, recipient)
log.Trace().
Interface("payload", response).
+ Int("provider_id", provider.index).
Msg("Pushover response")
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Pushover").
+ Int("provider_id", provider.index).
Msgf("Unable to send alert: %v", err)
config.Internal.Status.Notifications.Pushover[0].NotifFailure(err.Error())
return
@@ -87,6 +94,7 @@ func SendPushoverMessage(event models.Event, snapshot io.Reader) {
log.Info().
Str("event_id", event.ID).
Str("provider", "Pushover").
+ Int("provider_id", provider.index).
Msgf("Alert sent")
config.Internal.Status.Notifications.Pushover[0].NotifSuccess()
diff --git a/notifier/smtp.go b/notifier/smtp.go
index 8b5b2f1..e0ae2be 100644
--- a/notifier/smtp.go
+++ b/notifier/smtp.go
@@ -14,19 +14,21 @@ import (
)
// SendSMTP forwards alert data via email
-func SendSMTP(event models.Event, snapshot io.Reader) {
+func SendSMTP(event models.Event, snapshot io.Reader, provider notifMeta) {
+ profile := config.ConfigData.Alerts.SMTP[provider.index]
+
// Build notification
var message string
- if config.ConfigData.Alerts.SMTP.Template != "" {
- message = renderMessage(config.ConfigData.Alerts.SMTP.Template, event, "message", "SMTP")
+ if profile.Template != "" {
+ message = renderMessage(profile.Template, event, "message", "SMTP")
} else {
message = renderMessage("html", event, "message", "SMTP")
}
// Set up email alert
m := mail.NewMsg()
- m.From(config.ConfigData.Alerts.SMTP.From)
- m.To(ParseSMTPRecipients()...)
+ m.From(profile.From)
+ m.To(ParseSMTPRecipients(profile.Recipient)...)
title := renderMessage(config.ConfigData.Alerts.General.Title, event, "title", "SMTP")
m.Subject(title)
// Attach snapshot if one exists
@@ -40,19 +42,19 @@ func SendSMTP(event models.Event, snapshot io.Reader) {
time.Sleep(5 * time.Second)
// Set up SMTP Connection
- c, err := mail.NewClient(config.ConfigData.Alerts.SMTP.Server, mail.WithPort(config.ConfigData.Alerts.SMTP.Port))
+ c, err := mail.NewClient(profile.Server, mail.WithPort(profile.Port))
// Add authentication params if needed
- if config.ConfigData.Alerts.SMTP.User != "" && config.ConfigData.Alerts.SMTP.Password != "" {
+ if profile.User != "" && profile.Password != "" {
c.SetSMTPAuth(mail.SMTPAuthPlain)
- c.SetUsername(config.ConfigData.Alerts.SMTP.User)
- c.SetPassword(config.ConfigData.Alerts.SMTP.Password)
+ c.SetUsername(profile.User)
+ c.SetPassword(profile.Password)
}
// Mandatory TLS is enabled by default, so disable TLS if config flag is set
- if !config.ConfigData.Alerts.SMTP.TLS {
+ if !profile.TLS {
c.SetTLSPolicy(mail.NoTLS)
}
// Disable certificate verification if needed
- if config.ConfigData.Alerts.SMTP.Insecure {
+ if profile.Insecure {
c.SetTLSConfig(&tls.Config{InsecureSkipVerify: true})
}
@@ -61,6 +63,7 @@ func SendSMTP(event models.Event, snapshot io.Reader) {
Str("event_id", event.ID).
Str("provider", "SMTP").
Err(err).
+ Int("provider_id", provider.index).
Msg("Unable to send alert")
config.Internal.Status.Notifications.SMTP[0].NotifFailure(err.Error())
}
@@ -70,11 +73,12 @@ func SendSMTP(event models.Event, snapshot io.Reader) {
Strs("recipients", m.GetToString()).
Str("subject", title).
Interface("payload", message).
- Str("server", config.ConfigData.Alerts.SMTP.Server).
- Int("port", config.ConfigData.Alerts.SMTP.Port).
- Bool("tls", config.ConfigData.Alerts.SMTP.TLS).
- Str("username", config.ConfigData.Alerts.SMTP.User).
+ Str("server", profile.Server).
+ Int("port", profile.Port).
+ Bool("tls", profile.TLS).
+ Str("username", profile.User).
Str("password", "--secret removed--").
+ Int("provider_id", provider.index).
Msg("Send SMTP Alert")
// Send message
@@ -82,6 +86,7 @@ func SendSMTP(event models.Event, snapshot io.Reader) {
log.Warn().
Str("event_id", event.ID).
Str("provider", "SMTP").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.SMTP[0].NotifFailure(err.Error())
@@ -90,14 +95,15 @@ func SendSMTP(event models.Event, snapshot io.Reader) {
log.Info().
Str("event_id", event.ID).
Str("provider", "SMTP").
+ Int("provider_id", provider.index).
Msg("Alert sent")
config.Internal.Status.Notifications.SMTP[0].NotifSuccess()
}
// ParseSMTPRecipients splits individual email addresses from config file
-func ParseSMTPRecipients() []string {
+func ParseSMTPRecipients(recipientList string) []string {
var recipients []string
- list := strings.Split(config.ConfigData.Alerts.SMTP.Recipient, ",")
+ list := strings.Split(recipientList, ",")
for _, addr := range list {
recipients = append(recipients, strings.TrimSpace(addr))
}
diff --git a/notifier/telegram.go b/notifier/telegram.go
index b9a67bd..6294165 100644
--- a/notifier/telegram.go
+++ b/notifier/telegram.go
@@ -12,21 +12,24 @@ import (
)
// SendTelegramMessage sends alert through Telegram to individual users
-func SendTelegramMessage(event models.Event, snapshot io.Reader) {
+func SendTelegramMessage(event models.Event, snapshot io.Reader, provider notifMeta) {
+ profile := config.ConfigData.Alerts.Telegram[provider.index]
+
// Build notification
var message string
- if config.ConfigData.Alerts.Telegram.Template != "" {
- message = renderMessage(config.ConfigData.Alerts.Telegram.Template, event, "message", "Telegram")
+ if profile.Template != "" {
+ message = renderMessage(profile.Template, event, "message", "Telegram")
} else {
message = renderMessage("html", event, "message", "Telegram")
message = strings.ReplaceAll(message, "
", "")
}
- bot, err := tgbotapi.NewBotAPI(config.ConfigData.Alerts.Telegram.Token)
+ bot, err := tgbotapi.NewBotAPI(profile.Token)
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Telegram").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Telegram[0].NotifFailure(err.Error())
@@ -36,17 +39,19 @@ func SendTelegramMessage(event models.Event, snapshot io.Reader) {
if event.HasSnapshot {
// Attach & send snapshot
- photo := tgbotapi.NewPhoto(config.ConfigData.Alerts.Telegram.ChatID, tgbotapi.FileReader{Name: "Snapshot", Reader: snapshot})
+ photo := tgbotapi.NewPhoto(profile.ChatID, tgbotapi.FileReader{Name: "Snapshot", Reader: snapshot})
photo.Caption = message
photo.ParseMode = "HTML"
response, err := bot.Send(photo)
log.Trace().
Interface("content", response).
+ Int("provider_id", provider.index).
Msg("Send Telegram Alert")
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Telegram").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Telegram[0].NotifFailure(err.Error())
@@ -54,16 +59,18 @@ func SendTelegramMessage(event models.Event, snapshot io.Reader) {
}
} else {
// Send plain text message if no snapshot available
- msg := tgbotapi.NewMessage(config.ConfigData.Alerts.Telegram.ChatID, message)
+ msg := tgbotapi.NewMessage(profile.ChatID, message)
msg.ParseMode = "HTML"
response, err := bot.Send(msg)
log.Trace().
Interface("content", response).
+ Int("provider_id", provider.index).
Msg("Send Telegram Alert")
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Telegram").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Telegram[0].NotifFailure(err.Error())
@@ -73,6 +80,7 @@ func SendTelegramMessage(event models.Event, snapshot io.Reader) {
log.Info().
Str("event_id", event.ID).
Str("provider", "Telegram").
+ Int("provider_id", provider.index).
Msg("Alert sent")
config.Internal.Status.Notifications.Telegram[0].NotifSuccess()
}
diff --git a/notifier/webhook.go b/notifier/webhook.go
index d197264..6e6da16 100644
--- a/notifier/webhook.go
+++ b/notifier/webhook.go
@@ -12,14 +12,17 @@ import (
)
// SendWebhook sends alert through HTTP POST to target webhook
-func SendWebhook(event models.Event) {
+func SendWebhook(event models.Event, provider notifMeta) {
+ profile := config.ConfigData.Alerts.Webhook[provider.index]
+
// Build notification
var message string
- payload, err := json.Marshal(config.ConfigData.Alerts.Webhook.Template)
+ payload, err := json.Marshal(profile.Template)
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Webhook").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Webhook[0].NotifFailure(err.Error())
@@ -31,20 +34,21 @@ func SendWebhook(event models.Event) {
message = renderMessage("json", event, "message", "Webhook")
}
- headers := renderHTTPKV(config.ConfigData.Alerts.Webhook.Headers, event, "headers", "Webhook")
- params := renderHTTPKV(config.ConfigData.Alerts.Webhook.Params, event, "params", "Webhook")
+ headers := renderHTTPKV(profile.Headers, event, "headers", "Webhook")
+ params := renderHTTPKV(profile.Params, event, "params", "Webhook")
paramString := util.BuildHTTPParams(params...)
- if strings.ToUpper(config.ConfigData.Alerts.Webhook.Method) == "GET" {
- _, err = util.HTTPGet(config.ConfigData.Alerts.Webhook.Server, config.ConfigData.Alerts.Webhook.Insecure, paramString, headers...)
+ if strings.ToUpper(profile.Method) == "GET" {
+ _, err = util.HTTPGet(profile.Server, profile.Insecure, paramString, headers...)
} else {
- _, err = util.HTTPPost(config.ConfigData.Alerts.Webhook.Server, config.ConfigData.Alerts.Webhook.Insecure, []byte(message), paramString, headers...)
+ _, err = util.HTTPPost(profile.Server, profile.Insecure, []byte(message), paramString, headers...)
}
if err != nil {
log.Warn().
Str("event_id", event.ID).
Str("provider", "Webhook").
+ Int("provider_id", provider.index).
Err(err).
Msg("Unable to send alert")
config.Internal.Status.Notifications.Webhook[0].NotifFailure(err.Error())
@@ -53,6 +57,7 @@ func SendWebhook(event models.Event) {
log.Info().
Str("event_id", event.ID).
Str("provider", "Webhook").
+ Int("provider_id", provider.index).
Msg("Alert sent")
config.Internal.Status.Notifications.Webhook[0].NotifSuccess()
}