Skip to content

API-powered email delivery for Ruby apps. With support for Mailgun, Postmark, Resend and more.

License

Notifications You must be signed in to change notification settings

Rails-Designer/courrier

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Courrier

API-powered email delivery for Ruby apps.

A cute cartoon mascot wearing a blue postal uniform with red scarf and cap, carrying a leather messenger bag, representing an API-powered email delivery system for Ruby applications

# Quick example
class OrderEmail < Courrier::Email
  def subject = "Here is your order!"

  def text = "Thanks for ordering"

  def html = "<p>Thanks for ordering</p>"
end

OrderEmail.deliver to: "[email protected]"
Rails Designer logo

Sponsored By Rails Designer

Installation

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.

Usage

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: "[email protected]"

đź’ˇ Write your email content using the Minimal Email Editor.

Configuration

Courrier uses a configuration system with three levels (from lowest to highest priority):

  1. Global configuration
Courrier.configure do |config|
  config.provider = "postmark"
  config.api_key = "xyz"
  config.from = "[email protected]"
  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
  1. Email class defaults
class OrderEmail < Courrier::Email
  configure from: "[email protected]",
            cc: "[email protected]",
            provider: "mailgun",
end
  1. Instance options
OrderEmail.deliver to: "[email protected]",\
                   from: "[email protected]",\
                   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.

Custom Attributes

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: "[email protected]",\
                   download_url: downloads_path(token: "token")

These custom attributes are accessible directly in your email class:

def text
  <<~TEXT
    #{download_url}
  TEXT
end

Result Object

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.

Available Methods

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

Example

delivery = OrderEmail.deliver(to: "[email protected]")

if delivery.success?
  puts "Email sent successfully!"
  puts "Provider response: #{delivery.data}"
else
  puts "Failed to send email: #{delivery.error}"
end

Providers

Courrier supports these transactional email providers:

More Features

Additional functionality to help with development and testing:

Inbox (Rails only)

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.

Layout Support

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

Auto-generate Text from HTML

Automatically generate plain text versions from your HTML emails:

config.auto_generate_text = true # Defaults to false

Email Address Helper

Compose email addresses with display names:

class SignupsController < ApplicationController
  def create
    recipient = email_with_name("[email protected]", "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

Logger Provider

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)

Custom Providers

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.

FAQ

Is this a replacement for ActionMailer?

Yes! While different in approach, Courrier can fully replace ActionMailer. It's a modern alternative that focuses on API-based delivery. The main difference is in how emails are structured - Courrier uses a more straightforward, class-based approach.

Is this for Rails only?

Not at all! While Courrier has some Rails-specific goodies (like the inbox preview feature and generators), it works great with any Ruby application.

Can it send using SMTP?

No - Courrier is specifically built for API-based email delivery. If SMTP is needed, ActionMailer would be a better choices.

Can separate view templates be created (like ActionMailer)?

The approach is different here. Instead of separate view files, email content is defined right in the email class using text and html methods. Layouts can be used to share common templates. This makes emails more self-contained and easier to reason about.

What's the main benefit over ActionMailer?

Courrier offers a simpler, more modern approach to sending emails. Each email is a standalone class, configuration is straightforward (typically just only an API key is needed) and it packs few quality-of-life features (like the inbox feature and auto-generate text version).

Contributing

This project uses Standard for formatting Ruby code. Please make sure to run rake before submitting pull requests.

License

Courrier is released under the MIT License.

About

API-powered email delivery for Ruby apps. With support for Mailgun, Postmark, Resend and more.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Contributors 2

  •  
  •