2018-08-16 06:22:20 +00:00
// Statup
// Copyright (C) 2018. Hunter Long and the project contributors
// Written by Hunter Long <info@socialeck.com> and the project contributors
//
// https://github.com/hunterlong/statup
//
// The licenses for most software and other practical works are designed
// to take away your freedom to share and change the works. By contrast,
// the GNU General Public License is intended to guarantee your freedom to
// share and change all versions of a program--to make sure it remains free
// software for all its users.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
2018-07-11 03:06:21 +00:00
package notifiers
import (
2018-07-12 06:53:18 +00:00
"bytes"
2018-09-15 22:21:58 +00:00
"crypto/tls"
2018-07-11 03:06:21 +00:00
"fmt"
2018-09-12 04:14:22 +00:00
"github.com/hunterlong/statup/core/notifier"
2018-07-12 06:53:18 +00:00
"github.com/hunterlong/statup/types"
2018-07-11 03:06:21 +00:00
"github.com/hunterlong/statup/utils"
2018-07-12 06:53:18 +00:00
"gopkg.in/gomail.v2"
"html/template"
2018-07-11 03:06:21 +00:00
)
const (
2018-09-15 01:18:21 +00:00
MESSAGE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <title>Sample Email</title>\n\n\n</head>\n<body style=\"-webkit-text-size-adjust: none; box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; height: 100%; line-height: 1.4; margin: 0; width: 100% !important;\" bgcolor=\"#F2F4F6\"><style type=\"text/css\">\n body {\n width: 100% !important; height: 100%; margin: 0; line-height: 1.4; background-color: #F2F4F6; color: #74787E; -webkit-text-size-adjust: none;\n }\n @media only screen and (max-width: 600px) {\n .email-body_inner {\n width: 100% !important;\n }\n .email-footer {\n width: 100% !important;\n }\n }\n @media only screen and (max-width: 500px) {\n .button {\n width: 100% !important;\n }\n }\n</style>\n<table class=\"email-wrapper\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;\" bgcolor=\"#F2F4F6\">\n <tr>\n <td align=\"center\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; word-break: break-word;\">\n <table class=\"email-content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;\">\n\n <tr>\n <td class=\"email-body\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"-premailer-cellpadding: 0; -premailer-cellspacing: 0; border-bottom-color: #EDEFF2; border-bottom-style: solid; border-bottom-width: 1px; border-top-color: #EDEFF2; border-top-style: solid; border-top-width: 1px; box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%; word-break: break-word;\" bgcolor=\"#FFFFFF\">\n <table class=\"email-body_inner\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0 auto; padding: 0; width: 570px;\" bgcolor=\"#FFFFFF\">\n\n <tr>\n <td class=\"content-cell\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; padding: 35px; word-break: break-word;\">\n <h1 style=\"box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;\" align=\"left\">Looks Like Emails Work!</h1>\n <p style=\"box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 16px; line-height: 1.5em; margin-top: 0;\" align=\"left\">\n Since you got this email, it confirms that your Statup Status Page email system is working correctly.\n </p>\n </p>\n <p style=\"box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 16px; line-height: 1.5em; margin-top: 0;\" align=\"left\">\n Enjoy using Statup!\n <br />Statup.io Team</p>\n\n <table class=\"body-sub\" style=\" border - top - color : # EDEFF2 ; border - top - style : solid ; border - top - width : 1 px ; box - sizing : border - box ; font - family : Arial , ' Helve
FAILURE = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <title>Sample Email</title>\n\n\n</head>\n<body style=\"-webkit-text-size-adjust: none; box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; height: 100%; line-height: 1.4; margin: 0; width: 100% !important;\" bgcolor=\"#F2F4F6\"><style type=\"text/css\">\n body {\n width: 100% !important; height: 100%; margin: 0; line-height: 1.4; background-color: #F2F4F6; color: #74787E; -webkit-text-size-adjust: none;\n }\n @media only screen and (max-width: 600px) {\n .email-body_inner {\n width: 100% !important;\n }\n .email-footer {\n width: 100% !important;\n }\n }\n @media only screen and (max-width: 500px) {\n .button {\n width: 100% !important;\n }\n }\n</style>\n<table class=\"email-wrapper\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;\" bgcolor=\"#F2F4F6\">\n <tr>\n <td align=\"center\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; word-break: break-word;\">\n <table class=\"email-content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;\">\n\n <tr>\n <td class=\"email-body\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"-premailer-cellpadding: 0; -premailer-cellspacing: 0; border-bottom-color: #EDEFF2; border-bottom-style: solid; border-bottom-width: 1px; border-top-color: #EDEFF2; border-top-style: solid; border-top-width: 1px; box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%; word-break: break-word;\" bgcolor=\"#FFFFFF\">\n <table class=\"email-body_inner\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0 auto; padding: 0; width: 570px;\" bgcolor=\"#FFFFFF\">\n\n <tr>\n <td class=\"content-cell\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; padding: 35px; word-break: break-word;\">\n <h1 style=\"box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;\" align=\"left\">{{ .Service.Name }} is Offline!</h1>\n <p style=\"box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 16px; line-height: 1.5em; margin-top: 0;\" align=\"left\">\n Your Statup service '<a target=\"_blank\" href=\"{{.Service.Domain}}\">{{.Service.Name}}</a>' has been triggered with a HTTP status code of '{{.Service.LastStatusCode}}' and is currently offline based on your requirements. This failure was created on {{.Service.CreatedAt}}.\n </p>\n\n {{if .Service.LastResponse }}\n <h1 style=\"box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;\" align=\"left\">Last Response</h1>\n <p style=\" box - sizing : border - box ; color : # 74787 E ; font - family : Ar
2018-09-20 09:46:51 +00:00
SUCCESS = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n <title>Sample Email</title>\n\n\n</head>\n<body style=\"-webkit-text-size-adjust: none; box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; height: 100%; line-height: 1.4; margin: 0; width: 100% !important;\" bgcolor=\"#F2F4F6\"><style type=\"text/css\">\n body {\n width: 100% !important; height: 100%; margin: 0; line-height: 1.4; background-color: #F2F4F6; color: #74787E; -webkit-text-size-adjust: none;\n }\n @media only screen and (max-width: 600px) {\n .email-body_inner {\n width: 100% !important;\n }\n .email-footer {\n width: 100% !important;\n }\n }\n @media only screen and (max-width: 500px) {\n .button {\n width: 100% !important;\n }\n }\n</style>\n<table class=\"email-wrapper\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;\" bgcolor=\"#F2F4F6\">\n <tr>\n <td align=\"center\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; word-break: break-word;\">\n <table class=\"email-content\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;\">\n\n <tr>\n <td class=\"email-body\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"-premailer-cellpadding: 0; -premailer-cellspacing: 0; border-bottom-color: #EDEFF2; border-bottom-style: solid; border-bottom-width: 1px; border-top-color: #EDEFF2; border-top-style: solid; border-top-width: 1px; box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%; word-break: break-word;\" bgcolor=\"#FFFFFF\">\n <table class=\"email-body_inner\" align=\"center\" width=\"570\" cellpadding=\"0\" cellspacing=\"0\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0 auto; padding: 0; width: 570px;\" bgcolor=\"#FFFFFF\">\n\n <tr>\n <td class=\"content-cell\" style=\"box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; padding: 35px; word-break: break-word;\">\n <h1 style=\"box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;\" align=\"left\">{{ .Service.Name }} is Offline!</h1>\n <p style=\"box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 16px; line-height: 1.5em; margin-top: 0;\" align=\"left\">\n Your Statup service '<a target=\"_blank\" href=\"{{.Service.Domain}}\">{{.Service.Name}}</a>' has been triggered with a HTTP status code of '{{.Service.LastStatusCode}}' and is currently offline based on your requirements. This failure was created on {{.Service.CreatedAt}}.\n </p>\n\n {{if .Service.LastResponse }}\n <h1 style=\"box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;\" align=\"left\">Last Response</h1>\n <p style=\" box - sizing : border - box ; color : # 74787 E ; font - family : Ar
2018-07-11 03:06:21 +00:00
)
var (
2018-09-15 01:18:21 +00:00
mailer * gomail . Dialer
2018-07-11 03:06:21 +00:00
)
type Email struct {
2018-09-12 04:14:22 +00:00
* notifier . Notification
2018-07-11 03:06:21 +00:00
}
2018-09-15 01:18:21 +00:00
var emailer = & Email { & notifier . Notification {
Method : "email" ,
Title : "Email" ,
Description : "Send emails via SMTP when notification are online or offline." ,
Author : "Hunter Long" ,
AuthorUrl : "https://github.com/hunterlong" ,
Form : [ ] notifier . 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 : "Insert your Outgoing Email Address" ,
DbField : "Var1" ,
} , {
Type : "email" ,
Title : "Send Alerts To" ,
Placeholder : "Email Address" ,
DbField : "Var2" ,
} } ,
} }
2018-07-11 03:06:21 +00:00
func init ( ) {
2018-09-12 04:14:22 +00:00
err := notifier . AddNotifier ( emailer )
2018-09-10 09:01:04 +00:00
if err != nil {
2018-09-12 04:14:22 +00:00
panic ( err )
2018-07-12 06:53:18 +00:00
}
2018-07-11 03:06:21 +00:00
}
2018-09-15 22:39:17 +00:00
// Send will send the SMTP email with your authentication It accepts type: *EmailOutgoing
2018-09-15 01:18:21 +00:00
func ( u * Email ) Send ( msg interface { } ) error {
2018-09-15 22:21:58 +00:00
email := msg . ( * EmailOutgoing )
err := u . dialSend ( email )
if err != nil {
utils . Log ( 3 , fmt . Sprintf ( "Email Notifier could not send email: %v" , err ) )
return err
}
2018-07-12 06:53:18 +00:00
return nil
}
2018-09-15 05:07:17 +00:00
func ( u * Email ) OnTest ( n notifier . Notification ) ( bool , error ) {
2018-09-15 01:18:21 +00:00
email := & EmailOutgoing {
To : emailer . GetValue ( "var2" ) ,
Subject : "Test Email" ,
Template : MESSAGE ,
Data : nil ,
From : emailer . GetValue ( "var1" ) ,
}
u . AddQueue ( email )
2018-09-15 05:07:17 +00:00
return true , nil
2018-07-16 07:02:33 +00:00
}
2018-07-17 09:18:20 +00:00
type EmailOutgoing struct {
To string
Subject string
Template string
From string
Data interface { }
Source string
Sent bool
}
2018-09-15 22:39:17 +00:00
// OnFailure will trigger failing service
2018-09-10 09:01:04 +00:00
func ( u * Email ) OnFailure ( s * types . Service , f * types . Failure ) {
2018-09-15 01:18:21 +00:00
email := & EmailOutgoing {
To : emailer . GetValue ( "var2" ) ,
Subject : fmt . Sprintf ( "Service %v is Failing" , s . Name ) ,
Template : FAILURE ,
Data : interface { } ( s ) ,
From : emailer . GetValue ( "var1" ) ,
2018-07-12 04:49:18 +00:00
}
2018-09-15 01:18:21 +00:00
u . AddQueue ( email )
2018-09-20 09:46:51 +00:00
u . Online = false
2018-07-11 03:06:21 +00:00
}
2018-09-15 22:39:17 +00:00
// OnSuccess will trigger successful service
2018-09-10 09:01:04 +00:00
func ( u * Email ) OnSuccess ( s * types . Service ) {
2018-09-20 09:46:51 +00:00
if ! u . Online {
email := & EmailOutgoing {
To : emailer . GetValue ( "var2" ) ,
Subject : fmt . Sprintf ( "Service %v is Back Online" , s . Name ) ,
Template : SUCCESS ,
Data : interface { } ( s ) ,
From : emailer . GetValue ( "var1" ) ,
}
u . AddQueue ( email )
}
u . Online = true
2018-07-11 03:06:21 +00:00
}
2018-09-15 01:18:21 +00:00
func ( u * Email ) Select ( ) * notifier . Notification {
return u . Notification
}
2018-09-15 22:39:17 +00:00
// OnSave triggers when this notifier has been saved
2018-07-11 03:06:21 +00:00
func ( u * Email ) OnSave ( ) error {
utils . Log ( 1 , fmt . Sprintf ( "Notification %v is receiving updated information." , u . Method ) )
// Do updating stuff here
return nil
}
2018-07-17 09:18:20 +00:00
func ( u * Email ) dialSend ( email * EmailOutgoing ) error {
2018-09-16 18:37:01 +00:00
mailer = gomail . NewPlainDialer ( emailer . Host , emailer . Port , emailer . Username , emailer . Password )
2018-09-15 22:21:58 +00:00
mailer . TLSConfig = & tls . Config { InsecureSkipVerify : true }
emailSource ( email )
2018-07-12 06:53:18 +00:00
m := gomail . NewMessage ( )
m . SetHeader ( "From" , email . From )
m . SetHeader ( "To" , email . To )
m . SetHeader ( "Subject" , email . Subject )
m . SetBody ( "text/html" , email . Source )
2018-07-16 07:02:33 +00:00
if err := mailer . DialAndSend ( m ) ; err != nil {
2018-07-12 06:53:18 +00:00
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
}
2018-09-15 22:21:58 +00:00
func emailSource ( email * EmailOutgoing ) {
2018-09-15 01:18:21 +00:00
source := EmailTemplate ( email . Template , email . Data )
2018-07-12 06:53:18 +00:00
email . Source = source
}
2018-09-15 01:18:21 +00:00
func EmailTemplate ( contents string , data interface { } ) string {
2018-07-12 06:53:18 +00:00
t := template . New ( "email" )
2018-09-15 01:18:21 +00:00
t , err := t . Parse ( contents )
2018-07-12 06:53:18 +00:00
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
}