仰望星辰工作室

clearlove2.1

clearlove2.1/ internal/mailer/mailer.go 2.0 KB · 67 行 原始文件
1// Package mailer SMTP 邮件发送,用于注册验证码。
2// 兼容 465 端口(SSL 直连)与 587/25 端口(STARTTLS 或明文)。
3package mailer
4
5import (
6 "crypto/tls"
7 "encoding/base64"
8 "fmt"
9 "net"
10 "net/smtp"
11 "strings"
12)
13
14// Send 发送纯文本邮件。host/port/user/pass/from 来自后台 SMTP 设置
15func Send(host string, port string, user, pass, from, to, subject, body string) error {
16 addr := net.JoinHostPort(host, port)
17 auth := smtp.PlainAuth("", user, pass, host)
18 msg := buildMessage(from, to, subject, body)
19
20 if port == "465" {
21 conn, err := tls.Dial("tcp", addr, &tls.Config{ServerName: host})
22 if err != nil {
23 return fmt.Errorf("SSL 连接失败: %w", err)
24 }
25 c, err := smtp.NewClient(conn, host)
26 if err != nil {
27 return err
28 }
29 defer c.Close()
30 if err = c.Auth(auth); err != nil {
31 return fmt.Errorf("SMTP 认证失败: %w", err)
32 }
33 if err = c.Mail(from); err != nil {
34 return err
35 }
36 if err = c.Rcpt(to); err != nil {
37 return err
38 }
39 w, err := c.Data()
40 if err != nil {
41 return err
42 }
43 if _, err = w.Write(msg); err != nil {
44 return err
45 }
46 return w.Close()
47 }
48 return smtp.SendMail(addr, auth, from, []string{to}, msg)
49}
50
51// buildMessage 构造含 UTF-8 Base64 主题的邮件正文
52func buildMessage(from, to, subject, body string) []byte {
53 var b strings.Builder
54 b.WriteString("From: " + from + "\r\n")
55 b.WriteString("To: " + to + "\r\n")
56 b.WriteString("Subject: =?UTF-8?B?" + base64.StdEncoding.EncodeToString([]byte(subject)) + "?=\r\n")
57 b.WriteString("MIME-Version: 1.0\r\n")
58 b.WriteString("Content-Type: text/plain; charset=UTF-8\r\n\r\n")
59 b.WriteString(body)
60 return []byte(b.String())
61}
62
63// SendCode 发送注册验证码邮件
64func SendCode(host, port, user, pass, from, to, code string) error {
65 body := fmt.Sprintf("您正在注册 ClearLove 表白墙,验证码为:%s\n\n验证码 10 分钟内有效,若非本人操作请忽略本邮件。", code)
66 return Send(host, port, user, pass, from, to, "ClearLove 表白墙注册验证码", body)
67}