# 画面設計書 74-エージェントボット一覧画面

## 概要

本ドキュメントはChatwootのエージェントボット一覧画面に関する設計書です。Webhookベースのボットを作成・管理し、インボックスに割り当てる機能を提供する画面について記述しています。

### 本画面の処理概要

本画面では、エージェントボットの作成・編集・削除を管理します。エージェントボットは外部のWebhookエンドポイントと連携し、会話の自動応答やワークフローの自動化を実現します。各ボットにはアクセストークンが発行され、外部システムとのセキュアな通信に使用されます。

**業務上の目的・背景**：カスタマーサポートの自動化を実現するため、企業は独自のボットロジックを外部システムで実装し、Chatwootと連携させることができます。これにより、FAQ回答の自動化、チケットの振り分け、外部システムとの連携などが可能になり、サポート担当者の負荷軽減と対応品質の向上を実現します。

**画面へのアクセス方法**：サイドバーの「設定」から「エージェントボット」メニューを選択してアクセスします。または、URLで直接 `/app/accounts/:accountId/settings/agent-bots` にアクセスすることもできます。

**主要な操作・処理内容**：
1. ボット一覧の表示：登録済みボットの名前、説明、WebhookURLを表示
2. 新しいボットの追加：名前、説明、WebhookURL、アバターを設定して作成
3. 既存ボットの編集：ボット情報の更新
4. ボットの削除：不要なボットを削除
5. アクセストークンの管理：トークンのコピー、リセット

**画面遷移**：
- 遷移元：設定ホーム画面
- 遷移先：なし（モーダルで操作完結）

**権限による表示制御**：管理者（administrator）権限を持つユーザーのみがアクセス可能です。システムボット（system_bot）は編集・削除ボタンが非表示になります。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 181 | ボット応答 | 主機能 | エージェントボットの一覧表示と管理 |
| 182 | ボット割り当て | 補助機能 | ボットの配置設定（インボックス設定画面で実行） |

## 画面種別

一覧

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| パス | `/app/accounts/:accountId/settings/agent-bots` |
| ルート名 | `agent_bots` |
| コンポーネント | `Index.vue` |

## 入出力項目

### ボット追加/編集フォーム

| 項目名 | 項目ID | 種別 | 型 | 必須 | バリデーション | 説明 |
|--------|--------|------|-----|------|---------------|------|
| ボット名 | botName | 入力 | String | Yes | required | ボットの表示名 |
| 説明 | botDescription | 入力 | String | No | - | ボットの説明文 |
| WebhookURL | botUrl | 入力 | String | Yes | required, url | ボットのWebhookエンドポイント |
| アバター | botAvatar | 入力 | File | No | - | ボットのアバター画像 |

## 表示項目

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| ボット一覧 | agentBots | 登録済みボットのリスト |
| ボット名 | bot.name | ボットの表示名 |
| 説明 | bot.description | ボットの説明文 |
| WebhookURL | bot.outgoing_url / bot.bot_config.webhook_url | ボットのWebhookエンドポイント |
| アバター | bot.thumbnail | ボットのアバター画像 |
| システムボットバッジ | bot.system_bot | グローバルボット識別バッジ |
| アクセストークン | bot.access_token | APIアクセストークン（編集モーダル内） |

## イベント仕様

### 1-ボット追加ボタン押下

**トリガー**: 「Add Agent Bot」ボタンのクリック

**処理フロー**:
1. `modalType`を'create'に設定
2. `selectedBot`をクリア
3. `agentBotModalRef`のダイアログを開く
4. フォーム入力後、送信時に`agentBots/create`アクションを呼び出し
5. 成功時、レスポンスからアクセストークンを取得して表示
6. アクセストークン確認後、モーダルを閉じる

### 2-ボット編集ボタン押下

**トリガー**: 各ボット行の「Edit」ボタンのクリック

**処理フロー**:
1. `modalType`を'edit'に設定
2. `selectedBot`に対象ボットを設定
3. `agentBotModalRef`のダイアログを開く
4. フォーム編集後、送信時に`agentBots/update`アクションを呼び出し
5. 成功時、モーダルを閉じる

### 3-ボット削除ボタン押下

**トリガー**: 各ボット行の「Delete」ボタンのクリック

**処理フロー**:
1. `selectedBot`に対象ボットを設定
2. `agentBotDeleteDialogRef`を開く
3. 確認後、`confirmDeletion`を実行
4. `agentBots/delete`アクションを呼び出し
5. 成功時、アラートを表示しダイアログを閉じる

### 4-アクセストークンコピー

**トリガー**: アクセストークン表示エリアの「Copy」ボタンのクリック

**処理フロー**:
1. `copyTextToClipboard`でトークンをクリップボードにコピー
2. コピー成功のアラートを表示

### 5-アクセストークンリセット

**トリガー**: アクセストークン表示エリアの「Reset」ボタンのクリック

**処理フロー**:
1. `agentBots/resetAccessToken`アクションを呼び出し
2. 新しいトークンを受け取り、表示を更新
3. リセット成功のアラートを表示

### 6-アバター削除

**トリガー**: アバター領域の「Delete」ボタンのクリック

**処理フロー**:
1. `agentBots/deleteAgentBotAvatar`アクションを呼び出し
2. 成功時、ローカル状態のアバターをクリア
3. 削除成功のアラートを表示

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ボット追加 | agent_bots | INSERT | 新しいエージェントボットの作成 |
| ボット編集 | agent_bots | UPDATE | エージェントボット情報の更新 |
| ボット削除 | agent_bots | DELETE | エージェントボットの削除 |
| アバター削除 | active_storage_attachments | DELETE | ボットアバターの削除 |
| トークンリセット | agent_bots | UPDATE | アクセストークンの更新 |

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

#### agent_bots

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | account_id | 現在のアカウントID | - |
| INSERT | name | フォーム入力値 | ボット名 |
| INSERT | description | フォーム入力値 | 説明 |
| INSERT | outgoing_url | フォーム入力値 | WebhookURL |
| INSERT | bot_type | 'webhook' | 固定値 |
| INSERT | access_token | 自動生成 | APIトークン |
| UPDATE | name | フォーム入力値 | 編集時 |
| UPDATE | description | フォーム入力値 | 編集時 |
| UPDATE | outgoing_url | フォーム入力値 | 編集時 |
| UPDATE | access_token | 自動再生成 | リセット時 |
| DELETE | id | selectedBot.id | 削除対象ID |

## メッセージ仕様

| 種別 | キー | メッセージ | 表示条件 |
|------|-----|-----------|---------|
| 成功 | AGENT_BOTS.ADD.API.SUCCESS_MESSAGE | ボットが正常に作成されました | ボット追加成功時 |
| エラー | AGENT_BOTS.ADD.API.ERROR_MESSAGE | ボットの作成に失敗しました | ボット追加失敗時 |
| 成功 | AGENT_BOTS.EDIT.API.SUCCESS_MESSAGE | ボットが正常に更新されました | ボット編集成功時 |
| エラー | AGENT_BOTS.EDIT.API.ERROR_MESSAGE | ボットの更新に失敗しました | ボット編集失敗時 |
| 成功 | AGENT_BOTS.DELETE.API.SUCCESS_MESSAGE | ボットが正常に削除されました | ボット削除成功時 |
| エラー | AGENT_BOTS.DELETE.API.ERROR_MESSAGE | ボットの削除に失敗しました | ボット削除失敗時 |
| 成功 | AGENT_BOTS.ACCESS_TOKEN.COPY_SUCCESSFUL | トークンがコピーされました | コピー成功時 |
| 成功 | AGENT_BOTS.ACCESS_TOKEN.RESET_SUCCESS | トークンがリセットされました | リセット成功時 |
| エラー | AGENT_BOTS.ACCESS_TOKEN.RESET_ERROR | トークンのリセットに失敗しました | リセット失敗時 |
| 成功 | AGENT_BOTS.AVATAR.SUCCESS_DELETE | アバターが削除されました | アバター削除成功時 |
| エラー | AGENT_BOTS.AVATAR.ERROR_DELETE | アバターの削除に失敗しました | アバター削除失敗時 |
| 空状態 | AGENT_BOTS.LIST.404 | ボットが見つかりません | ボットが0件の場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 権限不足 | 管理者権限がない場合、画面にアクセスできない |
| API通信エラー | エラーメッセージをアラートで表示 |
| 無効なURL | バリデーションエラーを表示（url形式チェック） |
| ファイルアップロードエラー | アバターアップロード失敗時にエラーを表示 |

## 備考

- システムボット（system_bot=true）は編集・削除ボタンが非表示
- ボットタイプは現在'webhook'のみ対応
- アバター画像はFormDataでmultipart/form-dataとして送信
- アクセストークンは作成時のみ全文表示、以降は部分マスクされる場合がある
- ボットをインボックスに割り当てる操作は別画面（インボックス設定）で行う

---

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

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

### 推奨読解順序

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

まず、エージェントボットのデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | agentBots.js (store) | `app/javascript/dashboard/store/modules/agentBots.js` | stateのrecords配列構造、agentBotInboxの関係 |

**読解のコツ**: ボットオブジェクトにはname, description, outgoing_url, thumbnail, access_token, system_bot等のプロパティがある。FormDataで画像を含むデータを送信する仕組みを確認。

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

処理の起点となるVueコンポーネントを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Index.vue | `app/javascript/dashboard/routes/dashboard/settings/agentBots/Index.vue` | setup関数でのストアアクセス、テーブル表示ロジック |

**主要処理フロー**:
1. **行22-23**: `useMapGetter`でボット一覧とUIフラグを取得
2. **行75-77**: `onMounted`で`agentBots/get`アクションを呼び出し
3. **行40-49**: モーダルタイプに応じた追加/編集の切り替え
4. **行57-67**: `deleteAgentBot`でボット削除処理

#### Step 3: モーダルコンポーネントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AgentBotModal.vue | `app/javascript/dashboard/routes/dashboard/settings/agentBots/components/AgentBotModal.vue` | フォームバリデーション、アクセストークン表示 |

**主要処理フロー**:
- **行51-71**: Vuelidateによるバリデーション設定
- **行152-203**: `handleSubmit`でボット作成/更新処理
- **行229-245**: `onResetToken`でアクセストークンリセット
- **行133-149**: `handleAvatarDelete`でアバター削除

#### Step 4: APIレイヤーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | agentBots.js (API) | `app/javascript/dashboard/api/agentBots.js` | multipart/form-dataでのリクエスト送信 |

**主要処理フロー**:
- **行9-13**: `create`でFormData送信
- **行15-19**: `update`でFormData送信
- **行21-23**: `deleteAgentBotAvatar`でアバター削除
- **行25-27**: `resetAccessToken`でトークンリセット

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

```
Index.vue (エントリーポイント)
    │
    ├─ onMounted
    │      └─ store.dispatch('agentBots/get')
    │             └─ AgentBotsAPI.get()
    │
    ├─ openAddModal / openEditModal
    │      └─ AgentBotModal.vue
    │             ├─ handleSubmit
    │             │      └─ store.dispatch('agentBots/create' or 'update')
    │             │             └─ AgentBotsAPI.create() or update()
    │             │
    │             ├─ handleAvatarDelete
    │             │      └─ store.dispatch('agentBots/deleteAgentBotAvatar')
    │             │             └─ AgentBotsAPI.deleteAgentBotAvatar()
    │             │
    │             └─ onResetToken
    │                    └─ store.dispatch('agentBots/resetAccessToken')
    │                           └─ AgentBotsAPI.resetAccessToken()
    │
    └─ openDeletePopup
           └─ Dialog (削除確認)
                  └─ confirmDeletion
                         └─ store.dispatch('agentBots/delete')
                                └─ AgentBotsAPI.delete()
```

### データフロー図

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

ボットフォーム ─────────▶ FormData作成 ────────────────▶ API送信
      │                        │
      │                        ▼
      │                 agentBots/create ─────────────▶ ボット作成
      │                        │                          │
      │                        ▼                          ▼
      │                 レスポンス取得 ────────────────▶ access_token表示
      │
      └── アバター画像 ─▶ FormData.append ─────────────▶ multipart送信

[一覧表示]

store.agentBots ───────▶ v-for rendering ─────────────▶ テーブル行
      │                        │
      │                        ▼
      └── system_bot? ─────── 条件分岐 ────────────────▶ ボタン表示制御
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Index.vue | `app/javascript/dashboard/routes/dashboard/settings/agentBots/Index.vue` | ソース | メイン画面コンポーネント |
| AgentBotModal.vue | `app/javascript/dashboard/routes/dashboard/settings/agentBots/components/AgentBotModal.vue` | ソース | ボット追加/編集モーダル |
| agentBots.js (API) | `app/javascript/dashboard/api/agentBots.js` | ソース | API通信クラス |
| agentBots.js (store) | `app/javascript/dashboard/store/modules/agentBots.js` | ソース | Vuexストアモジュール |
| agentBot.routes.js | `app/javascript/dashboard/routes/dashboard/settings/agentBots/agentBot.routes.js` | ソース | ルーティング定義 |
| AccessToken.vue | `app/javascript/dashboard/routes/dashboard/settings/profile/AccessToken.vue` | ソース | アクセストークン表示コンポーネント |
| Avatar.vue | `app/javascript/dashboard/components-next/avatar/Avatar.vue` | ソース | アバターコンポーネント |
| Dialog.vue | `app/javascript/dashboard/components-next/dialog/Dialog.vue` | ソース | ダイアログコンポーネント |
