# 通知設計書 50-Flow Send Mail Action

## 概要

本ドキュメントは、ShopwareにおけるFlow Send Mail Actionの仕様を定義する設計書である。これはFlowビルダーで設定可能なメール送信アクションであり、任意のビジネスイベントに対してメールを自動送信するための中核機能について記載する。

### 本通知の処理概要

Flow Send Mail Actionは、ShopwareのFlowビルダーにおける主要なアクションの1つであり、MailAwareインターフェースを実装した任意のイベントに対してメール送信を実行する。管理画面のFlowビルダーからGUIで設定でき、テンプレート選択、受信者設定、添付ファイル設定など、高度なカスタマイズが可能である。

**業務上の目的・背景**：ECサイトでは、注文確認、発送通知、パスワードリセットなど、様々なビジネスイベントに応じてメール通知を送信する必要がある。Flow Send Mail Actionにより、これらのメール送信を管理画面からノーコードで設定でき、ビジネス要件に応じた柔軟な通知ワークフローを構築できる。

**通知の送信タイミング**：Flowビルダーで設定されたトリガーイベント（MailAware実装イベント）が発火した際に、定義された条件を満たす場合にメール送信が実行される。

**通知の受信者**：Flow設定で指定された受信者。default（イベントのMailRecipientStruct）、admin（管理者）、custom（カスタムアドレス）、contactFormMail（お問い合わせ送信者）から選択可能。

**通知内容の概要**：Flow設定で選択されたメールテンプレートに基づいて生成される。件名、本文、添付ファイルはテンプレートとFlow設定により決定される。

**期待されるアクション**：受信者はビジネスイベントに関連する通知を受け取り、必要なアクションを実行する。

## 通知種別

Flow通知（Flowビルダーアクション）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| アクション名 | action.mail.send |
| 送信方式 | 非同期（DelayableAction） |
| 優先度 | Flow設定に依存 |
| リトライ | 有（メッセージキュー経由） |

### 受信者設定オプション

| 受信者タイプ | 説明 | 設定方法 |
|-------------|------|---------|
| default | イベントのMailRecipientStruct | MailAware::getMailStruct() |
| admin | 管理者ユーザー | admin=trueのユーザーを検索 |
| custom | カスタムアドレス | Flow設定で直接指定 |
| contactFormMail | お問い合わせ送信者 | ContactFormEventのemail |

### テンプレート設定

| 設定項目 | 説明 |
|---------|------|
| mailTemplateId | 使用するメールテンプレートID |
| recipient | 受信者設定（type, data） |
| replyTo | 返信先設定 |

## 通知テンプレート

### テンプレート選択

Flow設定画面で、利用可能なメールテンプレートから選択する。テンプレートはmail_templateテーブルに登録されている必要がある。

### テンプレート変数

イベントが提供するデータ（getValues()、getAvailableData()）に基づいてテンプレート変数が決定される。

| 変数カテゴリ | 説明 | 例 |
|-------------|------|-----|
| イベント固有変数 | 各イベントが提供 | order, customer, product等 |
| 共通変数 | 全メールで利用可能 | salesChannel, eventName |
| Flow変数 | Flow設定由来 | 添付ファイル設定等 |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | 対象イベント | 条件 | 説明 |
|------------|-------------|------|------|
| Flowトリガー | MailAware実装イベント | Flow条件一致 | 任意のMailAwareイベント |

### 主要な対応イベント例

| イベント | 説明 |
|---------|------|
| checkout.order.placed | 注文完了 |
| customer.register | 顧客登録 |
| contact_form.send | お問い合わせ送信 |
| order.state.* | 注文ステータス変更 |
| customer.recovery.request | パスワードリカバリー |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| MailSendSubscriberConfig.skip() | 拡張機能でスキップ設定 |
| テンプレートID未設定 | mailTemplateIdが空 |
| テンプレート未存在 | 指定IDのテンプレートなし |
| 受信者空 | recipients配列が空 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ビジネスイベント発火] --> B[Flow Engine]
    B --> C{Flow条件一致?}
    C -->|No| D[スキップ]
    C -->|Yes| E[SendMailAction::handleFlow]
    E --> F{MailSendSubscriberConfig.skip?}
    F -->|Yes| D
    F -->|No| G{MailAwareデータ存在?}
    G -->|No| H[MailEventConfigurationException]
    G -->|Yes| I{mailTemplateId設定?}
    I -->|No| D
    I -->|Yes| J[テンプレート取得]
    J --> K{テンプレート存在?}
    K -->|No| D
    K -->|Yes| L[翻訳設定注入]
    L --> M[受信者決定]
    M --> N{受信者あり?}
    N -->|No| D
    N -->|Yes| O[DataBag構築]
    O --> P[FlowSendMailActionEvent発火]
    P --> Q[テンプレートタイプ更新]
    Q --> R[MailService::send呼び出し]
    R --> S[メール送信]
    S --> T[翻訳設定リセット]
    D --> U[終了]
    H --> U
    T --> U
```

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

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| mail_template | テンプレート取得 | mailTemplateIdで検索 |
| mail_template_type | テンプレートタイプ | templateData更新用 |
| user | 管理者情報 | admin受信者の場合 |
| flow | Flow設定 | アクション設定 |
| flow_sequence | シーケンス設定 | アクション順序 |

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

#### mail_template

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | テンプレートID | eventConfig['mailTemplateId'] |
| content_html | HTML本文 | 翻訳済み |
| content_plain | プレーン本文 | 翻訳済み |
| subject | 件名 | 翻訳済み |
| sender_name | 送信者名 | 翻訳済み |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| mail_template_type | UPDATE | templateDataの更新 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| MailEventConfigurationException | MailAwareデータ不足 | 例外ログ記録 |
| テンプレート未存在 | IDに対応するテンプレートなし | サイレントスキップ |
| 受信者空 | 受信者決定で空配列 | サイレントスキップ |
| 送信失敗 | SMTP等のエラー | try-catch→ログ記録 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | メッセージキュー設定に依存 |
| リトライ間隔 | メッセージキュー設定に依存 |
| リトライ対象エラー | 一時的な送信エラー |

## 配信設定

### レート制限

Flow設定およびシステム設定に依存。

### 配信時間帯

Flow設定の遅延実行機能（DelayableAction）を利用して制御可能。

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

- Flow設定は管理者のみがアクセス可能
- カスタム受信者設定による不正送信に注意
- テンプレート変数に含まれる機密情報の取り扱いに注意
- contactFormMailオプション使用時のメールアドレス検証

## 備考

- アクション名定数：SendMailAction::ACTION_NAME = 'action.mail.send'
- DelayableAction実装により遅延実行が可能
- FlowSendMailActionEventでテンプレートや受信者のカスタマイズが可能
- updateMailTemplate設定でtemplateDataの自動更新を制御

---

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

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

### 推奨読解順序

#### Step 1: アクションクラスを理解する

SendMailActionクラスの構造と主要メソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | ACTION_NAME（41行目）、handleFlow()（86行目〜）、requirements()（77-80行目） |

**読解のコツ**: FlowActionを継承しDelayableActionを実装。requirements()でMailAware必須を定義。handleFlow()がメイン処理。

#### Step 2: handleFlow()を詳細に理解する

メイン処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | handleFlow()（86-176行目）の各ステップ |

**主要処理フロー**:
1. **88-95行目**: MailSendSubscriberConfig取得とスキップ判定
2. **100-101行目**: MailAwareデータ存在チェック
3. **104-107行目**: recipient設定チェック
4. **109-111行目**: mailTemplateIdチェック
5. **113-117行目**: テンプレート取得
6. **119行目**: injectTranslator() - 翻訳設定
7. **126-134行目**: getRecipients() - 受信者決定
8. **136-155行目**: DataBag構築
9. **159行目**: FlowSendMailActionEvent発火
10. **161-168行目**: updateMailTemplateType()
11. **175行目**: send()呼び出し

#### Step 3: 受信者決定ロジックを理解する

getRecipients()メソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | getRecipients()（312-340行目） |

**受信者タイプ別処理**:
- **315-316行目**: RECIPIENT_CONFIG_CUSTOM - Flow設定のカスタムアドレス
- **317-326行目**: RECIPIENT_CONFIG_ADMIN - admin=trueのユーザー検索
- **327-336行目**: RECIPIENT_CONFIG_CONTACT_FORM_MAIL - お問い合わせ送信者
- **337-338行目**: default - MailRecipientStructの受信者

#### Step 4: テンプレート更新を理解する

updateMailTemplateType()メソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | updateMailTemplateType()（207-246行目） |

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

```
Business Event (MailAware)
    │
    └─ Flow Engine
           │
           └─ SendMailAction::handleFlow($flow)
                  │
                  ├─ MailSendSubscriberConfig チェック
                  │
                  ├─ MailAware データ検証
                  │      └─ MAIL_STRUCT, SALES_CHANNEL_ID
                  │
                  ├─ eventConfig 検証
                  │      └─ recipient, mailTemplateId
                  │
                  ├─ getMailTemplate($id, $context)
                  │      └─ mailTemplateRepository->search()
                  │
                  ├─ injectTranslator()
                  │      └─ translator->injectSettings()
                  │
                  ├─ getRecipients()
                  │      ├─ CUSTOM: eventConfig['data']
                  │      ├─ ADMIN: connection->fetchAllAssociative()
                  │      ├─ CONTACT_FORM_MAIL: contactFormData['email']
                  │      └─ default: mailStructRecipients
                  │
                  ├─ DataBag 構築
                  │      ├─ recipients, senderName
                  │      ├─ salesChannelId, languageId
                  │      ├─ templateId, customFields
                  │      ├─ contentHtml, contentPlain, subject
                  │      └─ attachmentsConfig
                  │
                  ├─ FlowSendMailActionEvent dispatch
                  │
                  ├─ updateMailTemplateType()
                  │      └─ mailTemplateTypeRepository->update()
                  │
                  └─ send()
                         └─ emailService->send()
```

### データフロー図

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

StorableFlow                    SendMailAction                       メール送信
  │                                  │                                    │
  ├─ MailAware データ                ├─ テンプレート取得                   ├─ recipients
  │   └─ MAIL_STRUCT                 │                                    ├─ subject
  │   └─ SALES_CHANNEL_ID            ├─ 受信者決定                        ├─ contentHtml
  │                                  │   └─ default/admin/custom/         ├─ contentPlain
  ├─ eventConfig                     │       contactFormMail              └─ attachments
  │   └─ mailTemplateId              │
  │   └─ recipient                   ├─ DataBag構築
  │                                  │
  └─ templateData                    ├─ FlowSendMailActionEvent
      └─ 各イベント固有データ          │
                                     └─ MailService::send()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | ソース | メイン処理クラス |
| FlowSendMailActionEvent.php | `src/Core/Content/Flow/Events/FlowSendMailActionEvent.php` | ソース | カスタマイズ用イベント |
| FlowMailVariables.php | `src/Core/Content/Flow/Dispatching/Action/FlowMailVariables.php` | ソース | メール変数定数 |
| MailService.php | `src/Core/Content/Mail/Service/MailService.php` | ソース | メール送信サービス |
| StorableFlow.php | `src/Core/Content/Flow/Dispatching/StorableFlow.php` | ソース | Flowデータコンテナ |
| MailAware.php | `src/Core/Framework/Event/MailAware.php` | インターフェース | メール対応イベント |
| flow.xml | `src/Core/Content/DependencyInjection/flow.xml` | 設定 | DIコンテナ設定 |
