# 機能設計書 9-Action Mailer

## 概要

本ドキュメントは、Ruby on RailsフレームワークにおけるAction Mailerの機能設計を記述する。Action Mailerは、メール作成・配信フレームワークとしてコントローラ/ビューパターンでメールを作成し、マルチパート・添付ファイルをサポートするコンポーネントである。

### 本機能の処理概要

Action Mailerは、MVCパターンに基づいてメールの生成と配信を行うフレームワークである。メーラークラス（コントローラに相当）とビュー（テンプレート）を使用してメールコンテンツを構築する。

**業務上の目的・背景**：Webアプリケーションでは、ユーザー登録確認、パスワードリセット、通知メール等、様々な場面でメール送信が必要となる。Action Mailerは、メール生成をコントローラ/ビューパターンで構造化し、HTML/テキストのマルチパートメール、添付ファイル、インラインイメージ等の複雑なメール構成を容易に実現する。また、Active Jobとの統合により、バックグラウンドでのメール配信も可能である。

**機能の利用シーン**：
- ユーザー登録確認メールの送信
- パスワードリセットメールの送信
- 注文確認・出荷通知メールの送信
- ニュースレター・キャンペーンメールの送信
- システム通知・アラートメールの送信
- メール受信処理との連携

**主要な処理内容**：
1. メーラークラスの定義と継承
2. メールテンプレート（HTML/テキスト）のレンダリング
3. マルチパートメール（HTML+テキスト）の生成
4. ファイル添付・インラインイメージの処理
5. 配信メソッド（SMTP、Sendmail等）の設定
6. Active Jobを使用した非同期配信
7. メールプレビュー機能
8. インターセプター・オブザーバーによるフック

**関連システム・外部連携**：
- Mail gem: メール生成・解析
- Active Job: 非同期配信
- SMTP/Sendmail: メール配信
- Mailgun/Mandrill/Postmark/SendGrid: 外部メールサービス

**権限による制御**：Action Mailerは直接的な認可制御を提供しない。アプリケーション層でメール送信の権限管理を行う。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | メーラープレビュー一覧画面 | 主機能 | ActionMailer::Preview.allによる全プレビュークラスの取得 |
| 6 | メーラー詳細画面 | 主機能 | 特定メーラーのアクション一覧取得処理 |
| 7 | メールプレビュー画面 | 主機能 | メールコンテンツのプレビュー生成・表示処理 |
| 22 | パスワードリセット申請画面（テンプレート） | 主機能 | パスワードリセット指示メールの送信処理 |

## 機能種別

メール配信フレームワーク / テンプレートエンジン

## 入力仕様

### 入力パラメータ

#### mail メソッド

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| to | String/Array | Yes | 宛先アドレス | 有効なメールアドレス |
| from | String | No | 送信元アドレス | 有効なメールアドレス |
| subject | String | No | 件名 | - |
| cc | String/Array | No | CCアドレス | - |
| bcc | String/Array | No | BCCアドレス | - |
| reply_to | String | No | 返信先アドレス | - |
| headers | Hash | No | カスタムヘッダ | - |

#### attachments

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | String | Yes | ファイル名 | - |
| content | String/IO | Yes | ファイル内容 | - |
| content_type | String | No | MIMEタイプ | - |

### 入力データソース

- アプリケーションコードからのメソッド呼び出し
- メールテンプレートファイル（app/views/mailer_name/）
- I18n翻訳ファイル
- 設定ファイル（config/environments/*.rb）

## 出力仕様

### 出力データ

#### mail

| 項目名 | 型 | 説明 |
|--------|-----|------|
| message | Mail::Message | 生成されたメールオブジェクト |

#### deliver_now / deliver_later

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Mail::Message / ActiveJob::Base | 配信結果またはジョブ |

### 出力先

- SMTP サーバー
- Sendmail
- 外部メールサービス（API経由）
- テスト環境：ActionMailer::Base.deliveries

## 処理フロー

### 処理シーケンス（メール送信）

```
1. メーラーメソッド呼び出し
   └─ UserMailer.welcome(user).deliver_later
2. メーラーアクション実行
   └─ インスタンス変数の設定
3. mail メソッド実行
   └─ メールオブジェクトの生成
4. テンプレートレンダリング
   └─ HTML/テキストテンプレートの処理
5. マルチパート構築
   └─ 複数フォーマットの統合
6. 添付ファイル処理
   └─ 添付ファイルの追加
7. 配信
   └─ deliver_now: 即時配信
   └─ deliver_later: Active Job経由で非同期配信
```

### フローチャート

```mermaid
flowchart TD
    A[メーラーメソッド呼び出し] --> B[メーラーアクション実行]
    B --> C[mail メソッド]
    C --> D[テンプレート検索]
    D --> E{複数フォーマット?}
    E -->|Yes| F[マルチパート生成]
    E -->|No| G[単一パート生成]
    F --> H[添付ファイル処理]
    G --> H
    H --> I{配信方法?}
    I -->|deliver_now| J[即時配信]
    I -->|deliver_later| K[Active Job キュー]
    K --> L[非同期配信]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | テンプレート命名 | app/views/mailer_name/action_name.format.erb の形式 | テンプレート検索時 |
| BR-002 | マルチパート自動生成 | 同名のhtml.erb と text.erb が存在する場合、自動的にマルチパート | テンプレートが複数ある場合 |
| BR-003 | デフォルト設定 | defaultメソッドでfrom等のデフォルト値を設定可能 | メール生成時 |
| BR-004 | 非同期配信 | deliver_laterはActive Jobを使用してキューに追加 | deliver_later使用時 |
| BR-005 | インターセプター | delivering_email前にインターセプターが呼び出される | メール送信前 |

### 計算ロジック

**マルチパート判定**：
```ruby
# action_name.html.erb と action_name.text.erb の両方が存在する場合
# -> multipart/alternative として生成
```

## データベース操作仕様

Action Mailer自体は直接データベース操作を行わない。

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | Action Mailer自体はDB操作を行わない |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Net::SMTPAuthenticationError | SMTP認証失敗 | 認証情報を確認 |
| - | Net::SMTPServerBusy | SMTPサーバービジー | リトライまたは待機 |
| - | Net::OpenTimeout | 接続タイムアウト | ネットワーク・サーバー状態を確認 |
| - | ActionView::MissingTemplate | テンプレートが見つからない | テンプレートファイルを作成 |

### リトライ仕様

deliver_later使用時、Active Jobのリトライ機能を利用可能。デフォルトでは自動リトライは行われない。

## トランザクション仕様

Action Mailerはトランザクション管理を直接行わない。トランザクション内でのメール送信には注意が必要（ロールバック時にメールは取り消されない）。

## パフォーマンス要件

- deliver_nowは同期的に配信するため、レスポンス時間に影響
- deliver_laterで非同期配信を推奨
- 大量配信時はバッチ処理を検討

## セキュリティ考慮事項

- SMTP認証情報はcredentialsで管理
- メールアドレスのバリデーション
- スパム防止のためのレート制限
- メール内容のサニタイズ

## 備考

Action Mailerは `actionmailer` gem として提供される。メールテスト機能を含む。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

Action Mailerのモジュール構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | action_mailer.rb | `actionmailer/lib/action_mailer.rb` | モジュール定義とautoload一覧 |

**読解のコツ**: `eager_autoload` と通常の `autoload` の違いに注目する。

**主要処理フロー**:
- **39-71行目**: ActionMailerモジュールの定義とautoload
- **42-44行目**: eager_autoloadでCollectorが定義
- **61-70行目**: eager_load!メソッドでMailをロード

#### Step 2: Baseクラスを理解する

メーラーの基底クラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | base.rb | `actionmailer/lib/action_mailer/base.rb` | ActionMailer::Baseの構成 |

**主要処理フロー**:
- **14-44行目**: クラスドキュメント。メーラーモデルの概念説明
- **45-89行目**: メールテンプレートとビューの説明
- **146-150行目**: 送信方法（deliver_now/deliver_later）の説明

#### Step 3: MessageDeliveryを理解する

メール配信オブジェクトを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | message_delivery.rb | `actionmailer/lib/action_mailer/message_delivery.rb` | MessageDeliveryクラス |

#### Step 4: Previewを理解する

メールプレビュー機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | preview.rb | `actionmailer/lib/action_mailer/preview.rb` | Previewクラス |

### プログラム呼び出し階層図

```
ActionMailer::Base
    │
    ├─ AbstractController::Base (継承)
    │      └─ コントローラ機能
    │
    ├─ mail メソッド
    │      └─ Mail::Message 生成
    │
    ├─ attachments
    │      └─ 添付ファイル管理
    │
    ├─ default
    │      └─ デフォルト設定
    │
    └─ MessageDelivery
           ├─ deliver_now
           │      └─ 即時配信
           └─ deliver_later
                  └─ MailDeliveryJob
                         └─ Active Job キュー
```

### データフロー図

```
[入力]                    [処理]                           [出力]

メーラー呼び出し ───▶ ActionMailer::Base ───▶ アクション実行
       │                      │
       ▼                      ▼
インスタンス変数 ───▶ mail メソッド ───▶ Mail::Message
       │                      │
       ▼                      ▼
テンプレート ───▶ Action View ───▶ メール本文
       │                           │
       ▼                           ▼
添付ファイル ───▶ attachments ───▶ マルチパート
       │
       ▼
deliver_now/later ───▶ SMTP/SendGrid等 ───▶ 配信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| action_mailer.rb | `actionmailer/lib/action_mailer.rb` | ソース | モジュールエントリーポイント |
| base.rb | `actionmailer/lib/action_mailer/base.rb` | ソース | メーラー基底クラス |
| message_delivery.rb | `actionmailer/lib/action_mailer/message_delivery.rb` | ソース | 配信オブジェクト |
| mail_delivery_job.rb | `actionmailer/lib/action_mailer/mail_delivery_job.rb` | ソース | 非同期配信ジョブ |
| preview.rb | `actionmailer/lib/action_mailer/preview.rb` | ソース | プレビュー機能 |
| test_helper.rb | `actionmailer/lib/action_mailer/test_helper.rb` | ソース | テストヘルパー |
| delivery_methods.rb | `actionmailer/lib/action_mailer/delivery_methods.rb` | ソース | 配信メソッド設定 |
| parameterized.rb | `actionmailer/lib/action_mailer/parameterized.rb` | ソース | パラメータ化メール |
| callbacks.rb | `actionmailer/lib/action_mailer/callbacks.rb` | ソース | コールバック |
| rescuable.rb | `actionmailer/lib/action_mailer/rescuable.rb` | ソース | 例外ハンドリング |
