# 通知設計書 99-service_desk_thank_you_email

## 概要

本ドキュメントは、GitLabにおけるService Desk感謝メール（service_desk_thank_you_email）の設計仕様を記述する。Service Deskに新しい問い合わせが作成された際に、問い合わせ元の外部ユーザーに対して送信される自動返信メールの仕組みを定義する。

### 本通知の処理概要

**業務上の目的・背景**：Service Deskはプロジェクトが外部ユーザーからの問い合わせを受け付けるための機能である。問い合わせを受け付けたことを自動で通知することで、外部ユーザーに安心感を与え、チケットの追跡番号を提供する。これによりカスタマーサポート品質の向上と問い合わせ管理の効率化が実現される。

**通知の送信タイミング**：Service Deskに宛てたメールが受信され、新しいWork Item（チケット）が作成された直後に通知がトリガーされる。

**通知の受信者**：問い合わせメールの送信者（work_item.external_author）が受信者となる。これは通常GitLabユーザーではない外部のエンドユーザーである。

**通知内容の概要**：サポートリクエストを受け付けたことの感謝、チケット番号（Work Item IID）、今後の対応予定に関するメッセージが含まれる。カスタムテンプレートが設定されている場合は、プロジェクト固有のメッセージを送信できる。

**期待されるアクション**：外部ユーザーは通知を受け取り、問い合わせが正常に受理されたことを確認する。チケット番号を控えておき、必要に応じて返信でコミュニケーションを継続することが期待される。

## 通知種別

メール通知

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 新規スレッド（mail_new_thread） |
| 優先度 | 高 |
| リトライ | Sidekiqのデフォルト設定に従う |

### 送信先決定ロジック

1. Work Itemの`external_author`を取得
2. 送信先メールアドレスとして使用

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | カスタムメール有効時はカスタムアドレス、無効時はデフォルト |
| 送信元名称 | service_desk_setting.outgoing_name または Support Bot |
| 件名 | `Re: {work_item_title} (#{work_item_iid})` |
| 形式 | HTML/テキスト |

### 本文テンプレート

```
Thank you for your support request! We are tracking your request as ticket #{issue_iid}, and will respond as soon as we can.

To unsubscribe from this issue, please paste the following link into your browser:
{unsubscribe_url}
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| @work_item | Work Itemオブジェクト | WorkItem.find(work_item_id) | Yes |
| @project | プロジェクト | @work_item.project | Yes |
| @support_bot | サポートBot | Users::Internal.support_bot | Yes |
| @service_desk_setting | Service Desk設定 | @project.service_desk_setting | No |
| @sent_notification | 送信通知レコード | SentNotification.record | Yes |
| %{ISSUE_ID} | チケット番号 | WorkItem.reference_prefix + @work_item.iid | Yes |
| %{ISSUE_PATH} | チケットパス | @work_item.to_reference(full: true) | Yes |
| %{ISSUE_DESCRIPTION} | チケット説明 | @work_item.description_html | No |
| %{UNSUBSCRIBE_URL} | 購読解除URL | unsubscribe_sent_notification_url | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| サービス呼び出し | Service Deskメール受信 | Work Item作成成功 | メール受信後の処理フロー内 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| external_author.blank? | 外部送信者が不明な場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[Service Deskメール受信] --> B[Work Item作成]
    B --> C[service_desk_thank_you_email呼び出し]
    C --> D[setup_service_desk_mail]
    D --> E[送信元設定]
    E --> F{カスタムテンプレート存在?}
    F -->|Yes| G[テンプレート展開]
    F -->|No| H[デフォルト本文]
    G --> I[mail_new_thread]
    H --> I
    I --> J[inject_service_desk_custom_email]
    J --> K{カスタムメール有効?}
    K -->|Yes| L[カスタムSMTP設定適用]
    K -->|No| M[デフォルトSMTP]
    L --> N[送信]
    M --> N
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| work_items | チケット情報 | iid, title, external_author |
| projects | プロジェクト情報 | プロジェクト名 |
| service_desk_settings | Service Desk設定 | outgoing_name, custom_email |
| users | ユーザー情報 | Support Bot |
| issue_email_participants | 外部参加者情報 | メールアドレス |

### テーブル別参照項目詳細

#### work_items

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| iid | チケット番号 | 直接参照 |
| title | チケットタイトル | 直接参照 |
| project_id | プロジェクトID | 直接参照 |
| description_html | 説明（HTML） | テンプレート展開用 |

#### service_desk_settings

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| outgoing_name | 送信者名 | 直接参照 |
| custom_email | カスタムメールアドレス | 直接参照 |
| custom_email_enabled | カスタムメール有効フラグ | 直接参照 |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| sent_notifications | INSERT | 送信通知記録 |

#### sent_notifications

| 操作 | 項目（カラム名） | 更新値 | 備考 |
|-----|-----------------|-------|------|
| INSERT | noteable_id | work_item.id | 返信追跡用 |
| INSERT | recipient_id | support_bot.id | 受信者ID |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 送信失敗 | SMTPエラー | Sidekiqによるリトライ |
| Work Item不存在 | WorkItem.find失敗 | 例外発生 |
| カスタムSMTPエラー | カスタムメール送信失敗 | ログ出力、エラー追跡 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Sidekiqデフォルト（25回） |
| リトライ間隔 | 指数バックオフ |
| リトライ対象エラー | SMTP接続エラー、タイムアウト |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし（個別通知） |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（リアルタイム送信）

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

- 外部ユーザーへの送信のため、内部情報を含まない
- カスタムメール機能では認証情報を暗号化して保存
- SentNotificationによる返信キーでメール返信の認証を実現
- 購読解除URLを含み、スパム対策に対応

## 備考

- service_deskレイアウトを使用（override_layout_lookup_table）
- カスタムテンプレート（thank_you）でプロジェクト固有のメッセージを設定可能
- Gitlab::Metrics::BackgroundTransactionでメトリクス記録

---

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

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

### 推奨読解順序

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

Service Desk関連のモデルと設定を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | service_desk_setting.rb | `app/models/service_desk_setting.rb` | outgoing_name, custom_email関連の設定 |

**読解のコツ**: custom_email_enabled?、custom_email_credentialで認証情報を管理する点に注意。

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

メーラークラスでの処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | service_desk.rb | `app/mailers/emails/service_desk.rb` | service_desk_thank_you_emailメソッド（19-38行目） |

**主要処理フロー**:
1. **20行目**: setup_service_desk_mail呼び出し
2. **22-27行目**: sender設定（カスタムメール対応）
3. **29-34行目**: オプション設定とテンプレート適用
4. **36行目**: mail_new_thread呼び出し
5. **37行目**: inject_service_desk_custom_email

#### Step 3: セットアップメソッドを理解する

共通セットアップ処理を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | service_desk.rb | `app/mailers/emails/service_desk.rb` | setup_service_desk_mailメソッド（146-160行目） |

**主要処理フロー**:
- **147行目**: WorkItem.find
- **148行目**: @project設定
- **149行目**: Support Bot取得
- **157-159行目**: SentNotification.record

#### Step 4: ビューテンプレートを理解する

メール本文の構造を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | service_desk_thank_you_email.html.haml | `app/views/notify/service_desk_thank_you_email.html.haml` | HTML形式のテンプレート |
| 4-2 | service_desk_thank_you_email.text.erb | `app/views/notify/service_desk_thank_you_email.text.erb` | テキスト形式のテンプレート |

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

```
Notify.service_desk_thank_you_email(work_item_id)
    │
    ├─ setup_service_desk_mail(work_item_id)
    │      ├─ WorkItem.find(work_item_id)
    │      ├─ @project設定
    │      ├─ Support Bot取得
    │      └─ SentNotification.record
    │
    ├─ sender設定
    │      └─ service_desk_sender_email_address（カスタムメール対応）
    │
    ├─ service_desk_template_content_options('thank_you')
    │      └─ template_content
    │             ├─ Gitlab::Template::ServiceDeskTemplate.find
    │             └─ substitute_template_replacements
    │
    ├─ mail_new_thread(@work_item, options)
    │      └─ 新規スレッドメール生成
    │
    └─ inject_service_desk_custom_email
           └─ カスタムSMTP設定適用（有効時）
```

### データフロー図

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

Service Deskメール    ───▶ Work Item作成              ───▶ service_desk_thank_you_email
(外部ユーザーから)         (メール受信処理)                  │
                                                           ▼
@work_item.iid        ───▶ テンプレート展開            ───▶ メール本文
@work_item.title           (カスタムまたはデフォルト)       │
                                                           ▼
ServiceDeskSetting    ───▶ 送信元設定                 ───▶ From/Reply-To
(custom_email等)           (カスタムメール対応)             │
                                                           ▼
                           inject_service_desk_custom_email
                           (SMTP設定)                       │
                                                           ▼
                                                      外部ユーザーへメール送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| service_desk.rb | `app/mailers/emails/service_desk.rb` | ソース | Service Deskメーラーモジュール |
| notify.rb | `app/mailers/notify.rb` | ソース | メインメーラークラス |
| service_desk_setting.rb | `app/models/service_desk_setting.rb` | ソース | Service Desk設定モデル |
| service_desk_thank_you_email.html.haml | `app/views/notify/service_desk_thank_you_email.html.haml` | テンプレート | HTML形式メール本文 |
| service_desk_thank_you_email.text.erb | `app/views/notify/service_desk_thank_you_email.text.erb` | テンプレート | テキスト形式メール本文 |
| layouts/service_desk.html.haml | `app/views/layouts/service_desk.html.haml` | レイアウト | Service Desk用メールレイアウト |
