
Research
/Security News
10 npm Typosquatted Packages Deploy Multi-Stage Credential Harvester
Socket researchers found 10 typosquatted npm packages that auto-run on install, show fake CAPTCHAs, fingerprint by IP, and deploy a credential stealer.
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.

Research
/Security News
Socket researchers found 10 typosquatted npm packages that auto-run on install, show fake CAPTCHAs, fingerprint by IP, and deploy a credential stealer.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.