email

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 8 Imported by: 0

README

email 包 — 邮件发送

所属层级: Infrastructure Layer
设计理念: 零外部依赖,原生 SMTP
设计灵感: Spring Mail + JavaMail

概述

email 包提供基于 Go 原生 net/smtp 的邮件发送功能,默认使用 163 邮箱服务器。

核心功能
功能 说明
原生 SMTP 使用 Go 标准库,无外部依赖
默认配置 开箱即用的 163 邮箱配置
灵活选项 支持自定义 SMTP 服务器、端口、认证
环境变量 密码从环境变量读取,安全配置
多格式支持 支持纯文本和 HTML 邮件

核心接口

Message 邮件结构
type Message struct {
    From        string            // 发件人(为空时使用默认发件人)
    To          []string          // 收件人列表
    Subject     string            // 邮件主题
    Body        string            // 纯文本内容
    HTML        string            // HTML 内容(优先于 Body)
    Attachments []Attachment      // 附件列表
    Headers     map[string]string // 自定义邮件头
}
Attachment 附件结构
type Attachment struct {
    Filename    string // 文件名
    ContentType string // MIME 类型
    Data        []byte // 文件数据
}
Sender 邮件发送器
type Sender struct {
    // ...
}
创建
// 使用默认配置
sender := email.NewSender()

// 使用自定义配置
sender := email.NewSender(
    email.WithHost("smtp.gmail.com"),
    email.WithPort(587),
    email.WithAuth("your@gmail.com", "your-password"),
)
发送邮件
err := sender.Send(ctx, &email.Message{
    To:      []string{"recipient@example.com"},
    Subject: "测试邮件",
    Body:    "这是一封测试邮件",
})

默认配置

配置项 默认值 说明
SMTP Host smtp.163.com 163 邮箱 SMTP 服务器
SMTP Port 25 SMTP 端口
From xudefa_163mail@163.com 默认发件人
Password 环境变量 ENHANCE_EMAIL_PASSWORD 密码从环境变量读取

配置选项

SenderOption 配置选项
选项 说明 示例
WithHost(host) 设置 SMTP 服务器 WithHost("smtp.gmail.com")
WithPort(port) 设置 SMTP 端口 WithPort(587)
WithAuth(user, pass) 设置认证信息 WithAuth("user@example.com", "password")
WithPasswordFromEnv() 从环境变量读取密码 WithPasswordFromEnv()

快速开始

1. 设置环境变量
export ENHANCE_EMAIL_PASSWORD="your-163-password"
2. 发送邮件
package main

import (
    "context"
    "github.com/xudefa/enhance/email"
)

func main() {
    // 使用默认配置创建发送器
    sender := email.NewSender()

    // 发送邮件
    err := sender.Send(context.Background(), &email.Message{
        To:      []string{"recipient@example.com"},
        Subject: "测试邮件",
        Body:    "这是一封测试邮件",
    })
    if err != nil {
        panic(err)
    }
}

API 参考

使用自定义 SMTP 服务器
sender := email.NewSender(
    email.WithHost("smtp.gmail.com"),
    email.WithPort(587),
    email.WithAuth("your@gmail.com", "your-password"),
)
发送 HTML 邮件
err := sender.Send(ctx, &email.Message{
    To:      []string{"user@example.com"},
    Subject: "欢迎注册",
    HTML:    "<h1>欢迎!</h1><p>感谢您的注册。</p>",
})
发送带附件的邮件
err := sender.Send(ctx, &email.Message{
    To:      []string{"user@example.com"},
    Subject: "带附件的邮件",
    Body:    "请查看附件",
    Attachments: []email.Attachment{
        {
            Filename:    "report.pdf",
            ContentType: "application/pdf",
            Data:        pdfData,
        },
    },
})
发送带自定义邮件头的邮件
err := sender.Send(ctx, &email.Message{
    To:      []string{"user@example.com"},
    Subject: "通知",
    Body:    "您有新的消息",
    Headers: map[string]string{
        "X-Priority": "1",
        "X-Custom":   "value",
    },
})
多个收件人
err := sender.Send(ctx, &email.Message{
    To:      []string{"user1@example.com", "user2@example.com"},
    Subject: "群发通知",
    Body:    "大家好!",
})

使用示例

发送欢迎邮件
func SendWelcomeEmail(userEmail string, userName string) error {
    sender := email.NewSender()
    
    message := &email.Message{
        To:      []string{userEmail},
        Subject: "欢迎使用我们的服务",
        HTML: fmt.Sprintf(`
            <h1>欢迎, %s!</h1>
            <p>感谢您的注册。</p>
            <p>如果您有任何问题,请随时联系我们。</p>
        `, userName),
    }
    
    return sender.Send(context.Background(), message)
}
发送密码重置邮件
func SendPasswordResetEmail(userEmail string, resetToken string) error {
    sender := email.NewSender()
    
    resetLink := fmt.Sprintf("https://example.com/reset?token=%s", resetToken)
    
    message := &email.Message{
        To:      []string{userEmail},
        Subject: "密码重置请求",
        HTML: fmt.Sprintf(`
            <h1>密码重置</h1>
            <p>请点击以下链接重置您的密码:</p>
            <a href="%s">重置密码</a>
            <p>此链接将在 24 小时后过期。</p>
        `, resetLink),
    }
    
    return sender.Send(context.Background(), message)
}
与依赖注入集成
// 注册 Email Sender
container.Register(
    reflect.TypeOf(&email.Sender{}),
    core.Bean(email.NewSender(
        email.WithHost("smtp.gmail.com"),
        email.WithPort(587),
        email.WithAuth("your@gmail.com", os.Getenv("EMAIL_PASSWORD")),
    )),
    core.Singleton(),
)

// 注入使用
type UserService struct {
    EmailSender *email.Sender `inject:"sender"`
}

func (s *UserService) CreateUser(name, emailAddr string) error {
    // 创建用户...
    
    // 发送欢迎邮件
    return s.EmailSender.Send(context.Background(), &email.Message{
        To:      []string{emailAddr},
        Subject: "欢迎",
        Body:    fmt.Sprintf("欢迎, %s!", name),
    })
}

最佳实践

1. 使用环境变量存储密码
// ✅ 推荐:从环境变量读取密码
sender := email.NewSender(
    email.WithAuth("user@gmail.com", os.Getenv("EMAIL_PASSWORD")),
)

// ⚠️ 不推荐:硬编码密码
sender := email.NewSender(
    email.WithAuth("user@gmail.com", "my-secret-password"),
)
2. 使用 HTML 邮件提升用户体验
// ✅ 推荐:使用 HTML 格式
message := &email.Message{
    HTML: "<h1>欢迎!</h1><p>感谢您的注册。</p>",
}

// ⚠️ 不推荐:仅使用纯文本
message := &email.Message{
    Body: "欢迎! 感谢您的注册。",
}
3. 设置合理的超时和重试
// ✅ 推荐:使用 context 控制超时
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

err := sender.Send(ctx, message)

// ⚠️ 不推荐:不设置超时
err := sender.Send(context.Background(), message)
4. 错误处理和日志记录
// ✅ 推荐:记录错误日志
err := sender.Send(ctx, message)
if err != nil {
    log.Error(ctx, "Failed to send email",
        log.KeyValue{Key: "to", Value: message.To},
        log.KeyValue{Key: "error", Value: err.Error()},
    )
    return err
}

// ⚠️ 不推荐:忽略错误
sender.Send(ctx, message)
5. 异步发送邮件
// ✅ 推荐:使用异步发送
go func() {
    err := sender.Send(context.Background(), message)
    if err != nil {
        log.Error(context.Background(), "Failed to send email", log.KeyValue{Key: "error", Value: err.Error()})
    }
}()

// ⚠️ 不推荐:同步发送阻塞请求
err := sender.Send(ctx, message)
if err != nil {
    return err
}

Documentation

Overview

Package email 提供邮件发送功能,用于 enhance 框架。

该模块提供统一的 SMTP 邮件发送接口,使用 Go 原生 net/smtp 库。 支持纯文本和 HTML 格式邮件发送。

架构设计

  • Sender: 邮件发送器接口,封装 SMTP 协议
  • Message: 邮件消息结构,包含收件人、主题、正文等
  • Attachment: 邮件附件结构
  • SenderOption: 发送器配置选项函数

核心功能

  • SMTP 发送: 支持标准 SMTP 协议发送邮件
  • 多收件人: 支持发送给多个收件人
  • HTML 邮件: 支持 HTML 格式邮件正文
  • 环境变量: 支持从环境变量读取 SMTP 密码

使用方式

创建发送器:

sender := email.NewSender()

发送邮件:

err := sender.Send(ctx, &email.Message{
    To:      []string{"recipient@example.com"},
    Subject: "测试",
    Body:    "你好!",
})

配置属性

  • email.smtp.host: SMTP 服务器地址(默认 localhost)
  • email.smtp.port: SMTP 端口(默认 25)
  • email.from: 发件人地址(必须显式设置)
  • email.password: SMTP 密码(从环境变量 ENHANCE_EMAIL_PASSWORD 读取)

配置示例

环境变量:

export EMAIL_SMTP_HOST=localhost
export EMAIL_SMTP_PORT=25
export EMAIL_FROM=sender@example.com
export ENHANCE_EMAIL_PASSWORD=your_password

Package email 提供邮件发送功能,用于 enhance 框架。

Index

Constants

View Source
const (
	// DefaultSMTPHost 默认 SMTP 主机地址。
	DefaultSMTPHost = "localhost"
	// DefaultSMTPPort 默认 SMTP 端口。
	DefaultSMTPPort = 25
	// DefaultFrom 默认发件人地址(必须显式设置)。
	DefaultFrom = ""
	// EnvPasswordKey 环境变量密码键名。
	EnvPasswordKey = "ENHANCE_EMAIL_PASSWORD"
)

默认配置常量。

Variables

This section is empty.

Functions

This section is empty.

Types

type Attachment

type Attachment struct {
	Filename    string // 文件名
	ContentType string // 内容类型
	Data        []byte // 文件数据
}

Attachment 邮件附件结构。

type Message

type Message struct {
	From        string            // 发件人地址
	To          []string          // 收件人列表
	Subject     string            // 邮件主题
	Body        string            // 纯文本正文
	HTML        string            // HTML 正文
	Attachments []Attachment      // 附件列表
	Headers     map[string]string // 自定义头部
}

Message 邮件消息结构。

type Sender

type Sender interface {
	// Send 发送邮件。
	Send(ctx context.Context, msg *Message) error

	// Close 关闭发送器并释放资源。
	Close() error
}

Sender 邮件发送器接口。

func NewSender

func NewSender(opts ...SenderOption) Sender

NewSender 创建邮件发送器。 注意:密码在构造时从环境变量读取一次并缓存,后续环境变量变更不会自动更新。 如需动态读取密码,请使用 WithPasswordFromEnv 选项或 WithAuth 选项。

type SenderOption

type SenderOption func(sender Sender)

SenderOption 发送器配置选项函数。

func WithAuth

func WithAuth(username, password string) SenderOption

WithAuth 设置认证信息。

func WithHost

func WithHost(host string) SenderOption

WithHost 设置 SMTP 主机地址。

func WithPasswordFromEnv

func WithPasswordFromEnv() SenderOption

WithPasswordFromEnv 从环境变量读取密码。

func WithPort

func WithPort(port int) SenderOption

WithPort 设置 SMTP 端口。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL