Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    zerobearing2

    rails-aimailers

    zerobearing2/rails-aimailers
    Coding
    21
    1 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Use when sending emails - ActionMailer with async delivery via SolidQueue, templates, previews, and testing

    SKILL.md

    Email with ActionMailer

    Send transactional and notification emails using ActionMailer, integrated with SolidQueue for async delivery. Create HTML and text templates, preview emails in development, and test thoroughly.

    - Sending transactional emails (password resets, confirmations, receipts) - Sending notification emails (updates, alerts, digests) - Delivering emails asynchronously via background jobs - Creating email templates with HTML and text versions - Testing email delivery and content - **Async Delivery** - ActionMailer integrates with SolidQueue for non-blocking email sending - **Template Support** - ERB templates for HTML and text email versions - **Preview in Development** - See emails without sending via /rails/mailers - **Testing Support** - Full test suite for delivery and content - **Layouts** - Shared layouts for consistent email branding - **Attachments** - Send files (PDFs, images) with emails Before completing mailer work: - ✅ Async delivery used (deliver_later, not deliver_now) - ✅ Both HTML and text templates provided - ✅ URL helpers used (not path helpers) - ✅ Email previews created for development - ✅ Mailer tests passing (delivery and content) - ✅ SolidQueue configured for background delivery - ALWAYS deliver emails asynchronously with deliver_later (NOT deliver_now) - Provide both HTML and text email templates - Use *_url helpers (NOT *_path) for links in emails - Set default 'from' address in ApplicationMailer - Create email previews for development (/rails/mailers) - Configure default_url_options for each environment - Use inline CSS for email styling (email clients strip external styles) - Test email delivery and content - Use parameterized mailers (.with()) for cleaner syntax

    ActionMailer Setup

    Configure ActionMailer for email delivery

    Mailer Class:

    # app/mailers/application_mailer.rb
    class ApplicationMailer < ActionMailer::Base
      default from: "noreply@example.com"
      layout "mailer"
    end
    
    # app/mailers/notification_mailer.rb
    class NotificationMailer < ApplicationMailer
      def welcome_email(user)
        @user = user
        @login_url = login_url
        mail(to: user.email, subject: "Welcome to Our App")
      end
    
      def password_reset(user)
        @user = user
        @reset_url = password_reset_url(user.reset_token)
        mail(to: user.email, subject: "Password Reset Instructions")
      end
    end
    

    HTML Template:

    <%# app/views/notification_mailer/welcome_email.html.erb %>
    <h1>Welcome, <%= @user.name %>!</h1>
    <p>Thanks for signing up. Get started by logging in:</p>
    <%= link_to "Login Now", @login_url, class: "button" %>
    

    Text Template:

    <%# app/views/notification_mailer/welcome_email.text.erb %>
    Welcome, <%= @user.name %>!
    
    Thanks for signing up. Get started by logging in:
    <%= @login_url %>
    

    Usage (Async with SolidQueue):

    # In controller or service
    NotificationMailer.welcome_email(@user).deliver_later
    NotificationMailer.password_reset(@user).deliver_later(queue: :mailers)
    

    Why: ActionMailer integrates seamlessly with SolidQueue for async delivery. Always use deliver_later to avoid blocking requests. Provide both HTML and text versions for compatibility.

    Using deliver_now in production (blocks HTTP request)
    # ❌ WRONG - Blocks HTTP request thread
    def create
      @user = User.create!(user_params)
      NotificationMailer.welcome_email(@user).deliver_now  # Blocks!
      redirect_to @user
    end
    
    # ✅ CORRECT - Async delivery via SolidQueue
    def create
      @user = User.create!(user_params)
      NotificationMailer.welcome_email(@user).deliver_later  # Non-blocking
      redirect_to @user
    end
    

    Why bad: deliver_now blocks the HTTP request until SMTP completes, creating slow response times and poor user experience. deliver_later uses SolidQueue to send email in background.

    Use .with() to pass parameters cleanly to mailers
    class NotificationMailer < ApplicationMailer
      def custom_notification
        @user = params[:user]
        @message = params[:message]
        mail(to: @user.email, subject: params[:subject])
      end
    end
    
    # Usage
    NotificationMailer.with(
      user: user,
      message: "Update available",
      subject: "System Alert"
    ).custom_notification.deliver_later
    

    Why: Cleaner syntax, easier to read and modify, and works seamlessly with background jobs.


    Email Templates

    Shared layouts for consistent email branding

    HTML Layout:

    <%# app/views/layouts/mailer.html.erb %>
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <style>
          body {
            font-family: Arial, sans-serif;
            max-width: 600px;
            margin: 0 auto;
            color: #333;
          }
          .header {
            background-color: #4F46E5;
            color: white;
            padding: 20px;
            text-align: center;
          }
          .content {
            padding: 20px;
          }
          .button {
            display: inline-block;
            padding: 12px 24px;
            background-color: #4F46E5;
            color: white;
            text-decoration: none;
            border-radius: 4px;
          }
          .footer {
            padding: 20px;
            text-align: center;
            font-size: 12px;
            color: #666;
          }
        </style>
      </head>
      <body>
        <div class="header">
          <h1>Your App</h1>
        </div>
        <div class="content">
          <%= yield %>
        </div>
        <div class="footer">
          <p>&copy; 2025 Your Company. All rights reserved.</p>
        </div>
      </body>
    </html>
    

    Text Layout:

    <%# app/views/layouts/mailer.text.erb %>
    ================================================================================
    YOUR APP
    ================================================================================
    
    <%= yield %>
    
    --------------------------------------------------------------------------------
    © 2025 Your Company. All rights reserved.
    

    Why: Consistent branding across all emails. Inline CSS ensures styling works across email clients.

    Attach files to emails (PDFs, CSVs, images)
    class ReportMailer < ApplicationMailer
      def monthly_report(user, data)
        @user = user
    
        # Regular attachment
        attachments["report.pdf"] = {
          mime_type: "application/pdf",
          content: generate_pdf(data)
        }
    
        # Inline attachment (for embedding in email body)
        attachments.inline["logo.png"] = File.read(
          Rails.root.join("app/assets/images/logo.png")
        )
    
        mail(to: user.email, subject: "Monthly Report")
      end
    end
    

    In template:

    <%# Reference inline attachment %>
    <%= image_tag attachments["logo.png"].url %>
    

    Why: Attach reports, exports, or inline images. Inline attachments can be referenced in email body with image_tag.

    Using *_path helpers instead of *_url in emails (broken links)
    # ❌ WRONG - Relative path doesn't work in emails
    def welcome_email(user)
      @user = user
      @login_url = login_path  # => "/login" (relative path)
      mail(to: user.email, subject: "Welcome")
    end
    
    # ✅ CORRECT - Full URL works in emails
    def welcome_email(user)
      @user = user
      @login_url = login_url  # => "https://example.com/login" (absolute URL)
      mail(to: user.email, subject: "Welcome")
    end
    
    # Required configuration
    # config/environments/production.rb
    config.action_mailer.default_url_options = { host: "example.com", protocol: "https" }
    

    Why bad: Emails are viewed outside your application context, so relative paths don't work. Always use *_url helpers to generate absolute URLs.


    Email Testing

    Preview emails in browser during development without sending

    Configuration:

    # Gemfile
    group :development do
      gem "letter_opener"
    end
    
    # config/environments/development.rb
    config.action_mailer.delivery_method = :letter_opener
    config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
    
    # config/environments/production.rb
    config.action_mailer.delivery_method = :smtp
    config.action_mailer.smtp_settings = {
      address: "smtp.sendgrid.net",
      port: 587,
      user_name: Rails.application.credentials.dig(:smtp, :username),
      password: Rails.application.credentials.dig(:smtp, :password),
      authentication: :plain,
      enable_starttls_auto: true
    }
    config.action_mailer.default_url_options = { host: "example.com", protocol: "https" }
    

    Why: letter_opener opens emails in browser during development - no SMTP setup needed. Test email appearance without actually sending.

    Preview all email variations at /rails/mailers
    # test/mailers/previews/notification_mailer_preview.rb
    class NotificationMailerPreview < ActionMailer::Preview
      # Preview at http://localhost:3000/rails/mailers/notification_mailer/welcome_email
      def welcome_email
        user = User.first || User.new(name: "Test User", email: "test@example.com")
        NotificationMailer.welcome_email(user)
      end
    
      def password_reset
        user = User.first || User.new(name: "Test User", email: "test@example.com")
        user.reset_token = "sample_token_123"
        NotificationMailer.password_reset(user)
      end
    
      # Preview with different data
      def welcome_email_long_name
        user = User.new(name: "Christopher Alexander Montgomery III", email: "long@example.com")
        NotificationMailer.welcome_email(user)
      end
    end
    

    Why: Mailer previews at /rails/mailers let you see all email variations without sending. Test different edge cases (long names, missing data, etc.).

    Test email delivery and content with ActionMailer::TestCase
    # test/mailers/notification_mailer_test.rb
    class NotificationMailerTest < ActionMailer::TestCase
      test "welcome_email sends with correct attributes" do
        user = users(:alice)
        email = NotificationMailer.welcome_email(user)
    
        # Test delivery
        assert_emails 1 do
          email.deliver_now
        end
    
        # Test attributes
        assert_equal [user.email], email.to
        assert_equal ["noreply@example.com"], email.from
        assert_equal "Welcome to Our App", email.subject
    
        # Test content
        assert_includes email.html_part.body.to_s, user.name
        assert_includes email.text_part.body.to_s, user.name
        assert_includes email.html_part.body.to_s, "Login Now"
      end
    
      test "delivers via background job" do
        user = users(:alice)
    
        assert_enqueued_with(job: ActionMailer::MailDeliveryJob, queue: "mailers") do
          NotificationMailer.welcome_email(user).deliver_later(queue: :mailers)
        end
      end
    
      test "password_reset includes reset link" do
        user = users(:alice)
        user.update!(reset_token: "test_token_123")
        email = NotificationMailer.password_reset(user)
    
        assert_includes email.html_part.body.to_s, "test_token_123"
        assert_includes email.html_part.body.to_s, "password_reset"
      end
    end
    

    Why: Test email delivery, content, and background job enqueuing. Verify recipients, subjects, and that emails are queued properly.


    Email Configuration

    Configure ActionMailer for each environment

    Development:

    # config/environments/development.rb
    config.action_mailer.delivery_method = :letter_opener
    config.action_mailer.perform_deliveries = true
    config.action_mailer.raise_delivery_errors = true
    config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
    

    Test:

    # config/environments/test.rb
    config.action_mailer.delivery_method = :test
    config.action_mailer.default_url_options = { host: "example.com" }
    

    Production:

    # config/environments/production.rb
    config.action_mailer.delivery_method = :smtp
    config.action_mailer.perform_deliveries = true
    config.action_mailer.raise_delivery_errors = false
    config.action_mailer.default_url_options = {
      host: ENV["APP_HOST"],
      protocol: "https"
    }
    
    config.action_mailer.smtp_settings = {
      address: ENV["SMTP_ADDRESS"],
      port: ENV["SMTP_PORT"],
      user_name: Rails.application.credentials.dig(:smtp, :username),
      password: Rails.application.credentials.dig(:smtp, :password),
      authentication: :plain,
      enable_starttls_auto: true
    }
    

    Why: Different configurations per environment. Development previews in browser, test stores emails in memory, production sends via SMTP.


    # test/mailers/notification_mailer_test.rb
    class NotificationMailerTest < ActionMailer::TestCase
      setup do
        @user = users(:alice)
      end
    
      test "welcome_email" do
        email = NotificationMailer.welcome_email(@user)
    
        assert_emails 1 { email.deliver_now }
        assert_equal [@user.email], email.to
        assert_equal ["noreply@example.com"], email.from
        assert_match @user.name, email.html_part.body.to_s
        assert_match @user.name, email.text_part.body.to_s
      end
    
      test "enqueues for async delivery" do
        assert_enqueued_with(job: ActionMailer::MailDeliveryJob) do
          NotificationMailer.welcome_email(@user).deliver_later
        end
      end
    
      test "uses correct queue" do
        assert_enqueued_with(job: ActionMailer::MailDeliveryJob, queue: "mailers") do
          NotificationMailer.welcome_email(@user).deliver_later(queue: :mailers)
        end
      end
    end
    
    # test/system/email_delivery_test.rb
    class EmailDeliveryTest < ApplicationSystemTestCase
      test "sends welcome email after signup" do
        visit signup_path
        fill_in "Email", with: "new@example.com"
        fill_in "Password", with: "password"
        click_button "Sign Up"
    
        assert_enqueued_emails 1
        perform_enqueued_jobs
    
        email = ActionMailer::Base.deliveries.last
        assert_equal ["new@example.com"], email.to
        assert_match "Welcome", email.subject
      end
    end
    

    - rails-ai:jobs - Background job processing with SolidQueue - rails-ai:views - Email templates and layouts - rails-ai:testing - Testing email delivery - rails-ai:project-setup - Environment-specific email configuration

    Official Documentation:

    • Rails Guides - Action Mailer Basics

    Gems & Libraries:

    • letter_opener - Preview emails in browser during development

    Tools:

    • Email on Acid - Email testing across clients

    Email Service Providers:

    • SendGrid Rails Guide
    Recommended Servers
    AgentMail
    AgentMail
    Repository
    zerobearing2/rails-ai
    Files