日英翻訳チャットシステム

R-EVS

海外のチームと開発の打合せが面倒なので、ChatGPTのAPI連携した、日英翻訳チャットシステムを作ってみました。Wordpressのプラグインなので、簡単に設置可能です。ご希望の方には無料で提供しております
ご希望の方は、以下のフォームからお申込みいただけます。

<?php
session_start();

/**
 * Plugin Name: ChatGPT Translation Plugin
 * Description: A chat system with GPT translation, styled like ChatGPT's layout, with admin API settings.
 * Version: 7.0
 * Author: Rencontru by Hisao Mori
 */

// ショートコードを登録
add_shortcode('chatgpt_translation_chat', 'display_chat_interface');

// 管理画面メニューにAPI設定を追加
add_action('admin_menu', 'chatgpt_translation_plugin_menu');

// Ajax処理を登録
add_action('wp_enqueue_scripts', 'chatgpt_translation_enqueue_scripts');
add_action('wp_ajax_nopriv_chatgpt_send_message', 'handle_chat_submission');
add_action('wp_ajax_chatgpt_send_message', 'handle_chat_submission');
add_action('wp_ajax_nopriv_chatgpt_get_chat_history', 'get_chat_history');
add_action('wp_ajax_chatgpt_get_chat_history', 'get_chat_history');

// フロントエンドのスクリプト登録
function chatgpt_translation_enqueue_scripts() {
    wp_enqueue_style('chatgpt-translation-css', plugins_url('chatgpt-translation.css', __FILE__)); // CSSファイルを読み込み
    wp_enqueue_script('chatgpt-translation-ajax', plugins_url('chatgpt-translation.js', __FILE__), ['jquery'], null, true);
    wp_localize_script('chatgpt-translation-ajax', 'chatgpt_translation_ajax', [
        'ajax_url' => admin_url('admin-ajax.php')
    ]);
}

// 管理画面メニューの追加
function chatgpt_translation_plugin_menu() {
    add_menu_page(
        'ChatGPT API設定', // ページタイトル
        'ChatGPT設定', // メニュータイトル
        'manage_options', // 権限
        'chatgpt-translation-settings', // メニューのスラッグ
        'chatgpt_translation_settings_page' // コールバック関数
    );
}

// 管理画面APIキー設定ページの表示
function chatgpt_translation_settings_page() {
    if (isset($_POST['submit'])) {
        update_option('chatgpt_ren_api_key', sanitize_text_field($_POST['chatgpt_api_key']));
        
        $api_key = get_option('chatgpt_ren_api_key');
        $test_result = test_chatgpt_connection($api_key);

        if ($test_result) {
            echo '<div class="notice notice-success is-dismissible"><p>接続完了</p></div>';
        } else {
            echo '<div class="notice notice-error is-dismissible"><p>接続ができませんでした。</p></div>';
        }
    }
    ?>
    <div class="wrap">
        <h1>ChatGPT API設定</h1>
        <form method="post" action="">
            <table class="form-table">
                <tr valign="top">
                    <th scope="row">APIキー</th>
                    <td>
                        <input type="text" name="chatgpt_api_key" value="<?php echo esc_attr(get_option('chatgpt_ren_api_key')); ?>" size="50"/>
                    </td>
                </tr>
            </table>
            <?php submit_button('保存して接続テスト'); ?>
        </form>
    </div>
    <?php
}

// API接続テスト
function test_chatgpt_connection($api_key) {
    $url = 'https://api.openai.com/v1/chat/completions';
    $data = [
        'model' => 'gpt-3.5-turbo',
        'messages' => [
            ['role' => 'system', 'content' => 'This is a test message.']
        ]
    ];

    $options = [
        'http' => [
            'header' => "Content-type: application/json\r\nAuthorization: Bearer " . $api_key,
            'method'  => 'POST',
            'content' => json_encode($data)
        ]
    ];

    $context = stream_context_create($options);
    $result = @file_get_contents($url, false, $context);

    if ($result === FALSE) {
        return false; // 接続失敗
    }

    return true; // 接続成功
}

// チャットインターフェースの表示
function display_chat_interface() {
    ob_start(); ?>
    <div id="chat-container" class="chat-desktop">
        <!-- 左フレーム: 入力フォーム -->
        <div id="chat-left-frame" class="chat-frame">
            <form id="chat-form" style="display: flex; flex-direction: column;">
                <!-- 日時表示のチェックボックス -->
                <label><input type="radio" name="date_display" value="date_time" checked> Time Display</label>
                <label><input type="radio" name="date_display" value="none"> No time Display</label><br><br>
                
                <input type="text" name="user_name" placeholder="Enter your name" required style="margin-bottom: 10px; width: 100%; height: 40px; font-size: 16px;">
                
                <!-- チェックボックスで翻訳の方向を選択 -->
                <label>
                    <input type="radio" name="translation_direction" value="ja_to_en" checked> Japanese to English
                </label>
                <label>
                    <input type="radio" name="translation_direction" value="en_to_ja"> English to Japanese
                </label><br><br>

                <textarea name="user_message" placeholder="Enter your message" required style="height: 120px; font-size: 16px; margin-bottom: 10px;"></textarea>
                <button type="submit" style="padding: 10px 20px;">Send a message</button>
            </form>
        </div>

        <!-- 右フレーム: チャット履歴 -->
        <div id="chat-right-frame" class="chat-frame">
            <div id="chat-history" style="flex-grow: 1; overflow-y: auto; padding: 10px; height: 100%;">
                <?php display_chat_history(); ?>
            </div>
        </div>
    </div>
    <?php
    return ob_get_clean();
}

// チャット履歴の表示(セッションによる日時表示の制御)
function display_chat_history() {
    $log_file = WP_CONTENT_DIR . "/chatgpt_log/chat_log.csv";

    if (file_exists($log_file)) {
        $file = fopen($log_file, 'r');
        $lines = [];

        while (($line = fgetcsv($file)) !== false) {
            $lines[] = $line;
        }
        fclose($file);

        // ログを逆順にして表示(最新のメッセージが上に来る)
        $lines = array_reverse($lines);

        // セッションの設定がない場合、日時表示有りがデフォルト
        if (!isset($_SESSION['date_display'])) {
            $_SESSION['date_display'] = 'date_time'; // デフォルトで日時表示
        }

        foreach ($lines as $line) {
            list($number, $date, $time, $name, $message) = $line;
            echo "<strong>{$name}</strong>: {$message}<br>";

            // 日時表示の設定に基づき、日時を表示または非表示にする
            if ($_SESSION['date_display'] === 'date_time') {
                echo "<small>{$date} {$time}</small><br>";
            }
        }
    } else {
        echo "まだチャット履歴はありません。";
    }
}

// メッセージ送信とログ保存(セッションを使った日時表示の制御)
function handle_chat_submission() {
    if (isset($_POST['user_message']) && isset($_POST['user_name'])) {
        $message = sanitize_text_field($_POST['user_message']);
        $name = sanitize_text_field($_POST['user_name']);
        $translation_direction = sanitize_text_field($_POST['translation_direction']);
        $_SESSION['date_display'] = sanitize_text_field($_POST['date_display']); // 日時表示の設定をセッションに保存

        $log_file = WP_CONTENT_DIR . "/chatgpt_log/chat_log.csv";

        // ディレクトリが存在しない場合、作成する
        if (!file_exists(WP_CONTENT_DIR . "/chatgpt_log/")) {
            mkdir(WP_CONTENT_DIR . "/chatgpt_log/", 0755, true);
        }

        // GPT APIにメッセージを送信して翻訳されたメッセージを取得
        $translated_message = translate_message_with_gpt($message, $translation_direction);

        // 日本時間を取得
        date_default_timezone_set('Asia/Tokyo');
        $date = date('Y-m-d');
        $time = date('H:i:s');

        // ログファイルにCSV形式でメッセージと翻訳結果を保存
        $file = fopen($log_file, 'a');
        $last_line_number = get_last_log_number($log_file);
        fputcsv($file, [$last_line_number + 1, $date, $time, $name, $message]); // メッセージを記録
        fputcsv($file, [$last_line_number + 1, $date, $time, "TRANS", $translated_message]); // 翻訳結果を記録
        fclose($file);

        // Ajaxに返すレスポンス
        if ($_SESSION['date_display'] === 'date_time') {
            echo nl2br("{$date} {$time} - {$name}: {$message}<br>TRANS: {$translated_message}");
        } else {
            echo nl2br("{$name}: {$message}<br>TRANS: {$translated_message}");
        }

        wp_die();  // Ajax終了
    }
}

// CSVファイルから最後のナンバーを取得する
function get_last_log_number($log_file) {
    $last_line = '';
    if (file_exists($log_file)) {
        $file = fopen($log_file, 'r');
        while (($line = fgetcsv($file)) !== false) {
            $last_line = $line;
        }
        fclose($file);
    }
    return isset($last_line[0]) ? (int)$last_line[0] : 0;
}

// GPT APIを使った翻訳処理
function translate_message_with_gpt($message, $translation_direction) {
    $api_key = get_option('chatgpt_ren_api_key');
    $url = 'https://api.openai.com/v1/chat/completions';

    $system_prompt = ($translation_direction == 'ja_to_en') ? 'Translate from Japanese to English.' : 'Translate from English to Japanese.';

    $data = [
        'model' => 'gpt-3.5-turbo',
        'messages' => [
            ['role' => 'system', 'content' => $system_prompt],
            ['role' => 'user', 'content' => $message]
        ]
    ];

    $options = [
        'http' => [
            'header' => "Content-type: application/json\r\nAuthorization: Bearer " . $api_key,
            'method'  => 'POST',
            'content' => json_encode($data)
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    if ($result === FALSE) {
        return "翻訳に失敗しました。";
    }

    $response = json_decode($result, true);
    return $response['choices'][0]['message']['content'];
}

// チャット履歴を取得(CSVから読み込む)
function get_chat_history() {
    $log_file = WP_CONTENT_DIR . "/chatgpt_log/chat_log.csv";

    if (file_exists($log_file)) {
        $file = fopen($log_file, 'r');
        $lines = [];

        while (($line = fgetcsv($file)) !== false) {
            $lines[] = $line;
        }
        fclose($file);

        // 日時表示設定を取得
        $date_display = isset($_POST['date_display']) ? $_POST['date_display'] : 'date_time'; // デフォルトで日時表示

        // ログを逆順にして表示(最新のメッセージを上にする)
        $lines = array_reverse($lines);

        foreach ($lines as $line) {
            list($number, $date, $time, $name, $message) = $line;
            echo "<strong>{$name}</strong>: {$message}<br>";

            // 日時表示の設定に基づいて日時を表示
            if ($date_display === 'date_time') {
                echo "<small>{$date} {$time}</small><br>";
            }
        }
    } else {
        echo "まだチャット履歴はありません。";
    }
    wp_die();
}

デモは以下よりテスト出来ます。

あわせて読みたい
Rencontru 日英チャットシステム 日英チャットシステム(テスト版)
  • URLをコピーしました!
目次