mailkit

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 25 Imported by: 0

README

MailKit

MailKit 是面向 Go 服务的通用邮件能力库,统一提供 SMTP 邮件发送、IMAP 邮箱查询、MIME 标准化,以及多邮箱账号动态托管。

它适合验证码、运营通知、工单归档和长期邮箱接收等场景。MailKit 只负责邮件协议、内容解析和账号生命周期,不承载调用方的业务判断。

核心能力

  • Sender:SMTP 密码或 XOAUTH2 认证,连接池复用,限并发批量发送,正文、HTML、附件及内嵌资源。
  • Mailbox:单邮箱 IMAP 查询,支持 UID、时间、地址、主题、标记和邮件头过滤。
  • Hub:同一进程动态注册、上线、下线、更新和移除多个不同服务商邮箱账号。
  • MIME:解析字符集、纯文本、HTML、附件和内嵌资源,并限制单封邮件与附件内存占用。
  • CursorStore:按 AccountID + Mailbox + UIDValidity + LastUID 协调至少一次邮件处理进度。
  • 自定义网络出口:SMTP、IMAP 共用 DialContext,可接 HTTP CONNECT、SOCKS5、专线或应用自己的拨号器。
  • 服务商配置:Gmail、Microsoft 365 / Outlook、QQ 邮箱、腾讯企业邮箱、网易 163/126 和自定义端点。

安装

go get github.com/ClownSketch/mailkit@v1.0.0

当前模块使用 Go 1.25.12。

快速发送

package main

import (
	"context"
	"log"

	"github.com/ClownSketch/mailkit"
)

func main() {
	provider, err := mailkit.BuiltinProvider(mailkit.ProviderQQ)
	if err != nil {
		log.Fatal(err)
	}

	sender, err := mailkit.NewSender(mailkit.SenderConfig{
		Endpoint: provider.SMTP,
		Auth:     mailkit.PasswordAuth("sender@qq.com", "app-password"),
	})
	if err != nil {
		log.Fatal(err)
	}
	defer sender.Close(context.Background())

	err = sender.Send(context.Background(), mailkit.OutgoingMessage{
		From:    mailkit.Address{Name: "MailKit", Email: "sender@qq.com"},
		To:      []mailkit.Address{{Email: "receiver@example.com"}},
		Subject: "MailKit test",
		Text:    "plain text body",
		HTML:    "<p>HTML body</p>",
	})
	if err != nil {
		log.Fatal(err)
	}
}

快速查询

mailbox, err := mailkit.OpenMailbox(ctx, mailkit.MailboxConfig{
	AccountID: "support-mailbox-01",
	Endpoint:  provider.IMAP,
	Auth:      mailkit.PasswordAuth("support@example.com", "app-password"),
})
if err != nil {
	return err
}
defer mailbox.Close(context.Background())

result, err := mailbox.Search(ctx, mailkit.SearchQuery{
	Mailbox:  "INBOX",
	AfterUID: 100,
	Subject:  "Service request",
	Limit:    50,
	Fetch: mailkit.FetchOptions{
		IncludeBody:        true,
		IncludeAttachments: false,
	},
})

动态托管邮箱

hub, err := mailkit.NewHub(mailkit.HubConfig{
	CursorStore: productionCursorStore,
	Handler: mailkit.MessageHandlerFunc(func(ctx context.Context, message mailkit.ReceivedMessage) mailkit.ProcessResult {
		if err := processMessageIdempotently(ctx, message); err != nil {
			return mailkit.RetryMessage(err)
		}
		return mailkit.CommitMessage()
	}),
})
if err != nil {
	return err
}

config := mailkit.NewAccountConfig("mail-account-01", provider, auth)
config.Query.Fetch.IncludeBody = true

if err := hub.Register(config); err != nil {
	return err
}
if err := hub.Online(ctx, config.ID); err != nil {
	return err
}

// 后台停用账号时只停止会话,账号配置和游标仍然保留。
if err := hub.Offline(ctx, config.ID); err != nil {
	return err
}

首次上线且尚无游标时,Hub 默认把游标初始化到邮箱当前最新 UID,只处理之后到达的新邮件。如果业务需要回放已有邮件,必须显式设置:

config.ReplayHistory = true

已有持久化游标时始终从游标继续,不受该开关影响。

处理语义

同一账号内按 UID 升序串行处理,不同账号并行运行:

  • CommitMessage():业务完成,保存游标。
  • RetryMessage(err):业务暂未完成,不推进游标,稍后重试同一封邮件。
  • SkipMessage(err):邮件永久不可处理,记录原因并推进游标。

MailKit 使用至少一次语义。如果业务已经成功,但外部 CursorStore 保存失败,同一邮件会再次投递。业务处理器必须以 AccountID + Mailbox + UIDValidity + UID 或自身稳定业务键实现幂等。

历史积压会先执行一次 UID 扫描,再按 BatchSize 分批抓取邮件内容,不会为每个批次重复全量搜索。邮箱历史非常大时,建议通过 Query.Since、发件人或主题条件缩小首次扫描范围。

MailKit 保证正文来自已认证连接的目标 IMAP 邮箱,并保留 UIDValidity + UID、服务端接收时间和原始邮件头。它不替调用方判断发件人身份和内容含义;需要验证外部发件人时,应结合 Authentication-Results、DKIM、SPF、DMARC 结果和调用方自己的规则。

生产边界

MailKit 负责协议和进程内生命周期,主项目负责:

  • 邮箱账号、开关和业务归属落库;
  • 密码、应用专用密码、Refresh Token 的加密存储;
  • OAuth2 Access Token 刷新;
  • 多节点账号租约,保证同一账号只由一个节点托管;
  • MySQL 或 Redis CursorStore;
  • 邮件内容识别、业务处理、告警和审计;
  • 业务处理幂等。

邮件正文只通过 MessageHandler.Handle() 交付。处理器返回 RetryMessage(err) 时游标不会前进,同一 UID 会再次交付;只有返回 CommitMessage() 或调用方明确返回 SkipMessage(err) 后才会推进游标。

Hub.Events() 只提供账号状态和处理结果的观测副本,供日志、指标和管理页面使用。观测消费者过慢时可能遗漏旧的状态副本,但不会丢失邮件正文、跳过 MessageHandler 或推进邮件游标。

文档

验证

go test ./...
go test -race ./...
go vet ./...
go test -run '^$' -bench . -benchmem ./...

测试包含本地 TCP SMTP/IMAP 协议链路、MIME、游标、连接复用、重试、200 账号并发上下线和关闭竞态。

License

MIT

Documentation

Overview

Package mailkit provides reusable email sending, mailbox access, and multi-account mailbox monitoring capabilities.

The package handles SMTP, IMAP, MIME parsing, account sessions, reconnects, cursors, and runtime status. Applications remain responsible for account persistence, credential protection, distributed ownership, and business interpretation of email content.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidConfig 表示调用方提交的配置不完整或不合法。
	ErrInvalidConfig = errors.New("mailkit: invalid config")
	// ErrClosed 表示目标组件已经关闭,不能继续处理新操作。
	ErrClosed = errors.New("mailkit: closed")
	// ErrAccountNotFound 表示 Hub 中不存在指定邮箱账号。
	ErrAccountNotFound = errors.New("mailkit: account not found")
	// ErrAccountExists 表示 Hub 中已经注册相同账号。
	ErrAccountExists = errors.New("mailkit: account already exists")
	// ErrCursorConflict 表示游标更新落后于当前已经提交的进度。
	ErrCursorConflict = errors.New("mailkit: cursor conflict")
	// ErrMessageTooLarge 表示邮件超过调用方允许的读取上限。
	ErrMessageTooLarge = errors.New("mailkit: message too large")
)

Functions

func IsTemporary

func IsTemporary(err error) bool

IsTemporary 判断错误是否适合稍后重试。

Types

type AccountConfig

type AccountConfig struct {
	ID                string          // ID 是应用定义的稳定账号标识。
	Endpoint          Endpoint        // Endpoint 是 IMAP 服务地址。
	Auth              Auth            // Auth 是 IMAP 认证信息。
	TLSConfig         *tls.Config     // TLSConfig 是可选的自定义 TLS 配置。
	DialContext       DialContextFunc // DialContext 是可选的自定义网络拨号函数。
	Mailbox           string          // Mailbox 是接收目录,空值使用 INBOX。
	Query             SearchQuery     // Query 是每轮接收都要应用的通用过滤条件。
	PreferIMAPIdle    bool            // PreferIMAPIdle 表示优先使用 IMAP IDLE。
	PollInterval      time.Duration   // PollInterval 是 IDLE 不可用或关闭时的轮询周期。
	IdleRefresh       time.Duration   // IdleRefresh 是主动重启 IDLE 命令的周期。
	ConnectTimeout    time.Duration   // ConnectTimeout 是 IMAP 建连超时。
	CommandTimeout    time.Duration   // CommandTimeout 是单次 IMAP 命令超时。
	BatchSize         int             // BatchSize 是每轮按 UID 获取的最大邮件数。
	ReplayHistory     bool            // ReplayHistory 表示首次上线或 UIDValidity 变化后回放已有邮件。
	RetryDelay        time.Duration   // RetryDelay 是业务要求重试同一封邮件前的等待时间。
	Reconnect         ReconnectPolicy // Reconnect 控制断线恢复退避。
	AllowInsecureAuth bool            // AllowInsecureAuth 允许在明文链路发送认证信息。
}

AccountConfig 描述 Hub 托管的一个邮箱账号。

func NewAccountConfig

func NewAccountConfig(id string, provider ProviderProfile, auth Auth) AccountConfig

NewAccountConfig 使用服务商配置创建邮箱账号。

func (AccountConfig) Validate

func (c AccountConfig) Validate() error

Validate 检查托管邮箱账号配置是否完整。

type AccountState

type AccountState string

AccountState 表示一个托管邮箱账号的运行状态。

const (
	// AccountStateOffline 表示账号已注册但没有运行会话。
	AccountStateOffline AccountState = "offline"
	// AccountStateConnecting 表示账号正在建立和认证连接。
	AccountStateConnecting AccountState = "connecting"
	// AccountStateOnline 表示账号正在接收邮件。
	AccountStateOnline AccountState = "online"
	// AccountStateReconnecting 表示账号正在恢复临时故障。
	AccountStateReconnecting AccountState = "reconnecting"
	// AccountStateStopping 表示账号正在停止当前会话。
	AccountStateStopping AccountState = "stopping"
	// AccountStateFault 表示账号遇到不可直接重试的配置、认证或协议错误。
	AccountStateFault AccountState = "fault"
)

type AccountStatus

type AccountStatus struct {
	AccountID       string       // AccountID 是邮箱账号标识。
	State           AccountState // State 是当前运行状态。
	Generation      uint64       // Generation 是当前会话代次。
	DesiredOnline   bool         // DesiredOnline 表示调用方是否要求账号在线。
	LastStateAt     time.Time    // LastStateAt 是最近状态变化时间。
	LastConnectedAt time.Time    // LastConnectedAt 是最近连接成功时间。
	LastMessageAt   time.Time    // LastMessageAt 是最近完成业务处理时间。
	LastError       string       // LastError 是最近错误文本,成功后会清空。
	Committed       uint64       // Committed 是成功处理数量。
	Skipped         uint64       // Skipped 是永久跳过数量。
	Retried         uint64       // Retried 是业务重试数量。
	Reconnects      uint64       // Reconnects 是断线重连次数。
	Cursor          Cursor       // Cursor 是最近已提交的处理进度。
}

AccountStatus 是托管邮箱账号的线程安全运行快照。

type Address

type Address struct {
	Name  string // Name 是收发件人的显示名称。
	Email string // Email 是完整邮箱地址。
}

Address 表示一个邮件地址及其可选显示名称。

func (Address) String

func (a Address) String() string

String 返回符合 RFC 5322 格式的邮件地址。

func (Address) Validate

func (a Address) Validate() error

Validate 检查邮箱地址是否合法。

type Attachment

type Attachment struct {
	Filename    string           // Filename 是收件人看到的文件名称。
	ContentType string           // ContentType 是可选 MIME 类型。
	ContentID   string           // ContentID 用于 HTML 内嵌资源引用。
	Inline      bool             // Inline 标记附件是否为内嵌资源。
	Source      AttachmentSource // Source 为每次发送打开独立内容流。
}

Attachment 描述一份待发送附件或内嵌资源。

func BytesAttachment

func BytesAttachment(filename string, data []byte) Attachment

BytesAttachment 使用内存数据创建可重复读取的附件。

func FileAttachment

func FileAttachment(path string) Attachment

FileAttachment 使用本地文件创建可重复读取的附件。

type AttachmentSource

type AttachmentSource func() (io.ReadCloser, error)

AttachmentSource 为每次发送尝试重新打开附件内容。

重试可能多次读取同一个附件,因此 Source 不能只返回已经消费过的 Reader。 同一个消息被并发发送时,Source 也必须能安全地返回彼此独立的 Reader。

type Auth

type Auth struct {
	// contains filtered or unexported fields
}

Auth 保存连接邮箱服务器所需的认证信息。

Auth 只能通过 PasswordAuth 或 OAuth2Auth 创建,避免调用方构造出模式 与凭证不匹配的状态。

func OAuth2Auth

func OAuth2Auth(username string, source TokenSource) Auth

OAuth2Auth 创建 XOAUTH2 认证。 @param username string 邮箱登录账号 @param source TokenSource Access Token 提供器 @return Auth 认证配置

func PasswordAuth

func PasswordAuth(username, password string) Auth

PasswordAuth 创建密码或应用专用密码认证。 @param username string 邮箱登录账号 @param password string 邮箱密码或应用专用密码 @return Auth 认证配置

func (Auth) GoString

func (a Auth) GoString() string

GoString 返回适用于 %#v 的脱敏认证摘要。

func (Auth) Mode

func (a Auth) Mode() AuthMode

Mode 返回认证方式。

func (Auth) String

func (a Auth) String() string

String 返回不包含密码和 TokenSource 内容的认证摘要。

func (Auth) Username

func (a Auth) Username() string

Username 返回邮箱登录账号。

type AuthMode

type AuthMode string

AuthMode 表示邮箱服务器使用的认证方式。

const (
	// AuthModePassword 使用邮箱密码或应用专用密码认证。
	AuthModePassword AuthMode = "password"
	// AuthModeXOAUTH2 使用 OAuth2 Access Token 通过 XOAUTH2 认证。
	AuthModeXOAUTH2 AuthMode = "xoauth2"
)

type BatchResult

type BatchResult struct {
	Results   []SendResult // Results 与输入邮件顺序一致。
	Succeeded int          // Succeeded 是成功数量。
	Failed    int          // Failed 是失败数量。
}

BatchResult 保存批量发送的有序结果和汇总数量。

type Cursor

type Cursor struct {
	Key         CursorKey // Key 是游标所属账号和邮箱目录。
	UIDValidity uint32    // UIDValidity 标识当前 UID 命名空间。
	LastUID     uint32    // LastUID 是最后已经提交的邮件 UID。
	UpdatedAt   time.Time // UpdatedAt 是游标更新时间。
}

Cursor 保存一个邮箱目录已经完成业务处理的进度。

type CursorKey

type CursorKey struct {
	AccountID string // AccountID 是调用方定义的账号标识。
	Mailbox   string // Mailbox 是 IMAP 邮箱目录。
}

CursorKey 唯一标识一个账号下的邮箱目录。

type CursorStore

type CursorStore interface {
	// Load 读取指定账号和邮箱目录的游标。
	Load(ctx context.Context, key CursorKey) (Cursor, bool, error)
	// Save 保存游标,并拒绝同一 UIDValidity 下的倒退更新。
	Save(ctx context.Context, cursor Cursor) error
	// Delete 删除指定账号和邮箱目录的游标。
	Delete(ctx context.Context, key CursorKey) error
}

CursorStore 保存 Hub 的邮件消费进度。

自定义实现必须保证同一 UIDValidity 下的 LastUID 只能向前推进。

type DialContextFunc

type DialContextFunc func(ctx context.Context, network, address string) (net.Conn, error)

DialContextFunc 建立到目标邮件服务器的原始网络连接。

调用方可以在这里接入 HTTP CONNECT、SOCKS5、专线或自定义网络出口。 隐式 TLS 由 MailKit 在原始连接建立后完成,函数本身不要提前包装 TLS。

type Endpoint

type Endpoint struct {
	Host    string  // Host 是邮箱服务器域名或 IP。
	Port    int     // Port 是邮箱服务器端口。
	TLSMode TLSMode // TLSMode 是连接加密方式。
}

Endpoint 描述一个 SMTP 或 IMAP 服务端点。

func (Endpoint) Validate

func (e Endpoint) Validate() error

Validate 检查服务端点是否可用于建立连接。

type Error

type Error struct {
	Op        string    // Op 记录失败的操作名称。
	Kind      ErrorKind // Kind 记录稳定错误分类。
	Temporary bool      // Temporary 标记错误是否适合稍后重试。
	Err       error     // Err 保存原始错误。
}

Error 保存 MailKit 操作失败时可用于判断和审计的信息。

func (*Error) Error

func (e *Error) Error() string

Error 返回带操作上下文的错误文本。

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap 返回原始错误,支持 errors.Is 和 errors.As。

type ErrorKind

type ErrorKind string

ErrorKind 描述邮件操作失败的稳定分类。

const (
	// ErrorKindConfig 表示配置错误。
	ErrorKindConfig ErrorKind = "config"
	// ErrorKindConnection 表示网络连接错误。
	ErrorKindConnection ErrorKind = "connection"
	// ErrorKindAuthentication 表示认证错误。
	ErrorKindAuthentication ErrorKind = "authentication"
	// ErrorKindProtocol 表示 SMTP 或 IMAP 协议错误。
	ErrorKindProtocol ErrorKind = "protocol"
	// ErrorKindMessage 表示邮件构建或解析错误。
	ErrorKindMessage ErrorKind = "message"
	// ErrorKindLifecycle 表示账号生命周期操作错误。
	ErrorKindLifecycle ErrorKind = "lifecycle"
)

type Event

type Event struct {
	Type       EventType    // Type 是事件类型。
	AccountID  string       // AccountID 是邮箱账号标识。
	State      AccountState // State 是事件发生时的账号状态。
	UID        uint32       // UID 是相关邮件 UID。
	MessageID  string       // MessageID 是相关邮件头标识。
	Err        error        // Err 是相关错误或跳过原因。
	OccurredAt time.Time    // OccurredAt 是事件发生时间。
}

Event 保存 Hub 生命周期和邮件处理事件。

type EventType

type EventType string

EventType 表示 Hub 运行事件类型。

const (
	// EventStateChanged 表示账号运行状态变化。
	EventStateChanged EventType = "state_changed"
	// EventMessageCommitted 表示邮件处理成功并已推进游标。
	EventMessageCommitted EventType = "message_committed"
	// EventMessageRetried 表示邮件业务处理要求重试。
	EventMessageRetried EventType = "message_retried"
	// EventMessageSkipped 表示邮件被永久跳过并已推进游标。
	EventMessageSkipped EventType = "message_skipped"
	// EventAccountError 表示账号会话或游标操作失败。
	EventAccountError EventType = "account_error"
)

type FetchOptions

type FetchOptions struct {
	IncludeBody        bool  // IncludeBody 控制是否解析文本和 HTML 正文。
	IncludeAttachments bool  // IncludeAttachments 控制是否读取附件内容。
	MaxMessageBytes    int64 // MaxMessageBytes 限制单封原始邮件大小,零使用默认值。
	MaxAttachmentBytes int64 // MaxAttachmentBytes 限制单个附件大小,零使用默认值。
}

FetchOptions 控制 IMAP 邮件内容的读取范围和内存上限。

type Hub

type Hub struct {
	// contains filtered or unexported fields
}

Hub 动态管理多个邮箱账号的上线、下线和邮件投递。

func NewHub

func NewHub(config HubConfig) (*Hub, error)

NewHub 创建多邮箱账号 Hub。 @param config HubConfig Hub 运行配置 @return *Hub 多账号 Hub @return error 创建失败信息

func (*Hub) Close

func (h *Hub) Close(ctx context.Context) error

Close 同时停止所有账号,并在完成后关闭事件通道。

func (*Hub) DroppedEvents

func (h *Hub) DroppedEvents() uint64

DroppedEvents 返回消费者过慢时被覆盖的观测副本数量。 @description 观测副本被覆盖不会影响邮件正文交付或游标推进 @return result uint64 被覆盖的观测副本数量

func (*Hub) Events

func (h *Hub) Events() <-chan Event

Events 返回账号状态和处理结果的只读观测通道。 @description 该通道不承载邮件正文,不参与 MessageHandler 调用和游标提交 @return result <-chan Event 运行观测事件通道

func (*Hub) List

func (h *Hub) List() []AccountStatus

List 返回所有账号的运行快照。

func (*Hub) Offline

func (h *Hub) Offline(ctx context.Context, accountID string) error

Offline 停止指定账号的接收会话并保留账号配置和游标。

func (*Hub) Online

func (h *Hub) Online(ctx context.Context, accountID string) error

Online 启动指定账号的独立接收会话。

func (*Hub) Register

func (h *Hub) Register(config AccountConfig) error

Register 注册邮箱账号,但不自动建立连接。

func (*Hub) Remove

func (h *Hub) Remove(ctx context.Context, accountID string) error

Remove 停止并删除账号,但不删除外部 CursorStore 中的游标。

func (*Hub) Status

func (h *Hub) Status(accountID string) (AccountStatus, bool)

Status 返回指定账号的运行快照。

func (*Hub) Update

func (h *Hub) Update(ctx context.Context, config AccountConfig) error

Update 替换账号配置;在线账号通过受控下线和重新上线应用新配置。

type HubConfig

type HubConfig struct {
	Handler     MessageHandler // Handler 处理按账号和 UID 排序的邮件。
	CursorStore CursorStore    // CursorStore 保存已经提交的邮件进度。
	EventBuffer int            // EventBuffer 是运行观测副本的通道容量,不参与邮件交付。
}

HubConfig 描述多账号 Hub 的公共依赖和事件缓冲。

type Mailbox

type Mailbox interface {
	// Search 查询并返回标准化邮件,结果按 UID 升序排列。
	Search(ctx context.Context, query SearchQuery) (SearchResult, error)
	// Close 关闭当前 IMAP 会话。
	Close(ctx context.Context) error
}

Mailbox 提供单个邮箱的显式查询能力。

func OpenMailbox

func OpenMailbox(ctx context.Context, config MailboxConfig) (Mailbox, error)

OpenMailbox 创建并认证一个单邮箱 IMAP 客户端。 @param ctx context.Context 上下文 @param config MailboxConfig 单邮箱配置 @return Mailbox 单邮箱客户端 @return error 打开失败信息

type MailboxConfig

type MailboxConfig struct {
	AccountID         string          // AccountID 是调用方定义的稳定账号标识。
	Endpoint          Endpoint        // Endpoint 是 IMAP 服务地址。
	Auth              Auth            // Auth 是 IMAP 认证信息。
	TLSConfig         *tls.Config     // TLSConfig 是可选的自定义 TLS 配置。
	DialContext       DialContextFunc // DialContext 是可选的自定义网络拨号函数。
	Mailbox           string          // Mailbox 是默认邮箱目录,空值使用 INBOX。
	ConnectTimeout    time.Duration   // ConnectTimeout 是建连超时。
	CommandTimeout    time.Duration   // CommandTimeout 是单次 IMAP 命令超时。
	AllowInsecureAuth bool            // AllowInsecureAuth 允许在明文链路发送认证信息。
}

MailboxConfig 描述一个独立 IMAP 连接。

func (MailboxConfig) Validate

func (c MailboxConfig) Validate() error

Validate 检查单邮箱配置是否完整。

type MemoryCursorStore

type MemoryCursorStore struct {
	// contains filtered or unexported fields
}

MemoryCursorStore 提供线程安全的进程内游标存储。

它适合测试和单进程临时任务。生产环境多节点部署应由应用实现 MySQL 或 Redis CursorStore,并同时负责账号的分布式归属。

func NewMemoryCursorStore

func NewMemoryCursorStore() *MemoryCursorStore

NewMemoryCursorStore 创建进程内游标存储。

func (*MemoryCursorStore) Delete

func (s *MemoryCursorStore) Delete(ctx context.Context, key CursorKey) error

Delete 删除指定游标。

func (*MemoryCursorStore) Load

func (s *MemoryCursorStore) Load(ctx context.Context, key CursorKey) (Cursor, bool, error)

Load 读取指定游标。

func (*MemoryCursorStore) Save

func (s *MemoryCursorStore) Save(ctx context.Context, cursor Cursor) error

Save 保存游标,并阻止旧会话覆盖较新的处理进度。

type MessageHandler

type MessageHandler interface {
	// Handle 处理一封邮件,并明确返回提交、重试或跳过决策。
	Handle(ctx context.Context, message ReceivedMessage) ProcessResult
}

MessageHandler 处理 Hub 按 UID 顺序投递的邮件。

type MessageHandlerFunc

type MessageHandlerFunc func(ctx context.Context, message ReceivedMessage) ProcessResult

MessageHandlerFunc 将普通函数适配为 MessageHandler。

func (MessageHandlerFunc) Handle

Handle 调用邮件处理函数。

type OutgoingMessage

type OutgoingMessage struct {
	MessageID   string              // MessageID 是可选的邮件唯一标识。
	From        Address             // From 是发件人。
	To          []Address           // To 是主收件人列表。
	CC          []Address           // CC 是抄送人列表。
	BCC         []Address           // BCC 是密送人列表。
	ReplyTo     []Address           // ReplyTo 是回复地址列表。
	Subject     string              // Subject 是邮件主题。
	Text        string              // Text 是纯文本正文。
	HTML        string              // HTML 是 HTML 正文。
	Headers     map[string][]string // Headers 保存调用方自定义邮件头。
	Attachments []Attachment        // Attachments 是附件和内嵌资源列表。
}

OutgoingMessage 描述一封待发送邮件。

func (OutgoingMessage) Validate

func (m OutgoingMessage) Validate() error

Validate 检查待发送邮件是否具备最小发送条件。

type ProcessAction

type ProcessAction string

ProcessAction 表示业务处理一封邮件后的游标决策。

const (
	// ProcessCommit 表示处理成功并允许推进游标。
	ProcessCommit ProcessAction = "commit"
	// ProcessRetry 表示本次未完成,必须保留游标并再次投递。
	ProcessRetry ProcessAction = "retry"
	// ProcessSkip 表示邮件永久不可处理,但允许推进游标。
	ProcessSkip ProcessAction = "skip"
)

type ProcessResult

type ProcessResult struct {
	Action ProcessAction // Action 决定当前邮件是否推进游标。
	Err    error         // Err 保存业务失败或跳过原因。
}

ProcessResult 保存业务处理结果。

func CommitMessage

func CommitMessage() ProcessResult

CommitMessage 返回成功处理结果。

func RetryMessage

func RetryMessage(err error) ProcessResult

RetryMessage 返回稍后重试结果。

func SkipMessage

func SkipMessage(err error) ProcessResult

SkipMessage 返回永久跳过结果。

type ProviderName

type ProviderName string

ProviderName 表示 MailKit 内置邮箱服务商。

const (
	// ProviderGmail 表示 Gmail 或 Google Workspace。
	ProviderGmail ProviderName = "gmail"
	// ProviderMicrosoft 表示 Outlook.com 或 Microsoft 365。
	ProviderMicrosoft ProviderName = "microsoft"
	// ProviderQQ 表示 QQ 邮箱。
	ProviderQQ ProviderName = "qq"
	// ProviderTencentExmail 表示腾讯企业邮箱。
	ProviderTencentExmail ProviderName = "tencent_exmail"
	// ProviderNetEase163 表示网易 163 邮箱。
	ProviderNetEase163 ProviderName = "netease_163"
	// ProviderNetEase126 表示网易 126 邮箱。
	ProviderNetEase126 ProviderName = "netease_126"
)

type ProviderProfile

type ProviderProfile struct {
	Name           string     // Name 是服务商配置名称。
	SMTP           Endpoint   // SMTP 是邮件发送端点。
	IMAP           Endpoint   // IMAP 是邮件接收端点。
	AuthModes      []AuthMode // AuthModes 是服务商支持的认证方式。
	PreferIMAPIdle bool       // PreferIMAPIdle 表示优先使用 IMAP IDLE。
}

ProviderProfile 描述服务商的 SMTP、IMAP 和能力默认值。

func BuiltinProvider

func BuiltinProvider(name ProviderName) (ProviderProfile, error)

BuiltinProvider 返回内置邮箱服务商配置的独立副本。 @param name ProviderName 内置服务商名称 @return ProviderProfile 服务商配置 @return error 获取失败信息

func (ProviderProfile) SupportsAuth

func (p ProviderProfile) SupportsAuth(mode AuthMode) bool

SupportsAuth 判断服务商是否声明支持指定认证方式。

func (ProviderProfile) Validate

func (p ProviderProfile) Validate() error

Validate 检查服务商配置是否完整。

type ReceivedAttachment

type ReceivedAttachment struct {
	Filename    string // Filename 是附件名称。
	ContentType string // ContentType 是附件 MIME 类型。
	ContentID   string // ContentID 是内嵌资源标识。
	Inline      bool   // Inline 标记是否为内嵌资源。
	Size        int64  // Size 是原始附件字节数。
	Data        []byte // Data 是按 FetchOptions 限制读取的附件内容。
}

ReceivedAttachment 保存一份已接收附件的标准化信息。

type ReceivedMessage

type ReceivedMessage struct {
	AccountID   string               // AccountID 是 MailKit 邮箱账号标识。
	Mailbox     string               // Mailbox 是邮件所在邮箱目录。
	UIDValidity uint32               // UIDValidity 标识当前 UID 命名空间。
	UID         uint32               // UID 是当前邮箱目录中的稳定邮件编号。
	MessageID   string               // MessageID 是邮件头中的 Message-ID。
	InReplyTo   string               // InReplyTo 是被回复邮件的 Message-ID。
	From        []Address            // From 是发件人列表。
	To          []Address            // To 是主收件人列表。
	CC          []Address            // CC 是抄送人列表。
	ReplyTo     []Address            // ReplyTo 是回复地址列表。
	Subject     string               // Subject 是邮件主题。
	Date        time.Time            // Date 是邮件头声明的发送时间。
	ReceivedAt  time.Time            // ReceivedAt 是 IMAP 服务器内部接收时间。
	Flags       []string             // Flags 是 IMAP 邮件标记。
	Headers     map[string][]string  // Headers 保存标准化后的邮件头。
	Text        string               // Text 是纯文本正文。
	HTML        string               // HTML 是 HTML 正文。
	Attachments []ReceivedAttachment // Attachments 是附件和内嵌资源。
	Size        uint32               // Size 是服务端报告的整封邮件大小。
	ParseError  error                // ParseError 是单封邮件的 MIME 解析错误。
}

ReceivedMessage 保存一封从 IMAP 获取并标准化后的邮件。

type ReconnectPolicy

type ReconnectPolicy struct {
	InitialDelay   time.Duration // InitialDelay 是第一次重连等待时间。
	MaxDelay       time.Duration // MaxDelay 是重连等待上限。
	Multiplier     float64       // Multiplier 是每次失败后的退避倍数。
	JitterFraction float64       // JitterFraction 是用于错开多账号重连的抖动比例。
}

ReconnectPolicy 控制邮箱会话断开后的指数退避。

func (ReconnectPolicy) Validate

func (p ReconnectPolicy) Validate() error

Validate 检查重连策略是否有效。

type RetryPolicy

type RetryPolicy struct {
	MaxAttempts int           // MaxAttempts 是包含首次发送的最大尝试次数。
	Backoff     time.Duration // Backoff 是两次发送尝试之间的固定等待时间。
}

RetryPolicy 控制 SMTP 临时错误的重试行为。

MaxAttempts 包含首次发送。默认值为 1,避免在服务端已经接收邮件但客户端 未收到响应的模糊场景中自动产生重复邮件。

type SearchQuery

type SearchQuery struct {
	Mailbox      string            // Mailbox 是待查询的邮箱目录,空值使用 INBOX。
	AfterUID     uint32            // AfterUID 只查询 UID 大于该值的邮件。
	Since        time.Time         // Since 按 IMAP 日期粒度查询该日期及之后的邮件。
	Before       time.Time         // Before 按 IMAP 日期粒度查询该日期之前的邮件。
	From         string            // From 按发件地址或名称匹配。
	To           string            // To 按收件地址或名称匹配。
	Subject      string            // Subject 按主题文本匹配。
	Text         string            // Text 按服务端全文搜索能力匹配。
	Headers      map[string]string // Headers 按指定邮件头匹配。
	WithFlags    []string          // WithFlags 要求邮件包含这些标记。
	WithoutFlags []string          // WithoutFlags 要求邮件不包含这些标记。
	Limit        int               // Limit 限制最终返回数量,零表示不额外限制。
	Fetch        FetchOptions      // Fetch 控制邮件内容读取范围。
}

SearchQuery 描述一个与具体 IMAP 库无关的邮件查询。

func (SearchQuery) Validate

func (q SearchQuery) Validate() error

Validate 检查查询范围是否有效。

type SearchResult

type SearchResult struct {
	Mailbox     string            // Mailbox 是本次查询的邮箱目录。
	UIDValidity uint32            // UIDValidity 标识当前 UID 命名空间。
	Messages    []ReceivedMessage // Messages 按 UID 升序排列。
}

SearchResult 保存一次 IMAP 查询的邮箱身份和邮件结果。

type SendResult

type SendResult struct {
	Index     int    // Index 是邮件在输入切片中的位置。
	MessageID string // MessageID 是调用方提供的邮件标识。
	Attempts  int    // Attempts 是实际发送尝试次数。
	Err       error  // Err 是最终错误,成功时为空。
}

SendResult 描述批量发送中单封邮件的执行结果。

type Sender

type Sender interface {
	// Send 发送一封邮件。
	Send(ctx context.Context, message OutgoingMessage) error
	// SendBatch 并发发送多封邮件,并按输入顺序返回结果。
	SendBatch(ctx context.Context, messages []OutgoingMessage) BatchResult
	// Stats 返回当前运行状态快照。
	Stats() SenderStats
	// Close 停止接收新任务,并等待进行中的发送完成。
	Close(ctx context.Context) error
}

Sender 提供并发受控、连接复用的 SMTP 发送能力。

func NewSender

func NewSender(config SenderConfig) (Sender, error)

NewSender 创建 SMTP Sender。 @param config SenderConfig SMTP 运行配置 @return Sender SMTP Sender @return error 创建失败信息

type SenderConfig

type SenderConfig struct {
	Endpoint              Endpoint        // Endpoint 是 SMTP 服务地址。
	Auth                  Auth            // Auth 是 SMTP 认证信息。
	TLSConfig             *tls.Config     // TLSConfig 是可选的自定义 TLS 配置。
	DialContext           DialContextFunc // DialContext 是可选的自定义网络拨号函数。
	Timeout               time.Duration   // Timeout 是 SMTP 建连和命令超时。
	MaxConnections        int             // MaxConnections 是并发 SMTP 连接上限。
	ConnectionMaxLifetime time.Duration   // ConnectionMaxLifetime 是连接最大复用时间。
	Retry                 RetryPolicy     // Retry 控制临时错误重试。
	AllowInsecureAuth     bool            // AllowInsecureAuth 允许在明文链路发送认证信息。
}

SenderConfig 描述 SMTP Sender 的运行配置。

func (SenderConfig) Validate

func (c SenderConfig) Validate() error

Validate 检查 SMTP Sender 配置是否完整。

type SenderStats

type SenderStats struct {
	Sent           uint64 // Sent 是发送成功数量。
	Failed         uint64 // Failed 是最终发送失败数量。
	Retried        uint64 // Retried 是额外重试次数。
	InFlight       int64  // InFlight 是当前正在发送的数量。
	MaxConnections int    // MaxConnections 是配置的最大并发连接数。
	Closed         bool   // Closed 表示 Sender 是否已经关闭。
}

SenderStats 是 Sender 的线程安全运行快照。

type TLSMode

type TLSMode string

TLSMode 表示邮箱服务器的传输加密方式。

const (
	// TLSModePlain 使用明文连接,仅适合受信任的内网或测试环境。
	TLSModePlain TLSMode = "plain"
	// TLSModeSTARTTLS 先建立明文连接,再升级为 TLS。
	TLSModeSTARTTLS TLSMode = "starttls"
	// TLSModeImplicit 建立连接时立即使用 TLS。
	TLSModeImplicit TLSMode = "implicit_tls"
)

type TokenSource

type TokenSource interface {
	Token(ctx context.Context) (string, error)
}

TokenSource 按需提供可用的 OAuth2 Access Token。

MailKit 不保存 Refresh Token,也不负责刷新凭证。应用可以在 Token 方法中完成缓存读取或刷新,并把最新 Access Token 返回给 MailKit。 Sender 可能通过多个连接并发调用 Token,具体实现必须保证并发安全。

type TokenSourceFunc

type TokenSourceFunc func(ctx context.Context) (string, error)

TokenSourceFunc 将普通函数适配为 TokenSource。

func (TokenSourceFunc) Token

func (f TokenSourceFunc) Token(ctx context.Context) (string, error)

Token 调用函数并返回当前 Access Token。

Directories

Path Synopsis
examples
hub command
query command
send command

Jump to

Keyboard shortcuts

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