golang简单高效的邮件发送功能插件库go-mail的使用

Golang简单高效的邮件发送功能插件库go-mail的使用

go-mail是一个易于使用但功能全面的Go语言邮件发送库,它遵循Go语言的惯用风格和最佳实践,主要依赖Go标准库和扩展包。

主要特性

  • 非常小的依赖项(主要依赖Go标准库和扩展包)
  • 现代、符合Go语言习惯的代码
  • 合理且安全的默认设置
  • 隐式SSL/TLS支持
  • 显式STARTTLS支持(多种策略)
  • 使用context实现更好的控制流和超时/取消处理
  • 支持多种SMTP认证方式
  • RFC5322兼容的邮件地址验证
  • 支持常见邮件头字段生成
  • 并发安全,可复用SMTP连接发送多封邮件
  • 支持附件和内联嵌入
  • 支持多种编码方式
  • 支持中间件
  • 支持通过本地sendmail命令发送邮件
  • 支持请求MDN和DSN
  • 支持DKIM签名
  • 消息对象实现了io.WriterToio.Reader接口
  • 支持Go的html/templatetext/template
  • 支持输出到文件
  • SMTP流量调试日志
  • 自定义错误类型
  • 自定义拨号上下文函数
  • 支持将消息输出为EML文件
  • S/MIME消息签名支持
  • UNIX域套接字支持

快速开始示例

package main

import (
	"context"
	"log"
	"time"

	"github.com/wneessen/go-mail"
)

func main() {
	// 创建新的邮件消息
	msg := mail.NewMsg()
	if err := msg.From("发件人 <from@example.com>"); err != nil {
		log.Fatalf("设置发件人失败: %s", err)
	}
	if err := msg.To("收件人 <to@example.com>"); err != nil {
		log.Fatalf("设置收件人失败: %s", err)
	}
	
	msg.Subject("测试邮件主题")
	msg.SetBodyString(mail.TypeTextPlain, "这是一封测试邮件的正文内容")

	// 创建SMTP客户端
	client, err := mail.NewClient(
		"smtp.example.com", 
		mail.WithPort(587),
		mail.WithSMTPAuth(mail.SMTPAuthPlain),
		mail.WithUsername("your_username"),
		mail.WithPassword("your_password"),
		mail.WithTLSPolicy(mail.TLSMandatory),
	)
	if err != nil {
		log.Fatalf("创建SMTP客户端失败: %s", err)
	}

	// 设置超时上下文
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	// 发送邮件
	if err := client.DialAndSend(ctx, msg); err != nil {
		log.Fatalf("发送邮件失败: %s", err)
	}

	log.Println("邮件发送成功!")
}

发送带附件的邮件示例

package main

import (
	"context"
	"log"
	"os"
	"time"

	"github.com/wneessen/go-mail"
)

func main() {
	// 创建新邮件消息
	msg := mail.NewMsg()
	msg.From("发件人 <from@example.com>")
	msg.To("收件人 <to@example.com>")
	msg.Subject("带附件的测试邮件")
	msg.SetBodyString(mail.TypeTextPlain, "这封邮件包含一个附件")

	// 添加附件
	if err := msg.AttachFile("path/to/your/file.txt"); err != nil {
		log.Fatalf("添加附件失败: %s", err)
	}

	// 创建SMTP客户端
	client, err := mail.NewClient(
		"smtp.example.com",
		mail.WithPort(587),
		mail.WithSMTPAuth(mail.SMTPAuthPlain),
		mail.WithUsername("your_username"),
		mail.WithPassword("your_password"),
	)
	if err != nil {
		log.Fatalf("创建SMTP客户端失败: %s", err)
	}

	// 发送邮件
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := client.DialAndSend(ctx, msg); err != nil {
		log.Fatalf("发送邮件失败: %s", err)
	}

	log.Println("带附件的邮件发送成功!")
}

发送HTML邮件示例

package main

import (
	"context"
	"log"
	"time"

	"github.com/wneessen/go-mail"
)

func main() {
	// 创建新邮件消息
	msg := mail.NewMsg()
	msg.From("发件人 <from@example.com>")
	msg.To("收件人 <to@example.com>")
	msg.Subject("HTML格式测试邮件")

	// 设置HTML正文
	htmlBody := `<html>
		<body>
			<h1>你好!</h1>
			<p>这是一封<strong>HTML格式</strong>的测试邮件。</p>
		</body>
	</html>`
	msg.SetBodyString(mail.TypeTextHTML, htmlBody)

	// 添加纯文本替代内容
	msg.AddAlternativeString(mail.TypeTextPlain, "你好!\n\n这是一封HTML格式的测试邮件。")

	// 创建SMTP客户端并发送
	client, err := mail.NewClient(
		"smtp.example.com",
		mail.WithPort(587),
		mail.WithSMTPAuth(mail.SMTPAuthPlain),
		mail.WithUsername("your_username"),
		mail.WithPassword("your_password"),
	)
	if err != nil {
		log.Fatalf("创建SMTP客户端失败: %s", err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := client.DialAndSend(ctx, msg); err != nil {
		log.Fatalf("发送邮件失败: %s", err)
	}

	log.Println("HTML邮件发送成功!")
}

使用模板发送邮件示例

package main

import (
	"bytes"
	"context"
	"html/template"
	"log"
	"time"

	"github.com/wneessen/go-mail"
)

type User struct {
	Name string
	URL  string
}

func main() {
	// 准备模板数据
	user := User{
		Name: "张三",
		URL:  "https://example.com/activate?token=abc123",
	}

	// 解析HTML模板
	tmpl, err := template.New("email").Parse(`
		<html>
			<body>
				<h1>你好, {{.Name}}!</h1>
				<p>感谢注册我们的服务。请点击以下链接激活您的账户:</p>
				<p><a href="{{.URL}}">{{.URL}}</a></p>
			</body>
		</html>
	`)
	if err != nil {
		log.Fatalf("解析模板失败: %s", err)
	}

	// 渲染模板到缓冲区
	var htmlBody bytes.Buffer
	if err := tmpl.Execute(&htmlBody, user); err != nil {
		log.Fatalf("执行模板失败: %s", err)
	}

	// 创建邮件消息
	msg := mail.NewMsg()
	msg.From("系统管理员 <admin@example.com>")
	msg.To(user.Name + " <user@example.com>")
	msg.Subject("账户激活邮件")

	// 设置HTML正文
	msg.SetBodyString(mail.TypeTextHTML, htmlBody.String())

	// 添加纯文本替代内容
	msg.AddAlternativeString(mail.TypeTextPlain, 
		"你好, " + user.Name + "!\n\n" +
		"感谢注册我们的服务。请访问以下链接激活您的账户:\n" +
		user.URL)

	// 创建SMTP客户端并发送
	client, err := mail.NewClient(
		"smtp.example.com",
		mail.WithPort(587),
		mail.WithSMTPAuth(mail.SMTPAuthPlain),
		mail.WithUsername("your_username"),
		mail.WithPassword("your_password"),
	)
	if err != nil {
		log.Fatalf("创建SMTP客户端失败: %s", err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := client.DialAndSend(ctx, msg); err != nil {
		log.Fatalf("发送邮件失败: %s", err)
	}

	log.Println("模板邮件发送成功!")
}

go-mail提供了丰富的功能和灵活的配置选项,可以满足各种邮件发送需求。更多详细用法可以参考官方文档。


更多关于golang简单高效的邮件发送功能插件库go-mail的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang简单高效的邮件发送功能插件库go-mail的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-mail: 一个简单高效的Golang邮件发送库

go-mail 是一个轻量级的Golang邮件发送库,它提供了简单易用的API来发送电子邮件。下面我将详细介绍如何使用这个库。

安装

go get github.com/go-mail/mail

基本使用示例

package main

import (
	"log"
	"github.com/go-mail/mail"
)

func main() {
	// 创建新的邮件消息
	m := mail.NewMessage()
	
	// 设置发件人
	m.SetHeader("From", "sender@example.com")
	
	// 设置收件人
	m.SetHeader("To", "recipient@example.com")
	
	// 设置抄送
	m.SetAddressHeader("Cc", "cc@example.com", "CC User")
	
	// 设置邮件主题
	m.SetHeader("Subject", "Test Email from go-mail")
	
	// 设置邮件正文(纯文本)
	m.SetBody("text/plain", "This is the plain text body of the email.")
	
	// 设置HTML格式的正文(可选)
	m.AddAlternative("text/html", "<h1>Hello</h1><p>This is the HTML body</p>")
	
	// 添加附件
	m.Attach("/path/to/file.pdf")
	
	// 创建SMTP客户端
	d := mail.NewDialer("smtp.example.com", 587, "user@example.com", "password")
	
	// 发送邮件
	if err := d.DialAndSend(m); err != nil {
		log.Fatal(err)
	}
	
	log.Println("Email sent successfully!")
}

高级功能

1. 使用TLS加密连接

d := mail.NewDialer("smtp.example.com", 465, "user@example.com", "password")
d.SSL = true // 使用SSL/TLS

2. 设置超时

d.Timeout = 10 * time.Second

3. 批量发送邮件

// 创建Dialer
d := mail.NewDialer("smtp.example.com", 587, "user@example.com", "password")

// 创建多个消息
messages := []*mail.Message{
	createMessage("recipient1@example.com", "Subject 1", "Body 1"),
	createMessage("recipient2@example.com", "Subject 2", "Body 2"),
}

// 打开连接
var sender mail.SendCloser
var err error
if sender, err = d.Dial(); err != nil {
	log.Fatal(err)
}

// 发送所有消息
for _, m := range messages {
	if err := mail.Send(sender, m); err != nil {
		log.Printf("Could not send email: %v", err)
	}
}

// 关闭连接
if err := sender.Close(); err != nil {
	log.Fatal(err)
}

func createMessage(to, subject, body string) *mail.Message {
	m := mail.NewMessage()
	m.SetHeader("From", "sender@example.com")
	m.SetHeader("To", to)
	m.SetHeader("Subject", subject)
	m.SetBody("text/plain", body)
	return m
}

4. 使用环境变量配置

import "os"

func main() {
	m := mail.NewMessage()
	m.SetHeader("From", os.Getenv("SMTP_FROM"))
	m.SetHeader("To", os.Getenv("SMTP_TO"))
	m.SetHeader("Subject", "Test Email")
	m.SetBody("text/plain", "Hello from go-mail!")
	
	d := mail.NewDialer(
		os.Getenv("SMTP_HOST"),
		587,
		os.Getenv("SMTP_USER"),
		os.Getenv("SMTP_PASS"),
	)
	
	if err := d.DialAndSend(m); err != nil {
		log.Fatal(err)
	}
}

最佳实践

  1. 连接池: 对于高频发送场景,保持连接打开而不是每次发送都重新连接
  2. 错误处理: 适当处理网络错误和SMTP错误
  3. 异步发送: 对于大量邮件,考虑使用goroutine异步发送
  4. 模板: 使用Go的模板引擎生成邮件内容
// 异步发送示例
func asyncSend(d *mail.Dialer, m *mail.Message, ch chan<- error) {
	ch <- d.DialAndSend(m)
}

func main() {
	d := mail.NewDialer("smtp.example.com", 587, "user", "pass")
	m := mail.NewMessage()
	// 设置消息内容...
	
	ch := make(chan error, 1)
	go asyncSend(d, m, ch)
	
	if err := <-ch; err != nil {
		log.Fatal(err)
	}
}

性能考虑

  1. 重用Dialer和连接
  2. 批量发送时保持连接打开
  3. 对于大量邮件,考虑使用工作池模式

go-mail 是一个简单但功能强大的库,适合大多数邮件发送需求。它支持TLS、附件、HTML邮件等常见功能,同时保持了简洁的API设计。

回到顶部