# 機能設計書 18-マルチチャネル対応

## 概要

本ドキュメントは、Chatwootのマルチチャネル対応機能について、その処理内容、データベース操作、およびコード構成を詳細に記述した設計書である。

### 本機能の処理概要

マルチチャネル対応機能は、Chatwootが複数のコミュニケーションチャネル（Email, SMS, Web Widget, WhatsApp, Facebook, Instagram, Twitter, Telegram, LINE, TikTok等）を統合的にサポートするための基盤機能である。各チャネルは独自のデータモデルを持ち、Channelableというポリモーフィックな仕組みで統一的に管理される。

**業務上の目的・背景**：現代のカスタマーサポートでは、顧客は多様なチャネルを通じてコミュニケーションを取る。Web チャット、メール、SNS、メッセージングアプリなど、顧客が好むチャネルでサポートを提供することが重要である。マルチチャネル対応により、すべてのチャネルからの問い合わせを単一のダッシュボードで管理できる。

**機能の利用シーン**：
- 新しいコミュニケーションチャネルの追加
- チャネル固有の設定変更
- チャネル認証情報の管理
- メッセージの送受信（チャネル固有のAPI連携）

**主要な処理内容**：
1. Channelable Concernによる共通インターフェースの提供
2. 各チャネルモデル（Channel::*）の実装
3. チャネル固有の認証・設定管理
4. チャネルごとのメッセージ送受信処理
5. Webhookによる外部サービスからのイベント受信

**関連システム・外部連携**：
- Facebook Graph API（Facebook, Instagram）
- WhatsApp Business API
- Twilio API（SMS, WhatsApp）
- Twitter API
- Telegram Bot API
- LINE Messaging API
- TikTok API
- 各種SMTP/IMAPサーバー（Email）

**権限による制御**：
- チャネルの作成・編集はAdministratorロールのみ
- チャネル認証情報はセキュアに暗号化保存

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 47 | インボックス一覧画面 | 参照画面 | 各チャネルタイプの表示 |
| 48 | インボックス新規作成画面 | 主画面 | 利用可能なチャネルの表示 |
| 49 | チャネル設定画面 | 主画面 | 各チャネルタイプの詳細設定 |

## 機能種別

データモデル / API連携 / 外部サービス統合

## 入力仕様

### チャネル種別と入力パラメータ

#### Channel::WebWidget
| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| website_url | String | Yes | Webサイト URL |
| widget_color | String | No | ウィジェットカラー（デフォルト: #1f93ff） |
| welcome_title | String | No | ウェルカムタイトル |
| welcome_tagline | String | No | ウェルカムタグライン |
| reply_time | Integer | No | 返信時間設定 |
| pre_chat_form_enabled | Boolean | No | プリチャットフォーム有効化 |

#### Channel::Email
| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| email | String | Yes | メールアドレス |
| imap_enabled | Boolean | No | IMAP有効化 |
| imap_address | String | No | IMAPサーバーアドレス |
| smtp_enabled | Boolean | No | SMTP有効化 |
| smtp_address | String | No | SMTPサーバーアドレス |

#### Channel::Whatsapp
| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| phone_number | String | Yes | 電話番号 |
| provider | String | No | プロバイダ（default / whatsapp_cloud） |
| provider_config | JSON | Yes | プロバイダ設定 |

#### Channel::Telegram
| パラメータ名 | 型 | 必須 | 説明 |
|-------------|-----|-----|------|
| bot_token | String | Yes | Telegramボットトークン |

#### その他のチャネル
各チャネルごとにEDITABLE_ATTRS定数で編集可能属性が定義されている。

### 入力データソース

- 画面入力（チャネル設定画面からの操作）
- API経由（REST API）
- OAuth認可フロー（Facebook, Instagram, Twitter等）

## 出力仕様

### 出力データ

各チャネルタイプに固有の属性を含むJSONオブジェクト。

### 出力先

- APIレスポンス（JSON形式）
- 外部APIへのメッセージ送信

## 処理フロー

### 処理シーケンス

```
1. チャネル作成リクエスト受信
   └─ InboxesController.create 経由

2. チャネルタイプ判定
   └─ allowed_channel_types でチェック

3. チャネルオブジェクト作成
   └─ channel_type_from_params でクラス取得
   └─ account_channels_method.create! で作成

4. チャネル固有の初期化処理
   ├─ WebWidget: website_token, hmac_token 自動生成
   ├─ Email: forward_to_email 自動生成
   ├─ Whatsapp: webhook_verify_token 生成, テンプレート同期
   └─ Telegram: Webhook設定

5. インボックスとの関連付け
   └─ inbox.channel = channel

6. レスポンス返却
```

### フローチャート

```mermaid
flowchart TD
    A[チャネル作成リクエスト] --> B{チャネルタイプ判定}
    B -->|web_widget| C[Channel::WebWidget作成]
    B -->|email| D[Channel::Email作成]
    B -->|whatsapp| E[Channel::Whatsapp作成]
    B -->|telegram| F[Channel::Telegram作成]
    B -->|line| G[Channel::Line作成]
    B -->|sms| H[Channel::Sms作成]
    B -->|api| I[Channel::Api作成]
    C --> J[固有初期化処理]
    D --> J
    E --> K[Webhook設定 + テンプレート同期]
    F --> L[Telegram Webhook設定]
    G --> J
    H --> J
    I --> J
    K --> M[インボックス作成]
    L --> M
    J --> M
    M --> N[レスポンス返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ユニーク制約 | 各チャネルの識別子（電話番号、メール等）はグローバルでユニーク | チャネル作成時 |
| BR-002 | 認証情報暗号化 | センシティブな認証情報（トークン、パスワード）は暗号化保存 | チャネル保存時 |
| BR-003 | プロバイダ検証 | WhatsAppのproviderはdefaultまたはwhatsapp_cloudのみ許可 | WhatsAppチャネル作成時 |
| BR-004 | Webhook自動設定 | Telegram、WhatsApp Cloudは作成時にWebhook自動設定 | チャネル作成後 |
| BR-005 | テンプレート同期 | WhatsAppチャネルは作成時にテンプレート自動同期 | WhatsAppチャネル作成後 |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| WebWidget作成 | channel_web_widgets | INSERT | WebWidgetチャネルレコード作成 |
| Email作成 | channel_email | INSERT | Emailチャネルレコード作成 |
| WhatsApp作成 | channel_whatsapp | INSERT | WhatsAppチャネルレコード作成 |
| Telegram作成 | channel_telegram | INSERT | Telegramチャネルレコード作成 |
| SMS作成 | channel_sms | INSERT | SMSチャネルレコード作成 |
| TwilioSMS作成 | channel_twilio_sms | INSERT | TwilioSMSチャネルレコード作成 |
| Line作成 | channel_line | INSERT | LINEチャネルレコード作成 |
| API作成 | channel_api | INSERT | APIチャネルレコード作成 |

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

各チャネルテーブルはチャネル固有の属性を持つ。共通してaccount_idカラムを持ち、アカウントとの関連を管理する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 403 | Forbidden | 操作権限がない | 権限確認メッセージ表示 |
| 422 | UnprocessableEntity | バリデーションエラー（ユニーク制約違反等） | エラー内容を表示 |
| 422 | UnprocessableEntity | プロバイダ設定エラー（認証失敗等） | 認証情報確認案内 |

### リトライ仕様

外部API連携（Webhook設定、テンプレート同期等）は失敗時にprompt_reauthorization!を呼び出し、再認証を促す。

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

チャネル作成はインボックス作成と同一トランザクション内で実行される。

## パフォーマンス要件

- チャネル作成: 5秒以内（外部API連携含む）
- 外部API連携はタイムアウト設定あり

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

- 認証情報（トークン、パスワード）はActiveRecord暗号化で保護
- Webhook URLにはセキュアトークンを含む
- HMAC検証によるWebhookリクエスト認証

## 備考

- 各チャネルはChannelable Concernをincludeし、共通インターフェースを持つ
- 新しいチャネルタイプを追加する場合はChannel::*モデルを作成し、Channelableをinclude

---

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

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

### 推奨読解順序

#### Step 1: 共通インターフェースを理解する

Channelable Concernで定義された共通インターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | channelable.rb | `app/models/concerns/channelable.rb` | 共通バリデーション、アソシエーション |

**読解のコツ**:
- `validates :account_id, presence: true` で必須のアカウント関連を確認
- `has_one :inbox, as: :channel, polymorphic: true` でポリモーフィック関連を確認
- `prepend_mod_with('Channelable')` でEnterprise拡張ポイントを確認

**主要処理フロー**:
1. **3-8行目**: included ブロック - バリデーション、アソシエーション定義
2. **10行目**: create_audit_log_entry - 監査ログ用フック（空実装）

#### Step 2: 各チャネルモデルを理解する

代表的なチャネルモデルの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | web_widget.rb | `app/models/channel/web_widget.rb` | WebWidgetチャネル |
| 2-2 | email.rb | `app/models/channel/email.rb` | Emailチャネル |
| 2-3 | whatsapp.rb | `app/models/channel/whatsapp.rb` | WhatsAppチャネル |
| 2-4 | telegram.rb | `app/models/channel/telegram.rb` | Telegramチャネル |

**Channel::WebWidget の主要処理フロー**:
1. **29行目**: `include Channelable`
2. **34-40行目**: `EDITABLE_ATTRS` - 編集可能属性定義
3. **47-48行目**: `has_secure_token` - トークン自動生成
4. **50-55行目**: `has_flags` - 機能フラグ定義
5. **63-81行目**: `web_widget_script` - 埋め込みスクリプト生成

**Channel::Whatsapp の主要処理フロー**:
1. **35行目**: `after_create :sync_templates`
2. **37行目**: `after_commit :setup_webhooks`
3. **43-49行目**: `provider_service` - プロバイダ別サービス取得

#### Step 3: インボックスとの関連を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | inbox.rb | `app/models/inbox.rb` | ポリモーフィック関連 |

**主要処理フロー**:
- **60行目**: `belongs_to :channel, polymorphic: true, dependent: :destroy`
- **113-159行目**: チャネルタイプ判定メソッド群

#### Step 4: コントローラでのチャネル作成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | チャネル作成処理 |

**主要処理フロー**:
1. **107-111行目**: `create_channel` - チャネルオブジェクト作成
2. **113-115行目**: `allowed_channel_types` - 許可チャネルタイプ
3. **188-198行目**: `channel_type_from_params` - パラメータからクラス取得
4. **200-202行目**: `get_channel_attributes` - チャネル固有属性取得

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

```
Api::V1::Accounts::InboxesController
    │
    ├─ create_channel
    │      │
    │      ├─ allowed_channel_types チェック
    │      │
    │      ├─ channel_type_from_params
    │      │      └─ 'web_widget' → Channel::WebWidget
    │      │      └─ 'email' → Channel::Email
    │      │      └─ 'whatsapp' → Channel::Whatsapp
    │      │      └─ 'telegram' → Channel::Telegram
    │      │      └─ 'line' → Channel::Line
    │      │      └─ 'sms' → Channel::Sms
    │      │      └─ 'api' → Channel::Api
    │      │
    │      └─ account.channels_method.create!
    │             │
    │             └─ Channel::* (各チャネルモデル)
    │                    │
    │                    ├─ include Channelable
    │                    │
    │                    ├─ バリデーション実行
    │                    │
    │                    └─ after_create コールバック
    │                           ├─ WebWidget: has_secure_token
    │                           ├─ Whatsapp: sync_templates, setup_webhooks
    │                           └─ Telegram: setup_telegram_webhook
    │
    └─ Inbox.create!(channel: channel)
```

### データフロー図

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

APIリクエスト ────────▶ InboxesController ────────────▶ JSONレスポンス
(channel: {type: ...})       │
                             ▼
                      create_channel
                             │
                             ▼
                    Channel::* モデル
                             │
                             ├───▶ channel_* テーブル
                             │
                             └───▶ 外部API連携
                                    ├─ Telegram Webhook
                                    ├─ WhatsApp Templates
                                    └─ Facebook Subscribe
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| channelable.rb | `app/models/concerns/channelable.rb` | Concern | チャネル共通インターフェース |
| web_widget.rb | `app/models/channel/web_widget.rb` | モデル | WebWidgetチャネル |
| email.rb | `app/models/channel/email.rb` | モデル | Emailチャネル |
| whatsapp.rb | `app/models/channel/whatsapp.rb` | モデル | WhatsAppチャネル |
| telegram.rb | `app/models/channel/telegram.rb` | モデル | Telegramチャネル |
| facebook_page.rb | `app/models/channel/facebook_page.rb` | モデル | Facebookチャネル |
| twitter_profile.rb | `app/models/channel/twitter_profile.rb` | モデル | Twitterチャネル |
| sms.rb | `app/models/channel/sms.rb` | モデル | SMSチャネル |
| twilio_sms.rb | `app/models/channel/twilio_sms.rb` | モデル | Twilio SMSチャネル |
| line.rb | `app/models/channel/line.rb` | モデル | LINEチャネル |
| api.rb | `app/models/channel/api.rb` | モデル | APIチャネル |
| instagram.rb | `app/models/channel/instagram.rb` | モデル | Instagramチャネル |
| tiktok.rb | `app/models/channel/tiktok.rb` | モデル | TikTokチャネル |
