You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sonic/service/impl/email.go

119 lines
3.4 KiB
Go

package impl
import (
"context"
"crypto/tls"
"fmt"
"net/smtp"
"github.com/jordan-wright/email"
"github.com/go-sonic/sonic/model/property"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/util/xerr"
)
type emailServiceImpl struct {
OptionService service.OptionService
}
func NewEmailService(optionService service.OptionService) service.EmailService {
return &emailServiceImpl{
OptionService: optionService,
}
}
type emailProperties struct {
Host string
Protocol string
SSLPort int
Username string
Password string
FromName string
}
func (e *emailServiceImpl) SendTextEmail(ctx context.Context, to, subject, content string) error {
emailEnable, err := e.OptionService.GetOrByDefaultWithErr(ctx, property.EmailIsEnabled, false)
if err != nil {
return err
}
if !emailEnable.(bool) {
return nil
}
emailProperties, err := e.getEmailProperties(ctx)
if err != nil {
return err
}
email := &email.Email{
To: []string{to},
From: emailProperties.FromName,
Subject: subject,
Text: []byte(content),
}
err = e.sendEmail(email, emailProperties)
return err
}
func (e *emailServiceImpl) SendTemplateEmail(ctx context.Context, to, subject string, content string) error {
emailEnable, err := e.OptionService.GetOrByDefaultWithErr(ctx, property.EmailIsEnabled, false)
if err != nil {
return err
}
if !emailEnable.(bool) {
return nil
}
emailProperties, err := e.getEmailProperties(ctx)
if err != nil {
return err
}
email := &email.Email{
To: []string{to},
From: emailProperties.FromName,
Subject: subject,
HTML: []byte(content),
}
err = e.sendEmail(email, emailProperties)
return err
}
func (e *emailServiceImpl) TestConnection() error {
panic("implement me")
}
func (e *emailServiceImpl) getEmailProperties(ctx context.Context) (emailProperties, error) {
getOrByDefault := func(ctx context.Context, p property.Property, defaultValue interface{}, err error) (interface{}, error) {
if err != nil {
return nil, err
}
return e.OptionService.GetOrByDefaultWithErr(ctx, p, defaultValue)
}
host, err := getOrByDefault(ctx, property.EmailHost, property.EmailHost.DefaultValue, nil)
protocol, err := getOrByDefault(ctx, property.EmailProtocol, property.EmailProtocol.DefaultValue, err)
sslPort, err := getOrByDefault(ctx, property.EmailSSLPort, property.EmailSSLPort.DefaultValue, err)
username, err := getOrByDefault(ctx, property.EmailUsername, property.EmailUsername.DefaultValue, err)
password, err := getOrByDefault(ctx, property.EmailPassword, property.EmailPassword.DefaultValue, err)
fromName, err := getOrByDefault(ctx, property.EmailFromName, property.EmailFromName.DefaultValue, err)
if err != nil {
return emailProperties{}, err
}
emailProperties := emailProperties{
Host: host.(string),
Protocol: protocol.(string),
SSLPort: sslPort.(int),
Username: username.(string),
Password: password.(string),
FromName: fromName.(string),
}
return emailProperties, nil
}
func (e *emailServiceImpl) sendEmail(email *email.Email, properties emailProperties) error {
err := email.SendWithTLS(fmt.Sprintf("%s:%d", properties.Host, properties.SSLPort),
smtp.PlainAuth("", properties.Username, properties.Password, properties.Host), &tls.Config{ServerName: properties.Host, MinVersion: tls.VersionTLS13})
if err != nil {
return xerr.Email.Wrapf(err, "发送邮件错误 emailProperties=%v", properties).WithStatus(xerr.StatusInternalServerError).
WithMsg("发送邮件错误")
}
return nil
}