A secure, modern Go library for sending emails through Gmail's SMTP service using OAuth 2.0 authentication. Built with security-first principles and compliance with Google's modern authentication requirements.
🔐 Security First
- OAuth 2.0 SASL XOAUTH2 authentication (Google-recommended)
- Optional App Password support (build-tag gated for personal accounts)
- Mandatory TLS encryption (STARTTLS on port 587 or SMTPS on port 465)
- Automatic credential redaction in logs and error messages
- Built-in security auditing with
gosecandgovulncheckintegration
📧 Rich Email Support
- HTML and plain text email bodies
- File attachments with automatic MIME type detection
- Inline images and embedded content
- Custom headers and email priorities
- Batch sending with per-message error handling
🛡️ Production Ready
- Concurrency-safe client with automatic token refresh
- Comprehensive error handling and validation
- Extensive test coverage (>80%)
- Security-focused logging with sensitive data protection
- Context support for timeouts and cancellation
🔧 Developer Friendly
- Simple, intuitive builder pattern API
- Comprehensive examples and documentation
- CLI tool for testing and automation
- Functional options for configuration
- Compatible with Go 1.22+
go get github.com/RezaArani/RAmailpackage main
import (
"context"
"log"
"github.com/RezaArani/RAmail/ramail"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
func main() {
// Setup OAuth 2.0 configuration
config := oauth2.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
Scopes: []string{"https://www.googleapis.com/auth/gmail.send"},
Endpoint: google.Endpoint,
}
// Your OAuth 2.0 token (see examples/ for how to obtain)
token := &oauth2.Token{
AccessToken: "your-access-token",
RefreshToken: "your-refresh-token",
// ... other token fields
}
// Create client
client, err := ramail.NewOAuth2Client(config, token)
if err != nil {
log.Fatal(err)
}
// Build and send email
message := ramail.NewMessage().
From("sender@gmail.com", "Your Name").
To("recipient@example.com", "Recipient Name").
Subject("Hello from RAmail!").
TextBody("This is a test email.").
HTMLBody("<p>This is a <strong>test email</strong>.</p>")
ctx := context.Background()
if err := client.Send(ctx, message); err != nil {
log.Fatal(err)
}
log.Println("Email sent successfully! 📧")
}The examples/ directory contains practical examples:
- OAuth Device Flow - Perfect for headless servers
- Simple Email - Basic email sending
- Attachments - File attachments and inline images
- App Password - Legacy authentication (build-tag gated)
# 1. Get OAuth credentials from Google Cloud Console
# 2. Run device flow to get token
cd examples/oauth-device-flow
go run main.go credentials.json
# 3. Send a test email
cd ../simple
go run main.go ../credentials.json ../token.jsonOAuth 2.0 is the secure, Google-recommended authentication method:
client, err := ramail.NewOAuth2Client(config, token)Advantages:
- ✅ Highest security standard
- ✅ Automatic token refresh
- ✅ Works with all Gmail account types
- ✅ Future-proof (Google's direction)
For personal Gmail accounts with 2-step verification:
// Only available when built with: go build -tags app_password
client, err := ramail.NewAppPasswordClient("user@gmail.com", "app-password")export GOOGLE_CLIENT_ID="your-google-client-id"
export GOOGLE_CLIENT_SECRET="your-google-client-secret"
export GOOGLE_CREDENTIALS_FILE="/path/to/credentials.json"
export GOOGLE_TOKEN_FILE="/path/to/token.json"client, err := ramail.NewOAuth2Client(
config,
token,
ramail.WithTimeout(45*time.Second),
ramail.WithTLSConfig(&tls.Config{MinVersion: tls.VersionTLS13}),
ramail.WithSMTPS(), // Use SMTPS instead of STARTTLS
)message := ramail.NewMessage().
From("sender@gmail.com", "Sender Name").
To("user1@example.com", "User One").
Cc("user2@example.com", "User Two").
Bcc("user3@example.com", "User Three").
ReplyTo("noreply@example.com", "No Reply").
Subject("Advanced Email").
TextBody("Plain text version").
HTMLBody("<p>Rich <strong>HTML</strong> content</p>").
Priority(ramail.PriorityHigh).
Header("X-Custom-Header", "Custom Value")
// Add attachments
data, _ := os.ReadFile("document.pdf")
message.AttachFile("document.pdf", "application/pdf", data)
// Add inline images
logoData, _ := os.ReadFile("logo.png")
message.InlineFile("logo", "logo.png", "image/png", logoData)RAmail includes a powerful CLI tool for sending emails:
go install github.com/RezaArani/RAmail/cmd/ramail-cli@latest# Send simple email
echo '{
"from": {"email": "sender@gmail.com"},
"to": [{"email": "recipient@example.com"}],
"subject": "CLI Test",
"text_body": "Hello from CLI!"
}' | ramail-cli -credentials credentials.json -token token.json
# Send from YAML file
cat email.yaml | ramail-cli -credentials creds.json -token token.json -format yaml
# Send with attachments
echo '{
"from": {"email": "sender@gmail.com"},
"to": [{"email": "recipient@example.com"}],
"subject": "Document",
"attachments": [{"filename": "report.pdf", "file_path": "./report.pdf"}]
}' | ramail-cli -credentials creds.json -token token.jsonaudit := ramail.AuditClientSecurity(client, ramail.DefaultSecurityConfig())
if audit.HasCriticalIssues() {
log.Fatal("Critical security issues found")
}
audit.PrintReport()logger := ramail.NewSecureLogger(ramail.DefaultSecurityConfig())
logger.Info("Token: %s", ramail.RedactToken(token)) // Automatically redactederr := ramail.ValidateTLSConfig(tlsConfig, ramail.DefaultSecurityConfig())
if err != nil {
log.Printf("TLS configuration issue: %v", err)
}- Personal Gmail: 500 emails/day
- Google Workspace: 2,000 emails/day
- Rate Limiting: ~100 emails per batch
For better deliverability, configure your domain's DNS:
SPF Record:
v=spf1 include:_spf.google.com ~all
DMARC Record:
v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com
DKIM: Enable in Google Workspace admin console.
# Unit tests
go test ./...
# With race detection and coverage
go test -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
# Security checks
gosec ./...
govulncheck ./...# Requires test SMTP server
go test -tags=integration ./...We welcome contributions! Please see CONTRIBUTING.md for guidelines.
git clone https://github.com/RezaArani/RAmail.git
cd RAmail
go mod download
go test ./...OAuth Token Expired
Error: failed to refresh OAuth token
Solution: Run the device flow example to refresh your token.
TLS Connection Failed
Error: failed to start TLS
Solution: Check system certificates and firewall settings for ports 587/465.
SMTP Authentication Failed
Error: SMTP authentication failed
Solution: Verify token has correct scopes and Gmail API is enabled.
// Enable credential logging (development only!)
logger := ramail.NewSecureLogger(ramail.SecurityConfig{LogCredentials: true})This project is licensed under the MIT License - see the LICENSE file for details.
- golang.org/x/oauth2 - OAuth 2.0 implementation
- Gmail API - Alternative REST API approach
- Google Cloud Console - Setup OAuth credentials
Made with ❤️ for secure email delivery
Star ⭐ the repo if RAmail helps you send emails securely!