ovpn-certman/services/email.go
2018-02-01 03:30:00 +01:00

121 lines
2.4 KiB
Go

package services
import (
"errors"
"log"
"time"
"github.com/go-mail/mail"
)
var (
ErrMailUninitializedConfig = errors.New("Mail: uninitialized config")
)
type EmailConfig struct {
From string
SMTPEnabled bool
SMTPServer string
SMTPPort int
SMTPUsername string
SMTPPassword string
SMTPTimeout time.Duration
}
type Email struct {
config *EmailConfig
mailChan chan *mail.Message
}
func NewEmail(conf *EmailConfig) *Email {
if conf == nil {
log.Println(ErrMailUninitializedConfig)
}
return &Email{
config: conf,
mailChan: make(chan *mail.Message, 4),
}
}
// Send sends an email to the receiver
func (email *Email) Send(to, subject, text, html string) error {
if email.config == nil {
log.Print("Error: trying to send mail with uninitialized config.")
return ErrMailUninitializedConfig
}
if !email.config.SMTPEnabled {
log.Printf("SMTP is disabled in config, printing out email text instead:\nTo: %s\n%s", to, text)
}
m := mail.NewMessage()
m.SetHeader("From", email.config.From)
m.SetHeader("To", to)
m.SetHeader("Subject", subject)
m.SetBody("text/plain", text)
if len(html) > 0 {
m.AddAlternative("text/html", html)
}
// put email in chan
email.mailChan <- m
return nil
}
// Daemon is a function that takes Mail and sends it without blocking.
// WIP
func (email *Email) Daemon() {
if email.config == nil {
log.Print("Error: trying to set up mail deamon with uninitialized config.")
return
}
if !email.config.SMTPEnabled {
log.Print("SMTP is disabled in config, emails will be printed instead.")
return
}
log.Print("Running mail sending routine")
d := mail.NewDialer(
email.config.SMTPServer,
email.config.SMTPPort,
email.config.SMTPUsername,
email.config.SMTPPassword)
var s mail.SendCloser
var err error
open := false
for {
select {
case m, ok := <-email.mailChan:
if !ok {
// channel is closed
log.Print("Channel closed")
return
}
if !open {
if s, err = d.Dial(); err != nil {
log.Print(err)
return
}
open = true
}
log.Printf("Trying to send mail")
if err := mail.Send(s, m); err != nil {
log.Printf("Mail: %s", err)
}
// Close the connection if no email was sent in the last X seconds.
case <-time.After(email.config.SMTPTimeout):
if open {
if err := s.Close(); err != nil {
log.Printf("Mail: Failed to close connection: %s", err)
}
open = false
}
}
}
}