Documentation
¶
Overview ¶
Package gomail provides a universal email library for Go applications.
gomail is designed to be drop-in ready for any project requiring email functionality, supporting both sending and receiving emails through multiple providers with a consistent, developer-friendly API.
Features ¶
- Multiple providers: SMTP, SendGrid, AWS SES (planned)
- Email receiving: IMAP, POP3 with markdown output (planned)
- Queue support: Redis-backed async sending (planned)
- Template rendering: HTML email templates
- Configuration agnostic: Your app manages secrets
- Type-safe API: Compile-time validation
Quick Start ¶
Basic email sending with SMTP:
package main
import (
"context"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Configure SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.gmail.com",
Port: 587,
Username: "your-email@gmail.com",
Password: "your-app-password",
From: "your-email@gmail.com",
UseTLS: true,
})
// Create email client
client := gomail.NewClient(provider)
// Send email
err := client.Send(context.Background(), &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Hello from gomail!",
Body: "This is a test email.",
IsHTML: false,
})
if err != nil {
log.Fatal(err)
}
}
HTML Emails ¶
Send HTML-formatted emails:
msg := &gomail.Message{
To: []string{"user@example.com"},
Subject: "Welcome!",
Body: "<h1>Welcome</h1><p>Thanks for signing up!</p>",
IsHTML: true,
}
err := client.Send(ctx, msg)
CC and BCC ¶
Include CC and BCC recipients:
msg := &gomail.Message{
To: []string{"primary@example.com"},
CC: []string{"cc@example.com"},
BCC: []string{"bcc@example.com"},
Subject: "Team Update",
Body: "Update for the team...",
}
Attachments ¶
Send emails with file attachments from disk or memory:
// Attachment from file
msg := &gomail.Message{
To: []string{"user@example.com"},
Subject: "Invoice Attached",
Body: "Please find your invoice attached.",
Attachments: []gomail.Attachment{
{
Filename: "invoice.pdf",
Path: "./invoices/invoice_123.pdf",
},
},
}
// In-memory attachment
csvData := []byte("Name,Email\nJohn,john@example.com")
msg := &gomail.Message{
To: []string{"user@example.com"},
Subject: "Contact List",
Body: "Here's the contact list.",
Attachments: []gomail.Attachment{
{
Filename: "contacts.csv",
Content: csvData,
ContentType: "text/csv",
},
},
}
// Multiple attachments
msg := &gomail.Message{
To: []string{"user@example.com"},
Subject: "Project Documents",
Body: "Project files attached.",
Attachments: []gomail.Attachment{
{Filename: "proposal.pdf", Path: "./proposal.pdf"},
{Filename: "budget.xlsx", Path: "./budget.xlsx"},
{Filename: "timeline.docx", Path: "./timeline.docx"},
},
}
Inline Images ¶
Embed images in HTML emails using Content-ID (CID):
htmlBody := `
<html>
<body>
<h1>Welcome!</h1>
<img src="cid:logo" alt="Company Logo" />
<p>Thanks for joining us!</p>
</body>
</html>
`
msg := &gomail.Message{
To: []string{"user@example.com"},
Subject: "Welcome Email",
Body: htmlBody,
IsHTML: true,
InlineImages: []gomail.InlineImage{
{
CID: "logo", // Referenced as "cid:logo" in HTML
Path: "./logo.png",
},
},
}
// In-memory inline image
imageData := []byte{ /* PNG or JPEG bytes */ }
msg := &gomail.Message{
To: []string{"user@example.com"},
Subject: "Dynamic Content",
Body: `<img src="cid:chart" />`,
IsHTML: true,
InlineImages: []gomail.InlineImage{
{
CID: "chart",
Content: imageData,
ContentType: "image/png",
},
},
}
Attachment Limits ¶
gomail enforces the following size limits:
- Attachments: 25MB per file
- Inline images: 10MB per file
MIME types are automatically detected from file extensions, or you can specify ContentType explicitly. Supported formats include PDF, images (PNG, JPEG, GIF), Microsoft Office documents, ZIP archives, and more.
Configuration Management ¶
gomail is configuration-agnostic. Your application is responsible for managing SMTP credentials securely:
- Use environment variables for development
- Use Docker secrets for production
- Store in database with encryption (AES-256-GCM recommended)
Example with environment variables:
import "os"
config := smtp.Config{
Host: os.Getenv("SMTP_HOST"),
Port: 587,
Username: os.Getenv("SMTP_USERNAME"),
Password: os.Getenv("SMTP_PASSWORD"),
From: os.Getenv("SMTP_FROM"),
UseTLS: true,
}
Error Handling ¶
gomail provides typed errors for better error handling:
err := client.Send(ctx, msg)
if err != nil {
switch e := err.(type) {
case *gomail.ValidationError:
log.Printf("Invalid message: %v", e)
case *gomail.SendError:
log.Printf("Send failed: %v", e)
case *gomail.TemplateError:
log.Printf("Template error: %v", e)
default:
log.Printf("Unknown error: %v", e)
}
}
Providers ¶
gomail supports multiple email providers through a common interface. Current and planned providers:
- SMTP (v0.1.0) - Universal SMTP server support
- SendGrid (v0.3.0 planned) - SendGrid API
- AWS SES (v0.4.0 planned) - Amazon Simple Email Service
Switch providers by changing the provider initialization:
// SMTP provider := smtp.New(smtpConfig) // SendGrid (planned v0.3.0) // provider := sendgrid.New(sendgridConfig) // AWS SES (planned v0.4.0) // provider := ses.New(sesConfig) client := gomail.NewClient(provider)
Async Sending with Queue (Planned v0.2.0) ¶
Queue emails for asynchronous sending with retry logic:
// Configure Redis queue (v0.2.0)
redisQueue := redis.New(redisClient, redis.QueueConfig{
QueueKey: "emails:outbox",
MaxRetries: 3,
RetryDelay: 5 * time.Minute,
})
// Create client with queue
client := gomail.NewClient(
provider,
gomail.WithQueue(redisQueue),
)
// Send async (queues the email)
err := client.SendAsync(ctx, msg)
// Start queue processor
go client.ProcessQueue(ctx)
Template Rendering (Planned v0.2.0) ¶
Render HTML emails from templates:
client := gomail.NewClient(
provider,
gomail.WithTemplates("./templates/*.html"),
)
err := client.SendFromTemplate(
ctx,
"welcome.html",
[]string{"user@example.com"},
"Welcome!",
map[string]interface{}{
"Name": "John",
"URL": "https://example.com",
},
)
Email Receiving (Planned v0.5.0) ¶
Receive and process emails with markdown output:
// Configure IMAP receiver
receiver := imap.New(&imap.Config{
Host: "imap.gmail.com",
Port: 993,
Username: "notifications@example.com",
Password: os.Getenv("EMAIL_PASSWORD"),
UseTLS: true,
Mailbox: "INBOX",
})
// Fetch new emails as markdown files
emails, err := receiver.FetchNew(ctx, &imap.FetchOptions{
MarkAsRead: true,
Limit: 50,
})
for _, email := range emails {
// Email saved to /data/emails/inbox/{id}.md
processEmail(email.FilePath)
}
Production Considerations ¶
Security:
- Always use TLS (UseTLS: true) for SMTP
- Never commit credentials to version control
- Use app-specific passwords for Gmail
- Encrypt passwords before database storage (AES-256-GCM)
Configuration:
- Use Docker secrets in production
- Validate SMTP settings before saving
- Implement test email functionality
- Document required environment variables
Performance:
- Use async sending for non-critical emails
- Implement rate limiting for bulk operations
- Monitor queue depth and processing time
- Set appropriate timeouts
Related Packages ¶
- github.com/ftrinciante/gomail/provider/smtp - SMTP provider
- github.com/ftrinciante/gomail/queue/redis - Redis queue (planned)
- github.com/ftrinciante/gomail/provider/sendgrid - SendGrid (planned)
- github.com/ftrinciante/gomail/provider/ses - AWS SES (planned)
- github.com/ftrinciante/gomail/receiver/imap - IMAP receiver (planned)
Examples ¶
See the examples directory for complete working examples:
- examples/basic - Simple SMTP email
- examples/with_queue - Using Redis queue (planned)
- examples/with_templates - HTML template rendering (planned)
Support ¶
For issues, questions, or contributions, visit: https://github.com/ftrinciante/gomail
Example ¶
Example demonstrates basic email sending with plain text.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Configure SMTP provider
config := smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "your-password",
From: "sender@example.com",
UseTLS: true,
}
// Create SMTP provider
provider := smtp.New(&config)
// Create email client
client := gomail.NewClient(provider)
defer client.Close()
// Create message
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Hello from gomail!",
Body: "This is a plain text email sent using the gomail library.",
IsHTML: false,
}
// Send email
err := client.Send(context.Background(), msg)
if err != nil {
log.Fatalf("Failed to send email: %v", err)
}
fmt.Println("Email sent successfully")
}
Output:
Example (AttachmentAndInlineImage) ¶
Example_attachmentAndInlineImage demonstrates sending an email with both attachments and inline images.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "your-email@example.com",
Password: "your-password",
From: "your-email@example.com",
UseTLS: true,
})
// Create client
client := gomail.NewClient(provider)
defer client.Close()
// Create HTML body with inline image reference
htmlBody := `
<html>
<body>
<img src="cid:logo" alt="Company Logo" style="width: 200px;" />
<h1>Monthly Report</h1>
<p>Please find the monthly report attached.</p>
<p>Best regards,<br/>The Team</p>
</body>
</html>
`
// Create message with both attachment and inline image
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Monthly Report - January 2026",
Body: htmlBody,
IsHTML: true,
Attachments: []gomail.Attachment{
{
Filename: "report_january_2026.pdf",
Path: "./testdata/report.pdf",
},
},
InlineImages: []gomail.InlineImage{
{
CID: "logo",
Path: "./testdata/logo.png",
},
},
}
// Send email
if err := client.Send(context.Background(), msg); err != nil {
log.Printf("Failed to send email: %v", err)
return
}
fmt.Println("Email sent successfully with attachment and inline image")
}
Output:
Example (AttachmentFromFile) ¶
Example_attachmentFromFile demonstrates sending an email with a file attachment. This example requires a valid SMTP server and test file to run.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "your-email@example.com",
Password: "your-password",
From: "your-email@example.com",
UseTLS: true,
})
// Create client
client := gomail.NewClient(provider)
defer client.Close()
// Create message with file attachment
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Invoice Attached",
Body: "Please find the invoice attached.",
IsHTML: false,
Attachments: []gomail.Attachment{
{
Filename: "invoice.pdf",
Path: "./testdata/invoice.pdf",
},
},
}
// Send email
if err := client.Send(context.Background(), msg); err != nil {
log.Printf("Failed to send email: %v", err)
return
}
fmt.Println("Email sent successfully with attachment")
}
Output:
Example (AttachmentInMemory) ¶
Example_attachmentInMemory demonstrates sending an email with an in-memory attachment. This example requires a valid SMTP server to run.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "your-email@example.com",
Password: "your-password",
From: "your-email@example.com",
UseTLS: true,
})
// Create client
client := gomail.NewClient(provider)
defer client.Close()
// Generate CSV data in memory
csvData := []byte("Name,Email,Phone\nJohn Doe,john@example.com,555-1234\nJane Smith,jane@example.com,555-5678")
// Create message with in-memory attachment
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Contact List",
Body: "Please find the contact list attached.",
IsHTML: false,
Attachments: []gomail.Attachment{
{
Filename: "contacts.csv",
Content: csvData,
ContentType: "text/csv",
},
},
}
// Send email
if err := client.Send(context.Background(), msg); err != nil {
log.Printf("Failed to send email: %v", err)
return
}
fmt.Println("Email sent successfully with in-memory attachment")
}
Output:
Example (AttachmentValidation) ¶
Example_attachmentValidation demonstrates attachment validation.
package main
import (
"fmt"
"github.com/ftrinciante/gomail"
)
func main() {
// Create message with invalid attachment (no filename)
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Test",
Body: "Test",
Attachments: []gomail.Attachment{
{
// Missing Filename - will fail validation
Path: "./testdata/file.pdf",
},
},
}
// Validate will fail
err := msg.Validate()
if err != nil {
fmt.Println("Validation failed: filename is required")
}
}
Output:
Example (BulkEmailWithQueue) ¶
Example_bulkEmailWithQueue demonstrates sending bulk emails with retry logic.
package main
import (
"context"
"fmt"
"time"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
goredis "github.com/ftrinciante/gomail/queue/redis"
"github.com/redis/go-redis/v9"
)
func main() {
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
defer redisClient.Close()
queue := goredis.New(redisClient, goredis.Config{
QueueKey: "emails:bulk:outbox",
MaxRetries: 5, // More retries for bulk operations
RetryDelay: 2 * time.Minute,
})
defer queue.Close()
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
client := gomail.NewClient(
provider,
gomail.WithQueue(queue),
gomail.WithTemplates("./templates/*.html"),
)
defer client.Close()
ctx := context.Background()
// Start multiple queue processors for parallel processing
for i := 0; i < 3; i++ {
go client.ProcessQueue(ctx)
}
// Bulk send
users := []string{
"user1@example.com",
"user2@example.com",
"user3@example.com",
// ... more users
}
for _, email := range users {
client.SendFromTemplateAsync(
ctx,
"newsletter.html",
[]string{email},
"Monthly Newsletter",
map[string]string{
"Month": "June",
"Year": "2026",
},
)
}
fmt.Printf("Bulk newsletter sent to %d recipients\n", len(users))
}
Output:
Example (CcAndBcc) ¶
Example_ccAndBcc demonstrates sending email with CC and BCC recipients.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
config := smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "your-password",
From: "sender@example.com",
UseTLS: true,
}
provider := smtp.New(&config)
client := gomail.NewClient(provider)
defer client.Close()
// Create message with CC and BCC
msg := &gomail.Message{
To: []string{"primary@example.com"},
CC: []string{"cc1@example.com", "cc2@example.com"},
BCC: []string{"bcc@example.com"},
Subject: "Team Update",
Body: "This email is sent to primary recipient with CC and BCC.",
IsHTML: false,
}
err := client.Send(context.Background(), msg)
if err != nil {
log.Fatalf("Failed to send email with CC/BCC: %v", err)
}
fmt.Println("Email with CC and BCC sent successfully")
}
Output:
Example (CustomHeaders) ¶
Example_customHeaders demonstrates adding custom email headers.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
config := smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "your-password",
From: "sender@example.com",
UseTLS: true,
}
provider := smtp.New(&config)
client := gomail.NewClient(provider)
defer client.Close()
// Create message with custom headers
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Custom Headers Example",
Body: "This email includes custom headers.",
IsHTML: false,
ReplyTo: "support@example.com",
Headers: map[string]string{
"X-Priority": "1",
"X-Mailer": "gomail/0.1.0",
"X-Campaign-ID": "spring-2026",
},
}
err := client.Send(context.Background(), msg)
if err != nil {
log.Fatalf("Failed to send email with custom headers: %v", err)
}
fmt.Println("Email with custom headers sent successfully")
}
Output:
Example (Html) ¶
Example_html demonstrates sending an HTML email with formatting.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Configure SMTP provider
config := smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "your-password",
From: "sender@example.com",
UseTLS: true,
}
provider := smtp.New(&config)
client := gomail.NewClient(provider)
defer client.Close()
// Create HTML message
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Welcome to gomail!",
Body: `
<html>
<body>
<h1>Welcome!</h1>
<p>This is an <strong>HTML email</strong> with formatting.</p>
<ul>
<li>Rich text support</li>
<li>Inline styles</li>
<li>Images and links</li>
</ul>
</body>
</html>
`,
IsHTML: true,
}
err := client.Send(context.Background(), msg)
if err != nil {
log.Fatalf("Failed to send HTML email: %v", err)
}
fmt.Println("HTML email sent successfully")
}
Output:
Example (InlineImage) ¶
Example_inlineImage demonstrates sending an HTML email with an inline image.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "your-email@example.com",
Password: "your-password",
From: "your-email@example.com",
UseTLS: true,
})
// Create client
client := gomail.NewClient(provider)
defer client.Close()
// Create HTML body that references the inline image using cid:logo
htmlBody := `
<html>
<body>
<h1>Welcome to Our Service</h1>
<p>Here is our company logo:</p>
<img src="cid:logo" alt="Company Logo" />
<p>Thank you for choosing us!</p>
</body>
</html>
`
// Create message with inline image
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Welcome Email",
Body: htmlBody,
IsHTML: true,
InlineImages: []gomail.InlineImage{
{
CID: "logo",
Path: "./testdata/logo.png",
},
},
}
// Send email
if err := client.Send(context.Background(), msg); err != nil {
log.Printf("Failed to send email: %v", err)
return
}
fmt.Println("Email sent successfully with inline image")
}
Output:
Example (InlineImageInMemory) ¶
Example_inlineImageInMemory demonstrates sending an HTML email with an in-memory inline image.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "your-email@example.com",
Password: "your-password",
From: "your-email@example.com",
UseTLS: true,
})
// Create client
client := gomail.NewClient(provider)
defer client.Close()
// Generate a simple 1x1 PNG in memory (for demonstration)
// In real use, you would load or generate actual image data
pngData := []byte{
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, // PNG signature
// ... (minimal PNG data would go here)
}
// Create HTML body that references the inline image
htmlBody := `
<html>
<body>
<h1>Dynamic Image</h1>
<p>Here is a dynamically generated image:</p>
<img src="cid:dynamic" alt="Dynamic Image" />
</body>
</html>
`
// Create message with in-memory inline image
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Dynamic Content Email",
Body: htmlBody,
IsHTML: true,
InlineImages: []gomail.InlineImage{
{
CID: "dynamic",
Content: pngData,
ContentType: "image/png",
},
},
}
// Send email
if err := client.Send(context.Background(), msg); err != nil {
log.Printf("Failed to send email: %v", err)
return
}
fmt.Println("Email sent successfully with in-memory inline image")
}
Output:
Example (MonitoringQueueHealth) ¶
Example_monitoringQueueHealth demonstrates monitoring queue health while processing emails.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
goredis "github.com/ftrinciante/gomail/queue/redis"
"github.com/redis/go-redis/v9"
)
func main() {
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
defer redisClient.Close()
queue := goredis.New(redisClient, goredis.Config{
QueueKey: "emails:outbox",
})
defer queue.Close()
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
client := gomail.NewClient(
provider,
gomail.WithQueue(queue),
)
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
// Start processor
go client.ProcessQueue(ctx)
// Queue some messages
for i := 0; i < 5; i++ {
client.SendAsync(ctx, &gomail.Message{
To: []string{fmt.Sprintf("user%d@example.com", i)},
Subject: "Test",
Body: "Test body",
})
}
// Monitor queue health
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
health, err := queue.Health(ctx)
if err != nil {
log.Printf("Health check failed: %v", err)
continue
}
fmt.Printf("Queue Health - Size: %d, DLQ: %d, Processing: %d\n",
health.QueueSize, health.DLQSize, health.ProcessingCount)
// Alert if DLQ has messages
if health.DLQSize > 0 {
log.Printf("WARNING: %d messages in dead letter queue", health.DLQSize)
}
}
}
}
Output:
Example (MultipleAttachments) ¶
Example_multipleAttachments demonstrates sending an email with multiple attachments. This example requires a valid SMTP server and test files to run.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "your-email@example.com",
Password: "your-password",
From: "your-email@example.com",
UseTLS: true,
})
// Create client
client := gomail.NewClient(provider)
defer client.Close()
// Create message with multiple attachments
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Project Documents",
Body: "<h1>Project Documents</h1><p>Please find all project documents attached.</p>",
IsHTML: true,
Attachments: []gomail.Attachment{
{
Filename: "proposal.pdf",
Path: "./testdata/proposal.pdf",
},
{
Filename: "budget.xlsx",
Path: "./testdata/budget.xlsx",
},
{
Filename: "timeline.docx",
Path: "./testdata/timeline.docx",
},
},
}
// Send email
if err := client.Send(context.Background(), msg); err != nil {
log.Printf("Failed to send email: %v", err)
return
}
fmt.Println("Email sent successfully with multiple attachments")
}
Output:
Example (MultipleRecipients) ¶
Example_multipleRecipients demonstrates sending to multiple recipients.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
config := smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "your-password",
From: "sender@example.com",
UseTLS: true,
}
provider := smtp.New(&config)
client := gomail.NewClient(provider)
defer client.Close()
// Create message with multiple recipients
msg := &gomail.Message{
To: []string{
"user1@example.com",
"user2@example.com",
"user3@example.com",
},
Subject: "Team Announcement",
Body: "This message is sent to multiple recipients.",
IsHTML: false,
}
err := client.Send(context.Background(), msg)
if err != nil {
log.Fatalf("Failed to send to multiple recipients: %v", err)
}
fmt.Println("Email sent to multiple recipients successfully")
}
Output:
Example (QueueWithTemplates) ¶
Example_queueWithTemplates demonstrates combining queue and templates for async templated emails.
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
goredis "github.com/ftrinciante/gomail/queue/redis"
"github.com/redis/go-redis/v9"
)
func main() {
// Create Redis client
redisClient := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
defer redisClient.Close()
// Create queue
queue := goredis.New(redisClient, goredis.Config{
QueueKey: "emails:outbox",
MaxRetries: 3,
RetryDelay: 5 * time.Minute,
})
defer queue.Close()
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
// Create client with BOTH queue and templates
client := gomail.NewClient(
provider,
gomail.WithQueue(queue),
gomail.WithTemplates("./templates/*.html"),
)
defer client.Close()
// Start queue processor in background
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
go func() {
if err := client.ProcessQueue(ctx); err != nil {
log.Printf("Queue processor: %v", err)
}
}()
// Send templated emails asynchronously
for i := 1; i <= 10; i++ {
err := client.SendFromTemplateAsync(
ctx,
"welcome.html",
[]string{fmt.Sprintf("user%d@example.com", i)},
"Welcome to Our Service!",
map[string]interface{}{
"Name": fmt.Sprintf("User %d", i),
"Number": i,
},
)
if err != nil {
log.Printf("Failed to queue email %d: %v", i, err)
}
}
fmt.Println("10 templated emails queued for async sending")
}
Output:
Example (Templates) ¶
Example_templates demonstrates sending emails with HTML templates.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create SMTP provider
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
// Create client with templates
// Templates are loaded from the glob pattern
client := gomail.NewClient(
provider,
gomail.WithTemplates("./templates/*.html"),
)
defer client.Close()
// Template data
data := map[string]interface{}{
"Name": "John Doe",
"Product": "Premium Plan",
"Price": 99,
"Discount": 10,
}
// Send using template
err := client.SendFromTemplate(
context.Background(),
"welcome.html",
[]string{"john@example.com"},
"Welcome to Our Service!",
data,
)
if err != nil {
log.Fatalf("Failed to send templated email: %v", err)
}
fmt.Println("Templated email sent")
}
Output:
Example (TemplatesAsync) ¶
Example_templatesAsync demonstrates async template email sending.
package main
import (
"context"
"fmt"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// This requires queue support
// See queue/redis examples for full implementation
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
client := gomail.NewClient(
provider,
gomail.WithTemplates("./templates/*.html"),
// gomail.WithQueue(queue), // Add queue for async
)
defer client.Close()
// Send template async (requires queue)
err := client.SendFromTemplateAsync(
context.Background(),
"welcome.html",
[]string{"user@example.com"},
"Welcome!",
map[string]string{"Name": "Charlie"},
)
if err != nil {
log.Printf("Note: Async sending requires queue configuration")
}
fmt.Println("Template queued for async sending")
}
Output:
Example (TemplatesCustomFunctions) ¶
Example_templatesCustomFunctions demonstrates using custom template functions.
package main
import (
"fmt"
)
func main() {
// Create a temporary template file for demonstration
tmplContent := `
<html>
<body>
<h1>Invoice for {{.Name}}</h1>
<p>Product: {{.Product}}</p>
<p>Price: ${{.Price}}</p>
<p>Discount: ${{.Discount}}</p>
<p>Tax (10%): ${{div (mul .Price 10) 100}}</p>
<p>Total: ${{sub (add .Price (div (mul .Price 10) 100)) .Discount}}</p>
</body>
</html>
`
// Custom functions available: add, sub, mul, div
// Example: {{add 5 10}} = 15
// Example: {{sub 100 20}} = 80
// Example: {{mul 10 5}} = 50
// Example: {{div 100 4}} = 25
_ = tmplContent // Use in actual implementation
fmt.Println("Template with custom functions")
}
Output:
Example (TemplatesFromFiles) ¶
Example_templatesFromFiles demonstrates loading templates from files.
package main
import (
"context"
"fmt"
"os"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
// Create temporary template directory
os.MkdirAll("./templates", 0755)
defer os.RemoveAll("./templates")
// Create welcome template
welcomeHTML := `
<html>
<body>
<h1>Welcome {{.Name}}!</h1>
<p>Thank you for joining us.</p>
</body>
</html>
`
os.WriteFile("./templates/welcome.html", []byte(welcomeHTML), 0644)
// Create notification template
notificationHTML := `
<html>
<body>
<h1>Notification</h1>
<p>{{.Message}}</p>
</body>
</html>
`
os.WriteFile("./templates/notification.html", []byte(notificationHTML), 0644)
// Create client with templates
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
client := gomail.NewClient(
provider,
gomail.WithTemplates("./templates/*.html"),
)
defer client.Close()
// Send welcome email
client.SendFromTemplate(
context.Background(),
"welcome.html",
[]string{"newuser@example.com"},
"Welcome!",
map[string]string{"Name": "Bob"},
)
// Send notification email
client.SendFromTemplate(
context.Background(),
"notification.html",
[]string{"user@example.com"},
"New Notification",
map[string]string{"Message": "You have a new message"},
)
fmt.Println("Emails sent from file templates")
}
Output:
Example (TemplatesInline) ¶
Example_templatesInline demonstrates inline template definition.
package main
import (
"context"
"fmt"
"html/template"
"log"
"github.com/ftrinciante/gomail"
"github.com/ftrinciante/gomail/provider/smtp"
)
func main() {
provider := smtp.New(&smtp.Config{
Host: "smtp.example.com",
Port: 587,
Username: "user@example.com",
Password: "password",
From: "noreply@example.com",
UseTLS: true,
})
client := gomail.NewClient(provider)
defer client.Close()
// Create inline template
tmpl := template.Must(template.New("welcome").Parse(`
<html>
<body>
<h1>Hello {{.Name}}!</h1>
<p>Welcome to our service.</p>
</body>
</html>
`))
// Set templates directly
client.SetTemplates(tmpl)
// Send using template
err := client.SendFromTemplate(
context.Background(),
"welcome",
[]string{"user@example.com"},
"Welcome!",
map[string]string{"Name": "Alice"},
)
if err != nil {
log.Fatalf("Failed to send: %v", err)
}
fmt.Println("Inline templated email sent")
}
Output:
Example (Validation) ¶
Example_validation demonstrates message validation before sending.
package main
import (
"fmt"
"log"
"github.com/ftrinciante/gomail"
)
func main() {
// Create a message with validation
msg := &gomail.Message{
To: []string{"recipient@example.com"},
Subject: "Validation Example",
Body: "Testing email validation.",
IsHTML: false,
}
// Validate the message
err := msg.Validate()
if err != nil {
log.Fatalf("Message validation failed: %v", err)
}
fmt.Println("Message validation passed")
// Example of invalid email
invalidMsg := &gomail.Message{
To: []string{"invalid-email"},
Subject: "Test",
Body: "Body",
}
err = invalidMsg.Validate()
if err != nil {
fmt.Println("Invalid message detected")
}
}
Output:
Index ¶
- func SaveEmailAsMarkdown(email *ReceivedEmail, outputDir string) error
- func ValidateEmail(email string) error
- type Attachment
- type AttachmentInfo
- type Client
- func (c *Client) Close() error
- func (c *Client) ProcessQueue(ctx context.Context) error
- func (c *Client) Send(ctx context.Context, msg *Message) error
- func (c *Client) SendAsync(ctx context.Context, msg *Message) error
- func (c *Client) SendFromTemplate(ctx context.Context, templateName string, to []string, subject string, ...) error
- func (c *Client) SendFromTemplateAsync(ctx context.Context, templateName string, to []string, subject string, ...) error
- func (c *Client) SetTemplates(tmpl *template.Template)
- type ClientOption
- type EmailProcessor
- type EmailSender
- type FetchOptions
- type InlineImage
- type Logger
- type Message
- type MetricsCollector
- type NoOpLogger
- func (n *NoOpLogger) Debug(ctx context.Context, msg string, fields map[string]interface{})
- func (n *NoOpLogger) Error(ctx context.Context, msg string, fields map[string]interface{})
- func (n *NoOpLogger) Info(ctx context.Context, msg string, fields map[string]interface{})
- func (n *NoOpLogger) Warn(ctx context.Context, msg string, fields map[string]interface{})
- type NoOpMetricsCollector
- func (n *NoOpMetricsCollector) RecordQueue(ctx context.Context, operation, queueName string, success bool)
- func (n *NoOpMetricsCollector) RecordSend(ctx context.Context, provider string, success bool, duration time.Duration)
- func (n *NoOpMetricsCollector) SetQueueLength(ctx context.Context, queueName string, length int64)
- type NoOpTracer
- type ObservabilityConfig
- type Queue
- type QueueError
- type ReceivedEmail
- type Receiver
- type ReceiverConfig
- type SendError
- type TemplateError
- type Tracer
- type ValidationError
Examples ¶
- Package
- Package (AttachmentAndInlineImage)
- Package (AttachmentFromFile)
- Package (AttachmentInMemory)
- Package (AttachmentValidation)
- Package (BulkEmailWithQueue)
- Package (CcAndBcc)
- Package (CustomHeaders)
- Package (Html)
- Package (InlineImage)
- Package (InlineImageInMemory)
- Package (MonitoringQueueHealth)
- Package (MultipleAttachments)
- Package (MultipleRecipients)
- Package (QueueWithTemplates)
- Package (Templates)
- Package (TemplatesAsync)
- Package (TemplatesCustomFunctions)
- Package (TemplatesFromFiles)
- Package (TemplatesInline)
- Package (Validation)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SaveEmailAsMarkdown ¶
func SaveEmailAsMarkdown(email *ReceivedEmail, outputDir string) error
SaveEmailAsMarkdown saves a received email as a markdown file with YAML frontmatter. The markdown file includes all email metadata, body content, and attachment information.
func ValidateEmail ¶
ValidateEmail validates an email address format using RFC 5322 parsing and additional regex validation.
Types ¶
type Attachment ¶
Attachment represents a file attachment to be sent with an email. Attachments can be loaded from disk (Path) or provided as in-memory bytes (Content). Only one of Path or Content should be set.
func (*Attachment) GetContent ¶
func (a *Attachment) GetContent() ([]byte, error)
GetContent returns the attachment content, loading from Path if necessary.
func (*Attachment) GetContentType ¶
func (a *Attachment) GetContentType() string
GetContentType returns the MIME type of the attachment. If ContentType is set, it returns that value. Otherwise, it attempts to detect the MIME type from the filename or content.
func (*Attachment) Validate ¶
func (a *Attachment) Validate() error
Validate checks if the attachment has valid configuration.
type AttachmentInfo ¶
type AttachmentInfo struct {
Filename string
Path string
ContentType string
ContentID string
Data []byte
Size int64
IsInline bool
}
AttachmentInfo contains metadata about an email attachment.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is the main email client that orchestrates sending emails.
func NewClient ¶
func NewClient(provider EmailSender, opts ...ClientOption) *Client
NewClient creates a new email client with the specified provider and options.
func (*Client) ProcessQueue ¶
ProcessQueue starts processing messages from the queue. This should be run in a goroutine. It will block until the context is canceled.
func (*Client) SendAsync ¶
SendAsync queues an email message for asynchronous sending. Requires a queue to be configured via WithQueue option.
func (*Client) SendFromTemplate ¶
func (c *Client) SendFromTemplate(ctx context.Context, templateName string, to []string, subject string, data interface{}) error
SendFromTemplate renders an email template with the provided data and sends it.
func (*Client) SendFromTemplateAsync ¶
func (c *Client) SendFromTemplateAsync(ctx context.Context, templateName string, to []string, subject string, data interface{}) error
SendFromTemplateAsync queues an email rendered from a template.
func (*Client) SetTemplates ¶
SetTemplates sets the template instance directly (useful for testing).
type ClientOption ¶
type ClientOption func(*Client)
ClientOption is a functional option for configuring the Client.
func WithQueue ¶
func WithQueue(queue Queue) ClientOption
WithQueue configures the client to use a queue for async sending.
func WithTemplates ¶
func WithTemplates(pattern string) ClientOption
WithTemplates loads email templates from the specified glob pattern. Example: "./templates/*.html"
type EmailProcessor ¶
type EmailProcessor func(*ReceivedEmail) error
EmailProcessor is a callback function for processing received emails.
type EmailSender ¶
EmailSender is the interface that email providers must implement.
type FetchOptions ¶
type FetchOptions struct {
// Since only fetches emails received after this date
Since *time.Time
// Before only fetches emails received before this date
Before *time.Time
// Folder specifies which mailbox/folder to fetch from (default: INBOX)
Folder string
// AttachmentDir is where to save attachments
AttachmentDir string
// MarkdownDir is where to save markdown files
MarkdownDir string
// Limit restricts the number of emails to fetch (0 = no limit)
Limit int
// MarkAsRead marks fetched emails as read
MarkAsRead bool
// Unseen only fetches unread emails
Unseen bool
// SaveAttachments saves attachments to disk
SaveAttachments bool
// SaveToMarkdown saves each email as a markdown file
SaveToMarkdown bool
}
FetchOptions configures how emails are fetched from the mail server.
type InlineImage ¶
InlineImage represents an inline image to be embedded in HTML emails using Content-ID (CID). Inline images are referenced in HTML using cid:<CID>, e.g., <img src="cid:logo">.
func (*InlineImage) GetContent ¶
func (i *InlineImage) GetContent() ([]byte, error)
GetContent returns the inline image content, loading from Path if necessary.
func (*InlineImage) GetContentType ¶
func (i *InlineImage) GetContentType() string
GetContentType returns the MIME type of the inline image. If ContentType is set, it returns that value. Otherwise, it attempts to detect the MIME type from the filename or content.
func (*InlineImage) Validate ¶
func (i *InlineImage) Validate() error
Validate checks if the inline image has valid configuration.
type Logger ¶
type Logger interface {
// Debug logs a debug-level message with structured fields.
Debug(ctx context.Context, msg string, fields map[string]interface{})
// Info logs an info-level message with structured fields.
Info(ctx context.Context, msg string, fields map[string]interface{})
// Warn logs a warning-level message with structured fields.
Warn(ctx context.Context, msg string, fields map[string]interface{})
// Error logs an error-level message with structured fields.
Error(ctx context.Context, msg string, fields map[string]interface{})
}
Logger defines an interface for structured logging. Implementations can integrate with zap, logrus, zerolog, or standard log package. This is a v1.0.0 interface - implementations will be provided in future versions.
Example zap implementation:
type ZapLogger struct {
logger *zap.Logger
}
func (l *ZapLogger) Debug(ctx context.Context, msg string, fields map[string]interface{}) {
l.logger.Debug(msg, zapFields(fields)...)
}
type Message ¶
type Message struct {
Headers map[string]string
ReplyTo string
From string
Subject string
Body string
BCC []string
Attachments []Attachment
InlineImages []InlineImage
CC []string
To []string
RetryCount int
MaxRetries int
IsHTML bool
}
Message represents an email message to be sent.
func (*Message) AllRecipients ¶
AllRecipients returns all recipient addresses (To, CC, BCC) combined.
type MetricsCollector ¶
type MetricsCollector interface {
// RecordSend records an email send operation.
// provider: SMTP provider name (smtp, sendgrid, ses, etc.)
// success: whether the send was successful
// duration: time taken to send the email
RecordSend(ctx context.Context, provider string, success bool, duration time.Duration)
// RecordQueue records queue operation metrics.
// operation: enqueue, dequeue, retry, dlq
// queueName: name of the queue
// success: whether the operation was successful
RecordQueue(ctx context.Context, operation, queueName string, success bool)
// SetQueueLength sets the current queue length gauge.
// queueName: name of the queue
// length: current number of items in the queue
SetQueueLength(ctx context.Context, queueName string, length int64)
}
MetricsCollector defines an interface for collecting email metrics. Implementations can integrate with Prometheus, StatsD, or other monitoring systems. This is a v1.0.0 interface - implementations will be provided in future versions.
Example Prometheus implementation:
type PrometheusCollector struct {
sendTotal *prometheus.CounterVec
sendDuration *prometheus.HistogramVec
queueLength *prometheus.GaugeVec
}
func (c *PrometheusCollector) RecordSend(ctx context.Context, provider string, success bool, duration time.Duration) {
status := "success"
if !success {
status = "failure"
}
c.sendTotal.WithLabelValues(provider, status).Inc()
c.sendDuration.WithLabelValues(provider).Observe(duration.Seconds())
}
type NoOpLogger ¶
type NoOpLogger struct{}
NoOpLogger is a no-op implementation of Logger. Used as default when no logger is configured.
func (*NoOpLogger) Debug ¶
func (n *NoOpLogger) Debug(ctx context.Context, msg string, fields map[string]interface{})
Debug is a no-op implementation that does nothing.
func (*NoOpLogger) Error ¶
func (n *NoOpLogger) Error(ctx context.Context, msg string, fields map[string]interface{})
Error is a no-op implementation that does nothing.
type NoOpMetricsCollector ¶
type NoOpMetricsCollector struct{}
NoOpMetricsCollector is a no-op implementation of MetricsCollector. Used as default when no metrics collector is configured.
func (*NoOpMetricsCollector) RecordQueue ¶
func (n *NoOpMetricsCollector) RecordQueue(ctx context.Context, operation, queueName string, success bool)
RecordQueue is a no-op implementation that does nothing.
func (*NoOpMetricsCollector) RecordSend ¶
func (n *NoOpMetricsCollector) RecordSend(ctx context.Context, provider string, success bool, duration time.Duration)
RecordSend is a no-op implementation that does nothing.
func (*NoOpMetricsCollector) SetQueueLength ¶
func (n *NoOpMetricsCollector) SetQueueLength(ctx context.Context, queueName string, length int64)
SetQueueLength is a no-op implementation that does nothing.
type NoOpTracer ¶
type NoOpTracer struct{}
NoOpTracer is a no-op implementation of Tracer. Used as default when no tracer is configured.
func (*NoOpTracer) AddEvent ¶
func (n *NoOpTracer) AddEvent(ctx context.Context, name string, attrs map[string]interface{})
AddEvent is a no-op implementation that does nothing.
func (*NoOpTracer) RecordError ¶
func (n *NoOpTracer) RecordError(ctx context.Context, err error)
RecordError is a no-op implementation that does nothing.
type ObservabilityConfig ¶
type ObservabilityConfig struct {
// Metrics collector for email operations (optional)
Metrics MetricsCollector
// Logger for structured logging (optional)
Logger Logger
// Tracer for distributed tracing (optional)
Tracer Tracer
}
ObservabilityConfig holds observability component implementations. Set these on the Client to enable metrics, logging, and tracing.
Example usage:
client := gomail.NewClient(provider)
client.SetObservability(gomail.ObservabilityConfig{
Metrics: &myPrometheusCollector,
Logger: &myZapLogger,
Tracer: &myOTelTracer,
})
type Queue ¶
type Queue interface {
Enqueue(ctx context.Context, msg *Message) error
Dequeue(ctx context.Context) (*Message, error)
Close() error
}
Queue is the interface for email queue implementations.
type QueueError ¶
QueueError represents an error that occurred during queue operations.
func (*QueueError) Error ¶
func (e *QueueError) Error() string
func (*QueueError) Unwrap ¶
func (e *QueueError) Unwrap() error
type ReceivedEmail ¶
type ReceivedEmail struct {
ReceivedAt time.Time
Date time.Time
Headers map[string][]string
InReplyTo string
Priority string
RawHeaders string
FilePath string
MessageID string
BodyText string
Body string
ID string
From string
FromName string
ReplyTo string
Subject string
CC []string
BCC []string
Flags []string
To []string
References []string
Labels []string
Attachments []AttachmentInfo
UID uint32
IsHTML bool
}
ReceivedEmail represents an email message that has been received and processed. This is separate from Message which is used for sending emails.
func LoadEmailFromMarkdown ¶
func LoadEmailFromMarkdown(filePath string) (*ReceivedEmail, error)
LoadEmailFromMarkdown loads an email from a markdown file. This is useful for re-processing emails that were previously saved.
type Receiver ¶
type Receiver interface {
// Connect establishes connection to the mail server
Connect(ctx context.Context) error
// Disconnect closes the connection to the mail server
Disconnect() error
// FetchNew fetches new/unread emails based on options
FetchNew(ctx context.Context, opts *FetchOptions) ([]*ReceivedEmail, error)
// FetchAll fetches all emails based on options
FetchAll(ctx context.Context, opts *FetchOptions) ([]*ReceivedEmail, error)
// MarkAsRead marks specified emails as read
MarkAsRead(ctx context.Context, uids []uint32) error
// Move moves emails to another folder
Move(ctx context.Context, uids []uint32, destFolder string) error
// Delete deletes specified emails
Delete(ctx context.Context, uids []uint32) error
// Stream monitors for new emails and calls handler for each new email
Stream(ctx context.Context, handler func(*ReceivedEmail) error) error
}
Receiver is the interface for receiving and fetching emails.
type ReceiverConfig ¶
type ReceiverConfig struct {
// OutputDir is the base directory for saving emails
OutputDir string
// AttachmentDir is the directory for saving attachments
AttachmentDir string
// SaveAttachments controls whether to save attachments to disk
SaveAttachments bool
// SaveToMarkdown controls whether to save emails as markdown files
SaveToMarkdown bool
}
ReceiverConfig contains common configuration for email receivers.
type TemplateError ¶
TemplateError represents an error that occurred during template rendering.
func (*TemplateError) Error ¶
func (e *TemplateError) Error() string
func (*TemplateError) Unwrap ¶
func (e *TemplateError) Unwrap() error
type Tracer ¶
type Tracer interface {
// StartSpan starts a new tracing span.
// name: operation name (e.g., "smtp.send", "queue.enqueue")
// attrs: span attributes (provider, recipient count, etc.)
// Returns a new context and a function to end the span.
StartSpan(ctx context.Context, name string, attrs map[string]interface{}) (context.Context, func())
// AddEvent adds an event to the current span.
// name: event name (e.g., "authentication_success", "tls_handshake")
// attrs: event attributes
AddEvent(ctx context.Context, name string, attrs map[string]interface{})
// RecordError records an error in the current span.
RecordError(ctx context.Context, err error)
}
Tracer defines an interface for distributed tracing. Implementations can integrate with OpenTelemetry, Jaeger, Zipkin, or AWS X-Ray. This is a v1.0.0 interface - implementations will be provided in future versions.
Example OpenTelemetry implementation:
type OTelTracer struct {
tracer trace.Tracer
}
func (t *OTelTracer) StartSpan(ctx context.Context, name string, attrs map[string]interface{}) (context.Context, func()) {
ctx, span := t.tracer.Start(ctx, name)
for k, v := range attrs {
span.SetAttributes(attribute.String(k, fmt.Sprint(v)))
}
return ctx, func() { span.End() }
}
type ValidationError ¶
ValidationError represents an email validation error.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
basic
command
|
|
|
Package provider defines the interface for email providers.
|
Package provider defines the interface for email providers. |
|
sendgrid
Package sendgrid provides a SendGrid API-based email provider for the gomail library.
|
Package sendgrid provides a SendGrid API-based email provider for the gomail library. |
|
ses
Package ses provides an AWS SES (Simple Email Service) provider for the gomail library.
|
Package ses provides an AWS SES (Simple Email Service) provider for the gomail library. |
|
smtp
Package smtp provides an SMTP email provider implementation for gomail.
|
Package smtp provides an SMTP email provider implementation for gomail. |
|
queue
|
|
|
redis
Package redis provides a Redis-backed queue implementation for gomail.
|
Package redis provides a Redis-backed queue implementation for gomail. |
|
receiver
|
|
|
imap
Package imap provides an IMAP-based email receiver implementation for the gomail library.
|
Package imap provides an IMAP-based email receiver implementation for the gomail library. |