> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sendpost.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ruby on Rails Quickstart

> Learn how to send emails with SendPost in your Ruby on Rails application using ActionMailer, mailers, and background jobs

## Prerequisites

To get the most out of this guide, you'll need to:

* [**Create a SendPost Account**](https://app.sendpost.io/register)
* [**Ruby on Rails 6.0+**](https://rubyonrails.org/)
* [**Ruby 2.7+**](https://www.ruby-lang.org/en/downloads/)
* A **Sub-Account API Key** from your SendPost dashboard

<Info>
  You can find your API keys in your [SendPost Dashboard](https://app.sendpost.io). Make sure to use your Sub-Account API Key for sending emails.
</Info>

## 1. Install Dependencies

Add to your `Gemfile`:

```ruby Ruby theme={null}
gem 'sendpost_ruby_sdk'
```

Install:

```bash theme={null}
bundle install
```

## 2. Environment Setup

Add to `config/application.rb` or `config/environments/production.rb`:

```ruby Ruby theme={null}
config.action_mailer.delivery_method = :sendpost
config.action_mailer.default_url_options = { host: 'yourdomain.com' }
```

Create or update `config/initializers/sendpost.rb`:

```ruby Ruby theme={null}
SendPost.configure do |config|
  config.api_key = ENV['SENDPOST_API_KEY']
  config.host = 'https://api.sendpost.io/api/v1'
end
```

Add to `.env` or `config/application.yml`:

```env theme={null}
SENDPOST_API_KEY=your_sub_account_api_key
```

## 3. Create Custom Mail Delivery Method

Create `app/mailers/sendpost_delivery_method.rb`:

```ruby Ruby theme={null}
require 'sendpost_ruby_sdk'

class SendpostDeliveryMethod
  def initialize(settings)
    @api_key = settings[:api_key] || ENV['SENDPOST_API_KEY']
    @from_email = settings[:from_email] || 'hello@playwithsendpost.io'
    @from_name = settings[:from_name] || 'SendPost'
  end

  def deliver!(mail)
    api_instance = SendPost::EmailApi.new
    
    email_message = SendPost::EmailMessage.new
    email_message.from = SendPost::From.new(
      email: @from_email,
      name: @from_name
    )
    
    # Set recipients
    recipients = []
    mail.to.each do |to_email|
      recipient = SendPost::To.new(email: to_email)
      recipient.name = mail[:to].display_names.first if mail[:to].display_names.any?
      recipients << recipient
    end
    email_message.to = recipients
    
    # Set subject
    email_message.subject = mail.subject
    
    # Set body
    if mail.multipart?
      email_message.html_body = mail.html_part.body.to_s
      email_message.text_body = mail.text_part.body.to_s
    else
      if mail.content_type&.include?('text/html')
        email_message.html_body = mail.body.to_s
      else
        email_message.text_body = mail.body.to_s
      end
    end
    
    # Set tracking
    email_message.track_opens = true
    email_message.track_clicks = true
    
    # Send email
    begin
      response = api_instance.send_email(@api_key, email_message)
      Rails.logger.info "Email sent via SendPost: #{response.message_id}"
    rescue => e
      Rails.logger.error "SendPost error: #{e.message}"
      raise e
    end
  end
end
```

## 4. Configure ActionMailer

Update `config/environments/production.rb`:

```ruby Ruby theme={null}
config.action_mailer.delivery_method = :sendpost
config.action_mailer.sendpost_settings = {
  api_key: ENV['SENDPOST_API_KEY'],
  from_email: 'hello@playwithsendpost.io',
  from_name: 'Your App Name'
}
```

## 5. Send Your First Email

### Using ActionMailer

Create a mailer:

```bash theme={null}
rails generate mailer UserMailer welcome_email
```

Update `app/mailers/user_mailer.rb`:

```ruby Ruby theme={null}
class UserMailer < ApplicationMailer
  default from: 'hello@playwithsendpost.io'

  def welcome_email(user)
    @user = user
    @first_name = user.first_name
    
    mail(
      to: @user.email,
      subject: 'Welcome {{firstName}}!'
    ) do |format|
      format.html { render 'welcome_email' }
      format.text { render 'welcome_email' }
    end
  end
end
```

Create `app/views/user_mailer/welcome_email.html.erb`:

```erb ERB theme={null}
<h1>Welcome, <%= @first_name %>!</h1>
<p>Thank you for joining us. We're excited to have you on board.</p>
<p>Get started by exploring our features:</p>
<ul>
  <li>Feature 1</li>
  <li>Feature 2</li>
  <li>Feature 3</li>
</ul>
<p>If you have any questions, just reply to this email.</p>
<p><a href="{{unsubscribe}}">Unsubscribe</a></p>
```

Create `app/views/user_mailer/welcome_email.text.erb`:

```erb ERB theme={null}
Welcome, <%= @first_name %>!

Thank you for joining us. We're excited to have you on board.

Get started by exploring our features:
- Feature 1
- Feature 2
- Feature 3

If you have any questions, just reply to this email.

Unsubscribe: {{unsubscribe}}
```

Send the email:

```ruby Ruby theme={null}
UserMailer.welcome_email(user).deliver_now
# or
UserMailer.welcome_email(user).deliver_later
```

## 6. Common Use Cases

### Password Reset Email

Create `app/mailers/user_mailer.rb`:

```ruby Ruby theme={null}
class UserMailer < ApplicationMailer
  default from: 'hello@playwithsendpost.io'

  def password_reset_email(user, reset_token)
    @user = user
    @reset_url = "#{Rails.application.config.action_mailer.default_url_options[:host]}/reset-password?token=#{reset_token}"
    
    mail(
      to: @user.email,
      subject: 'Reset Your Password'
    )
  end
end
```

Create `app/views/user_mailer/password_reset_email.html.erb`:

```erb ERB theme={null}
<h2>Hello <%= @user.first_name %>,</h2>
<p>We received a request to reset your password. Click the button below:</p>
<p>
  <a href="<%= @reset_url %>" style="background-color: #5750EC; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; display: inline-block;">
    Reset Password
  </a>
</p>
<p>Or copy and paste this link: <%= @reset_url %></p>
<p>This link will expire in 1 hour.</p>
<p>If you didn't request this, please ignore this email.</p>
```

### Order Confirmation Email

```ruby Ruby theme={null}
class OrderMailer < ApplicationMailer
  default from: 'hello@playwithsendpost.io'

  def order_confirmation(order)
    @order = order
    @user = order.user
    @items = order.items
    
    mail(
      to: @user.email,
      subject: "Order #{@order.id} Confirmed"
    )
  end
end
```

Create `app/views/order_mailer/order_confirmation.html.erb`:

```erb ERB theme={null}
<h1>Thank you for your order, <%= @user.first_name %>!</h1>
<p>Your order <strong><%= @order.id %></strong> has been confirmed.</p>

<h2>Order Details</h2>
<table style="width: 100%; border-collapse: collapse;">
  <thead>
    <tr style="background-color: #f5f5f5;">
      <th style="padding: 12px; text-align: left; border: 1px solid #ddd;">Item</th>
      <th style="padding: 12px; text-align: left; border: 1px solid #ddd;">Quantity</th>
      <th style="padding: 12px; text-align: right; border: 1px solid #ddd;">Price</th>
    </tr>
  </thead>
  <tbody>
    <% @items.each do |item| %>
    <tr>
      <td style="padding: 12px; border: 1px solid #ddd;"><%= item.name %></td>
      <td style="padding: 12px; border: 1px solid #ddd;"><%= item.quantity %></td>
      <td style="padding: 12px; text-align: right; border: 1px solid #ddd;">$<%= item.price %></td>
    </tr>
    <% end %>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2" style="padding: 12px; text-align: right; border: 1px solid #ddd;"><strong>Total:</strong></td>
      <td style="padding: 12px; text-align: right; border: 1px solid #ddd;"><strong>$<%= @order.total %></strong></td>
    </tr>
  </tfoot>
</table>

<p>We'll send you a shipping confirmation once your order is on its way.</p>
<p><a href="{{unsubscribe}}">Unsubscribe from order updates</a></p>
```

## 7. Using Background Jobs

### With Sidekiq

Create `app/jobs/email_job.rb`:

```ruby Ruby theme={null}
class EmailJob < ApplicationJob
  queue_as :default

  def perform(user_id, email_type, options = {})
    user = User.find(user_id)
    
    case email_type
    when 'welcome'
      UserMailer.welcome_email(user).deliver_now
    when 'password_reset'
      UserMailer.password_reset_email(user, options[:reset_token]).deliver_now
    when 'order_confirmation'
      UserMailer.order_confirmation(options[:order]).deliver_now
    end
  end
end
```

Use it:

```ruby Ruby theme={null}
EmailJob.perform_later(user.id, 'welcome')
EmailJob.perform_later(user.id, 'password_reset', reset_token: token)
```

### With ActiveJob

```ruby Ruby theme={null}
class SendWelcomeEmailJob < ApplicationJob
  queue_as :default

  def perform(user_id)
    user = User.find(user_id)
    UserMailer.welcome_email(user).deliver_now
  end
end
```

## 8. Direct API Usage

Create `app/services/sendpost_service.rb`:

```ruby Ruby theme={null}
require 'sendpost_ruby_sdk'

class SendpostService
  def self.send_email(to:, subject:, html_body:, text_body: nil, custom_fields: {})
    api_instance = SendPost::EmailApi.new
    
    email_message = SendPost::EmailMessage.new
    email_message.from = SendPost::From.new(
      email: 'hello@playwithsendpost.io',
      name: 'SendPost'
    )
    
    recipient = SendPost::To.new(email: to)
    recipient.custom_fields = custom_fields if custom_fields.any?
    email_message.to = [recipient]
    
    email_message.subject = subject
    email_message.html_body = html_body
    email_message.text_body = text_body || html_body.gsub(/<[^>]*>/, '')
    email_message.track_opens = true
    email_message.track_clicks = true
    
    begin
      response = api_instance.send_email(ENV['SENDPOST_API_KEY'], email_message)
      { success: true, message_id: response.message_id }
    rescue => e
      Rails.logger.error "SendPost error: #{e.message}"
      { success: false, error: e.message }
    end
  end
end
```

Use it:

```ruby Ruby theme={null}
result = SendpostService.send_email(
  to: 'user@example.com',
  subject: 'Welcome {{firstName}}!',
  html_body: '<h1>Welcome, {{firstName}}!</h1>',
  custom_fields: { firstName: 'John' }
)
```

## 9. Testing

### In Development

Add to `config/environments/development.rb`:

```ruby Ruby theme={null}
config.action_mailer.delivery_method = :test
# or use letter_opener for preview
config.action_mailer.delivery_method = :letter_opener
```

### In Test

Add to `config/environments/test.rb`:

```ruby Ruby theme={null}
config.action_mailer.delivery_method = :test
```

Test mailer:

```ruby Ruby theme={null}
# spec/mailers/user_mailer_spec.rb
require 'rails_helper'

RSpec.describe UserMailer, type: :mailer do
  describe '#welcome_email' do
    let(:user) { create(:user) }
    let(:mail) { UserMailer.welcome_email(user) }

    it 'renders the headers' do
      expect(mail.subject).to eq('Welcome {{firstName}}!')
      expect(mail.to).to eq([user.email])
      expect(mail.from).to eq(['hello@playwithsendpost.io'])
    end

    it 'renders the body' do
      expect(mail.body.encoded).to match(user.first_name)
    end
  end
end
```

<Warning>
  Make sure your sender email domain is verified in your SendPost account before sending emails.
</Warning>

## 10. Next Steps

Explore more examples and use cases:

<Columns cols={3}>
  <Card title="Ruby on Rails Documentation" icon="ruby" href="https://guides.rubyonrails.org/">
    Learn more about Ruby on Rails
  </Card>

  <Card title="SendPost Ruby SDK" icon="gem" href="https://github.com/sendpost/sendpost-ruby-sdk">
    View the official SDK on GitHub
  </Card>

  <Card title="ActionMailer Guide" icon="book" href="https://guides.rubyonrails.org/action_mailer_basics.html">
    Learn more about ActionMailer
  </Card>

  <Card title="Quickstart Example" icon="github" href="https://github.com/sendpost/sendpost-ruby-on-rails-example">
    View a complete working example on GitHub
  </Card>
</Columns>
