chain_mail
chain_mail is a Ruby gem that ensures your transactional emails never fail by automatically switching between multiple email providers (SendGrid, Postmark, Mailgun, SES, etc.) when one fails to send. No more lost emails, no more manual intervention required.
Why chain_mail?
- Zero Downtime: If one provider fails, emails automatically route to the next available provider
- Easy Setup: Simple configuration with familiar Rails patterns
- Multiple Providers: Built-in support for all major email services
- Error Aggregation: Get detailed reports on any delivery issues
Installation
Add this line to your application's Gemfile:
gem 'chain_mail'And then execute:
$ bundle install
Or install it yourself as:
$ gem install chain_mail
Usage
Rails Setup
Add a configuration initializer at config/initializers/chain_mail.rb:
ChainMail.configure do |config|
config.providers = [
{ send_grid: { api_key: ENV["SENDGRID_API_KEY"] } },
{ mailgun: { domain: ENV["MAILGUN_DOMAIN"], api_key: ENV["MAILGUN_API_KEY"] } },
# Add more providers as needed
]
endSet the delivery method in your environment config (e.g. config/environments/production.rb):
config.action_mailer.delivery_method = :chain_mailSend an email using ActionMailer:
class UserMailer < ApplicationMailer
def welcome_email(user)
mail(
to: user.email,
from: 'noreply@example.com',
subject: 'Welcome!',
body: 'Hello and welcome!'
)
end
endRequirements
- Ruby 3.0 or higher
- Rails 6.0+ (for Rails integration)
- Active email provider accounts (SendGrid, Postmark, etc.)
Architecture
- Configuration: Set up providers and credentials in an initializer or before sending.
- Delivery: Handles failover, input validation, and error aggregation.
- Providers: Each adapter implements a standardized interface and error handling.
Supported Email Providers
chain_mail includes built-in support for the following email providers. Here's how to configure each one in your Rails initializer:
Amazon SES
ChainMail.configure do |config|
config.providers = [
{ ses: {
region: ENV["AWS_REGION"],
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
} }
]
endBrevo (formerly Sendinblue)
ChainMail.configure do |config|
config.providers = [
{ brevo: {
api_key: ENV["BREVO_API_KEY"],
sandbox: ENV["BREVO_SANDBOX"] == "true" # optional
} }
]
endMailgun
ChainMail.configure do |config|
config.providers = [
{ mailgun: {
domain: ENV["MAILGUN_DOMAIN"],
api_key: ENV["MAILGUN_API_KEY"]
} }
]
endOneSignal
ChainMail.configure do |config|
config.providers = [
{ one_signal: { api_key: ENV["ONESIGNAL_API_KEY"] } }
]
endPostmark
ChainMail.configure do |config|
config.providers = [
{ postmark: { api_key: ENV["POSTMARK_API_KEY"] } }
]
endSendGrid
ChainMail.configure do |config|
config.providers = [
{ send_grid: { api_key: ENV["SENDGRID_API_KEY"] } }
]
endSendPulse
ChainMail.configure do |config|
config.providers = [
{ send_pulse: {
client_id: ENV["SENDPULSE_CLIENT_ID"],
client_secret: ENV["SENDPULSE_CLIENT_SECRET"]
} }
]
endMultiple Providers by Priority (send_grid -> mailgun -> ses)
ChainMail.configure do |config|
config.providers = [
{ send_grid: { api_key: ENV["SENDGRID_API_KEY"]} },
{ mailgun: {
domain: ENV["MAILGUN_DOMAIN"],
api_key: ENV["MAILGUN_API_KEY"]
} },
{ ses: {
region: ENV["AWS_REGION"],
access_key_id: ENV["AWS_ACCESS_KEY_ID"],
secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
} }
]
endNote: Always store API keys and credentials securely using environment variables. Providers are tried in the order listed - the first available provider will handle the email delivery.
Provider Priorities & Dynamic Configuration
- Providers are tried in the order listed in
config.providers. - You can register/unregister adapters at runtime:
ChainMail.register_provider(:custom, CustomProviderClass)
ChainMail.unregister_provider(:send_grid)- You can update provider priorities or credentials dynamically:
ChainMail.config.providers = [
{ custom: { api_key: "CUSTOM_API_KEY" } },
{ mailgun: { domain: "MAILGUN_DOMAIN", api_key: "MAILGUN_API_KEY" } }
]- API keys and credentials should be stored securely, e.g. using environment variables.
Star History
Development
Check out the repo and start developing!
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/taltas/chain_mail.
