Documentation
¶
Overview ¶
Package mail provides comprehensive email sending and SMTP server functionality with support for templates, queuing, and notification handling.
Features:
- SMTP client for sending emails with various authentication methods
- SMTP server for receiving emails with notification handlers
- HTML template support with embedded and custom templates
- Queue integration for asynchronous email processing
- TLS/STARTTLS encryption support
- Attachment support
- Statistics tracking
- Retry mechanisms with exponential backoff
Example Usage:
package main import ( "context" "time" "github.com/Valentin-Kaiser/go-core/mail" "github.com/Valentin-Kaiser/go-core/queue" ) func main() { // Create mail configuration config := mail.DefaultConfig() config.SMTP.Host = "smtp.gmail.com" config.SMTP.Port = 587 config.SMTP.Username = "your-email@gmail.com" config.SMTP.Password = "your-password" config.SMTP.From = "noreply@example.com" config.SMTP.Auth = true config.SMTP.Encryption = "STARTTLS" // Create queue manager queueManager := queue.NewManager() // Create mail manager mailManager := mail.NewManager(config, queueManager) // Start the manager ctx := context.Background() if err := mailManager.Start(ctx); err != nil { panic(err) } defer mailManager.Stop(ctx) // Send a simple email message := mail.NewMessage(). To("recipient@example.com"). Subject("Test Email"). TextBody("Hello, this is a test email!"). Build() if err := mailManager.Send(ctx, message); err != nil { panic(err) } // Send an email with template templateMessage := mail.NewMessage(). To("user@example.com"). Subject("Welcome!"). Template("welcome.html", map[string]interface{}{ "FirstName": "John", "ActivationURL": "https://example.com/activate?token=abc123", }). Build() if err := mailManager.SendAsync(ctx, templateMessage); err != nil { panic(err) } }
SMTP Server Example:
config := mail.DefaultConfig() config.Server.Enabled = true config.Server.Host = "localhost" config.Server.Port = 2525 config.Server.Domain = "example.com" config.Server.Auth = true config.Server.Username = "admin" config.Server.Password = "password" mailManager := mail.NewManager(config, nil) // Add notification handler mailManager.AddNotificationHandler(func(ctx context.Context, from string, to []string, data []byte) error { log.Printf("Received email from %s to %v", from, to) return nil }) if err := mailManager.Start(ctx); err != nil { panic(err) }
Index ¶
- func NewLoginAuth(username, password string) smtp.Auth
- type Attachment
- type AuthMethod
- type ClientConfig
- type Config
- type EncryptionMethod
- type LoginAuth
- type Manager
- func (m *Manager) AddNotificationHandler(handler NotificationHandler) error
- func (m *Manager) GetStats() *Stats
- func (m *Manager) IsRunning() bool
- func (m *Manager) NotifyMessageReceived()
- func (m *Manager) ReloadTemplates() error
- func (m *Manager) Send(ctx context.Context, message *Message) error
- func (m *Manager) SendAsync(ctx context.Context, message *Message) error
- func (m *Manager) SendTestEmail(ctx context.Context, to string) error
- func (m *Manager) Start(_ context.Context) error
- func (m *Manager) Stop(ctx context.Context) error
- func (m *Manager) WithFS(filesystem fs.FS) *Manager
- func (m *Manager) WithFileServer(templatesPath string) *Manager
- type Message
- type MessageBuilder
- func (b *MessageBuilder) Attach(attachment Attachment) *MessageBuilder
- func (b *MessageBuilder) AttachFile(fileHeader *multipart.FileHeader) *MessageBuilder
- func (b *MessageBuilder) AttachInline(filename, contentType, contentID string, content []byte) *MessageBuilder
- func (b *MessageBuilder) AttachInlineFromReader(filename, contentType, contentID string, reader io.Reader, size int64) *MessageBuilder
- func (b *MessageBuilder) BCC(bcc ...string) *MessageBuilder
- func (b *MessageBuilder) Build() (*Message, error)
- func (b *MessageBuilder) CC(cc ...string) *MessageBuilder
- func (b *MessageBuilder) From(from string) *MessageBuilder
- func (b *MessageBuilder) HTMLBody(html string) *MessageBuilder
- func (b *MessageBuilder) Header(key, value string) *MessageBuilder
- func (b *MessageBuilder) Metadata(key, value string) *MessageBuilder
- func (b *MessageBuilder) Priority(priority Priority) *MessageBuilder
- func (b *MessageBuilder) ReplyTo(replyTo string) *MessageBuilder
- func (b *MessageBuilder) ScheduleAt(scheduleAt time.Time) *MessageBuilder
- func (b *MessageBuilder) Subject(subject string) *MessageBuilder
- func (b *MessageBuilder) Template(name string, data interface{}) *MessageBuilder
- func (b *MessageBuilder) TextBody(text string) *MessageBuilder
- func (b *MessageBuilder) To(to ...string) *MessageBuilder
- type NotificationHandler
- type Priority
- type QueueConfig
- type Recipient
- type Sender
- type Server
- type ServerConfig
- type Stats
- type TemplateConfig
- type TemplateData
- type TemplateManager
- func (tm *TemplateManager) LoadTemplate(name string) (*template.Template, error)
- func (tm *TemplateManager) ReloadTemplates() error
- func (tm *TemplateManager) RenderTemplate(name string, data interface{}) (string, error)
- func (tm *TemplateManager) WithDefaultFuncs() *TemplateManager
- func (tm *TemplateManager) WithFS(filesystem fs.FS) *TemplateManager
- func (tm *TemplateManager) WithFileServer(templatesPath string) *TemplateManager
- func (tm *TemplateManager) WithTemplateFunc(key string, fn interface{}) *TemplateManager
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewLoginAuth ¶
NewLoginAuth creates a new LOGIN authenticator
Types ¶
type Attachment ¶
type Attachment struct { // Filename is the name of the file Filename string `json:"filename"` // ContentType is the MIME content type ContentType string `json:"content_type"` // Content is the file content Content []byte `json:"content,omitempty"` // Reader is an alternative to Content for streaming large files Reader io.Reader `json:"-"` // Size is the size of the attachment in bytes Size int64 `json:"size"` // Inline indicates if the attachment should be displayed inline Inline bool `json:"inline"` // ContentID is used for inline attachments ContentID string `json:"content_id,omitempty"` }
Attachment represents a file attachment
type AuthMethod ¶
type AuthMethod string
AuthMethod represents SMTP authentication methods
const ( // AuthMethodPlain represents PLAIN authentication AuthMethodPlain AuthMethod = "PLAIN" // AuthMethodCRAMMD5 represents CRAM-MD5 authentication AuthMethodCRAMMD5 AuthMethod = "CRAMMD5" // AuthMethodLogin represents LOGIN authentication AuthMethodLogin AuthMethod = "LOGIN" )
type ClientConfig ¶ added in v1.4.1
type ClientConfig struct { // Host is the SMTP server hostname Host string `yaml:"host" json:"host"` // Port is the SMTP server port Port int `yaml:"port" json:"port"` // Username for SMTP authentication Username string `yaml:"username" json:"username"` // Password for SMTP authentication Password string `yaml:"password" json:"password"` // From address for outgoing emails From string `yaml:"from" json:"from"` // FQDN for HELO command FQDN string `yaml:"fqdn" json:"fqdn"` // Authentication enabled Auth bool `yaml:"auth" json:"auth"` // AuthMethod defines the authentication method (PLAIN, CRAMMD5, LOGIN) AuthMethod string `yaml:"auth_method" json:"auth_method"` // Encryption method (NONE, STARTTLS, TLS) Encryption string `yaml:"encryption" json:"encryption"` // SkipCertificateVerification skips TLS certificate verification SkipCertificateVerification bool `yaml:"skip_cert_verification" json:"skip_cert_verification"` // Timeout for SMTP operations Timeout time.Duration `yaml:"timeout" json:"timeout"` // MaxRetries for failed email sending MaxRetries int `yaml:"max_retries" json:"max_retries"` // RetryDelay between retries RetryDelay time.Duration `yaml:"retry_delay" json:"retry_delay"` }
ClientConfig holds the SMTP client configuration for sending emails
func (*ClientConfig) TLSConfig ¶ added in v1.4.1
func (c *ClientConfig) TLSConfig() *tls.Config
TLSConfig returns a TLS configuration for the SMTP client
func (*ClientConfig) Validate ¶ added in v1.4.1
func (c *ClientConfig) Validate() error
type Config ¶
type Config struct { // SMTP Client Configuration Client ClientConfig `yaml:"smtp" json:"smtp"` // SMTP Server Configuration Server ServerConfig `yaml:"server" json:"server"` // Queue Configuration Queue QueueConfig `yaml:"queue" json:"queue"` // Templates Configuration Templates TemplateConfig `yaml:"templates" json:"templates"` }
Config holds the configuration for the mail package
type EncryptionMethod ¶
type EncryptionMethod string
EncryptionMethod represents SMTP encryption methods
const ( // EncryptionNone represents no encryption EncryptionNone EncryptionMethod = "NONE" // EncryptionSTARTTLS represents STARTTLS encryption EncryptionSTARTTLS EncryptionMethod = "STARTTLS" // EncryptionTLS represents TLS encryption EncryptionTLS EncryptionMethod = "TLS" )
type LoginAuth ¶
type LoginAuth struct {
// contains filtered or unexported fields
}
LoginAuth implements LOGIN authentication for SMTP
type Manager ¶
type Manager struct { TemplateManager *TemplateManager // contains filtered or unexported fields }
Manager manages email sending and SMTP server functionality
func NewManager ¶
NewManager creates a new mail manager
func (*Manager) AddNotificationHandler ¶
func (m *Manager) AddNotificationHandler(handler NotificationHandler) error
AddNotificationHandler adds a notification handler to the SMTP server
func (*Manager) NotifyMessageReceived ¶
func (m *Manager) NotifyMessageReceived()
NotifyMessageReceived notifies that a message was received by the SMTP server
func (*Manager) ReloadTemplates ¶
ReloadTemplates reloads all templates
func (*Manager) SendTestEmail ¶
SendTestEmail sends a test email
func (*Manager) WithFileServer ¶
WithFileServer configures the template manager to load templates from a file path
type Message ¶
type Message struct { // ID is a unique identifier for the message ID string `json:"id"` // From is the sender's email address From string `json:"from"` // To is a list of recipient email addresses To []string `json:"to"` // CC is a list of carbon copy recipient email addresses CC []string `json:"cc,omitempty"` // BCC is a list of blind carbon copy recipient email addresses BCC []string `json:"bcc,omitempty"` // ReplyTo is the reply-to email address ReplyTo string `json:"reply_to,omitempty"` // Subject is the email subject Subject string `json:"subject"` // TextBody is the plain text body of the email TextBody string `json:"text_body,omitempty"` // HTMLBody is the HTML body of the email HTMLBody string `json:"html_body,omitempty"` // Template is the name of the template to use Template string `json:"template,omitempty"` // TemplateData is the data to pass to the template TemplateData interface{} `json:"template_data,omitempty"` // Attachments is a list of file attachments Attachments []Attachment `json:"attachments,omitempty"` // Headers contains additional email headers Headers map[string]string `json:"headers,omitempty"` // Priority is the message priority Priority Priority `json:"priority"` // CreatedAt is when the message was created CreatedAt time.Time `json:"created_at"` // ScheduleAt is when the message should be sent (optional) ScheduleAt *time.Time `json:"schedule_at,omitempty"` // Metadata contains additional metadata Metadata map[string]string `json:"metadata,omitempty"` }
Message represents an email message
type MessageBuilder ¶
type MessageBuilder struct { Error error // Error is used to capture any errors during building // contains filtered or unexported fields }
MessageBuilder provides a fluent interface for building messages
func (*MessageBuilder) Attach ¶
func (b *MessageBuilder) Attach(attachment Attachment) *MessageBuilder
Attach adds a file attachment
func (*MessageBuilder) AttachFile ¶
func (b *MessageBuilder) AttachFile(fileHeader *multipart.FileHeader) *MessageBuilder
AttachFile adds a file attachment from a multipart file header Returns the builder for chaining. If an error occurs, it logs the error and continues without adding the attachment.
func (*MessageBuilder) AttachInline ¶
func (b *MessageBuilder) AttachInline(filename, contentType, contentID string, content []byte) *MessageBuilder
AttachInline adds an inline file attachment with Content-ID for embedding in HTML
func (*MessageBuilder) AttachInlineFromReader ¶
func (b *MessageBuilder) AttachInlineFromReader(filename, contentType, contentID string, reader io.Reader, size int64) *MessageBuilder
AttachInlineFromReader adds an inline file attachment from a reader with Content-ID for embedding in HTML
func (*MessageBuilder) BCC ¶
func (b *MessageBuilder) BCC(bcc ...string) *MessageBuilder
BCC sets the blind carbon copy recipient email addresses
func (*MessageBuilder) Build ¶
func (b *MessageBuilder) Build() (*Message, error)
Build returns the built message
func (*MessageBuilder) CC ¶
func (b *MessageBuilder) CC(cc ...string) *MessageBuilder
CC sets the carbon copy recipient email addresses
func (*MessageBuilder) From ¶
func (b *MessageBuilder) From(from string) *MessageBuilder
From sets the sender's email address
func (*MessageBuilder) HTMLBody ¶
func (b *MessageBuilder) HTMLBody(html string) *MessageBuilder
HTMLBody sets the HTML body
func (*MessageBuilder) Header ¶
func (b *MessageBuilder) Header(key, value string) *MessageBuilder
Header sets a custom header
func (*MessageBuilder) Metadata ¶
func (b *MessageBuilder) Metadata(key, value string) *MessageBuilder
Metadata sets metadata for the message
func (*MessageBuilder) Priority ¶
func (b *MessageBuilder) Priority(priority Priority) *MessageBuilder
Priority sets the message priority
func (*MessageBuilder) ReplyTo ¶
func (b *MessageBuilder) ReplyTo(replyTo string) *MessageBuilder
ReplyTo sets the reply-to email address
func (*MessageBuilder) ScheduleAt ¶
func (b *MessageBuilder) ScheduleAt(scheduleAt time.Time) *MessageBuilder
ScheduleAt sets when the message should be sent
func (*MessageBuilder) Subject ¶
func (b *MessageBuilder) Subject(subject string) *MessageBuilder
Subject sets the email subject
func (*MessageBuilder) Template ¶
func (b *MessageBuilder) Template(name string, data interface{}) *MessageBuilder
Template sets the template name and data
func (*MessageBuilder) TextBody ¶
func (b *MessageBuilder) TextBody(text string) *MessageBuilder
TextBody sets the plain text body
func (*MessageBuilder) To ¶
func (b *MessageBuilder) To(to ...string) *MessageBuilder
To sets the recipient email addresses
type NotificationHandler ¶
NotificationHandler is a function that handles incoming SMTP messages
type QueueConfig ¶
type QueueConfig struct { // Enabled indicates if queue processing should be used Enabled bool `yaml:"enabled" json:"enabled"` // WorkerCount is the number of workers processing mail jobs WorkerCount int `yaml:"worker_count" json:"worker_count"` // QueueName is the name of the queue for mail jobs QueueName string `yaml:"queue_name" json:"queue_name"` // Priority for mail jobs Priority int `yaml:"priority" json:"priority"` // MaxAttempts for failed mail jobs MaxAttempts int `yaml:"max_attempts" json:"max_attempts"` // JobTimeout for mail job processing JobTimeout time.Duration `yaml:"job_timeout" json:"job_timeout"` }
QueueConfig holds the queue configuration for mail processing
func (*QueueConfig) Validate ¶ added in v1.4.1
func (c *QueueConfig) Validate() error
type Recipient ¶
type Recipient struct { // Email is the recipient's email address Email string `json:"email"` // Name is the recipient's display name Name string `json:"name,omitempty"` // Type is the recipient type (to, cc, bcc) Type string `json:"type"` }
Recipient represents an email recipient
type Sender ¶
type Sender interface { // Send sends an email message Send(ctx context.Context, message *Message) error // SendAsync sends an email message asynchronously using the queue SendAsync(ctx context.Context, message *Message) error }
Sender is the interface for sending emails
func NewSMTPSender ¶
func NewSMTPSender(config ClientConfig, templateManager *TemplateManager) Sender
NewSMTPSender creates a new SMTP sender
type Server ¶
type Server interface { // Start starts the SMTP server Start(ctx context.Context) error // Stop stops the SMTP server Stop(ctx context.Context) error // AddHandler adds a notification handler AddHandler(handler NotificationHandler) // IsRunning returns true if the server is running IsRunning() bool }
Server is the interface for SMTP servers
func NewSMTPServer ¶
func NewSMTPServer(config ServerConfig, manager *Manager) Server
NewSMTPServer creates a new SMTP server
type ServerConfig ¶
type ServerConfig struct { // Enabled indicates if the SMTP server should be started Enabled bool `yaml:"enabled" json:"enabled"` // Host to bind the server to Host string `yaml:"host" json:"host"` // Port to bind the server to Port int `yaml:"port" json:"port"` // Domain name for the server Domain string `yaml:"domain" json:"domain"` // Authentication required for incoming messages Auth bool `yaml:"auth" json:"auth"` // Username for server authentication Username string `yaml:"username" json:"username"` // Password for server authentication Password string `yaml:"password" json:"password"` // TLS encryption enabled TLS bool `yaml:"tls" json:"tls"` // Certificate file path for TLS CertFile string `yaml:"cert_file" json:"cert_file"` // Key file path for TLS KeyFile string `yaml:"key_file" json:"key_file"` // ReadTimeout for server connections ReadTimeout time.Duration `yaml:"read_timeout" json:"read_timeout"` // WriteTimeout for server connections WriteTimeout time.Duration `yaml:"write_timeout" json:"write_timeout"` // MaxMessageBytes is the maximum size of a message MaxMessageBytes int64 `yaml:"max_message_bytes" json:"max_message_bytes"` // MaxRecipients is the maximum number of recipients per message MaxRecipients int `yaml:"max_recipients" json:"max_recipients"` // AllowInsecureAuth allows authentication over non-TLS connections AllowInsecureAuth bool `yaml:"allow_insecure_auth" json:"allow_insecure_auth"` // MaxConcurrentHandlers limits the number of concurrent notification handlers MaxConcurrentHandlers int `yaml:"max_concurrent_handlers" json:"max_concurrent_handlers"` }
ServerConfig holds the SMTP server configuration
func (*ServerConfig) TLSConfig ¶
func (c *ServerConfig) TLSConfig() *tls.Config
TLSConfig returns a TLS configuration for the SMTP server
func (*ServerConfig) Validate ¶ added in v1.4.1
func (c *ServerConfig) Validate() error
type Stats ¶
type Stats struct { // SentCount is the number of emails sent SentCount int64 `json:"sent_count"` // FailedCount is the number of emails that failed to send FailedCount int64 `json:"failed_count"` // QueuedCount is the number of emails currently queued QueuedCount int64 `json:"queued_count"` // ReceivedCount is the number of emails received by the server ReceivedCount int64 `json:"received_count"` // LastSent is the timestamp of the last sent email LastSent *time.Time `json:"last_sent,omitempty"` // LastReceived is the timestamp of the last received email LastReceived *time.Time `json:"last_received,omitempty"` }
Stats represents mail statistics
type TemplateConfig ¶
type TemplateConfig struct { // DefaultTemplate is the name of the default template DefaultTemplate string `yaml:"default_template" json:"default_template"` // AutoReload indicates if templates should be reloaded on change AutoReload bool `yaml:"auto_reload" json:"auto_reload"` // FileSystem for loading templates (internal use - not serializable) FileSystem fs.FS `yaml:"-" json:"-"` // TemplatesPath is the path to custom email templates (used with WithFileServer) TemplatesPath string `yaml:"templates_path" json:"templates_path"` }
TemplateConfig holds the template configuration
func (*TemplateConfig) Validate ¶ added in v1.4.1
func (c *TemplateConfig) Validate() error
type TemplateData ¶
type TemplateData struct { // Subject is the email subject Subject string `json:"subject"` // Data is the custom data for the template Data interface{} `json:"data"` // Metadata contains additional metadata Metadata map[string]interface{} `json:"metadata,omitempty"` }
TemplateData represents data passed to email templates
type TemplateManager ¶
type TemplateManager struct { Error error // contains filtered or unexported fields }
TemplateManager implements the TemplateManager interface
func NewTemplateManager ¶
func NewTemplateManager(config TemplateConfig) *TemplateManager
NewTemplateManager creates a new template manager
func (*TemplateManager) LoadTemplate ¶
func (tm *TemplateManager) LoadTemplate(name string) (*template.Template, error)
LoadTemplate loads a template by name
func (*TemplateManager) ReloadTemplates ¶
func (tm *TemplateManager) ReloadTemplates() error
ReloadTemplates reloads all templates
func (*TemplateManager) RenderTemplate ¶
func (tm *TemplateManager) RenderTemplate(name string, data interface{}) (string, error)
RenderTemplate renders a template with the given data
func (*TemplateManager) WithDefaultFuncs ¶ added in v1.4.1
func (tm *TemplateManager) WithDefaultFuncs() *TemplateManager
func (*TemplateManager) WithFS ¶
func (tm *TemplateManager) WithFS(filesystem fs.FS) *TemplateManager
WithFS configures the template manager to load templates from a filesystem
func (*TemplateManager) WithFileServer ¶
func (tm *TemplateManager) WithFileServer(templatesPath string) *TemplateManager
WithFileServer configures the template manager to load templates from a file path
func (*TemplateManager) WithTemplateFunc ¶ added in v1.4.1
func (tm *TemplateManager) WithTemplateFunc(key string, fn interface{}) *TemplateManager