84 lines
2.7 KiB
Go
84 lines
2.7 KiB
Go
package email
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net/smtp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gopkg.in/gomail.v2"
|
|
)
|
|
|
|
type EmailConfig struct {
|
|
Enabled bool `yaml:"enabled" json:"enabled"` // 是否启用邮件发送
|
|
Host string `yaml:"host" json:"host"` // SMTP服务器地址
|
|
Port int `yaml:"port" json:"port"` // SMTP服务器端口
|
|
Username string `yaml:"username" json:"username"` // SMTP用户名
|
|
Password string `yaml:"password" json:"password"` // SMTP密码
|
|
TLSSkipVerify bool `yaml:"tlsSkipVerify" json:"tlsSkipVerify"` // 是否跳过TLS证书验证
|
|
From string `yaml:"from" json:"from"` // 发件人邮箱地址
|
|
To string `yaml:"to" json:"to"` // 收件人邮箱地址列表
|
|
Subject string `yaml:"subject" json:"subject"` // 邮件主题
|
|
Body string `yaml:"body" json:"body"` // 邮件正文内容
|
|
}
|
|
|
|
// 简单邮件发送函数
|
|
// 该函数使用标准库的 smtp 包发送邮件
|
|
// 注意:此函数不支持 TLS 加密,建议使用 gomail 包发送邮件以支持 TLS 和其他高级功能
|
|
// gomail 包的使用示例见 SendEmailWithGomail 函数
|
|
func SendEmail(email EmailConfig) error {
|
|
username := email.Username
|
|
from := email.From
|
|
password := email.Password
|
|
to := email.To
|
|
subject := email.Subject
|
|
body := email.Body
|
|
smtpHost := email.Host
|
|
smtpPort := email.Port
|
|
|
|
msg := "From: " + from + "\n" +
|
|
"To: " + to + "\n" +
|
|
"Subject: " + subject + "\n\n" +
|
|
body
|
|
auth := smtp.PlainAuth(from, username, password, smtpHost)
|
|
return smtp.SendMail(smtpHost+":"+strconv.Itoa(smtpPort), auth, from, []string{to}, []byte(msg))
|
|
}
|
|
|
|
func SendEmailWithGomail(email EmailConfig) error {
|
|
m := gomail.NewMessage()
|
|
m.SetHeader("From", email.From)
|
|
m.SetHeader("To", strings.Split(email.To, ",")...) // 支持多个收件人
|
|
m.SetHeader("Subject", email.Subject)
|
|
m.SetBody("text/plain", email.Body)
|
|
|
|
d := gomail.NewDialer(email.Host, email.Port, email.Username, email.Password)
|
|
|
|
// 配置 TLS
|
|
d.TLSConfig = &tls.Config{
|
|
InsecureSkipVerify: email.TLSSkipVerify,
|
|
}
|
|
|
|
// gomail 会自动处理 STARTTLS
|
|
if err := d.DialAndSend(m); err != nil {
|
|
fmt.Printf("Failed to DialAndSend:%v", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// RemoveDuplicateEmails 去除重复的邮箱地址
|
|
func RemoveDuplicateEmails(emails []string) []string {
|
|
emailMap := make(map[string]struct{})
|
|
var uniqueEmails []string
|
|
|
|
for _, email := range emails {
|
|
if _, exists := emailMap[email]; !exists {
|
|
emailMap[email] = struct{}{}
|
|
uniqueEmails = append(uniqueEmails, email)
|
|
}
|
|
}
|
|
|
|
return uniqueEmails
|
|
}
|