Skip to content

Latest commit

 

History

167 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

goemail

goemail

Production-ready email package for Go with SMTP support, templating, retries, connection pooling, DKIM signing, and provider adapters for SendGrid, Mailgun, and AWS SES.

Go Reference Go Report Card Go Version CI GitHub tag License: MIT codecov

Documentation · API Reference · Changelog

Why goemail?

net/smtp gets you a connection and a DATA command. Everything past that — the parts that turn "I can send one email" into "I can run this in production" — is what goemail provides:

Capability goemail Raw net/smtp
Retry with exponential backoff ✓ You build it
Connection pooling for high throughput ✓ You build it
Rate limiting ✓ You build it
DKIM signing (RSA-SHA256 / Ed25519-SHA256) ✓ You build it
HTML templates, attachments, batch sending ✓ You build it
Provider HTTP adapters (SendGrid, Mailgun, AWS SES) ✓ You build it
Middleware (logging, metrics, hooks, recovery) ✓ You build it
Header injection protection, address validation ✓ You build it
Async sending with a buffered worker queue ✓ You build it

goemail isn't a replacement for net/smtp — the default Sender is built on top of it. It's the reliability and delivery layer around raw SMTP that most services sending email end up writing themselves, packaged once and kept production-safe by default.

✨ Features

  • 📤 SMTP Support - TLS/STARTTLS, authentication
  • 📝 Templating - Go templates for HTML and plain text emails
  • 📎 Attachments - Send files with proper MIME encoding
  • 🔄 Retry Logic - Exponential backoff with configurable attempts
  • ⚡ Rate Limiting - Built-in rate limiting to prevent overwhelming servers
  • 🔍 Logging Interface - Bring your own logger (slog, zap, logrus, etc.)
  • 🧪 Testing - Mock sender for easy testing
  • 🎯 Builder API - Fluent, chainable API for constructing emails
  • 🔒 Security - Email header injection protection, address validation
  • 🎨 Batch Sending - Send multiple emails concurrently with limits
  • 🔗 Connection Pooling - Reuse SMTP connections for high-throughput sending
  • 🔌 Middleware Pipeline - Composable middleware for logging, metrics, recovery, and hooks
  • 🔀 Async Sending - Background queue worker with configurable workers and buffer
  • 🌐 Provider Adapters - SendGrid, Mailgun, and AWS SES via HTTP APIs (providers modules)
  • ✍️ DKIM Signing - Sign outgoing emails with RSA-SHA256 or Ed25519-SHA256 (RFC 6376/8463)
  • 📊 Context Support - Full context.Context integration for timeouts and cancellation

📦 Installation

go get github.com/KARTIKrocks/goemail

🚀 Quick Start

Basic Email

package main

import (
    "context"
    "log"
    "time"

    "github.com/KARTIKrocks/goemail"
)

func main() {
    // Configure SMTP
    config := email.SMTPConfig{
        Host:     "smtp.gmail.com",
        Port:     587,
        Username: "your-email@gmail.com",
        Password: "your-app-password",
        From:     "your-email@gmail.com",
        UseTLS:   true,
    }

    // Create sender and mailer
    sender, err := email.NewSMTPSender(config)
    if err != nil {
        log.Fatal(err)
    }
    mailer := email.NewMailer(sender, config.From)
    defer mailer.Close()

    // Send email
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()

    err = mailer.Send(ctx,
        []string{"recipient@example.com"},
        "Hello!",
        "This is a test email.",
    )

    if err != nil {
        log.Fatal(err)
    }
}

HTML Email with Template

// Create template
tmpl := email.NewTemplate("welcome")
tmpl.SetSubject("Welcome {{.Name}}!")

tmpl.SetHTMLTemplate(`
<!DOCTYPE html>
<html>
<body>
    <h1>Hello {{.Name}}!</h1>
    <p>Welcome to our service. Click below to get started:</p>
    <a href="{{.VerifyLink}}">Verify Email</a>
</body>
</html>
`)

// Register template
mailer.RegisterTemplate("welcome", tmpl)

// Send using template
data := map[string]any{
    "Name":       "John Doe",
    "VerifyLink": "https://example.com/verify/abc123",
}

err := mailer.SendTemplate(ctx, []string{"john@example.com"}, "welcome", data)

With Attachments

// Read file
pdfData, _ := os.ReadFile("invoice.pdf")

email := email.NewEmail().
    SetFrom("billing@example.com").
    AddTo("customer@example.com").
    SetSubject("Your Invoice").
    SetBody("Please find your invoice attached.").
    AddAttachment("invoice.pdf", "application/pdf", pdfData)

err := mailer.SendEmail(ctx, email)

📖 Documentation

Full guides live at kartikrocks.github.io/goemail:

Guide Covers
Getting Started Install and send your first email
SMTP & Configuration SMTPConfig, provider relay settings (Gmail, SendGrid, SES, Mailgun), connection pooling
Mailer Send, SendHTML, SendTemplate, batch sending, Close
Email Builder The fluent Email builder API
Templates Registering and rendering HTML/text templates
Middleware Logging, metrics, recovery, and hooks middleware
Async Sending Buffered worker queue for non-blocking sends
Reliability Retry logic, rate limiting, context timeouts
DKIM Signing RSA-SHA256 / Ed25519-SHA256 signing (RFC 6376/8463)
Provider Adapters SendGrid, Mailgun, and AWS SES via HTTP APIs, plus the OpenTelemetry tracing middleware
Webhooks Parsing provider delivery-event webhooks
Metrics The MetricsCollector interface and a worked Prometheus example
Logging Bringing your own logger
Security Credential handling, header injection protection, address validation, App Passwords
Testing Unit-testing code that sends email with MockSender

Exact type signatures are generated from source on pkg.go.dev.

Runnable programs are in examples/ — basic, template, attachment, batch, pool, middleware, and testing.

🔒 Security

goemail signs and sends outbound mail with credentials and key material you provide, so header/CRLF injection, credential handling, and DKIM signing are treated as part of the API, not an afterthought. v0.2.0 (CHANGELOG.md) enforced a minimum of TLS 1.2 on STARTTLS connections and closed several CRLF/header-injection gaps that v0.1.0 did not catch.

Every push and pull request to main is scanned by CodeQL, with a full re-scan weekly to catch newly published query patterns against unchanged code. govulncheck gates every merge on advisories that are reachable from this code's call graph. Both run separately against each of the five modules — the root package and the four providers/* sub-modules — because a scan started from the root stops at the nested go.mod boundaries and would miss the providers' own dependency trees. Dependabot tracks updates across all five modules, the docs site, and the GitHub Actions themselves.

See SECURITY.md for supported versions, what is in scope, and how to report a vulnerability privately.

📝 License

MIT

🤝 Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

About

A batteries-included Go library for sending email — SMTP, templates, attachments, async queue, middleware, DKIM, and pluggable providers.

Topics

Resources

Contributing

Security policy

Stars

5 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages