122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
package mail
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"io"
|
|
|
|
"apigo.cc/go/file"
|
|
"github.com/jaytaylor/html2text"
|
|
"gopkg.in/gomail.v2"
|
|
)
|
|
|
|
// SendOption 发送选项
|
|
type SendOption struct {
|
|
Cc []string
|
|
Bcc []string
|
|
HTML bool
|
|
Attachments []Attachment
|
|
Embeds []Attachment
|
|
}
|
|
|
|
// Send 发送邮件
|
|
func (m *Mailbox) Send(to []string, subject, content string, option *SendOption) error {
|
|
if m.config == nil || m.config.Username == "" {
|
|
return fmt.Errorf("mailbox not configured")
|
|
}
|
|
|
|
msg := gomail.NewMessage()
|
|
if m.config.SenderName != "" {
|
|
msg.SetHeader("From", msg.FormatAddress(m.config.Username, m.config.SenderName))
|
|
} else {
|
|
msg.SetHeader("From", m.config.Username)
|
|
}
|
|
|
|
msg.SetHeader("To", to...)
|
|
msg.SetHeader("Subject", subject)
|
|
|
|
useHTML := false
|
|
if option != nil {
|
|
if len(option.Cc) > 0 {
|
|
msg.SetHeader("Cc", option.Cc...)
|
|
}
|
|
if len(option.Bcc) > 0 {
|
|
msg.SetHeader("Bcc", option.Bcc...)
|
|
}
|
|
for _, attachment := range option.Attachments {
|
|
if attachment.Path != "" {
|
|
if file.Exists(attachment.Path) {
|
|
msg.Attach(attachment.Path)
|
|
} else {
|
|
m.logger.Error("Mail attachment file not found", "path", attachment.Path)
|
|
}
|
|
} else if len(attachment.Data) > 0 {
|
|
name := attachment.Name
|
|
if name == "" {
|
|
name = "attachment"
|
|
}
|
|
msg.Attach(name, gomail.SetCopyFunc(func(w io.Writer) error {
|
|
_, err := w.Write(attachment.Data)
|
|
return err
|
|
}))
|
|
}
|
|
}
|
|
for _, embed := range option.Embeds {
|
|
if embed.Path != "" {
|
|
if file.Exists(embed.Path) {
|
|
msg.Embed(embed.Path)
|
|
} else {
|
|
m.logger.Error("Mail embed file not found", "path", embed.Path)
|
|
}
|
|
} else if len(embed.Data) > 0 {
|
|
name := embed.Name
|
|
if name == "" {
|
|
name = "image"
|
|
}
|
|
msg.Embed(name, gomail.SetCopyFunc(func(w io.Writer) error {
|
|
_, err := w.Write(embed.Data)
|
|
return err
|
|
}))
|
|
}
|
|
}
|
|
useHTML = option.HTML
|
|
}
|
|
|
|
if useHTML {
|
|
msg.SetBody("text/html", content)
|
|
if textContent, err := html2text.FromString(content, html2text.Options{TextOnly: true, PrettyTables: true}); err == nil {
|
|
msg.AddAlternative("text/plain", textContent)
|
|
} else {
|
|
m.logger.Warning("Convert HTML to text failed", "err", err)
|
|
msg.AddAlternative("text/plain", content)
|
|
}
|
|
} else {
|
|
msg.SetBody("text/plain", content)
|
|
}
|
|
|
|
password := ""
|
|
if m.config.Password != nil {
|
|
p := m.config.Password.Open()
|
|
password = p.String()
|
|
defer p.Close()
|
|
}
|
|
|
|
dialer := gomail.NewDialer(m.config.SMTPHost, m.config.SMTPPort, m.config.Username, password)
|
|
if m.config.SMTPPort == 465 {
|
|
dialer.SSL = true
|
|
} else {
|
|
dialer.TLSConfig = &tls.Config{
|
|
ServerName: m.config.SMTPHost,
|
|
InsecureSkipVerify: false,
|
|
}
|
|
}
|
|
|
|
err := dialer.DialAndSend(msg)
|
|
if err != nil {
|
|
m.logger.Error("Send mail failed", "err", err, "to", to, "subject", subject)
|
|
} else {
|
|
m.logger.Info("Send mail success", "to", to, "subject", subject)
|
|
}
|
|
return err
|
|
}
|