From 1197b09b2968a86c01dbf719b79e69c1a091c147 Mon Sep 17 00:00:00 2001 From: Hunter Long Date: Wed, 11 Jul 2018 23:53:18 -0700 Subject: [PATCH] notifier update --- .travis.yml | 2 +- Dockerfile | 2 +- handlers/routes.go | 2 +- handlers/settings.go | 11 +- notifiers/email.go | 216 +++++++++++++++++++++++++++----------- notifiers/notifiers.go | 8 +- notifiers/slack.go | 5 + source/tmpl/settings.html | 2 +- 8 files changed, 178 insertions(+), 70 deletions(-) diff --git a/.travis.yml b/.travis.yml index ae717ce6..fcc62ea1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ services: env: global: - - VERSION=0.29.8 + - VERSION=0.29.9 - DB_HOST=localhost - DB_USER=travis - DB_PASS= diff --git a/Dockerfile b/Dockerfile index 316d0aca..b8d18201 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:latest -ENV VERSION=v0.29.8 +ENV VERSION=v0.29.9 RUN apk --no-cache add libstdc++ ca-certificates RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \ diff --git a/handlers/routes.go b/handlers/routes.go index 207f1fa3..873afe43 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -37,7 +37,7 @@ func Router() *mux.Router { r.Handle("/settings", http.HandlerFunc(SaveSettingsHandler)).Methods("POST") r.Handle("/settings/css", http.HandlerFunc(SaveSASSHandler)).Methods("POST") r.Handle("/settings/build", http.HandlerFunc(SaveAssetsHandler)).Methods("GET") - r.Handle("/settings/notifier_{{id}}", http.HandlerFunc(SaveNotificationHandler)).Methods("POST") + r.Handle("/settings/notifier/{id}", http.HandlerFunc(SaveNotificationHandler)).Methods("POST") r.Handle("/plugins/download/{name}", http.HandlerFunc(PluginsDownloadHandler)) r.Handle("/plugins/{name}/save", http.HandlerFunc(PluginSavedHandler)).Methods("POST") r.Handle("/help", http.HandlerFunc(HelpHandler)) diff --git a/handlers/settings.go b/handlers/settings.go index dee7a811..59951b21 100644 --- a/handlers/settings.go +++ b/handlers/settings.go @@ -1,6 +1,8 @@ package handlers import ( + "fmt" + "github.com/gorilla/mux" "github.com/hunterlong/statup/core" "github.com/hunterlong/statup/notifiers" "github.com/hunterlong/statup/utils" @@ -84,13 +86,15 @@ func SaveAssetsHandler(w http.ResponseWriter, r *http.Request) { } func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) { + var err error if !IsAuthenticated(r) { http.Redirect(w, r, "/", http.StatusSeeOther) return } + vars := mux.Vars(r) r.ParseForm() - notifierId := r.PostForm.Get("id") + notifierId := vars["id"] enabled := r.PostForm.Get("enable") host := r.PostForm.Get("host") @@ -103,6 +107,7 @@ func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) { apiSecret := r.PostForm.Get("api_secret") limits := int64(utils.StringInt(r.PostForm.Get("limits"))) notifer := notifiers.Select(utils.StringInt(notifierId)) + if host != "" { notifer.Host = host } @@ -135,7 +140,7 @@ func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) { } else { notifer.Enabled = false } - notifer, err := notifer.Update() + notifer, err = notifer.Update() if err != nil { utils.Log(3, err) } @@ -145,5 +150,7 @@ func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) { go notify.Run() } + utils.Log(1, fmt.Sprintf("Notifier saved: %v", notifer)) + http.Redirect(w, r, "/settings", http.StatusSeeOther) } diff --git a/notifiers/email.go b/notifiers/email.go index 7a39808e..ab9631c0 100644 --- a/notifiers/email.go +++ b/notifiers/email.go @@ -1,8 +1,14 @@ package notifiers import ( + "bytes" + "crypto/tls" "fmt" + "github.com/GeertJohan/go.rice" + "github.com/hunterlong/statup/types" "github.com/hunterlong/statup/utils" + "gopkg.in/gomail.v2" + "html/template" "time" ) @@ -14,56 +20,59 @@ const ( var ( emailer *Email emailArray []string + emailQueue []*types.Email ) type Email struct { *Notification + mailer *gomail.Dialer } // DEFINE YOUR NOTIFICATION HERE. func init() { - emailer = &Email{&Notification{ - Id: EMAIL_ID, - Method: EMAIL_METHOD, - Form: []NotificationForm{{ - id: 1, - Type: "text", - Title: "SMTP Host", - Placeholder: "Insert your SMTP Host here.", - DbField: "Host", - }, { - id: 1, - Type: "text", - Title: "SMTP Username", - Placeholder: "Insert your SMTP Username here.", - DbField: "Username", - }, { - id: 1, - Type: "password", - Title: "SMTP Password", - Placeholder: "Insert your SMTP Password here.", - DbField: "Password", - }, { - id: 1, - Type: "number", - Title: "SMTP Port", - Placeholder: "Insert your SMTP Port here.", - DbField: "Port", - }, { - id: 1, - Type: "text", - Title: "Outgoing Email Address", - Placeholder: "Insert your Outgoing Email Address", - DbField: "Var1", - }, { - id: 1, - Type: "number", - Title: "Limits per Hour", - Placeholder: "How many emails can it send per hour", - DbField: "Limits", - }}, - }} + emailer = &Email{ + Notification: &Notification{ + Id: EMAIL_ID, + Method: EMAIL_METHOD, + Form: []NotificationForm{{ + id: 1, + Type: "text", + Title: "SMTP Host", + Placeholder: "Insert your SMTP Host here.", + DbField: "Host", + }, { + id: 1, + Type: "text", + Title: "SMTP Username", + Placeholder: "Insert your SMTP Username here.", + DbField: "Username", + }, { + id: 1, + Type: "password", + Title: "SMTP Password", + Placeholder: "Insert your SMTP Password here.", + DbField: "Password", + }, { + id: 1, + Type: "number", + Title: "SMTP Port", + Placeholder: "Insert your SMTP Port here.", + DbField: "Port", + }, { + id: 1, + Type: "text", + Title: "Outgoing Email Address", + Placeholder: "Insert your Outgoing Email Address", + DbField: "Var1", + }, { + id: 1, + Type: "number", + Title: "Limits per Hour", + Placeholder: "How many emails can it send per hour", + DbField: "Limits", + }}, + }} add(emailer) } @@ -75,37 +84,62 @@ func (u *Email) Select() *Notification { // WHEN NOTIFIER LOADS func (u *Email) Init() error { - //err := SendSlack("its online") + err := u.Install() - u.Install() + if err == nil { + notifier, _ := SelectNotification(u.Id) + forms := u.Form + u.Notification = notifier + u.Form = forms + if u.Enabled { + + utils.Log(1, fmt.Sprintf("Loading SMTP Emailer using host: %v:%v", u.Notification.Host, u.Notification.Port)) + u.mailer = gomail.NewDialer(u.Notification.Host, u.Notification.Port, u.Notification.Username, u.Notification.Password) + u.mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true} + + go u.Run() + } + } //go u.Run() return nil } +func (u *Email) Test() error { + //email := &types.Email{ + // To: "info@socialeck.com", + // Subject: "Test Email", + // Template: "message.html", + // Data: nil, + // From: emailer.Var1, + //} + //SendEmail(core.EmailBox, email) + return nil +} + // AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS func (u *Email) Run() error { - //var sentAddresses []string - //for _, email := range emailArray { - // if inArray(sentAddresses, email.To) || email.Sent { - // emailQueue = removeEmail(emailQueue, email) - // continue - // } - // e := email - // go func(email *types.Email) { - // err := dialSend(email) - // if err == nil { - // email.Sent = true - // sentAddresses = append(sentAddresses, email.To) - // utils.Log(1, fmt.Sprintf("Email '%v' sent to: %v using the %v template (size: %v)", email.Subject, email.To, email.Template, len([]byte(email.Source)))) - // emailQueue = removeEmail(emailQueue, email) - // } - // }(e) - //} + var sentAddresses []string + for _, email := range emailQueue { + if inArray(sentAddresses, email.To) || email.Sent { + emailQueue = removeEmail(emailQueue, email) + continue + } + e := email + go func(email *types.Email) { + err := u.dialSend(email) + if err == nil { + email.Sent = true + sentAddresses = append(sentAddresses, email.To) + utils.Log(1, fmt.Sprintf("Email '%v' sent to: %v using the %v template (size: %v)", email.Subject, email.To, email.Template, len([]byte(email.Source)))) + emailQueue = removeEmail(emailQueue, email) + } + }(e) + } time.Sleep(60 * time.Second) - //if EmailComm.Enabled { - //EmailRoutine() - //} + if u.Enabled { + return u.Run() + } return nil } @@ -149,3 +183,59 @@ func (u *Email) Install() error { } return err } + +func (u *Email) dialSend(email *types.Email) error { + m := gomail.NewMessage() + m.SetHeader("From", email.From) + m.SetHeader("To", email.To) + m.SetHeader("Subject", email.Subject) + m.SetBody("text/html", email.Source) + if err := u.mailer.DialAndSend(m); err != nil { + utils.Log(3, fmt.Sprintf("Email '%v' sent to: %v using the %v template (size: %v) %v", email.Subject, email.To, email.Template, len([]byte(email.Source)), err)) + return err + } + return nil +} + +func SendEmail(box *rice.Box, email *types.Email) { + source := EmailTemplate(box, email.Template, email.Data) + email.Source = source + emailQueue = append(emailQueue, email) +} + +func EmailTemplate(box *rice.Box, tmpl string, data interface{}) string { + emailTpl, err := box.String(tmpl) + if err != nil { + utils.Log(3, err) + } + t := template.New("email") + t, err = t.Parse(emailTpl) + if err != nil { + utils.Log(3, err) + } + var tpl bytes.Buffer + if err := t.Execute(&tpl, data); err != nil { + utils.Log(2, err) + } + result := tpl.String() + return result +} + +func removeEmail(emails []*types.Email, em *types.Email) []*types.Email { + var newArr []*types.Email + for _, e := range emails { + if e != em { + newArr = append(newArr, e) + } + } + return newArr +} + +func inArray(a []string, v string) bool { + for _, i := range a { + if i == v { + return true + } + } + return false +} diff --git a/notifiers/notifiers.go b/notifiers/notifiers.go index 160e218e..07401e2f 100644 --- a/notifiers/notifiers.go +++ b/notifiers/notifiers.go @@ -26,6 +26,7 @@ func Load() []AllNotifiers { n := comm.(Notifier) n.Init() notifiers = append(notifiers, n) + n.Test() } return notifiers } @@ -56,6 +57,7 @@ type Notifier interface { OnFailure() error OnSuccess() error Select() *Notification + Test() error } type NotificationForm struct { @@ -79,6 +81,7 @@ func SelectNotification(id int64) (*Notification, error) { func (n *Notification) Update() (*Notification, error) { n.CreatedAt = time.Now() err := Collections.Find("id", n.Id).Update(n) + return n, err } @@ -107,7 +110,10 @@ func SelectNotifier(id int64) Notifier { var notifier Notifier for _, n := range AllCommunications { notif := n.(Notifier) - return notif + n := notif.Select() + if n.Id == id { + return notif + } } return notifier } diff --git a/notifiers/slack.go b/notifiers/slack.go index 52093f6e..ed5648bd 100644 --- a/notifiers/slack.go +++ b/notifiers/slack.go @@ -62,6 +62,11 @@ func (u *Slack) Init() error { return err } +func (u *Slack) Test() error { + SendSlack("Slack notifications on your Statup server is working!") + return nil +} + // AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS func (u *Slack) Run() error { for _, msg := range slackMessages { diff --git a/source/tmpl/settings.html b/source/tmpl/settings.html index 42ffc267..26b2a705 100644 --- a/source/tmpl/settings.html +++ b/source/tmpl/settings.html @@ -123,7 +123,7 @@ {{ range .Communications }}
-
+ {{range .Form}}