refactor: reorganize modules and add Linux build tooling
This commit is contained in:
152
module/base/sender/internal/logic/mail/send.go
Normal file
152
module/base/sender/internal/logic/mail/send.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package mail
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/mail"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
|
||||
"bsm/full/module/base/sender/internal/config"
|
||||
"bsm/full/module/base/sender/internal/excode"
|
||||
"bsm/full/module/base/sender/internal/impl"
|
||||
"bsm/full/module/base/sender/internal/models"
|
||||
pb "bsm/full/module/base/sender/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
func Send(ctx context.Context, in *pb.SendMailRequest) (reply *pb.SendMailReply, err error) {
|
||||
provider := strings.ToLower(in.GetProvider())
|
||||
|
||||
// 校验参数
|
||||
if in.GetTemplateKey() == "" || provider == "" || in.GetTo() == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
// 校验配置
|
||||
cfg, ok := config.Spec.SMTP[provider]
|
||||
if !ok || cfg == nil {
|
||||
return nil, excode.ErrProviderIsNil
|
||||
}
|
||||
|
||||
// 检验邮箱格式
|
||||
if !ValidateEmail(in.GetTo()) {
|
||||
return nil, excode.ErrEmail
|
||||
}
|
||||
|
||||
// 获取模板
|
||||
var tplRecord models.SenderTemplate
|
||||
err = impl.DBService.Where("key=?", in.GetTemplateKey()).First(&tplRecord).Error
|
||||
if err != nil {
|
||||
return nil, errcode.ErrNotFound(1404, "template")
|
||||
}
|
||||
|
||||
// 解析模板
|
||||
tmpl, err := template.New("page").Parse(tplRecord.Body)
|
||||
if err != nil {
|
||||
return nil, excode.ErrTemplate
|
||||
}
|
||||
|
||||
// 发送邮件
|
||||
switch provider {
|
||||
case "qq":
|
||||
err = QQ(cfg, tmpl, in.GetTo(), tplRecord.Subjet, in.GetParamters())
|
||||
default:
|
||||
return nil, excode.ErrNotProvider
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pb.SendMailReply{
|
||||
Data: vars.OK,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func ValidateEmail(s string) bool {
|
||||
_, err := mail.ParseAddress(s)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func QQ(cfg *config.SmtpConf, tmpl *template.Template, to string, subject string, args map[string]string) error {
|
||||
// 建立TLS加密连接
|
||||
conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", cfg.Endpoint, cfg.Port), &tls.Config{
|
||||
ServerName: cfg.Endpoint,
|
||||
MinVersion: tls.VersionTLS12, // 强制TLS1.2+
|
||||
InsecureSkipVerify: false,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("TLS连接失败: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建SMTP客户端(带超时控制)
|
||||
client, err := smtp.NewClient(conn, cfg.Endpoint)
|
||||
if err != nil {
|
||||
client.Close()
|
||||
fmt.Println("SMTP客户端初始化失败: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置认证
|
||||
auth := smtp.PlainAuth("", cfg.Username, cfg.Password, cfg.Endpoint)
|
||||
if err := client.Auth(auth); err != nil {
|
||||
client.Close()
|
||||
fmt.Println("认证失败: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置发件人和收件人
|
||||
err = client.Mail(cfg.FromAddress)
|
||||
if err != nil {
|
||||
client.Close()
|
||||
fmt.Println("发件人设置失败: ", err)
|
||||
return err
|
||||
}
|
||||
err = client.Rcpt(to)
|
||||
if err != nil {
|
||||
fmt.Println("发件人设置失败: ", err)
|
||||
client.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建一个写入SMTP服务器的标准写入器
|
||||
writer, err := client.Data()
|
||||
if err != nil {
|
||||
client.Close()
|
||||
return err
|
||||
}
|
||||
defer writer.Close()
|
||||
|
||||
// 构建邮件正文
|
||||
mailBody := "From: " + cfg.FromName + "<" + cfg.FromAddress + ">\n"
|
||||
mailBody += "To: " + to + "\n"
|
||||
mailBody += "Subject: " + subject + "\n\n"
|
||||
|
||||
// 执行模板,将结果写入邮件正文
|
||||
var buf bytes.Buffer
|
||||
err = tmpl.Execute(&buf, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mailBody += buf.String()
|
||||
|
||||
// 将邮件正文发送到SMTP服务器
|
||||
if _, err := writer.Write([]byte(mailBody)); err != nil {
|
||||
client.Close()
|
||||
fmt.Printf("写入邮件内容失败: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writer.Close(); err != nil {
|
||||
client.Close()
|
||||
fmt.Printf("关闭数据流失败: %v", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user