2018-07-11 03:06:21 +00:00
package notifiers
import (
2018-07-12 06:53:18 +00:00
"bytes"
"crypto/tls"
2018-07-11 03:06:21 +00:00
"fmt"
2018-07-12 06:53:18 +00:00
"github.com/GeertJohan/go.rice"
"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
"time"
)
const (
EMAIL_ID int64 = 1
EMAIL_METHOD = "email"
)
var (
emailer * Email
emailArray [ ] string
2018-07-12 06:53:18 +00:00
emailQueue [ ] * types . Email
2018-07-16 07:02:33 +00:00
emailBox * rice . Box
mailer * gomail . Dialer
2018-07-11 03:06:21 +00:00
)
type Email struct {
* Notification
}
// DEFINE YOUR NOTIFICATION HERE.
func init ( ) {
2018-07-12 06:53:18 +00:00
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" ,
} } ,
} }
2018-07-11 03:06:21 +00:00
add ( emailer )
}
// Select Obj
func ( u * Email ) Select ( ) * Notification {
return u . Notification
}
// WHEN NOTIFIER LOADS
func ( u * Email ) Init ( ) error {
2018-07-16 07:02:33 +00:00
emailBox = rice . MustFindBox ( "emails" )
2018-07-12 06:53:18 +00:00
err := u . Install ( )
2018-07-16 07:02:33 +00:00
utils . Log ( 1 , fmt . Sprintf ( "Creating Mailer: %v:%v" , u . Notification . Host , u . Notification . Port ) )
2018-07-11 03:06:21 +00:00
2018-07-12 06:53:18 +00:00
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 ) )
2018-07-16 07:02:33 +00:00
mailer = gomail . NewDialer ( u . Notification . Host , u . Notification . Port , u . Notification . Username , u . Notification . Password )
mailer . TLSConfig = & tls . Config { InsecureSkipVerify : true }
2018-07-12 06:53:18 +00:00
go u . Run ( )
}
}
2018-07-11 03:06:21 +00:00
return nil
}
2018-07-12 06:53:18 +00:00
func ( u * Email ) Test ( ) error {
2018-07-16 07:02:33 +00:00
if u . Enabled {
email := & types . Email {
To : "info@socialeck.com" ,
Subject : "Test Email" ,
Template : "message.html" ,
Data : nil ,
From : emailer . Var1 ,
}
SendEmail ( emailBox , email )
}
2018-07-12 06:53:18 +00:00
return nil
}
2018-07-16 07:02:33 +00:00
type emailMessage struct {
Service * types . Service
}
2018-07-11 03:06:21 +00:00
// AFTER NOTIFIER LOADS, IF ENABLED, START A QUEUE PROCESS
func ( u * Email ) Run ( ) error {
2018-07-12 06:53:18 +00:00
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 )
}
2018-07-11 03:06:21 +00:00
time . Sleep ( 60 * time . Second )
2018-07-12 06:53:18 +00:00
if u . Enabled {
return u . Run ( )
}
2018-07-11 03:06:21 +00:00
return nil
}
// ON SERVICE FAILURE, DO YOUR OWN FUNCTIONS
2018-07-14 02:37:39 +00:00
func ( u * Email ) OnFailure ( s * types . Service ) error {
2018-07-12 04:49:18 +00:00
if u . Enabled {
2018-07-16 07:02:33 +00:00
msg := emailMessage {
Service : s ,
}
email := & types . Email {
To : "info@socialeck.com" ,
Subject : fmt . Sprintf ( "Service %v is Failing" , s . Name ) ,
Template : "failure.html" ,
Data : msg ,
From : emailer . Var1 ,
}
SendEmail ( emailBox , email )
2018-07-12 04:49:18 +00:00
}
2018-07-11 03:06:21 +00:00
return nil
}
// ON SERVICE SUCCESS, DO YOUR OWN FUNCTIONS
2018-07-14 02:37:39 +00:00
func ( u * Email ) OnSuccess ( s * types . Service ) error {
2018-07-12 04:49:18 +00:00
if u . Enabled {
2018-07-16 07:02:33 +00:00
2018-07-12 04:49:18 +00:00
}
2018-07-11 03:06:21 +00:00
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 {
2018-07-16 07:02:33 +00:00
fmt . Println ( "installing emailer" )
2018-07-11 03:06:21 +00:00
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
}
2018-07-12 06:53:18 +00:00
func ( u * Email ) dialSend ( email * types . Email ) error {
2018-07-16 07:02:33 +00:00
fmt . Println ( "sending dailsend to emailer" )
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
}
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
}