126 lines
2.5 KiB
Go
126 lines
2.5 KiB
Go
|
|
package main
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"crypto/tls"
|
|||
|
|
"fmt"
|
|||
|
|
"log"
|
|||
|
|
"net/smtp"
|
|||
|
|
"os"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const (
|
|||
|
|
smtpServer = "smtp.exmail.qq.com"
|
|||
|
|
smtpPort = 465
|
|||
|
|
maxRetries = 3
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func main() {
|
|||
|
|
log.Println("Service Cli Mode Start ...")
|
|||
|
|
log.Println("Done!")
|
|||
|
|
err := sendEmail(
|
|||
|
|
os.Getenv("BSM_SMTP_TO"),
|
|||
|
|
"Go邮件测试",
|
|||
|
|
"这是一封通过Go语言发送的测试邮件",
|
|||
|
|
)
|
|||
|
|
if err != nil {
|
|||
|
|
fmt.Printf("发送失败: %v\n", err)
|
|||
|
|
} else {
|
|||
|
|
fmt.Println("邮件发送成功")
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func sendEmail(to, subject, body string) error {
|
|||
|
|
smtpUser := os.Getenv("BSM_SMTP_USER")
|
|||
|
|
smtpPassword := os.Getenv("BSM_SMTP_PASSWORD")
|
|||
|
|
if smtpUser == "" || smtpPassword == "" || to == "" {
|
|||
|
|
return fmt.Errorf("BSM_SMTP_USER, BSM_SMTP_PASSWORD and BSM_SMTP_TO are required")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 配置SMTP认证信息(需使用授权码)
|
|||
|
|
auth := smtp.PlainAuth(
|
|||
|
|
"",
|
|||
|
|
smtpUser,
|
|||
|
|
smtpPassword,
|
|||
|
|
smtpServer,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 邮件内容构建(符合RFC822标准)
|
|||
|
|
msg := fmt.Sprintf("To: %s\r\n"+
|
|||
|
|
"From: %s\r\n"+
|
|||
|
|
"Subject: %s\r\n"+
|
|||
|
|
"Content-Type: text/plain; charset=UTF-8\r\n\r\n"+
|
|||
|
|
"%s",
|
|||
|
|
to,
|
|||
|
|
smtpUser,
|
|||
|
|
subject,
|
|||
|
|
body,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 建立TLS连接
|
|||
|
|
tlsConfig := &tls.Config{
|
|||
|
|
ServerName: smtpServer,
|
|||
|
|
InsecureSkipVerify: false,
|
|||
|
|
MinVersion: tls.VersionTLS12,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var lastErr error
|
|||
|
|
for i := 0; i < maxRetries; i++ {
|
|||
|
|
conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", smtpServer, smtpPort), tlsConfig)
|
|||
|
|
if err != nil {
|
|||
|
|
lastErr = fmt.Errorf("TLS连接失败: %v", err)
|
|||
|
|
time.Sleep(2 * time.Second)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
client, err := smtp.NewClient(conn, smtpServer)
|
|||
|
|
if err != nil {
|
|||
|
|
conn.Close()
|
|||
|
|
lastErr = fmt.Errorf("SMTP客户端创建失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err := client.Auth(auth); err != nil {
|
|||
|
|
client.Close()
|
|||
|
|
lastErr = fmt.Errorf("认证失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err := client.Mail("yanweidong@senlinai.com"); err != nil {
|
|||
|
|
client.Close()
|
|||
|
|
lastErr = fmt.Errorf("MAIL命令失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err := client.Rcpt(to); err != nil {
|
|||
|
|
client.Close()
|
|||
|
|
lastErr = fmt.Errorf("RCPT命令失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
w, err := client.Data()
|
|||
|
|
if err != nil {
|
|||
|
|
client.Close()
|
|||
|
|
lastErr = fmt.Errorf("DATA命令失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if _, err := w.Write([]byte(msg)); err != nil {
|
|||
|
|
client.Close()
|
|||
|
|
lastErr = fmt.Errorf("写入邮件内容失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err := w.Close(); err != nil {
|
|||
|
|
client.Close()
|
|||
|
|
lastErr = fmt.Errorf("关闭数据流失败: %v", err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
client.Quit()
|
|||
|
|
return nil
|
|||
|
|
}
|
|||
|
|
return lastErr
|
|||
|
|
|
|||
|
|
}
|