package notifiers import ( "crypto/tls" "fmt" "github.com/go-mail/mail" "github.com/statping/statping/types/failures" "github.com/statping/statping/types/notifications" "github.com/statping/statping/types/notifier" "github.com/statping/statping/types/null" "github.com/statping/statping/types/services" "github.com/statping/statping/utils" "time" ) var _ notifier.Notifier = (*emailer)(nil) const ( mainEmailTemplate = ` Statping email
` ) var ( mailer *mail.Dialer ) type emailer struct { *notifications.Notification } func (e *emailer) Select() *notifications.Notification { return e.Notification } var email = &emailer{¬ifications.Notification{ Method: "email", Title: "email", Description: "Send emails via SMTP when services are online or offline.", Author: "Hunter Long", AuthorUrl: "https://github.com/hunterlong", Icon: "far fa-envelope", SuccessData: "Service {{.Service.Name}} is Back Online", FailureData: "Service {{.Service.Name}} is Offline", DataType: "text", Limits: 30, Form: []notifications.NotificationForm{{ Type: "text", Title: "SMTP Host", Placeholder: "Insert your SMTP Host here.", DbField: "Host", }, { Type: "text", Title: "SMTP Username", Placeholder: "Insert your SMTP Username here.", DbField: "Username", }, { Type: "password", Title: "SMTP Password", Placeholder: "Insert your SMTP Password here.", DbField: "Password", }, { Type: "number", Title: "SMTP Port", Placeholder: "Insert your SMTP Port here.", DbField: "Port", }, { Type: "text", Title: "Outgoing Email Address", Placeholder: "outgoing@email.com", DbField: "Var1", }, { Type: "email", Title: "Send Alerts To", Placeholder: "sendto@email.com", DbField: "Var2", }, { Type: "text", Title: "Disable TLS/SSL", Placeholder: "", SmallText: "To Disable TLS/SSL insert 'true'", DbField: "api_key", }}}, } type emailOutgoing struct { To string Subject string Template string From string Data replacer Source string Sent bool } // OnFailure will trigger failing service func (e *emailer) OnFailure(s *services.Service, f *failures.Failure) error { subject := fmt.Sprintf("Service %s is Offline", s.Name) email := &emailOutgoing{ To: e.Var2, Subject: subject, Template: mainEmailTemplate, Data: replacer{ Service: s, Failure: f, }, From: e.Var1, } return e.dialSend(email) } // OnSuccess will trigger successful service func (e *emailer) OnSuccess(s *services.Service) error { subject := fmt.Sprintf("Service %s is Back Online", s.Name) email := &emailOutgoing{ To: e.Var2, Subject: subject, Template: mainEmailTemplate, Data: replacer{ Service: s, Failure: &failures.Failure{}, }, From: e.Var1, } return e.dialSend(email) } // OnTest triggers when this notifier has been saved func (e *emailer) OnTest() (string, error) { testService := services.Service{ Id: 1, Name: "Example Service", Domain: "https://www.youtube.com/watch?v=-u6DvRyyKGU", ExpectedStatus: 200, Interval: 30, Type: "http", Method: "GET", Timeout: 20, LastStatusCode: 200, Expected: null.NewNullString("test example"), LastResponse: "this is an example response", CreatedAt: utils.Now().Add(-24 * time.Hour), } subject := fmt.Sprintf("Service %v is Back Online", testService.Name) email := &emailOutgoing{ To: e.Var2, Subject: subject, Template: mainEmailTemplate, Data: replacer{ Service: &testService, Failure: &failures.Failure{}, }, From: e.Var1, } err := e.dialSend(email) return subject, err } func (e *emailer) dialSend(email *emailOutgoing) error { mailer = mail.NewDialer(e.Host, e.Port, e.Username, e.Password) m := mail.NewMessage() // if email setting TLS is Disabled if e.ApiKey == "true" { mailer.SSL = false } else { mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true} } m.SetHeader("From", email.From) m.SetHeader("To", email.To) m.SetHeader("Subject", email.Subject) m.SetBody("text/html", ReplaceTemplate(email.Template, email.Data)) if err := mailer.DialAndSend(m); err != nil { utils.Log.Errorln(fmt.Sprintf("email '%v' sent to: %v (size: %v) %v", email.Subject, email.To, len([]byte(email.Source)), err)) return err } return nil }