Files
crawlab/core/notification/mail.go

179 lines
4.3 KiB
Go

package notification
import (
"errors"
"github.com/apex/log"
"github.com/crawlab-team/crawlab/core/models/models/v2"
"github.com/matcornic/hermes/v2"
"gopkg.in/gomail.v2"
"net/mail"
"runtime/debug"
"strconv"
"strings"
)
func SendMail(m *models.NotificationSettingMail, to, cc, title, content string) error {
// theme
theme := new(MailThemeFlat)
// hermes instance
h := hermes.Hermes{
Theme: theme,
Product: hermes.Product{
Logo: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICAgIDxnIGZpbGw9Im5vbmUiPgogICAgICAgIDxjaXJjbGUgY3g9IjE1MCIgY3k9IjE1MCIgcj0iMTMwIiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjQwIiBzdHJva2U9IiM0MDllZmYiPgogICAgICAgIDwvY2lyY2xlPgogICAgICAgIDxjaXJjbGUgY3g9IjE1MCIgY3k9IjE1MCIgcj0iMTEwIiBmaWxsPSJ3aGl0ZSI+CiAgICAgICAgPC9jaXJjbGU+CiAgICAgICAgPGNpcmNsZSBjeD0iMTUwIiBjeT0iMTUwIiByPSI3MCIgZmlsbD0iIzQwOWVmZiI+CiAgICAgICAgPC9jaXJjbGU+CiAgICAgICAgPHBhdGggZD0iCiAgICAgICAgICAgIE0gMTUwLDE1MAogICAgICAgICAgICBMIDI4MCwyMjUKICAgICAgICAgICAgQSAxNTAsMTUwIDkwIDAgMCAyODAsNzUKICAgICAgICAgICAgIiBmaWxsPSIjNDA5ZWZmIj4KICAgICAgICA8L3BhdGg+CiAgICA8L2c+Cjwvc3ZnPgo=",
Name: "Crawlab",
Copyright: "© 2024 Crawlab-Team",
},
}
// config
port, _ := strconv.Atoi(m.Port)
password := m.Password
SMTPUser := m.User
smtpConfig := smtpAuthentication{
Server: m.Server,
Port: port,
SenderEmail: m.SenderEmail,
SenderIdentity: m.SenderIdentity,
SMTPPassword: password,
SMTPUser: SMTPUser,
}
options := sendOptions{
To: to,
Cc: cc,
Subject: title,
}
// add style
content += theme.GetStyle()
// markdown
markdown := hermes.Markdown(content + GetFooter())
// email instance
email := hermes.Email{
Body: hermes.Body{
Signature: "Happy Crawling ☺",
FreeMarkdown: markdown,
},
}
// generate html
html, err := h.GenerateHTML(email)
if err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return err
}
// generate text
text, err := h.GeneratePlainText(email)
if err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return err
}
// send the email
if err := send(smtpConfig, options, html, text); err != nil {
log.Errorf(err.Error())
debug.PrintStack()
return err
}
return nil
}
type smtpAuthentication struct {
Server string
Port int
SenderEmail string
SenderIdentity string
SMTPUser string
SMTPPassword string
}
// sendOptions are options for sending an email
type sendOptions struct {
To string
Subject string
Cc string
}
// send email
func send(smtpConfig smtpAuthentication, options sendOptions, htmlBody string, txtBody string) error {
if smtpConfig.Server == "" {
return errors.New("SMTP server config is empty")
}
if smtpConfig.Port == 0 {
return errors.New("SMTP port config is empty")
}
if smtpConfig.SMTPUser == "" {
return errors.New("SMTP user is empty")
}
if smtpConfig.SenderIdentity == "" {
return errors.New("SMTP sender identity is empty")
}
if smtpConfig.SenderEmail == "" {
return errors.New("SMTP sender email is empty")
}
if options.To == "" {
return errors.New("no receiver emails configured")
}
from := mail.Address{
Name: smtpConfig.SenderIdentity,
Address: smtpConfig.SenderEmail,
}
var toList []string
if strings.Contains(options.To, ";") {
toList = strings.Split(options.To, ";")
// trim space
for i, to := range toList {
toList[i] = strings.TrimSpace(to)
}
} else {
toList = []string{options.To}
}
m := gomail.NewMessage()
m.SetHeader("From", from.String())
m.SetHeader("To", getRecipientList(options.To)...)
m.SetHeader("Subject", options.Subject)
if options.Cc != "" {
m.SetHeader("Cc", getRecipientList(options.Cc)...)
}
m.SetBody("text/plain", txtBody)
m.AddAlternative("text/html", htmlBody)
d := gomail.NewDialer(smtpConfig.Server, smtpConfig.Port, smtpConfig.SMTPUser, smtpConfig.SMTPPassword)
return d.DialAndSend(m)
}
func getRecipientList(value string) (values []string) {
if strings.Contains(value, ";") {
values = strings.Split(value, ";")
// trim space
for i, v := range values {
values[i] = strings.TrimSpace(v)
}
} else {
values = []string{value}
}
return values
}
func GetFooter() string {
return `
[Github](https://github.com/crawlab-team/crawlab) | [Documentation](http://docs.crawlab.cn) | [Docker](https://hub.docker.com/r/tikazyq/crawlab)
`
}