# 画面設計書 49-チャネル設定画面

## 概要

本ドキュメントは、Chatwootのチャネル設定画面（ChannelFactory）の設計仕様を定義するものである。

### 本画面の処理概要

選択されたチャネルタイプに応じた設定フォームを動的に表示するファクトリーコンポーネント。Facebook、Website、Twitter、API、Email、SMS、WhatsApp、LINE、Telegram、Instagram、TikTok、Voiceの各チャネル設定画面を切り替えて表示する。

**業務上の目的・背景**：インボックス作成フローの2番目のステップであり、チャネル選択画面（ChannelList）で選択されたチャネルタイプに基づいて、そのチャネル固有の設定フォームを表示する。各チャネルには独自の認証フロー（OAuth、APIキー、Webhook等）や設定項目があり、このファクトリーパターンにより柔軟にチャネル設定画面を切り替えることができる。

**画面へのアクセス方法**：インボックス新規作成画面（ChannelList）でチャネルを選択することで自動的に遷移する。管理者権限を持つユーザーのみがアクセス可能。

**主要な操作・処理内容**：
1. 選択されたチャネルタイプに応じた設定コンポーネントの動的レンダリング
2. 各チャネル固有の設定入力（認証情報、API キー、Webhook URL等）
3. OAuth認証フロー（Facebook、Instagram、TikTok等）への遷移
4. インボックス作成APIの呼び出し

**画面遷移**：
- 遷移元：インボックス新規作成画面（ChannelList）
- 遷移先：エージェント追加画面、OAuth認証画面（チャネルによる）

**権限による表示制御**：管理者（administrator）のみがアクセス可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | マルチチャネル対応 | 主機能 | 各チャネルタイプの詳細設定 |
| 133 | Facebook認可 | 遷移先機能 | Facebook Pages認可フロー |
| 134 | Google認可 | 遷移先機能 | Google認可フロー |
| 135 | Microsoft認可 | 遷移先機能 | Microsoft認可フロー |
| 136 | Twitter認可 | 遷移先機能 | Twitter認可フロー |
| 137 | Instagram認可 | 遷移先機能 | Instagram認可フロー |
| 138 | TikTok認可 | 遷移先機能 | TikTok認可フロー |
| 140 | WhatsApp認可 | 遷移先機能 | WhatsApp認可フロー |

## 画面種別

登録

## URL/ルーティング

```
/app/accounts/:accountId/settings/inboxes/new/:sub_page
```

- ルート名: `settings_inboxes_page_channel`
- パラメータ:
  - `accountId`: アカウントID
  - `sub_page`: チャネルタイプ（website, facebook, whatsapp, sms, email, api, telegram, line, instagram, tiktok, voice）

## 入出力項目

チャネルタイプにより異なる。代表的なチャネルの入力項目を以下に示す。

### Website チャネル

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| Webサイト名 | String | ○ | インボックス表示名 |
| ドメイン | String | - | Webサイトのドメイン |
| ウィジェットカラー | Color | - | チャットウィジェットの色 |
| ウェルカムタイトル | String | - | ウィジェットの見出し |
| ウェルカムメッセージ | String | - | ウィジェットの説明文 |

### Email チャネル

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| チャネル名 | String | ○ | インボックス表示名 |
| メールアドレス | String | ○ | 受信メールアドレス |
| IMAP設定 | Object | △ | IMAPサーバー設定（手動設定時） |
| SMTP設定 | Object | △ | SMTPサーバー設定（手動設定時） |

### API チャネル

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| チャネル名 | String | ○ | インボックス表示名 |
| Webhook URL | String | - | コールバックURL |

## 表示項目

ChannelFactoryはレンダリング関数でチャネルコンポーネントを動的に切り替えるため、表示項目は各チャネルコンポーネントに依存する。

### 共通構造

| 項目名 | 型 | 説明 |
|--------|-----|------|
| チャネル設定フォーム | Component | 選択されたチャネルタイプに対応するVueコンポーネント |

## イベント仕様

### 1-コンポーネント動的レンダリング

**トリガー**: ルートパラメータ（sub_page）に基づく

**処理フロー**:
1. ChannelFactoryがpropsでchannelNameを受け取る
2. render関数でchannelViewList[channelName]を参照
3. 対応するチャネルコンポーネントをVue.h()でレンダリング
4. 存在しないチャネルタイプの場合はnullを返す

### 2-インボックス作成（各チャネルコンポーネント内）

**トリガー**: フォーム送信ボタンクリック

**処理フロー**:
1. 各チャネルコンポーネントでフォームバリデーション
2. inboxes/createChannel または専用のcreateアクションをディスパッチ
3. APIエンドポイント`POST /api/v1/accounts/:accountId/inboxes`にリクエスト
4. 成功時：エージェント追加画面または設定完了画面へ遷移
5. 失敗時：エラーメッセージ表示

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| インボックス作成 | inboxes | INSERT | インボックスレコード作成 |
| インボックス作成 | channel_web_widgets / channel_email / etc | INSERT | チャネル固有テーブルにレコード作成 |

### テーブル別更新項目詳細

各チャネルタイプにより異なる。チャネル共通のinboxesテーブルの項目を以下に示す。

#### inboxes

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | account_id | 現在のアカウントID | |
| INSERT | name | フォーム入力値 | インボックス名 |
| INSERT | channel_type | Channel::WebWidget等 | チャネルタイプ |
| INSERT | channel_id | 作成されたチャネルID | ポリモーフィック関連 |

## メッセージ仕様

各チャネルコンポーネントにより異なる。共通的なメッセージを以下に示す。

| 種別 | メッセージキー | メッセージ内容 |
|------|---------------|---------------|
| 成功 | - | インボックス作成成功時は次画面へ遷移 |
| エラー | INBOX_MGMT.ADD.*.API.ERROR_MESSAGE | インボックス作成エラー |
| バリデーション | INBOX_MGMT.ADD.*.VALIDATION.* | 入力バリデーションエラー |

## 例外処理

| 例外状態 | 処理内容 |
|----------|---------|
| 無効なチャネルタイプ | nullをレンダリング（何も表示しない） |
| API通信エラー | エラートースト表示 |
| OAuth認証失敗 | エラーメッセージ表示、リトライ促進 |
| 権限不足 | 403エラー、アクセス拒否画面表示 |

## 備考

- ChannelFactoryはdefineComponentとrender関数を使用した動的コンポーネントレンダリング
- 各チャネルコンポーネントは独立したフォームとバリデーションロジックを持つ
- OAuth認証が必要なチャネル（Facebook、Instagram、TikTok等）は外部認証フローへリダイレクト
- WhatsAppはEmbedded Signup（埋め込みサインアップ）フローをサポート

---

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

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

### 推奨読解順序

#### Step 1: ファクトリーパターンを理解する

まず、ChannelFactoryの動的レンダリングロジックを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ChannelFactory.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/ChannelFactory.vue` | render関数と channelViewList |

**読解のコツ**:
- channelViewListオブジェクトでチャネルキーとコンポーネントをマッピング
- propsでchannelNameを受け取り、対応するコンポーネントをh()でレンダリング

#### Step 2: 代表的なチャネルコンポーネントを理解する

Website チャネルを例に、チャネルコンポーネントの構造を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Website.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue` | フォーム構造とAPI呼び出し |

#### Step 3: ルーティングを理解する

ルーティング設定を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | inbox.routes.js | `app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js` | settings_inboxes_page_channel定義 |

**主要処理フロー**:
- **L73-84**: settings_inboxes_page_channelルート定義
- **L81-83**: propsでroute.params.sub_pageをchannelNameとして渡す

#### Step 4: API層を理解する

バックエンドとの通信。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | webChannel.js | `app/javascript/dashboard/api/channel/webChannel.js` | WebChannel API |
| 4-2 | inboxes.js (store) | `app/javascript/dashboard/store/modules/inboxes.js` | createChannel action |

#### Step 5: バックエンドを理解する

Rails側のコントローラ。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | create action |

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

```
ChannelFactory.vue
    │
    ├─ props: channelName (from route.params.sub_page)
    │
    └─ render()
           └─ h(channelViewList[channelName])
                  │
                  ├─ Website.vue (channelName = 'website')
                  ├─ Facebook.vue (channelName = 'facebook')
                  ├─ Whatsapp.vue (channelName = 'whatsapp')
                  ├─ Email.vue (channelName = 'email')
                  ├─ Sms.vue (channelName = 'sms')
                  ├─ Api.vue (channelName = 'api')
                  ├─ Telegram.vue (channelName = 'telegram')
                  ├─ Line.vue (channelName = 'line')
                  ├─ Instagram.vue (channelName = 'instagram')
                  ├─ Tiktok.vue (channelName = 'tiktok')
                  └─ Voice.vue (channelName = 'voice')
                         │
                         └─ フォーム送信
                                └─ inboxes/createWebsiteChannel dispatch
                                       └─ WebChannel.create()
                                              └─ POST /api/v1/.../inboxes
```

### データフロー図

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

ルートパラメータ  ───▶  ChannelFactory.render()  ───▶  チャネルコンポーネント
(sub_page)                     │
                               │
フォーム入力     ───▶  各チャネルコンポーネント  ───▶  インボックス作成
                               │
                        createChannel dispatch   ───▶  次画面遷移
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ChannelFactory.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/ChannelFactory.vue` | ソース | ファクトリーコンポーネント |
| Website.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Website.vue` | ソース | Websiteチャネル設定 |
| Facebook.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Facebook.vue` | ソース | Facebookチャネル設定 |
| Whatsapp.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Whatsapp.vue` | ソース | WhatsAppチャネル設定 |
| Email.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Email.vue` | ソース | Emailチャネル設定 |
| Sms.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Sms.vue` | ソース | SMSチャネル設定 |
| Api.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Api.vue` | ソース | APIチャネル設定 |
| Telegram.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Telegram.vue` | ソース | Telegramチャネル設定 |
| Line.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Line.vue` | ソース | LINEチャネル設定 |
| Instagram.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Instagram.vue` | ソース | Instagramチャネル設定 |
| Tiktok.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Tiktok.vue` | ソース | TikTokチャネル設定 |
| Voice.vue | `app/javascript/dashboard/routes/dashboard/settings/inbox/channels/Voice.vue` | ソース | Voiceチャネル設定 |
| inbox.routes.js | `app/javascript/dashboard/routes/dashboard/settings/inbox/inbox.routes.js` | 設定 | ルーティング定義 |
| inboxes.js (store) | `app/javascript/dashboard/store/modules/inboxes.js` | ソース | Vuexストアモジュール |
| webChannel.js | `app/javascript/dashboard/api/channel/webChannel.js` | ソース | WebChannel API |
| inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | ソース | Railsコントローラ |
