【パート2】ChatGPTをデスクトップ上から使えるようにデスクトップアプリ化してみた|Node.js & Electron

前回はElectronというNode.jsのフレームワークを使い、ChatGPTをデスクトップアプリとして開く所までいきました。

ですが、これではただページが開けるだけであり、利便性が高いとは言えません。

なので、もう少し使いやすくしていきたいと思います。

1. ショートカットキーの登録


ただアプリを実行して起動するだけでは、WebサイトでChatGPTを開くのとあまり変わらず、デスクトップアプリ化した意味がありません。

なので次はショートカットキーを登録し、いつでもChatGPTの画面を開けるようにしていきます。

まずは、既存の「index.js」のコードを下記のコードに変更してください。

    // モジュールのインポート
    const { app, globalShortcut, BrowserWindow } = require('electron');

    // メインウィンドウの変数
    let mainWindow = null;

    // ウィンドウを作成する関数を定義
    function createWindow () {
      // メインウインドウを作成
      mainWindow = new BrowserWindow({
        width: 1000,
        height: 1000,
        webPreferences: {
          nodeIntegration: false,
        },
        // 初期状態を非表示
        show: false,
      });

      // パスを指定
      let mainPath = 'https://chat.openai.com';
      mainWindow.loadURL(mainPath);

      // ウィンドウが閉じられた時にmainWindowにnullを設定する
      mainWindow.on('closed', () => {
        mainWindow = null;
      });
    }

    // アプリケーションが起動した時に呼び出されるイベントリスナー
    app.on('ready',() => {
      // メインウィンドウの作成
      createWindow();

      // ショートカットキーの登録
      globalShortcut.register('Shift+P', () => {
        if (!mainWindow.isVisible()) {
          mainWindow.show();
        } else {
          mainWindow.hide();
        }
      });
    });

変更点は、一番上の「モジュールのインポート」部分と、中間辺りの「初期状態を非表示」下の方の「ショートカットキーの登録」部分です。

1-1. モジュールのインポート

    // モジュールのインポート
    const { app, globalShortcut, BrowserWindow } = require('electron');  

「globalShortcut」というモジュールを追加しています。

これはオペレーティングシステムに対してグローバルなショートカットを登録・解除できるモジュールで、「グローバルなショートカット」なので、アプリケーションをアクティブ(選択状態)にしていない場合でも動きます。

なので、今回のアプリケーションのウィンドウを選択しておらず、YouTubeなど他の事をしている時でも、ショートカットキーの動作を行えます。

1-2. 初期状態を非表示

      // 初期状態を非表示
    show: false;  

「show: false;」という指定を追加する事によって、プログラムの実行時に非表示の状態になります。

1-3. ショートカットキーの登録

      // ショートカットキーの登録
    globalShortcut.register('Shift+P', () => {
      if (!mainWindow.isVisible()) {
        mainWindow.show();
      } else {
        mainWindow.hide();
      }
    });  

この部分はショートカットキーを設定しているコードになります。

まず、「globalShortcut.register('Shift+P', () => {...})」という部分でShiftキーとPキーを押した時のショートカットを登録します。

そして、そのコールバック関数内の「if (!mainWindow.isVisible())」でメインウインドウが表示されているかの分岐処理をしています。

「表示されていない場合」は「mainWindow.show()」でウインドウを表示させ、「表示されている場合」は「mainWindow.hide()」ウインドウを非表示に変更します。

1-4. ショートカットキー登録の注意点

「globalShortcut.register('Shift+P', () => {...})」では「Shiftキー」と「Pキー」の同時押しの判定をしていますが、この部分が「globalShortcut.register('A+P', () => {...})」の場合だと、「Pキー」のみの判定しか動作しませんでした。

他にも、「globalShortcut.register('Shift+A+P', () => {...})」とAキーの判定を追加していても、最後のPキーとShiftキーの判定しか残りません。

Shiftキー + 何かのキー だと正常に2つのキーの同時押しで判定がされます。

もし、これを解消したい場合は以下のコードのようにすると良いと思います。

      const { app, globalShortcut, BrowserWindow } = require('electron');

    let mainWindow = null;

    let keyA = false;
    let keyB = false;
    let keyC = false;

    function createWindow() {
      // メインウィンドウを作成
      mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          nodeIntegration: false
        }
      });

      mainWindow.loadFile('index.html');

      // ウィンドウが閉じられたときの処理
      mainWindow.on('closed', () => {
        mainWindow = null;
      });
    }

    app.on('ready', () => {
      createWindow();

      // Aキーが押されたときの処理
      globalShortcut.register('A', () => {
        keyA = true;
        checkKeys();
      });

      // Aキーが離されたときの処理
      globalShortcut.register('A+Up', () => {
        keyA = false;
      });

      // Bキーが押されたときの処理
      globalShortcut.register('B', () => {
        keyB = true;
        checkKeys();
      });

      // Bキーが離されたときの処理
      globalShortcut.register('B+Up', () => {
        keyB = false;
      });

      // Cキーが押されたときの処理
      globalShortcut.register('C', () => {
        keyC = true;
        checkKeys();
      });

      // Cキーが離されたときの処理
      globalShortcut.register('C+Up', () => {
        keyC = false;
      });
    });

    // 3つのキーが押されているかを確認する関数
    function checkKeys() {
      if (keyA && keyB && keyC) {
        if (!mainWindow.isVisible()) {
          mainWindow.show();
        } else {
          mainWindow.hide();
        }
      }
    }

    app.on('will-quit', () => {
      // ショートカットの登録解除

2. ショートカットキー動作確認

前回と同じように、確認を行っていきます。

まず、「Shift + Ctrl + @」を押してターミナルを開き、「npx electron index,js」を入力してください。


index.js内で「show: false;」を指定しているので、ここでエンターを押しても何も表示されないはずです。


この状態で「Ctrlキー」と「Pキー」を同時押しするとChatGPTが起動します。


そして、もう一度「Ctrlキー」と「Pキー」を同時押しするとウインドウが非表示になります。


3. ショートカットキーの割り当てについて

今回、ChatPGTのウインドウを表示させる際のショートカットキーとして「Shiftキー + Pキー」を割り当てましたが、通常の文章で大文字のPを入力しようとすると、ChatGPTの画面が起動してしまいます。


「英語の p を大文字にすると P」と入力しようとした所、ウィンドウが起動してしまいました。

このままでは既存のキー入力に支障が出てしまうので、キーを変えた方が良さそうですね。

4. パート2まとめ

パート2ではショートカットキーを割り当て、やっとデスクトップアプリ化をした恩恵がありました。

ですが、まだこのままではいちいちターミナルから起動させなければならず、実用化レベルではないと言えます。

次回以降ではもう少し利便性を高めたいと思います。