# Mailer Patterns

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-thibautbaissac-rails-ai-agents-mailer-patterns`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ThibautBaissac](https://agentstack.voostack.com/s/thibautbaissac)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ThibautBaissac](https://github.com/ThibautBaissac)
- **Source:** https://github.com/ThibautBaissac/rails_ai_agents/tree/main/.claude_37signals/skills/mailer-patterns
- **Website:** https://thibautbaissac.github.io/

## Install

```sh
agentstack add skill-thibautbaissac-rails-ai-agents-mailer-patterns
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Mailer Patterns

## Philosophy: Minimal Mailers, Bundled Notifications

- Plain-text first, minimal HTML styling with inline CSS
- Bundle notifications instead of sending one email per event
- Transactional emails only (no marketing campaigns)
- `deliver_later` for individual emails; `deliver_now` is acceptable inside background jobs that already run asynchronously (e.g., digest delivery jobs)
- Email previews for development
- No email service abstraction layers (use Action Mailer directly)

## Project Knowledge

**Stack:** Action Mailer (built-in), Solid Queue for background delivery,
email previews in development, plain text + HTML multipart emails.

**Multi-tenancy:** Account-scoped emails, from address includes account
context, unsubscribe links scoped to account.

**Commands:**
```bash
rails generate mailer Comment mentioned         # Generate mailer
rails generate mailer Digest daily_activity      # With methods
# Visit http://localhost:3000/rails/mailers      # Preview emails
```

## Pattern 1: Simple Transactional Mailers

```ruby
# app/mailers/application_mailer.rb
class ApplicationMailer ")
  layout "mailer"
end

# app/mailers/comment_mailer.rb
class CommentMailer 
Hi ,

 mentioned you in a comment on :

""

View the card: 

---
You're receiving this because you were mentioned.

Hi ,

 mentioned you in a comment on
   :

  

```

## Pattern 3: Bundled Notifications (Digest Emails)

See @references/bundled-notifications.md for full details.

```ruby
# app/mailers/digest_mailer.rb
class DigestMailer = 5 ||
      oldest_pending_notification_age > 1.hour
  end

  def send_digest
    return unless should_send_digest?
    notifications = pending_notifications
    DigestMailer.pending_notifications(@user, notifications).deliver_later
    notifications.update_all(sent_at: Time.current)
  end

  private

  def pending_notifications
    @user.notifications.where(sent_at: nil)
      .where("created_at > ?", 1.hour.ago)
      .order(created_at: :desc)
  end
end

# app/jobs/send_digest_emails_job.rb
class SendDigestEmailsJob 

---

  
    
    
    
      body { margin: 0; padding: 0; font-family: -apple-system, sans-serif;
             font-size: 16px; line-height: 1.5; color: #333; background: #f5f5f5; }
      a { color: #0066cc; }
    
  
  
    
      
      
        
      
    
  

```

## Delivery Configuration

```ruby
# config/environments/production.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.perform_deliveries = true
config.action_mailer.default_url_options = { host: ENV["APP_HOST"] }

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

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

## Boundaries

### Always
- Create both `.text.erb` and `.html.erb` templates
- Use `deliver_later` for individual emails; `deliver_now` is acceptable inside background jobs that already run asynchronously (e.g., digest delivery jobs)
- Check user email preferences before sending
- Include unsubscribe links in emails
- Use inline CSS for HTML emails (no external stylesheets)
- Scope emails to account context
- Create email previews for development

### Ask First
- Digest frequency and bundling thresholds
- Whether to include inline attachments (logos)
- SMTP provider configuration

### Never
- Send one email per event (bundle notifications)
- Mix marketing and transactional emails
- Use external CSS in email templates
- Build email service abstraction layers
- Send emails synchronously in request cycle
- Skip email preferences check

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ThibautBaissac](https://github.com/ThibautBaissac)
- **Source:** [ThibautBaissac/rails_ai_agents](https://github.com/ThibautBaissac/rails_ai_agents)
- **License:** MIT
- **Homepage:** https://thibautbaissac.github.io/

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-thibautbaissac-rails-ai-agents-mailer-patterns
- Seller: https://agentstack.voostack.com/s/thibautbaissac
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
