mirror of
				https://github.com/yangjian102621/geekai.git
				synced 2025-11-04 16:23:42 +08:00 
			
		
		
		
	support send email use TLS
This commit is contained in:
		@@ -30,6 +30,7 @@ type AppConfig struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SmtpConfig struct {
 | 
			
		||||
	UseTls   bool // 是否使用 TLS 发送
 | 
			
		||||
	Host     string
 | 
			
		||||
	Port     int
 | 
			
		||||
	AppName  string // 应用名称
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,11 @@ package service
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"chatplus/core/types"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mime"
 | 
			
		||||
	"net/smtp"
 | 
			
		||||
	"net/textproto"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type SmtpService struct {
 | 
			
		||||
@@ -19,12 +21,18 @@ func NewSmtpService(appConfig *types.AppConfig) *SmtpService {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SmtpService) SendVerifyCode(to string, code int) error {
 | 
			
		||||
	subject := "ChatPlus注册验证码"
 | 
			
		||||
	body := fmt.Sprintf("您正在注册 ChatPlus AI 助手账户,注册验证码为 %d,请不要告诉他人。如非本人操作,请忽略此邮件。", code)
 | 
			
		||||
	subject := "Geek-AI 注册验证码"
 | 
			
		||||
	body := fmt.Sprintf("您正在注册 Geek-AI 助手账户,注册验证码为 %d,请不要告诉他人。如非本人操作,请忽略此邮件。", code)
 | 
			
		||||
 | 
			
		||||
	// 设置SMTP客户端配置
 | 
			
		||||
	auth := smtp.PlainAuth("", s.config.From, s.config.Password, s.config.Host)
 | 
			
		||||
	if s.config.UseTls {
 | 
			
		||||
		return s.sendTLS(auth, to, subject, body)
 | 
			
		||||
	} else {
 | 
			
		||||
		return s.send(auth, to, subject, body)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SmtpService) send(auth smtp.Auth, to string, subject string, body string) error {
 | 
			
		||||
	// 对主题进行MIME编码
 | 
			
		||||
	encodedSubject := mime.QEncoding.Encode("UTF-8", subject)
 | 
			
		||||
	// 组装邮件
 | 
			
		||||
@@ -34,11 +42,83 @@ func (s *SmtpService) SendVerifyCode(to string, code int) error {
 | 
			
		||||
	message.WriteString(fmt.Sprintf("Subject: %s\r\n", encodedSubject))
 | 
			
		||||
	message.WriteString("\r\n" + body)
 | 
			
		||||
 | 
			
		||||
	// 发送邮件
 | 
			
		||||
	// 发送邮件
 | 
			
		||||
	err := smtp.SendMail(s.config.Host+":"+fmt.Sprint(s.config.Port), auth, s.config.From, []string{to}, message.Bytes())
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error sending email: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SmtpService) sendTLS(auth smtp.Auth, to string, subject string, body string) error {
 | 
			
		||||
	// TLS配置
 | 
			
		||||
	tlsConfig := &tls.Config{
 | 
			
		||||
		ServerName: s.config.Host,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 建立TLS连接
 | 
			
		||||
	conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", s.config.Host, s.config.Port), tlsConfig)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error connecting to SMTP server: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer conn.Close()
 | 
			
		||||
 | 
			
		||||
	client, err := smtp.NewClient(conn, s.config.Host)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error creating SMTP client: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer client.Quit()
 | 
			
		||||
 | 
			
		||||
	// 身份验证
 | 
			
		||||
	if err = client.Auth(auth); err != nil {
 | 
			
		||||
		return fmt.Errorf("error authenticating: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 设置寄件人
 | 
			
		||||
	if err = client.Mail(s.config.From); err != nil {
 | 
			
		||||
		return fmt.Errorf("error setting sender: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 设置收件人
 | 
			
		||||
	if err = client.Rcpt(to); err != nil {
 | 
			
		||||
		return fmt.Errorf("error setting recipient: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送邮件内容
 | 
			
		||||
	wc, err := client.Data()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error getting data writer: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
	defer wc.Close()
 | 
			
		||||
 | 
			
		||||
	header := make(textproto.MIMEHeader)
 | 
			
		||||
	header.Set("From", s.config.From)
 | 
			
		||||
	header.Set("To", to)
 | 
			
		||||
	header.Set("Subject", subject)
 | 
			
		||||
 | 
			
		||||
	// 将邮件头写入
 | 
			
		||||
	for key, values := range header {
 | 
			
		||||
		for _, value := range values {
 | 
			
		||||
			_, err = fmt.Fprintf(wc, "%s: %s\r\n", key, value)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return fmt.Errorf("error sending email header: %v", err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	_, _ = fmt.Fprintln(wc)
 | 
			
		||||
	// 将邮件内容写入
 | 
			
		||||
	_, err = fmt.Fprintf(wc, body)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error sending email: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 发送完毕
 | 
			
		||||
	err = wc.Close()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("error closing data writer: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user