Send emails with Ruby on Rails

In this quickstart, you'll learn how to send transactional emails from your Ruby on Rails 6, 7, or 8 app with Sidemail. You'll set up the SDK, send your first email, and see examples for common use cases like welcome emails, password resets, and scheduled reports.

Before you start

  1. Create a Sidemail account → get your API key
  2. Add a sending domain → set up your domain for sending

1. Install

Add the gem to your Gemfile:

bundle add sidemail

2. Add your API key

Add your Sidemail API key to .env (if using dotenv-rails) or your credentials file.

SIDEMAIL_API_KEY=your-api-key

3. Configure the service

We recommend creating a Service Object to manage the Sidemail client instance. This keeps your code clean and makes it easy to access the client throughout your application.

# app/services/sidemail_service.rb
require "sidemail"

class SidemailService
  def self.client
    # The SDK automatically reads SIDEMAIL_API_KEY from ENV
    @client ||= Sidemail.new
  end
end

4. Send a welcome email

Send an email from your controller.

# app/controllers/registrations_controller.rb
class RegistrationsController < ApplicationController
  def create
    @user = User.create(user_params)

    if @user.persisted?
      SidemailService.client.send_email(
        toAddress: @user.email,
        fromAddress: "[email protected]",
        fromName: "Your App",
        templateName: "Welcome",
        templateProps: { firstName: @user.first_name }
      )

      redirect_to root_path, notice: "User registered!"
    else
      render :new
    end
  end
end

5. Send a password reset email

# app/controllers/passwords_controller.rb
class PasswordsController < ApplicationController
  def create
    user = User.find_by(email: params[:email])

    if user
      token = user.generate_reset_token

      SidemailService.client.send_email(
        toAddress: user.email,
        fromAddress: "[email protected]",
        fromName: "Your App",
        templateName: "Password Reset",
        templateProps: {
          actionUrl: edit_password_url(token: token)
        }
      )
    end

    redirect_to login_path, notice: "If an account exists, we sent a reset link."
  end
end

6. Send a weekly report (Rake Task)

Create a Rake task to send emails on a schedule.

# lib/tasks/reports.rake
namespace :reports do
  desc "Send weekly report"
  task weekly: :environment do
    new_signups = User.where("created_at > ?", 1.week.ago).count
    chart_data = [100, 200, 300, 400, 200, 300, 200, 500]

    SidemailService.client.send_email(
      toAddress: "[email protected]",
      fromAddress: "[email protected]",
      fromName: "My App",
      templateName: "Weekly Report",
      templateProps: {
        signups: new_signups,
        chart: chart_data
      }
    )

    puts "Weekly report sent!"
  end
end

Run it via cron or Heroku Scheduler:

rake reports:weekly

7. Send email via ActiveJob

Decouple email sending from your controllers by using ActiveJob.

# app/jobs/send_welcome_email_job.rb
class SendWelcomeEmailJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)

    SidemailService.client.send_email(
      toAddress: user.email,
      fromAddress: "[email protected]",
      fromName: "My App",
      templateName: "Welcome",
      templateProps: { firstName: user.first_name }
    )
  end
end

Usage in controller:

SendWelcomeEmailJob.perform_later(@user.id)

8. Send HTML email (with ERB)

Use ActionController::Base.render to generate HTML from an ERB template.

# app/controllers/invoices_controller.rb
def send_invoice
  html_content = ActionController::Base.new.render_to_string(
    template: "emails/invoice",
    layout: false,
    locals: { amount: 99 }
  )

  SidemailService.client.send_email(
    toAddress: current_user.email,
    fromAddress: "[email protected]",
    fromName: "Your App",
    subject: "Your Invoice",
    html: html_content
  )

  render json: { message: "Invoice sent!" }
end

9. Send Markdown email

Store your markdown content in a file (e.g. app/views/emails/welcome.md) and load it.

markdown = File.read(Rails.root.join("app/views/emails/welcome.md"))

# Subject and sender are defined in the markdown frontmatter
SidemailService.client.send_email(
  toAddress: "[email protected]",
  markdown: markdown,
  templateProps: {
    name: "John",
    link: "https://example.com"
  }
)

10. Send plain text email

SidemailService.client.send_email(
  toAddress: "[email protected]",
  fromAddress: "[email protected]",
  fromName: "Your App",
  subject: "Hello",
  text: "Hello! 👋"
)

11. Schedule email

Send email later. Set scheduledAt to an ISO date string.

SidemailService.client.send_email(
  toAddress: "[email protected]",
  fromAddress: "[email protected]",
  fromName: "Your App",
  templateName: "Welcome",
  templateProps: { firstName: "Alex" },
  scheduledAt: 1.hour.from_now.utc.iso8601
)

12. Send with attachment

Use the Sidemail.file_to_attachment helper to attach files.

pdf_data = File.read(Rails.root.join("storage/invoices/invoice.pdf"))
attachment = Sidemail.file_to_attachment("invoice.pdf", pdf_data)

SidemailService.client.send_email(
  toAddress: "[email protected]",
  fromAddress: "[email protected]",
  fromName: "Your App",
  subject: "Your invoice",
  text: "See attached.",
  attachments: [attachment]
)

13. Handle errors

begin
  SidemailService.client.send_email(
    # ...
  )
rescue Sidemail::Error => e
  Rails.logger.error("Sidemail error: #{e.message}")
  # Handle error (e.g. notify Sentry/Honeybadger)
end