# 機能設計書 132-APIチャネル

## 概要

本ドキュメントは、Chatwootシステムにおける「APIチャネル」機能の設計仕様を記載する。APIチャネルは、外部システムとChatwootを連携するためのカスタム統合チャネルである。

### 本機能の処理概要

APIチャネルは、Chatwootが標準でサポートしていないメッセージングプラットフォームやカスタムアプリケーションとの連携を可能にする汎用チャネル機能である。Webhook URLを設定することで、Chatwootからの応答を外部システムに送信できる。

**業務上の目的・背景**：
企業は様々なコミュニケーションチャネル（社内システム、独自開発アプリ、特定業界向けプラットフォーム等）を使用しており、Chatwootの標準チャネルだけでは対応できないケースがある。APIチャネルは、開発者が任意のシステムとChatwootを連携させるための拡張ポイントを提供し、統一的なカスタマーサポート基盤の構築を可能にする。

**機能の利用シーン**：
- 独自開発のモバイルアプリからChatwootへメッセージを送信する場合
- 社内システムとChatwootを連携してサポートチケットを管理する場合
- Chatwootが標準サポートしていないメッセージングプラットフォームと連携する場合
- IoTデバイスからの通知をChatwootで受信・対応する場合

**主要な処理内容**：
1. APIチャネルの作成とidentifier（一意識別子）の自動生成
2. Webhook URLの設定によるエージェント応答の外部送信
3. HMAC認証によるセキュアなAPI呼び出し
4. 追加属性（additional_attributes）によるカスタム設定
5. Public APIを通じた外部からのメッセージ受信
6. エージェント応答時間ウィンドウの設定

**関連システム・外部連携**：
- 外部システム（Webhook受信側）
- Public API（メッセージ受信用）
- HMACによる署名検証

**権限による制御**：
- インボックスの作成・編集にはAdministrator権限が必要
- Public APIは認証不要だが、HMAC必須設定時は署名検証が必要
- エージェントはインボックスメンバーとして割り当てられることで会話に参加可能

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 47 | インボックス一覧画面 | 参照画面 | インボックスの一覧表示 |
| 48 | インボックス新規作成画面 | 主画面 | 新しいAPIチャネルインボックスの作成 |
| 50 | インボックス設定画面 | 主画面 | 既存インボックスの詳細設定 |

## 機能種別

CRUD操作 / API連携 / Webhook配信

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| webhook_url | String | No | エージェント応答送信先URL | 最大長: URL_LENGTH_LIMIT |
| hmac_mandatory | Boolean | No | HMAC認証の必須化 | デフォルト: false |
| additional_attributes | JSONB | No | カスタム追加属性 | 任意のJSONオブジェクト |
| agent_reply_time_window | Integer | No | エージェント応答時間ウィンドウ（秒） | 0より大きい正の整数 |

### 入力データソース

- 管理画面でのユーザー入力
- API経由でのプログラマティック設定
- Public API経由での外部システムからのメッセージ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| identifier | String | APIチャネル識別用トークン（自動生成、一意） |
| hmac_token | String | HMAC検証用シークレットトークン（自動生成、一意） |
| inbox_id | Integer | 作成されたインボックスID |
| webhook_url | String | 設定されたWebhook URL |

### 出力先

- 管理画面への表示
- API レスポンス（JSON形式）
- Webhook URL（エージェント応答時）

## 処理フロー

### 処理シーケンス

```
1. インボックス作成リクエスト受信
   └─ 管理者がチャネルタイプ「api」を選択

2. バリデーション実行
   └─ webhook_url 長さチェック
   └─ agent_reply_time_window 値チェック（設定されている場合）

3. チャネル作成
   └─ Channel::Api レコード作成
   └─ identifier 自動生成（SecureRandom）
   └─ hmac_token 自動生成（SecureRandom）

4. インボックス作成
   └─ Inbox レコード作成
   └─ チャネルとの関連付け

5. 外部システムからのメッセージ受信（運用時）
   └─ Public API経由でメッセージ受信
   └─ HMAC検証（hmac_mandatory時）
   └─ 会話・メッセージ作成

6. エージェント応答時（運用時）
   └─ Webhook URLへ応答を送信
```

### フローチャート

```mermaid
flowchart TD
    A[開始: インボックス作成リクエスト] --> B{チャネルタイプ = api?}
    B -->|No| C[他チャネル処理へ]
    B -->|Yes| D[バリデーション実行]
    D --> E{webhook_url長さOK?}
    E -->|No| F[エラーレスポンス]
    E -->|Yes| G{agent_reply_time_window > 0?}
    G -->|No かつ 設定あり| F
    G -->|Yes または 未設定| H[Channel::Api作成]
    H --> I[identifier生成]
    I --> J[hmac_token生成]
    J --> K[Inbox作成]
    K --> L[成功レスポンス]
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-132-01 | 一意識別子 | identifierとhmac_tokenは一意である必要がある | チャネル作成時 |
| BR-132-02 | HMAC必須時検証 | hmac_mandatoryがtrueの場合、署名なしリクエストは拒否 | Public API呼び出し時 |
| BR-132-03 | Webhook送信 | webhook_urlが設定されている場合、エージェント応答時にWebhookを送信 | エージェントメッセージ送信時 |
| BR-132-04 | 応答時間ウィンドウ | agent_reply_time_windowが設定されている場合、指定時間内のみ応答可能 | エージェントメッセージ送信時 |
| BR-132-05 | URL長さ制限 | webhook_urlはURL_LENGTH_LIMIT（システム定義）を超えてはならない | チャネル作成・更新時 |

### 計算ロジック

特になし。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| チャネル作成 | channel_api | INSERT | 新規APIチャネル作成 |
| インボックス作成 | inboxes | INSERT | インボックス作成とチャネル関連付け |
| 設定更新 | channel_api | UPDATE | チャネル設定の更新 |
| 削除 | channel_api | DELETE | チャネル削除（非同期） |
| 削除 | inboxes | DELETE | インボックス削除（非同期） |

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

#### channel_api

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | account_id | Current.account.id | アカウントID、NOT NULL |
| INSERT | identifier | SecureRandom自動生成 | 一意制約あり |
| INSERT | hmac_token | SecureRandom自動生成 | 一意制約あり |
| INSERT | webhook_url | params[:webhook_url] | Webhook送信先URL |
| INSERT | hmac_mandatory | params[:hmac_mandatory] or false | HMAC必須フラグ |
| INSERT | additional_attributes | params[:additional_attributes] | JSON形式の追加属性 |
| UPDATE | 各設定カラム | params値 | 許可された属性のみ |

#### inboxes

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | name | 'API' or params[:name] | インボックス名 |
| INSERT | channel_type | 'Channel::Api' | チャネルタイプ |
| INSERT | channel_id | 作成されたチャネルID | ポリモーフィック関連 |
| INSERT | account_id | Current.account.id | アカウントID |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 422 | Validation Error | webhook_urlがURL_LENGTH_LIMIT超過 | 短いURLを使用 |
| 422 | Validation Error | agent_reply_time_windowが0以下 | 正の整数を指定 |
| 422 | Validation Error | identifierの重複 | 再生成（システム内部処理） |
| 403 | Forbidden | HMAC検証失敗 | 正しいHMAC署名で再リクエスト |

### リトライ仕様

- トークン生成時に重複が発生した場合、has_secure_tokenにより自動的に再生成される
- Webhook送信失敗時のリトライはWebhookJobの設定に依存

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

チャネル作成とインボックス作成はActiveRecord::Base.transactionでラップされ、いずれかが失敗した場合はロールバックされる。

## パフォーマンス要件

- API レスポンス: 200ms以内
- identifierとhmac_tokenにはユニークインデックスが設定
- Webhook送信は非同期ジョブで実行

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

- HMAC認証によるリクエスト検証が可能
- identifierは公開されるが、hmac_tokenは管理者のみアクセス可能
- Webhook URLへの送信はHTTPS推奨
- CSRFトークンによる保護（管理API）

## 備考

- APIチャネルはChatwootの拡張性の要となる機能
- Public APIを通じて外部システムからメッセージを受信
- Webhook機能でエージェント応答を外部システムに連携

---

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

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

### 推奨読解順序

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

まず、APIチャネルのデータモデルとデータベーススキーマを理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | api.rb | `app/models/channel/api.rb` | チャネルモデルの定義、EDITABLE_ATTRS、バリデーション |
| 1-2 | channelable.rb | `app/models/concerns/channelable.rb` | 共通のチャネル機能 |

**読解のコツ**:
- `has_secure_token`はRailsの機能で、一意のトークンを自動生成
- `EDITABLE_ATTRS`は更新可能な属性のホワイトリスト
- `ensure_valid_agent_reply_time_window`はカスタムバリデーション

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

管理APIのコントローラーがエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | インボックスCRUD操作の実装 |

**主要処理フロー**:
1. **30-42行目**: create アクション - チャネル作成とインボックス作成をトランザクション内で実行
2. **107-110行目**: create_channel - チャネルタイプに応じたチャネル作成
3. **113-115行目**: allowed_channel_types - 許可されるチャネルタイプに「api」が含まれる

#### Step 3: モデルの詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | api.rb | `app/models/channel/api.rb` | 全体構造の再確認 |

**主要処理フロー**:
- **21-24行目**: モデル定義とテーブル名設定
- **25行目**: EDITABLE_ATTRS定義（webhook_url, hmac_mandatory, additional_attributes）
- **27行目**: identifier のhas_secure_token
- **28行目**: hmac_token のhas_secure_token
- **29行目**: ensure_valid_agent_reply_time_window バリデーション
- **30行目**: webhook_url の長さバリデーション
- **32-34行目**: name メソッド（'API'を返す）
- **38-43行目**: ensure_valid_agent_reply_time_window - カスタムバリデーションロジック

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

```
Api::V1::Accounts::InboxesController#create
    |
    +-- create_channel
    |       |
    |       +-- Channel::Api.create!
    |               |
    |               +-- has_secure_token :identifier
    |               +-- has_secure_token :hmac_token
    |               +-- validate :ensure_valid_agent_reply_time_window
    |               +-- validates :webhook_url, length: { maximum: ... }
    |
    +-- Current.account.inboxes.build
            |
            +-- Inbox.save!

Public API (メッセージ受信時)
    |
    +-- HMAC検証（hmac_mandatory時）
    |
    +-- Contact/Conversation/Message作成

WebhookJob (エージェント応答時)
    |
    +-- webhook_url へ POST送信
```

### データフロー図

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

管理者入力           --> InboxesController#create     --> Inbox + Channel作成
(webhook_url等)          |                                 |
                         +-- Channel::Api.create!          +-- identifier
                         +-- Inbox.create!                  +-- hmac_token

外部システム         --> Public API                    --> 会話・メッセージ作成
(メッセージ送信)         |                                 |
                         +-- HMAC検証                       +-- Contact作成
                         +-- Message作成                    +-- Conversation作成

エージェント応答     --> WebhookJob                    --> Webhook送信
(メッセージ送信)         |                                 |
                         +-- HTTPリクエスト構築             +-- 外部システムへ配信
                         +-- webhook_url へ POST
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| api.rb | `app/models/channel/api.rb` | モデル | APIチャネルのデータモデル |
| channelable.rb | `app/models/concerns/channelable.rb` | Concern | チャネル共通機能 |
| inboxes_controller.rb | `app/controllers/api/v1/accounts/inboxes_controller.rb` | コントローラー | インボックスCRUD API |
| limits.rb | `app/models/limits.rb` | 定数 | URL_LENGTH_LIMIT等の制限値定義 |
| webhook_job.rb | `app/jobs/webhook_job.rb` | ジョブ | Webhook送信の非同期処理 |
