
Security News
New Website “Is It Really FOSS?” Tracks Transparency in Open Source Distribution Models
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
API-powered email delivery for Ruby apps.
# Quick example
OrderEmail.deliver to: "recipient@railsdesigner.com"
Sponsored By Rails Designer
Add the gem:
bundle add courrier
Generate the configuration file:
bin/rails generate courrier:install
This creates config/initializers/courrier.rb
for configuring email providers and default settings.
Generate a new email:
bin/rails generate courrier:email Order
class OrderEmail < Courrier::Email
def subject = "Here is your order!"
def text
<<~TEXT
text body here
TEXT
end
def html
<<~HTML
html body here
HTML
end
end
# OrderEmail.deliver to: "recipient@railsdesigner.com"
💡 Write your email content using the Minimal Email Editor.
Courrier uses a configuration system with three levels (from lowest to highest priority):
Courrier.configure do |config|
config.provider = "postmark"
config.api_key = "xyz"
config.from = "devs@railsdesigner.com"
config.default_url_options = { host: "railsdesigner.com" }
# Provider-specific configuration
config.providers.loops.transactional_id = "default-template"
config.providers.mailgun.domain = "notifications.railsdesigner.com"
end
class OrderEmail < Courrier::Email
configure from: "orders@railsdesigner.com",
cc: "records@railsdesigner.com",
provider: "mailgun",
end
OrderEmail.deliver to: "recipient@railsdesigner.com",\
from: "shop@railsdesigner.com",\
provider: "sendgrid",\
api_key: "sk_a1b1c3"
Provider and API key settings can be overridden using environment variables (COURRIER_PROVIDER
and COURRIER_API_KEY
) for both global configuration and email class defaults.
Besides the standard email attributes (from
, to
, reply_to
, etc.), you can pass any additional attributes that will be available in your email templates:
OrderEmail.deliver to: "recipient@railsdesigner.com",\
download_url: downloads_path(token: "token")
These custom attributes are accessible directly in your email class:
def text
<<~TEXT
#{download_url}
TEXT
end
When sending an email through Courrier, a Result
object is returned that provides information about the delivery attempt. This object offers a simple interface to check the status and access response data.
Method | Return Type | Description |
---|---|---|
success? | Boolean | Returns true if the API request was successful |
response | Net::HTTP::Response | The raw HTTP response from the email provider |
data | Hash | Parsed JSON response body from the provider |
error | Exception | Contains any error that occurred during delivery |
delivery = OrderEmail.deliver(to: "recipient@example.com")
if delivery.success?
puts "Email sent successfully!"
puts "Provider response: #{delivery.data}"
else
puts "Failed to send email: #{delivery.error}"
end
Courrier supports these transactional email providers:
⚠️ Some providers still need manual verification of their implementation. If you're using one of these providers, please help verify the implementation by sharing your experience in this GitHub issue. 🙏
Additional functionality to help with development and testing:
You can preview your emails in the inbox:
config.provider = "inbox"
# And add to your routes:
mount Courrier::Engine => "/courrier"
If you want to automatically open every email in your default browser:
config.provider = "inbox"
config.inbox.auto_open = true
Emails are automatically cleared with bin/rails tmp:clear
, or manually with bin/rails courrier:clear
.
Wrap your email content using layouts:
class OrderEmail < Courrier::Email
layout text: "%{content}\n\nThanks for your order!",
html: "<div>\n%{content}\n</div>"
end
Using a method:
class OrderEmail < Courrier::Email
layout html: :html_layout
def html_layout
<<~HTML
<div style='font-family: ui-sans-serif, system-ui;'>
%{content}
</div>
HTML
end
end
Using a separate class:
class OrderEmail < Courrier::Email
layout html: OrderLayout
end
class OrderLayout
self.call
<<~HTML
<div style='font-family: ui-sans-serif, system-ui;'>
%{content}
</div>
HTML
end
end
Automatically generate plain text versions from your HTML emails:
config.auto_generate_text = true # Defaults to false
Compose email addresses with display names:
class SignupsController < ApplicationController
def create
recipient = email_with_name("devs@railsdesigner.com", "Rails Designer Devs")
WelcomeEmail.deliver to: recipient
end
end
In Plain Ruby Objects:
class Signup
include Courrier::Email::Address
def send_welcome_email(user)
recipient = email_with_name(user.email_address, user.name)
WelcomeEmail.deliver to: recipient
end
end
Use Ruby's built-in Logger for development and testing:
config.provider = "logger" # Outputs emails to STDOUT
config.logger = custom_logger # Optional: defaults to ::Logger.new($stdout)
Create your own provider by inheriting from Courrier::Email::Providers::Base
:
class CustomProvider < Courrier::Email::Providers::Base
ENDPOINT_URL = ""
def body = ""
def headers = ""
end
Then configure it:
config.provider = "CustomProvider"
Check the existing providers for implementation examples.
This project uses Standard for formatting Ruby code. Please make sure to run rake
before submitting pull requests.
Courrier is released under the MIT License.
FAQs
Unknown package
We found that courrier demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.
Security News
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.