# 機能設計書 103-メール通知

## 概要

本ドキュメントは、Chatwootにおけるメール形式の通知配信機能について記述する。各種イベント発生時に、エージェントに対してメールで通知を配信する機能である。

### 本機能の処理概要

**業務上の目的・背景**：カスタマーサポート業務において、エージェントがChatwootアプリケーションを開いていない場合でも、重要なイベントの発生を知らせる必要がある。メール通知により、オフライン状態のエージェントにも確実に情報を届けることができ、顧客対応の遅延を防止する。

**機能の利用シーン**：
- 新しい会話が作成された時（conversation_creation）
- 会話がエージェントに割り当てられた時（conversation_assignment）
- 担当会話に新しいメッセージが到着した時（assigned_conversation_new_message）
- 参加中の会話に新しいメッセージが到着した時（participating_conversation_new_message）
- メンションされた時（conversation_mention）

**主要な処理内容**：
1. 通知イベント発生時のジョブキューへの登録
2. 通知の既読状態確認（既読の場合は配信スキップ）
3. ユーザーの確認状態確認（未確認ユーザーには配信しない）
4. ユーザーの通知設定（email_flags）の確認
5. Liquid テンプレートを使用したメール生成・配信

**関連システム・外部連携**：
- SMTP: メール配信サーバー
- Liquidテンプレート: 動的なメール内容生成
- OnlineStatusTracker: エージェントのオンライン状態確認

**権限による制御**：メール通知は各ユーザーの通知設定（email_flags）に基づいて配信される。また、ユーザーがオンライン状態の場合、新規メッセージ通知は送信されない（スパム防止）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 89 | プロフィール設定画面 | 参照画面 | メール通知の有効/無効設定 |

## 機能種別

非同期処理 / 外部連携（メール配信）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| notification | Notification | Yes | 通知オブジェクト | - |

### 入力データソース

- DBテーブル: notifications テーブルから通知情報を取得
- DBテーブル: notification_settings テーブルから配信設定を取得
- DBテーブル: users テーブルからエージェント情報を取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| to | String | 送信先メールアドレス |
| subject | String | メール件名 |
| body | String | メール本文（Liquidテンプレートから生成） |

### 出力先

- メール: SMTPサーバー経由でエージェントのメールアドレスへ配信

## 処理フロー

### 処理シーケンス

```
1. 通知作成（Notificationモデル）
   └─ after_create_commit で process_notification_delivery 実行

2. メール通知ジョブのキューイング
   └─ Notification::EmailNotificationJob.perform_later(notification)

3. ジョブ実行（非同期）
   ├─ 既読確認（read_at が設定されていたらスキップ）
   └─ Notification::EmailNotificationService.new(notification:).perform

4. サービスでの配信前チェック
   ├─ 既読確認（再度）
   ├─ ユーザー確認状態チェック（confirmed_at）
   └─ 通知設定確認（email_flags）

5. メール配信
   └─ AgentNotifications::ConversationNotificationsMailer で配信
```

### フローチャート

```mermaid
flowchart TD
    A[通知作成] --> B{メール設定有効?}
    B -->|No| C[処理終了]
    B -->|Yes| D[ジョブキューイング]
    D --> E{既読?}
    E -->|Yes| C
    E -->|No| F[EmailNotificationService実行]
    F --> G{既読?}
    G -->|Yes| C
    G -->|No| H{ユーザー確認済み?}
    H -->|No| C
    H -->|Yes| I{メール設定有効?}
    I -->|No| C
    I -->|Yes| J{オンライン?<br>新規メッセージ通知の場合}
    J -->|Yes| C
    J -->|No| K[メール送信]
    K --> C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-103-01 | 既読スキップ | 既に既読の通知にはメールを送信しない | read_at が設定済みの場合 |
| BR-103-02 | 未確認ユーザースキップ | メールアドレス未確認のユーザーには送信しない | confirmed_at が null の場合 |
| BR-103-03 | 購読確認 | email_flags で該当通知タイプが有効な場合のみ配信 | 常時 |
| BR-103-04 | オンラインスキップ | 新規メッセージ通知はオンラインユーザーには送信しない | assigned/participating_conversation_new_message |
| BR-103-05 | SMTP必須 | SMTP設定がない場合は送信しない（開発環境除く） | smtp_config_set_or_development? |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 設定確認 | notification_settings | SELECT | メールフラグの確認 |
| 通知確認 | notifications | SELECT | read_at の確認 |
| ユーザー確認 | users | SELECT | confirmed_at の確認 |

### テーブル別操作詳細

#### notifications

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | read_at | 既読確認 | null でない場合は配信スキップ |

#### users

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | confirmed_at | メール確認状態 | null の場合は配信スキップ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | SMTP接続エラー | SMTPサーバーに接続できない | Active Jobのリトライ機構に依存 |
| - | 配信失敗 | メールアドレスが無効 | ログ出力、エラー追跡システムへ通知 |

### リトライ仕様

- Active Jobのデフォルトリトライ機構に依存
- SMTP一時エラーの場合は自動リトライ

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

- メール送信は非同期のため、トランザクション外で実行
- Active Jobによるジョブ管理

## パフォーマンス要件

- 非同期処理のためUIブロッキングなし
- deliver_later によるキューイング

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

- SMTP認証: 設定されたSMTP認証情報を使用
- Liquidテンプレート: XSS対策済みのテンプレートエンジン
- メールアドレス: 確認済みユーザーのみに送信

## 備考

- オンラインステータス確認により、リアルタイムで通知を確認できるユーザーにはメールを送信しない
- Liquidテンプレートを使用することで、カスタマイズ可能なメール内容を実現

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | notification.rb | `app/models/notification.rb` | 通知タイプと配信トリガー |
| 1-2 | notification_setting.rb | `app/models/notification_setting.rb` | email_flags の構造 |

**読解のコツ**: `NOTIFICATION_TYPES`で対応している通知タイプを確認し、`EMAIL_NOTIFICATION_FLAGS`でフラグの対応関係を理解する。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | notification.rb | `app/models/notification.rb` | 通知作成後のコールバック |

**主要処理フロー**:
- **52行目**: `after_create_commit :process_notification_delivery`
- **155-163行目**: `process_notification_delivery` - ジョブキューイング
- **161行目**: `Notification::EmailNotificationJob.perform_later(self)`

#### Step 3: ジョブ層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | email_notification_job.rb | `app/jobs/notification/email_notification_job.rb` | 既読チェックとサービス呼び出し |

**主要処理フロー**:
- **5-6行目**: 既読確認（read_at.present?）
- **8行目**: サービス呼び出し

#### Step 4: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | email_notification_service.rb | `app/services/notification/email_notification_service.rb` | メール配信ロジック |

**主要処理フロー**:
- **5-6行目**: 既読確認
- **7-8行目**: ユーザー確認状態チェック
- **9行目**: 通知設定確認
- **13-14行目**: メーラー呼び出し

#### Step 5: メーラー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | conversation_notifications_mailer.rb | `app/mailers/agent_notifications/conversation_notifications_mailer.rb` | 各通知タイプのメール生成 |

**主要処理フロー**:
- **2-11行目**: `conversation_creation` - 会話作成通知
- **13-21行目**: `conversation_assignment` - 会話割り当て通知
- **23-32行目**: `conversation_mention` - メンション通知
- **34-44行目**: `assigned_conversation_new_message` - 担当会話新規メッセージ通知
- **37行目**: `OnlineStatusTracker.get_presence` - オンラインチェック

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

```
Notification (モデル)
    │
    └─ after_create_commit
           │
           └─ process_notification_delivery
                  │
                  └─ Notification::EmailNotificationJob.perform_later
                         │
                         ├─ read_at確認（スキップ判定）
                         │
                         └─ Notification::EmailNotificationService.perform
                                │
                                ├─ read_at確認
                                ├─ confirmed_at確認
                                ├─ email_flags確認
                                │
                                └─ ConversationNotificationsMailer
                                       │
                                       ├─ conversation_creation
                                       ├─ conversation_assignment
                                       ├─ conversation_mention
                                       ├─ assigned_conversation_new_message
                                       │      └─ OnlineStatusTracker.get_presence
                                       └─ participating_conversation_new_message
                                              └─ OnlineStatusTracker.get_presence
```

### データフロー図

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

Notification ─────▶ EmailNotificationService ─────▶ SMTPサーバー
(通知データ)              │                              │
                         │                              └─ エージェントへメール配信
                         ▼
              notification_settings ───▶ 配信可否判定
              (email_flags)
                         │
                         ▼
              OnlineStatusTracker ───▶ オンライン判定
              (新規メッセージ通知時)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| notification.rb | `app/models/notification.rb` | モデル | 通知データモデル、配信トリガー |
| email_notification_job.rb | `app/jobs/notification/email_notification_job.rb` | ジョブ | 非同期実行のジョブクラス |
| email_notification_service.rb | `app/services/notification/email_notification_service.rb` | サービス | メール配信判定ロジック |
| conversation_notifications_mailer.rb | `app/mailers/agent_notifications/conversation_notifications_mailer.rb` | メーラー | メール生成・送信 |
| notification_setting.rb | `app/models/notification_setting.rb` | モデル | 通知設定（email_flags） |
| application_mailer.rb | `app/mailers/application_mailer.rb` | メーラー | 基底メーラークラス |
