mirror of https://github.com/statping/statping
new notifiers package, easier to make your own notifier
parent
bf2ece12fe
commit
28c7c8b201
13
cli.go
13
cli.go
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/joho/godotenv"
|
||||
|
@ -246,18 +245,6 @@ func FakeSeed(plug plugin.PluginActions) {
|
|||
}
|
||||
fakeUser.Create()
|
||||
|
||||
comm := ¬ifiers.Notification{
|
||||
Id: 1,
|
||||
Method: "email",
|
||||
}
|
||||
core.Create(comm)
|
||||
|
||||
comm2 := ¬ifiers.Notification{
|
||||
Id: 2,
|
||||
Method: "slack",
|
||||
}
|
||||
core.Create(comm2)
|
||||
|
||||
for i := 0; i <= 50; i++ {
|
||||
dd := core.HitData{
|
||||
Latency: rand.Float64(),
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
)
|
||||
|
||||
func LoadDefaultCommunications() {
|
||||
//communications.EmailComm = SelectCommunication(1)
|
||||
//emailer := communications.EmailComm
|
||||
//if emailer.Enabled {
|
||||
// admin, _ := SelectUser(1)
|
||||
// communications.LoadEmailer(emailer)
|
||||
// email := &types.Email{
|
||||
// To: admin.Email,
|
||||
// Subject: "Test Email",
|
||||
// Template: "message.html",
|
||||
// Data: nil,
|
||||
// From: emailer.Var1,
|
||||
// }
|
||||
// communications.SendEmail(EmailBox, email)
|
||||
// go communications.EmailRoutine()
|
||||
//}
|
||||
//communications.SlackComm = SelectCommunication(2)
|
||||
//slack := communications.SlackComm
|
||||
//if slack.Enabled {
|
||||
// communications.LoadSlack(slack.Host)
|
||||
// msg := fmt.Sprintf("Slack loaded on your Statup Status Page!")
|
||||
// communications.SendSlack(msg)
|
||||
// go communications.SlackRoutine()
|
||||
//}
|
||||
}
|
||||
|
||||
func LoadComms() {
|
||||
for _, c := range CoreApp.Communications {
|
||||
if c.Enabled {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SelectAllCommunications() ([]*notifiers.Notification, error) {
|
||||
var c []*notifiers.Notification
|
||||
col := DbSession.Collection("communication").Find()
|
||||
err := col.OrderBy("id").All(&c)
|
||||
//CoreApp.Communications = c
|
||||
//communications.LoadComms(c)
|
||||
return c, err
|
||||
}
|
||||
|
||||
func Create(c *notifiers.Notification) (int64, error) {
|
||||
//c.CreatedAt = time.Now()
|
||||
//uuid, err := DbSession.Collection("communication").Insert(c)
|
||||
//if err != nil {
|
||||
// utils.Log(3, err)
|
||||
//}
|
||||
//if uuid == nil {
|
||||
// utils.Log(2, err)
|
||||
// return 0, err
|
||||
//}
|
||||
//c.Id = uuid.(int64)
|
||||
//c.Routine = make(chan struct{})
|
||||
//if CoreApp != nil {
|
||||
// CoreApp.Communications = append(CoreApp.Communications, c.Communicator)
|
||||
//}
|
||||
//return uuid.(int64), err
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func Disable(c *notifiers.Notification) {
|
||||
c.Enabled = false
|
||||
Update(c)
|
||||
}
|
||||
|
||||
func Enable(c *notifiers.Notification) {
|
||||
c.Enabled = true
|
||||
Update(c)
|
||||
}
|
||||
|
||||
func Update(c *notifiers.Notification) *notifiers.Notification {
|
||||
col := DbSession.Collection("communication").Find("id", c.Id)
|
||||
col.Update(c)
|
||||
SelectAllCommunications()
|
||||
return c
|
||||
}
|
||||
|
||||
func SelectCommunication(id int64) *notifiers.Notification {
|
||||
var comm *notifiers.Notification
|
||||
col := DbSession.Collection("communication").Find("id", id)
|
||||
err := col.One(&comm)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
return nil
|
||||
}
|
||||
return comm
|
||||
}
|
13
core/core.go
13
core/core.go
|
@ -29,7 +29,7 @@ type Core struct {
|
|||
Plugins []plugin.Info
|
||||
Repos []PluginJSON
|
||||
AllPlugins []plugin.PluginActions
|
||||
Communications []*notifiers.Notification
|
||||
Communications []notifiers.AllNotifiers
|
||||
DbConnection string
|
||||
started time.Time
|
||||
}
|
||||
|
@ -60,19 +60,10 @@ func NewCore() *Core {
|
|||
|
||||
func InitApp() {
|
||||
SelectCore()
|
||||
|
||||
notifiers.Collections = DbSession.Collection("communication")
|
||||
|
||||
SelectAllCommunications()
|
||||
InsertDefaultComms()
|
||||
LoadDefaultCommunications()
|
||||
SelectAllServices()
|
||||
CheckServices()
|
||||
|
||||
notifiers.Load()
|
||||
|
||||
CoreApp.Communications = notifiers.AllCommunications
|
||||
|
||||
CoreApp.Communications = notifiers.Load()
|
||||
go DatabaseMaintence()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"upper.io/db.v3/lib/sqlbuilder"
|
||||
)
|
||||
|
||||
|
@ -19,48 +17,14 @@ func OnSuccess(s *Service) {
|
|||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnSuccess(structs.Map(s))
|
||||
}
|
||||
notifiers.OnSuccess()
|
||||
}
|
||||
|
||||
func OnFailure(s *Service, f FailureData) {
|
||||
for _, p := range CoreApp.AllPlugins {
|
||||
p.OnFailure(structs.Map(s))
|
||||
}
|
||||
if notifiers.SendSlack("im failing") != nil {
|
||||
onFailureSlack(s, f)
|
||||
}
|
||||
if notifiers.EmailComm != nil {
|
||||
onFailureEmail(s, f)
|
||||
}
|
||||
}
|
||||
|
||||
func onFailureSlack(s *Service, f FailureData) {
|
||||
slack := SelectCommunication(2)
|
||||
if slack.Enabled {
|
||||
//msg := fmt.Sprintf("Service %v is currently offline! Issue: %v", s.Name, f.Issue)
|
||||
//communications.SendSlack(msg)
|
||||
}
|
||||
}
|
||||
|
||||
type failedEmail struct {
|
||||
Service *Service
|
||||
FailureData FailureData
|
||||
Domain string
|
||||
}
|
||||
|
||||
func onFailureEmail(s *Service, f FailureData) {
|
||||
email := SelectCommunication(1)
|
||||
if email.Enabled {
|
||||
data := failedEmail{s, f, CoreApp.Domain}
|
||||
admin, _ := SelectUser(1)
|
||||
email := &types.Email{
|
||||
To: admin.Email,
|
||||
Subject: fmt.Sprintf("Service %v is Down", s.Name),
|
||||
Template: "failure.html",
|
||||
Data: data,
|
||||
From: email.Var1,
|
||||
}
|
||||
notifiers.SendEmail(EmailBox, email)
|
||||
}
|
||||
notifiers.OnFailure()
|
||||
}
|
||||
|
||||
func OnSettingsSaved(c *Core) {
|
||||
|
|
|
@ -2,32 +2,10 @@ package core
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"os"
|
||||
)
|
||||
|
||||
func InsertDefaultComms() {
|
||||
emailer := SelectCommunication(1)
|
||||
if emailer == nil {
|
||||
emailer := ¬ifiers.Notification{
|
||||
Method: "email",
|
||||
Removable: false,
|
||||
Enabled: false,
|
||||
}
|
||||
Create(emailer)
|
||||
}
|
||||
slack := SelectCommunication(2)
|
||||
if slack == nil {
|
||||
slack := ¬ifiers.Notification{
|
||||
Method: "slack",
|
||||
Removable: false,
|
||||
Enabled: false,
|
||||
}
|
||||
Create(slack)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteConfig() {
|
||||
err := os.Remove("./config.yml")
|
||||
if err != nil {
|
||||
|
|
|
@ -37,8 +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/email", http.HandlerFunc(SaveEmailSettingsHandler)).Methods("POST")
|
||||
r.Handle("/settings/slack", http.HandlerFunc(SaveSlackSettingsHandler)).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))
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"net/http"
|
||||
)
|
||||
|
@ -84,65 +84,62 @@ func SaveAssetsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func SaveEmailSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
func SaveNotificationHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthenticated(r) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
emailer := core.SelectCommunication(1)
|
||||
r.ParseForm()
|
||||
smtpHost := r.PostForm.Get("host")
|
||||
smtpUser := r.PostForm.Get("username")
|
||||
smtpPass := r.PostForm.Get("password")
|
||||
smtpPort := int(utils.StringInt(r.PostForm.Get("port")))
|
||||
smtpOutgoing := r.PostForm.Get("address")
|
||||
enabled := r.PostForm.Get("enable_email")
|
||||
|
||||
emailer.Host = smtpHost
|
||||
emailer.Username = smtpUser
|
||||
if smtpPass != "#######################" {
|
||||
emailer.Password = smtpPass
|
||||
notifierId := r.PostForm.Get("id")
|
||||
enabled := r.PostForm.Get("enable")
|
||||
|
||||
host := r.PostForm.Get("host")
|
||||
port := int(utils.StringInt(r.PostForm.Get("port")))
|
||||
username := r.PostForm.Get("username")
|
||||
password := r.PostForm.Get("password")
|
||||
var1 := r.PostForm.Get("var1")
|
||||
var2 := r.PostForm.Get("var2")
|
||||
apiKey := r.PostForm.Get("api_key")
|
||||
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
|
||||
}
|
||||
if port != 0 {
|
||||
notifer.Port = port
|
||||
}
|
||||
if username != "" {
|
||||
notifer.Username = username
|
||||
}
|
||||
if password != "" && password != "##########" {
|
||||
notifer.Password = password
|
||||
}
|
||||
if var1 != "" {
|
||||
notifer.Var1 = var1
|
||||
}
|
||||
if var2 != "" {
|
||||
notifer.Var2 = var2
|
||||
}
|
||||
if apiKey != "" {
|
||||
notifer.ApiKey = apiKey
|
||||
}
|
||||
if apiSecret != "" {
|
||||
notifer.ApiSecret = apiSecret
|
||||
}
|
||||
if limits != 0 {
|
||||
notifer.Limits = limits
|
||||
}
|
||||
emailer.Port = smtpPort
|
||||
emailer.Var1 = smtpOutgoing
|
||||
emailer.Enabled = false
|
||||
if enabled == "on" {
|
||||
emailer.Enabled = true
|
||||
notifer.Enabled = true
|
||||
} else {
|
||||
notifer.Enabled = false
|
||||
}
|
||||
core.Update(emailer)
|
||||
|
||||
sample := &types.Email{
|
||||
To: SessionUser(r).Email,
|
||||
Subject: "Test Email",
|
||||
Template: "message.html",
|
||||
From: emailer.Var1,
|
||||
notifer, err := notifer.Update()
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
notifiers.LoadEmailer(emailer)
|
||||
notifiers.SendEmail(core.EmailBox, sample)
|
||||
notifiers.EmailComm = emailer
|
||||
if emailer.Enabled {
|
||||
utils.Log(1, "Starting Email Routine, 1 unique email per 60 seconds")
|
||||
go notifiers.EmailRoutine()
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
func SaveSlackSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if !IsAuthenticated(r) {
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
slack := core.SelectCommunication(2)
|
||||
r.ParseForm()
|
||||
slackWebhook := r.PostForm.Get("slack_url")
|
||||
enable := r.PostForm.Get("enable_slack")
|
||||
slack.Enabled = false
|
||||
if enable == "on" && slackWebhook != "" {
|
||||
slack.Enabled = true
|
||||
//go communications.SlackRoutine()
|
||||
}
|
||||
slack.Host = slackWebhook
|
||||
core.Update(slack)
|
||||
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
||||
msg := fmt.Sprintf("%v - %v - %v", notifierId, notifer, enabled)
|
||||
w.Write([]byte(msg))
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"github.com/gorilla/sessions"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/handlers"
|
||||
"github.com/hunterlong/statup/notifiers"
|
||||
"github.com/rendon/testcli"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
|
@ -218,7 +219,6 @@ func RunMySQLMakeConfig(t *testing.T, db string) {
|
|||
|
||||
err = core.DbConnection(core.Configs.Connection)
|
||||
assert.Nil(t, err)
|
||||
core.InsertDefaultComms()
|
||||
}
|
||||
|
||||
func RunInsertMysqlSample(t *testing.T) {
|
||||
|
@ -254,7 +254,8 @@ func RunSelectAllMysqlServices(t *testing.T) {
|
|||
|
||||
func RunSelectAllMysqlCommunications(t *testing.T) {
|
||||
var err error
|
||||
comms, err := core.SelectAllCommunications()
|
||||
notifiers.Collections = core.DbSession.Collection("communication")
|
||||
comms := notifiers.Load()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(comms))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package notifiers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
EMAIL_ID int64 = 1
|
||||
EMAIL_METHOD = "email"
|
||||
)
|
||||
|
||||
var (
|
||||
emailer *Email
|
||||
emailArray []string
|
||||
)
|
||||
|
||||
type Email struct {
|
||||
*Notification
|
||||
}
|
||||
|
||||
// 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",
|
||||
}},
|
||||
}}
|
||||
|
||||
add(emailer)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *Email) Select() *Notification {
|
||||
return u.Notification
|
||||
}
|
||||
|
||||
// WHEN NOTIFIER LOADS
|
||||
func (u *Email) Init() error {
|
||||
//err := SendSlack("its online")
|
||||
|
||||
u.Install()
|
||||
|
||||
//go u.Run()
|
||||
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)
|
||||
//}
|
||||
time.Sleep(60 * time.Second)
|
||||
//if EmailComm.Enabled {
|
||||
//EmailRoutine()
|
||||
//}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) OnFailure() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving a failure notification.", u.Method))
|
||||
|
||||
// Do failing stuff here!
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) OnSuccess() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving a successful notification.", u.Method))
|
||||
|
||||
// Do checking or any successful things here
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
func (u *Email) OnSave() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
|
||||
|
||||
// Do updating stuff here
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Email) Install() error {
|
||||
inDb, err := emailer.Notification.isInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return err
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("new notifier #%v installed: %v", newNotifer, u.Method))
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
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"
|
||||
)
|
||||
|
||||
var (
|
||||
mailer *gomail.Dialer
|
||||
emailQueue []*types.Email
|
||||
EmailComm *Notification
|
||||
)
|
||||
|
||||
func EmailRoutine() {
|
||||
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 := 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()
|
||||
}
|
||||
}
|
||||
|
||||
func 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 := 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 LoadEmailer(mail *Notification) {
|
||||
utils.Log(1, fmt.Sprintf("Loading SMTP Emailer using host: %v:%v", mail.Host, mail.Port))
|
||||
mailer = gomail.NewDialer(mail.Host, mail.Port, mail.Username, mail.Password)
|
||||
mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
|
@ -1,25 +1,33 @@
|
|||
package notifiers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"strings"
|
||||
"time"
|
||||
"upper.io/db.v3"
|
||||
)
|
||||
|
||||
var (
|
||||
AllCommunications []*Notification
|
||||
AllCommunications []AllNotifiers
|
||||
Collections db.Collection
|
||||
)
|
||||
|
||||
func add(c *Notification) {
|
||||
type AllNotifiers interface{}
|
||||
|
||||
func add(c interface{}) {
|
||||
AllCommunications = append(AllCommunications, c)
|
||||
}
|
||||
|
||||
func Load() {
|
||||
func Load() []AllNotifiers {
|
||||
utils.Log(1, "Loading notifiers")
|
||||
var notifiers []AllNotifiers
|
||||
for _, comm := range AllCommunications {
|
||||
comm.Init()
|
||||
n := comm.(Notifier)
|
||||
n.Init()
|
||||
notifiers = append(notifiers, n)
|
||||
}
|
||||
return notifiers
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
|
@ -43,26 +51,93 @@ type Notification struct {
|
|||
|
||||
type Notifier interface {
|
||||
Init() error
|
||||
Install() error
|
||||
Run() error
|
||||
OnFailure() error
|
||||
OnSuccess() error
|
||||
Select() *Notification
|
||||
}
|
||||
|
||||
type NotificationForm struct {
|
||||
id int64
|
||||
Type string
|
||||
Title string
|
||||
Placeholder string
|
||||
DbField string
|
||||
}
|
||||
|
||||
func (n *Notification) isInDatabase() (bool, error) {
|
||||
return Collections.Find("id", n.Id).Exists()
|
||||
}
|
||||
|
||||
func (n *Notification) Update() (*Notification, error) {
|
||||
n.CreatedAt = time.Now()
|
||||
err := Collections.Find("id", n.Id).Update(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func InsertDatabase(n *Notification) (int64, error) {
|
||||
n.CreatedAt = time.Now()
|
||||
newId, err := Collections.Insert(n)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return newId.(int64), err
|
||||
}
|
||||
|
||||
func Select(id int64) *Notification {
|
||||
var notifier *Notification
|
||||
for _, n := range AllCommunications {
|
||||
notif := n.(Notifier)
|
||||
notifier = notif.Select()
|
||||
if notifier.Id == id {
|
||||
return notifier
|
||||
}
|
||||
}
|
||||
return notifier
|
||||
}
|
||||
|
||||
func (f NotificationForm) Value() string {
|
||||
notifier := Select(f.id)
|
||||
return notifier.GetValue(f.DbField)
|
||||
}
|
||||
|
||||
func (n *Notification) GetValue(dbField string) string {
|
||||
dbField = strings.ToLower(dbField)
|
||||
switch dbField {
|
||||
case "host":
|
||||
return n.Host
|
||||
case "port":
|
||||
return fmt.Sprintf("%v", n.Port)
|
||||
case "username":
|
||||
return n.Username
|
||||
case "password":
|
||||
if n.Password != "" {
|
||||
return "##########"
|
||||
}
|
||||
case "var1":
|
||||
return n.Var1
|
||||
case "var2":
|
||||
return n.Var2
|
||||
case "api_key":
|
||||
return n.ApiKey
|
||||
case "api_secret":
|
||||
return n.ApiSecret
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func OnFailure() {
|
||||
for _, comm := range AllCommunications {
|
||||
comm.OnFailure()
|
||||
n := comm.(Notifier)
|
||||
n.OnFailure()
|
||||
}
|
||||
}
|
||||
|
||||
func OnSuccess() {
|
||||
for _, comm := range AllCommunications {
|
||||
comm.OnSuccess()
|
||||
n := comm.(Notifier)
|
||||
n.OnSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,39 +9,53 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
SLACK_ID int64 = 2
|
||||
SLACK_METHOD = "slack"
|
||||
SLACK_ID = 2
|
||||
SLACK_METHOD = "slack"
|
||||
)
|
||||
|
||||
var (
|
||||
slacker *Notification
|
||||
slacker *Slack
|
||||
slackMessages []string
|
||||
)
|
||||
|
||||
type Slack struct {
|
||||
*Notification
|
||||
}
|
||||
|
||||
// DEFINE YOUR NOTIFICATION HERE.
|
||||
func init() {
|
||||
slacker = &Notification{
|
||||
slacker = &Slack{&Notification{
|
||||
Id: SLACK_ID,
|
||||
Method: SLACK_METHOD,
|
||||
Host: "https://webhooksurl.slack.com/***",
|
||||
Form: []NotificationForm{{
|
||||
id: 2,
|
||||
Type: "text",
|
||||
Title: "Incoming Webhook Url",
|
||||
Placeholder: "Insert your Slack webhook URL here.",
|
||||
}},
|
||||
DbField: "Host",
|
||||
}}},
|
||||
}
|
||||
add(slacker)
|
||||
}
|
||||
|
||||
// Select Obj
|
||||
func (u *Slack) Select() *Notification {
|
||||
return u.Notification
|
||||
}
|
||||
|
||||
// WHEN NOTIFIER LOADS
|
||||
func (u *Notification) Init() error {
|
||||
func (u *Slack) Init() error {
|
||||
err := SendSlack("its online")
|
||||
go u.Run()
|
||||
|
||||
u.Install()
|
||||
|
||||
//go u.Run()
|
||||
return err
|
||||
}
|
||||
|
||||
// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS
|
||||
func (u *Notification) Run() error {
|
||||
func (u *Slack) Run() error {
|
||||
for _, msg := range slackMessages {
|
||||
utils.Log(1, fmt.Sprintf("Sending JSON to Slack Webhook: %v", msg))
|
||||
client := http.Client{Timeout: 15 * time.Second}
|
||||
|
@ -69,7 +83,7 @@ func SendSlack(msg string) error {
|
|||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Notification) OnFailure() error {
|
||||
func (u *Slack) OnFailure() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving a failure notification.", u.Method))
|
||||
|
||||
// Do failing stuff here!
|
||||
|
@ -78,7 +92,7 @@ func (u *Notification) OnFailure() error {
|
|||
}
|
||||
|
||||
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
|
||||
func (u *Notification) OnSuccess() error {
|
||||
func (u *Slack) OnSuccess() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving a successful notification.", u.Method))
|
||||
|
||||
// Do checking or any successful things here
|
||||
|
@ -87,10 +101,24 @@ func (u *Notification) OnSuccess() error {
|
|||
}
|
||||
|
||||
// ON SAVE OR UPDATE OF THE NOTIFIER FORM
|
||||
func (u *Notification) OnSave() error {
|
||||
func (u *Slack) OnSave() error {
|
||||
utils.Log(1, fmt.Sprintf("Notification %v is receiving updated information.", u.Method))
|
||||
|
||||
// Do updating stuff here
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
|
||||
func (u *Slack) Install() error {
|
||||
inDb, err := slacker.Notification.isInDatabase()
|
||||
if !inDb {
|
||||
newNotifer, err := InsertDatabase(u.Notification)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
return err
|
||||
}
|
||||
utils.Log(1, fmt.Sprintf("new notifier #%v installed: %v", newNotifer, u.Method))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
package notifiers
|
|
@ -32,12 +32,9 @@
|
|||
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||
<a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Settings</a>
|
||||
<a class="nav-link" id="v-pills-style-tab" data-toggle="pill" href="#v-pills-style" role="tab" aria-controls="v-pills-style" aria-selected="false">Theme Editor</a>
|
||||
<a class="nav-link" id="v-pills-email-tab" data-toggle="pill" href="#v-pills-email" role="tab" aria-controls="v-pills-email" aria-selected="true">Email Settings</a>
|
||||
|
||||
{{ range .Communications }}
|
||||
<a class="nav-link text-capitalize" id="v-pills-{{underscore .Method}}-tab" data-toggle="pill" href="#v-pills-{{underscore .Method}}" role="tab" aria-controls="v-pills-{{underscore .Method}}" aria-selected="false">{{.Method}}</a>
|
||||
{{ end }}
|
||||
|
||||
{{ range .Communications }}
|
||||
<a class="nav-link text-capitalize" id="v-pills-{{underscore .Method}}-tab" data-toggle="pill" href="#v-pills-{{underscore .Method}}" role="tab" aria-controls="v-pills-{{underscore .Method}}" aria-selected="false">{{.Method}}</a>
|
||||
{{ end }}
|
||||
<a class="nav-link" id="v-pills-browse-tab" data-toggle="pill" href="#v-pills-browse" role="tab" aria-controls="v-pills-home" aria-selected="false">Browse Plugins</a>
|
||||
{{ range .Plugins }}
|
||||
<a class="nav-link text-capitalize" id="v-pills-{{underscore .Name}}-tab" data-toggle="pill" href="#v-pills-{{underscore .Name}}" role="tab" aria-controls="v-pills-profile" aria-selected="false">{{.Name}}</a>
|
||||
|
@ -126,17 +123,17 @@
|
|||
|
||||
{{ range .Communications }}
|
||||
<div class="tab-pane fade" id="v-pills-{{underscore .Method}}" role="tabpanel" aria-labelledby="v-pills-{{underscore .Method }}-tab">
|
||||
<form method="POST" action="/settings/{{ .Method }}">
|
||||
<form method="POST" action="/settings/notifier_{{ .Id }}">
|
||||
{{range .Form}}
|
||||
<div class="form-group">
|
||||
<label class="text-capitalize" for="{{underscore .Title}}">{{.Title}}</label>
|
||||
<input type="{{.Type}}" name="{{underscore .Title}}" class="form-control" value="" id="{{underscore .Title}}" placeholder="{{.Placeholder}}">
|
||||
<input type="{{.Type}}" name="{{underscore .DbField}}" class="form-control" value="{{ .Value }}" id="{{underscore .Title}}" placeholder="{{.Placeholder}}">
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<span class="switch">
|
||||
<input type="checkbox" name="enable_{{ .Method }}" class="switch" id="switch-{{ .Method }}" {{if .Enabled}}checked{{end}}>
|
||||
<input type="checkbox" name="enable" class="switch" id="switch-{{ .Method }}" {{if .Enabled}}checked{{end}}>
|
||||
<label for="switch-{{ .Method }}">Enable {{ .Method }}</label>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -149,63 +146,6 @@
|
|||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
||||
{{ with $c := index .Communications 0 }}
|
||||
<div class="tab-pane fade" id="v-pills-{{ $c.Method }}" role="tabpanel" aria-labelledby="v-pills-{{ $c.Method }}-tab">
|
||||
|
||||
<form method="POST" action="/settings/{{ $c.Method }}">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="host">SMTP Host</label>
|
||||
<input type="text" name="host" class="form-control" value="{{ $c.Host }}" id="host" placeholder="Great Uptime">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="username">SMTP Username</label>
|
||||
<input type="text" name="username" class="form-control" value="{{ $c.Username }}" id="username" placeholder="Great Uptime">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">SMTP Password</label>
|
||||
<input type="password" name="password" class="form-control" value="{{ if $c.Password }}#######################{{end}}" id="password">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="port">SMTP Port</label>
|
||||
<input type="number" name="port" class="form-control" value="{{ $c.Port }}" id="port" placeholder="587">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="address">Outgoing Email Address</label>
|
||||
<input type="text" name="address" class="form-control" value="{{ $c.Var1 }}" id="address" placeholder="noreply@domain.com">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="limit">Limit Emails per Hour</label>
|
||||
<input type="number" name="limit" class="form-control" value="30" id="limit" placeholder="noreply@domain.com">
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<span class="switch">
|
||||
<input type="checkbox" name="enable_{{ $c.Method }}" class="switch" id="switch-{{ $c.Method }}" {{if .Enabled}}checked{{end}}>
|
||||
<label for="switch-{{ $c.Method }}">Enable Emails</label>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<button type="submit" class="btn btn-primary btn-block">Save Email Settings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
||||
|
||||
<div class="tab-pane fade" id="v-pills-browse" role="tabpanel" aria-labelledby="v-pills-browse-tab">
|
||||
{{ range .Repos }}
|
||||
<div class="card col-6" style="width: 18rem;">
|
||||
|
|
Loading…
Reference in New Issue