# 機能設計書 44-メッセージ翻訳

## 概要

本ドキュメントは、Chatwootにおけるメッセージの多言語翻訳機能の設計を記述します。

### 本機能の処理概要

Google Cloud Translation APIを使用して、会話内のメッセージを指定した言語に翻訳する機能を提供します。翻訳結果はメッセージに保存され、同一言語への再翻訳リクエスト時にはキャッシュから返却されます。

**業務上の目的・背景**：グローバルなカスタマーサポートにおいて、エージェントと顧客が異なる言語を使用する場合があります。メッセージ翻訳機能により、言語の壁を越えたコミュニケーションが可能になり、多言語対応のサポートチームを効率的に運用できます。翻訳結果をキャッシュすることで、API呼び出しを最小限に抑えコスト削減にも貢献します。

**機能の利用シーン**：
- エージェントが外国語の顧客メッセージを理解する場面
- 顧客が外国語のエージェント返信を理解する場面
- 多言語サポートチームでの言語間連携場面

**主要な処理内容**：
1. 翻訳リクエストの受信とキャッシュチェック
2. Google Cloud Translation APIへの翻訳リクエスト送信
3. 翻訳結果のメッセージへの保存
4. 翻訳結果のレスポンス返却

**関連システム・外部連携**：
- Google Cloud Translation API（v3）
- Integrations Hook設定（google_translate）

**権限による制御**：会話にアクセス可能なユーザーが翻訳機能を利用できます。Google Translate統合が設定されている必要があります。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | 会話詳細画面 | 主画面 | メッセージの多言語翻訳 |

## 機能種別

データ連携 / 外部API呼び出し

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | Integer | Yes | 翻訳対象のメッセージID | 存在するメッセージID |
| target_language | String | Yes | 翻訳先言語コード | BCP-47形式（例：ja, en, zh-CN） |

### 入力データソース

- API：`POST /api/v1/accounts/{account_id}/conversations/{conversation_id}/messages/{id}/translate`
- 画面入力：会話詳細画面の翻訳ボタン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| content | String | 翻訳されたテキスト |

### 出力先

- API レスポンス：JSON形式で翻訳結果を返却
- データベース：messagesテーブルのcontent_attributes.translations

## 処理フロー

### 処理シーケンス

```
1. APIリクエスト受信
   └─ translateアクションが呼び出される
2. キャッシュチェック
   └─ message.translations[target_language]の存在確認
3. キャッシュヒット時
   └─ 200 OKで即座に返却（API呼び出しなし）
4. キャッシュミス時
   └─ ProcessorService初期化
5. Hook設定確認
   └─ google_translate hookの存在チェック
6. 翻訳コンテンツ取得
   └─ Emailの場合はHTML/テキストコンテンツを優先
7. Google API呼び出し
   └─ translate_textメソッドで翻訳実行
8. 結果保存
   └─ message.translations[target_language]に保存
9. レスポンス返却
   └─ 翻訳結果をJSON形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[翻訳リクエスト受信] --> B{翻訳キャッシュ存在?}
    B -->|Yes| C[200 OK 即座に返却]
    B -->|No| D[ProcessorService初期化]
    D --> E{google_translate Hook存在?}
    E -->|No| F[nil返却]
    E -->|Yes| G{Emailチャネル?}
    G -->|Yes| H[HTML/テキストコンテンツ取得]
    G -->|No| I[message.content取得]
    H --> J[Google API呼び出し]
    I --> J
    J --> K{翻訳成功?}
    K -->|No| L[nil返却]
    K -->|Yes| M[translations保存]
    M --> N[翻訳結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-001 | 翻訳キャッシュ | 同一言語への翻訳は2回目以降キャッシュから返却 | 翻訳リクエスト時 |
| BR-44-002 | Hook必須 | google_translate hookが設定されていない場合は翻訳不可 | 翻訳リクエスト時 |
| BR-44-003 | Email優先コンテンツ | Emailの場合はHTML > テキスト > contentの順で翻訳対象を決定 | Emailインボックス時 |
| BR-44-004 | 言語コード変換 | target_languageのアンダースコアをハイフンに変換（BCP-47準拠） | API呼び出し時 |

### 計算ロジック

特に複雑な計算ロジックはありません。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 翻訳結果保存 | messages | UPDATE | content_attributes.translationsの更新 |

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

#### messages

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | content_attributes | 翻訳キャッシュの確認 | JSON内のtranslationsキー |
| UPDATE | content_attributes | {translations: {target_language: translated_text}} | マージして保存 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 404 | メッセージ未検出 | 指定されたIDのメッセージが存在しない | 正しいメッセージIDを指定 |
| - | 翻訳失敗 | Google API呼び出し失敗 | null が返却される（エラーではない） |
| - | Hook未設定 | google_translate hookが存在しない | 管理画面でGoogle Translate統合を設定 |

### リトライ仕様

Google APIへのリトライはSDK側で処理されます。アプリケーションレベルでの明示的なリトライは行いません。

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

単一メッセージレコードの更新のため、明示的なトランザクション制御は不要です。

## パフォーマンス要件

- 翻訳結果のキャッシュにより、同一言語への再翻訳はAPI呼び出しなしで即座に返却
- Google Cloud Translation APIの呼び出しは同期処理（ユーザーの待機が発生）

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

- Google Cloud認証情報はhook.settingsに安全に保存
- 翻訳内容は外部APIに送信されることをユーザーに告知する必要あり
- アカウント境界を超えたメッセージへのアクセスは不可

## 備考

- Google Cloud Translation API v3を使用しています
- 言語コードはBCP-47形式（例：ja, en-US, zh-CN）を使用します
- Emailメッセージの場合、HTML形式で翻訳することで書式を維持します

---

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

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

### 推奨読解順序

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

まず、翻訳結果の保存場所を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | message.rb | `app/models/message.rb` | content_attributesのstore定義（109-111行目）、translationsアクセサ |

**読解のコツ**: translationsはcontent_attributesのstoreアクセサとして定義されており、{言語コード: 翻訳テキスト}のハッシュ形式で保存されます。

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

APIエンドポイントの処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | messages_controller.rb | `app/controllers/api/v1/accounts/conversations/messages_controller.rb` | translateアクション（39-55行目） |

**主要処理フロー**:
1. **39-40行目**: キャッシュチェック、存在すれば即座に返却
2. **42-45行目**: ProcessorServiceで翻訳を実行
3. **47-52行目**: 翻訳結果をtranslationsにマージして保存
4. **54行目**: 翻訳結果をJSONで返却

#### Step 3: 翻訳サービスを理解する

Google Cloud Translation APIとの連携を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | processor_service.rb | `lib/integrations/google_translate/processor_service.rb` | 翻訳処理の実装 |

**主要処理フロー**:
- **6-22行目**: performメソッドでhookチェック、翻訳コンテンツ取得、API呼び出し
- **26-28行目**: bcp47_language_codeで言語コード変換
- **51-57行目**: translation_contentでEmail優先ロジック
- **67-69行目**: hookメソッドでgoogle_translate hookを取得
- **71-75行目**: clientメソッドでGoogle Cloud SDKクライアントを初期化

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

```
MessagesController#translate
    │
    ├─ already_translated_content_available?
    │      └─ message.translations[target_language]チェック
    │
    └─ Integrations::GoogleTranslate::ProcessorService#perform
           │
           ├─ hook (google_translate統合の取得)
           │
           ├─ translation_content
           │      ├─ email_content[:html] (Email HTML)
           │      ├─ email_content[:text] (Email テキスト)
           │      └─ message.content (デフォルト)
           │
           └─ client.translate_text
                  │
                  └─ Google::Cloud::Translate::V3::TranslationService::Client
                         │
                         └─ Google Cloud Translation API
```

### データフロー図

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

message_id          ───▶ MessagesController#translate   ───▶ DB (messages.content_attributes.translations)
target_language                   │
                                  │
                    ┌─────────────┼─────────────┐
                    │             │             │
                    ▼             ▼             ▼
              キャッシュ    ProcessorService    nil
              ヒット時          │              (Hook無し)
                    │             │
                    │             ▼
                    │      Google Cloud
                    │      Translation API
                    │             │
                    │             ▼
                    └────────────▶ JSON Response
                                   {content: "翻訳結果"}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| messages_controller.rb | `app/controllers/api/v1/accounts/conversations/messages_controller.rb` | コントローラー | 翻訳APIエンドポイント |
| processor_service.rb | `lib/integrations/google_translate/processor_service.rb` | サービス | Google翻訳API連携 |
| detect_language_service.rb | `lib/integrations/google_translate/detect_language_service.rb` | サービス | 言語検出（関連機能） |
| message.rb | `app/models/message.rb` | モデル | 翻訳結果の保存先 |
| hook.rb | `app/models/integrations/hook.rb` | モデル | Google翻訳統合設定 |
