diff --git a/core/checker.go b/core/checker.go index 6eff907e..2f837f80 100644 --- a/core/checker.go +++ b/core/checker.go @@ -263,6 +263,7 @@ func recordSuccess(s *Service) { s.CreateHit(hit) s.Online = true notifier.OnSuccess(s.Service) + s.SuccessNotified = true } // recordFailure will create a new 'Failure' record in the database for a offline service @@ -277,5 +278,8 @@ func recordFailure(s *Service, issue string) { utils.Log(2, fmt.Sprintf("Service %v Failing: %v | Lookup in: %0.2f ms", s.Name, issue, fail.PingTime*1000)) s.CreateFailure(fail) s.Online = false + s.SuccessNotified = false + s.UpdateNotify = CoreApp.UpdateNotify.Bool + s.DownText = s.DowntimeText() notifier.OnFailure(s.Service, fail.Failure) } diff --git a/core/notifier/events.go b/core/notifier/events.go index de9eb1b5..a6a93246 100644 --- a/core/notifier/events.go +++ b/core/notifier/events.go @@ -38,6 +38,19 @@ func OnFailure(s *types.Service, f *types.Failure) { if !s.AllowNotifications.Bool { return } + + // check if User wants to receive every Status Change + if s.UpdateNotify { + // send only if User hasn't been already notified about the Downtime + if !s.UserNotified { + s.UserNotified = true + goto sendMessages + } else { + return + } + } + +sendMessages: for _, comm := range AllCommunications { if isType(comm, new(BasicEvents)) && isEnabled(comm) && inLimits(comm) { notifier := comm.(Notifier).Select() @@ -45,7 +58,6 @@ func OnFailure(s *types.Service, f *types.Failure) { comm.(BasicEvents).OnFailure(s, f) } } - } // OnSuccess will be triggered when a service is successful - BasicEvents interface @@ -53,6 +65,12 @@ func OnSuccess(s *types.Service) { if !s.AllowNotifications.Bool { return } + + // check if User wants to receive every Status Change + if s.UpdateNotify && s.UserNotified { + s.UserNotified = false + } + for _, comm := range AllCommunications { if isType(comm, new(BasicEvents)) && isEnabled(comm) && inLimits(comm) { notifier := comm.(Notifier).Select() @@ -60,7 +78,6 @@ func OnSuccess(s *types.Service) { comm.(BasicEvents).OnSuccess(s) } } - } // OnNewService is triggered when a new service is created - ServiceEvents interface diff --git a/handlers/function.go b/handlers/function.go index d17f1452..7ac44649 100644 --- a/handlers/function.go +++ b/handlers/function.go @@ -63,6 +63,9 @@ var handlerFuncs = func(w http.ResponseWriter, r *http.Request) template.FuncMap "USE_CDN": func() bool { return core.CoreApp.UseCdn.Bool }, + "UPDATENOTIFY": func() bool { + return core.CoreApp.UpdateNotify.Bool + }, "QrAuth": func() string { return fmt.Sprintf("statping://setup?domain=%v&api=%v", core.CoreApp.Domain, core.CoreApp.ApiSecret) }, diff --git a/handlers/settings.go b/handlers/settings.go index 89b5839b..93976c84 100644 --- a/handlers/settings.go +++ b/handlers/settings.go @@ -62,11 +62,15 @@ func saveSettingsHandler(w http.ResponseWriter, r *http.Request) { timeFloat, _ := strconv.ParseFloat(timezone, 10) app.Timezone = float32(timeFloat) + app.UpdateNotify = types.NewNullBool(form.Get("update_notify") == "true") + app.UseCdn = types.NewNullBool(form.Get("enable_cdn") == "on") core.CoreApp, err = core.UpdateCore(app) if err != nil { utils.Log(3, fmt.Sprintf("issue updating Core: %v", err.Error())) } + + //notifiers.OnSettingsSaved(core.CoreApp.ToCore()) ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings") } diff --git a/notifiers/discord.go b/notifiers/discord.go index 82cb1c70..2d9c345b 100644 --- a/notifiers/discord.go +++ b/notifiers/discord.go @@ -75,9 +75,14 @@ func (u *discord) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *discord) OnSuccess(s *types.Service) { - if !s.Online { + if !s.Online || !s.SuccessNotified { u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id)) - msg := fmt.Sprintf(`{"content": "Your service '%v' is back online!"}`, s.Name) + var msg interface{} + if s.UpdateNotify { + s.UpdateNotify = false + } + msg = s.DownText + u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg) } } diff --git a/notifiers/email.go b/notifiers/email.go index dd08e355..d57beee1 100644 --- a/notifiers/email.go +++ b/notifiers/email.go @@ -198,11 +198,17 @@ func (u *email) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *email) OnSuccess(s *types.Service) { - if !s.Online { + if !s.Online || !s.SuccessNotified { + var msg string + if s.UpdateNotify { + s.UpdateNotify = false + } + msg = s.DownText + u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id)) email := &emailOutgoing{ To: u.Var2, - Subject: fmt.Sprintf("Service %v is Back Online", s.Name), + Subject: msg, Template: mainEmailTemplate, Data: interface{}(s), From: u.Var1, diff --git a/notifiers/line_notify.go b/notifiers/line_notify.go index 4e5cd3f8..7409f249 100644 --- a/notifiers/line_notify.go +++ b/notifiers/line_notify.go @@ -78,16 +78,22 @@ func (u *lineNotifier) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *lineNotifier) OnSuccess(s *types.Service) { - if !s.Online { + if !s.Online || !s.SuccessNotified { + var msg string + if s.UpdateNotify { + s.UpdateNotify = false + } + msg = s.DownText + u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id)) - msg := fmt.Sprintf("Your service '%v' is back online!", s.Name) u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg) } } // OnSave triggers when this notifier has been saved func (u *lineNotifier) OnSave() error { - utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method)) - // Do updating stuff here + msg := fmt.Sprintf("Notification %v is receiving updated information.", u.Method) + utils.Log(1, msg) + u.AddQueue("saved", message) return nil } diff --git a/notifiers/mobile.go b/notifiers/mobile.go index 3cceebf1..ed238580 100644 --- a/notifiers/mobile.go +++ b/notifiers/mobile.go @@ -105,10 +105,16 @@ func (u *mobilePush) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *mobilePush) OnSuccess(s *types.Service) { data := dataJson(s, nil) - if !s.Online { + if !s.Online || !s.SuccessNotified { + var msgStr string + if s.UpdateNotify { + s.UpdateNotify = false + } + msgStr = s.DownText + u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id)) msg := &pushArray{ - Message: fmt.Sprintf("Your service '%v' is back online!", s.Name), + Message: msgStr, Title: "Service Online", Topic: mobileIdentifier, Data: data, diff --git a/notifiers/telegram.go b/notifiers/telegram.go index 000b3292..6215cf43 100644 --- a/notifiers/telegram.go +++ b/notifiers/telegram.go @@ -97,9 +97,14 @@ func (u *telegram) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *telegram) OnSuccess(s *types.Service) { - if !s.Online { + if !s.Online || !s.SuccessNotified { u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id)) - msg := fmt.Sprintf("Your service '%v' is back online!", s.Name) + var msg interface{} + if s.UpdateNotify { + s.UpdateNotify = false + } + msg = s.DownText + u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg) } } diff --git a/notifiers/twilio.go b/notifiers/twilio.go index 6dcf9fbd..e660173d 100644 --- a/notifiers/twilio.go +++ b/notifiers/twilio.go @@ -107,9 +107,14 @@ func (u *twilio) OnFailure(s *types.Service, f *types.Failure) { // OnSuccess will trigger successful service func (u *twilio) OnSuccess(s *types.Service) { - if !s.Online { + if !s.Online || !s.SuccessNotified { u.ResetUniqueQueue(fmt.Sprintf("service_%v", s.Id)) - msg := fmt.Sprintf("Your service '%v' is back online!", s.Name) + var msg string + if s.UpdateNotify { + s.UpdateNotify = false + } + msg = s.DownText + u.AddQueue(fmt.Sprintf("service_%v", s.Id), msg) } } diff --git a/source/tmpl/settings.gohtml b/source/tmpl/settings.gohtml index 39cd66b1..05324939 100644 --- a/source/tmpl/settings.gohtml +++ b/source/tmpl/settings.gohtml @@ -37,6 +37,20 @@ +
+
+ + + + + + + + + +
+
+
diff --git a/types/core.go b/types/core.go index 03756cc2..ca73c684 100644 --- a/types/core.go +++ b/types/core.go @@ -37,6 +37,7 @@ type Core struct { Version string `gorm:"column:version" json:"version"` MigrationId int64 `gorm:"column:migration_id" json:"migration_id,omitempty"` UseCdn NullBool `gorm:"column:use_cdn;default:false" json:"using_cdn,omitempty"` + UpdateNotify NullBool `gorm:"column:update_notify;default:false" json:"update_notify,omitempty"` Timezone float32 `gorm:"column:timezone;default:-8.0" json:"timezone,omitempty"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` diff --git a/types/service.go b/types/service.go index f0435dba..a904f980 100644 --- a/types/service.go +++ b/types/service.go @@ -50,6 +50,10 @@ type Service struct { Checkpoint time.Time `gorm:"-" json:"-"` SleepDuration time.Duration `gorm:"-" json:"-"` LastResponse string `gorm:"-" json:"-"` + UserNotified bool `gorm:"-" json:"-"` // True if the User was already notified about a Downtime + UpdateNotify bool `gorm:"-" json:"-"` // This Variable is a simple copy of `core.CoreApp.UpdateNotify.Bool` + DownText string `gorm:"-" json:"-"` // Contains the current generated Downtime Text + SuccessNotified bool `gorm:"-" json:"-"` // Is 'true' if the user has already be informed that the Services now again available LastStatusCode int `gorm:"-" json:"status_code"` LastOnline time.Time `gorm:"-" json:"last_success"` Failures []FailureInterface `gorm:"-" json:"failures,omitempty"`