mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
108 lines
2.6 KiB
Go
108 lines
2.6 KiB
Go
package mail
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"net/mail"
|
|
"net/smtp"
|
|
"strings"
|
|
|
|
"github.com/kataras/iris/config"
|
|
"github.com/kataras/iris/utils"
|
|
)
|
|
|
|
var buf = utils.NewBufferPool(64)
|
|
|
|
type (
|
|
// Service is the interface which mail sender should implement
|
|
Service interface {
|
|
// Send sends a mail to recipients
|
|
// the body can be html also
|
|
Send(to []string, subject, body string) error
|
|
}
|
|
|
|
mailer struct {
|
|
config config.Mail
|
|
fromAddr mail.Address
|
|
auth smtp.Auth
|
|
authenticated bool
|
|
}
|
|
)
|
|
|
|
// New creates and returns a new Service
|
|
func New(cfg config.Mail) Service {
|
|
m := &mailer{config: cfg}
|
|
|
|
if cfg.FromAlias == "" {
|
|
if !cfg.UseCommand && cfg.Username != "" && strings.Contains(cfg.Username, "@") {
|
|
m.fromAddr = mail.Address{cfg.Username[0:strings.IndexByte(cfg.Username, '@')], cfg.Username}
|
|
}
|
|
} else {
|
|
m.fromAddr = mail.Address{cfg.FromAlias, cfg.Username}
|
|
}
|
|
|
|
return m
|
|
}
|
|
|
|
// Send sends a mail to recipients
|
|
// the body can be html also
|
|
func (m *mailer) Send(to []string, subject, body string) error {
|
|
if m.config.UseCommand {
|
|
return m.sendCmd(to, subject, body)
|
|
}
|
|
|
|
return m.sendSMTP(to, subject, body)
|
|
}
|
|
|
|
func (m *mailer) sendSMTP(to []string, subject, body string) error {
|
|
buffer := buf.Get()
|
|
defer buf.Put(buffer)
|
|
|
|
if !m.authenticated {
|
|
if m.config.Username == "" || m.config.Password == "" || m.config.Host == "" || m.config.Port <= 0 {
|
|
return fmt.Errorf("Username, Password, Host & Port cannot be empty when using SMTP!")
|
|
}
|
|
m.auth = smtp.PlainAuth("", m.config.Username, m.config.Password, m.config.Host)
|
|
m.authenticated = true
|
|
}
|
|
|
|
fullhost := fmt.Sprintf("%s:%d", m.config.Host, m.config.Port)
|
|
|
|
/* START: This one helped me https://gist.github.com/andelf/5004821 */
|
|
header := make(map[string]string)
|
|
header["From"] = m.fromAddr.String()
|
|
header["To"] = strings.Join(to, ",")
|
|
header["Subject"] = subject
|
|
header["MIME-Version"] = "1.0"
|
|
header["Content-Type"] = "text/html; charset=\"utf-8\""
|
|
header["Content-Transfer-Encoding"] = "base64"
|
|
|
|
message := ""
|
|
for k, v := range header {
|
|
message += fmt.Sprintf("%s: %s\r\n", k, v)
|
|
}
|
|
message += "\r\n" + base64.StdEncoding.EncodeToString([]byte(body))
|
|
|
|
/* END */
|
|
|
|
return smtp.SendMail(
|
|
fmt.Sprintf(fullhost),
|
|
m.auth,
|
|
m.config.Username,
|
|
to,
|
|
[]byte(message),
|
|
)
|
|
}
|
|
|
|
func (m *mailer) sendCmd(to []string, subject, body string) error {
|
|
buffer := buf.Get()
|
|
defer buf.Put(buffer)
|
|
|
|
cmd := utils.CommandBuilder("mail", "-s", subject, strings.Join(to, ","))
|
|
cmd.AppendArguments("-a", "Content-type: text/html") //always html on
|
|
|
|
cmd.Stdin = buffer
|
|
_, err := cmd.Output()
|
|
return err
|
|
}
|