Go 语言封装邮件发送功能

Go 语言封装邮件发送功能

  • [🏆 目标](#🏆 目标)
  • [📦 依赖包](#📦 依赖包)
  • [🌟 项目结构](#🌟 项目结构)
  • [🚀 代码实现](#🚀 代码实现)
  • [🛠️ 主要方法说明](#🛠️ 主要方法说明)
  • [🧪 单元测试](#🧪 单元测试)
  • [🌈 使用示例](#🌈 使用示例)
  • [🏆 代码亮点](#🏆 代码亮点)
  • [🌟 改进方向](#🌟 改进方向)
  • [🚀 总结](#🚀 总结)

在现代 Web 开发中,邮件发送功能是一个常见的需求,特别是在用户注册、密码重置、通知等场景中,往往需要通过邮件发送验证码或其他信息。本文将介绍如何在 Go 语言中封装一个通用的邮件发送包,支持验证码发送和通用邮件发送。


🏆 目标

封装一个邮件发送的包

支持 SMTP 协议发送邮件

提供发送验证码和普通邮件的功能

通过结构体和方法实现面向对象的设计

完善的单元测试,确保代码健壮性


📦 依赖包

在开始之前,需要引入以下依赖包:

bash 复制代码
go get github.com/jordan-wright/email
go get go.uber.org/zap
go get github.com/stretchr/testify
github.com/jordan-wright/email:一个常用的 Go 语言邮件发送库,简化 SMTP 发送流程。

go.uber.org/zap:Uber 开发的高效日志库,用于记录日志。

github.com/stretchr/testify:Go 的单元测试库。

🌟 项目结构

bash 复制代码
├── email
│   ├── email.go
│   └── email_test.go
├── model
│   └── cache.go
├── pkg
│   └── logger.go
├── go.mod
├── go.sum
└── main.go

🚀 代码实现

📌 email/email.go

创建 email/email.go 文件,封装邮件发送功能。

go 复制代码
package email

import (
	"fmt"
	"gin-mall/model"
	"gin-mall/pkg/logger"
	"net/smtp"
	"time"

	"github.com/jordan-wright/email"
	"go.uber.org/zap"
)

// Email 邮件
type Email struct {
	config  Config   // 邮件配置
	From    string   // 发件人
	To      []string // 收件人
	Subject string   // 主题
	Body    string   // 内容
}

// Config 邮件配置
type Config struct {
	SMTPServer string // SMTP服务器
	SMTPPort   int    // SMTP端口
	Username   string // 用户名
	Password   string // 密码
}

// NewEmail 创建Email实例
func NewEmail(config Config) *Email {
	e := &Email{config: config}
	e.From = config.Username
	return e
}

// SetFrom 设置发件人
func (e *Email) SetFrom(from string) {
	e.From = from
}

// SetTo 设置收件人
func (e *Email) SetTo(to []string) {
	e.To = to
}

// AppendTo 添加收件人
func (e *Email) AppendTo(to string) {
	e.To = append(e.To, to)
}

// SetSubject 设置邮件主题
func (e *Email) SetSubject(subject string) {
	e.Subject = subject
}

// SetBody 设置邮件内容
func (e *Email) SetBody(body string) {
	e.Body = body
}

// Send 发送邮件
func (e *Email) Send() error {
	auth := smtp.PlainAuth("", e.config.Username, e.config.Password, e.config.SMTPServer)

	host := fmt.Sprintf("%s:%d", e.config.SMTPServer, e.config.SMTPPort)

	eClient := email.NewEmail()
	eClient.From = e.From
	eClient.To = e.To
	eClient.Subject = e.Subject
	eClient.Text = []byte(e.Body)

	err := eClient.Send(host, auth)
	if err != nil {
		return err
	}

	return nil
}

// SendVerifyCode 发送验证码
func (e *Email) SendVerifyCode(receiver, code, key string) error {
	// 保存验证码到缓存
	err := model.CacheDb.Set(key, code, 5*time.Minute)
	if err != nil {
		logger.Error("设置缓存失败", zap.Error(err))
		return err
	}

	// 发送邮件
	msg := fmt.Sprintf("【XXX】您的验证码是: %s, 请在5分钟内完成验证.", code)
	e.AppendTo(receiver)
	e.SetSubject("GinMall 验证码")
	e.SetBody(msg)

	return e.Send()
}

🛠️ 主要方法说明

方法名 功能 说明
NewEmail 创建新的邮件实例 通过传入 SMTP 配置,创建 Email 结构体
SetFrom 设置发件人 可自定义发件人
SetTo 设置收件人 直接设置收件人数组
AppendTo 添加收件人 动态添加收件人
SetSubject 设置主题 设置邮件的标题
SetBody 设置内容 设置邮件的内容
Send 发送邮件 通过 SMTP 协议发送邮件
SendVerifyCode 发送验证码 生成并发送验证码

🧪 单元测试

📌 email/email_test.go

创建 email/email_test.go,对邮件发送功能进行测试。

go 复制代码
package email

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSendEmail(t *testing.T) {
	config := Config{
		SMTPServer: "smtp.163.com",
		SMTPPort:   25,
		Username:   "your-email@163.com",
		Password:   "your-password",
	}

	email := NewEmail(config)
	assert.NotNil(t, email)

	email.SetFrom(config.Username)
	email.AppendTo("receiver@example.com")
	email.SetSubject("Test Email")
	email.SetBody("This is a test email.")

	err := email.Send()
	assert.Nil(t, err)

	t.Logf("Email sent successfully")
}

🌈 使用示例

在 main.go 文件中直接调用封装好的方法来发送邮件:

go 复制代码
package main

import (
	"log"
	"gin-mall/email"
)

func main() {
	config := email.Config{
		SMTPServer: "smtp.163.com",
		SMTPPort:   25,
		Username:   "your-email@163.com",
		Password:   "your-password",
	}

	email := email.NewEmail(config)
	email.SetFrom(config.Username)
	email.AppendTo("receiver@example.com")
	email.SetSubject("Welcome to GinMall")
	email.SetBody("Thank you for signing up to GinMall!")

	err := email.Send()
	if err != nil {
		log.Fatalf("Failed to send email: %v", err)
	} else {
		log.Println("Email sent successfully")
	}
}

🏆 代码亮点

✅ 面向对象设计,封装良好

✅ 使用 go.uber.org/zap 记录日志

✅ 使用 github.com/jordan-wright/email 简化 SMTP 发送

✅ 使用 github.com/stretchr/testify 进行单元测试


🌟 改进方向

  1. 支持 HTML 格式的邮件内容

  2. 支持添加附件

  3. 通过配置文件设置邮件参数

  4. 添加邮件发送失败的重试机制


🚀 总结

通过封装 github.com/jordan-wright/email,我们可以快速实现邮件发送功能。封装良好的结构体和方法,使代码更易于扩展和复用。希望本文能帮助你在 Go 项目中高效地实现邮件功能!

相关推荐
知守观几秒前
多模块架构演进:横向分层 vs 纵向领域,13 个真实项目的切分对照
java·后端·微服务
Ai-_Man1 分钟前
Coze扣子还是不可以导出左侧所有对话,只能点进去单条内容导出,方法不对吗?
开发语言·人工智能·ai·小程序·1024程序员节
raindayinrain10 分钟前
c++设计模式
开发语言·c++·设计模式
hiahiahia12318 分钟前
Streaming Model Output
开发语言·前端
熊猫钓鱼>_>44 分钟前
鸿蒙PC高分屏与键鼠交互适配:DPI缩放、右键菜单一次讲清
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙·鸿蒙心迹
吧啦蹦吧1 小时前
org.springframework.context.ApplicationListener
log4j
紧跟先前的步伐1 小时前
Go AI Agent 实战 22|完善 Agent 执行循环:从工具调用到最终回答
人工智能·ai·golang
系统集成-鹰翔1 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
octopus_c1 小时前
C++ 运算符重载详解 && 日期类的实现
开发语言·c++
Eiceblue1 小时前
用 Python 给 Word 文档加水印:文字、图片与批量处理
开发语言·vscode·python·word