ChatGPTを使いながらChromeの拡張機能を作ってみた

# ChatGPTを使ってChrome拡張機能を自作した

## 1. はじめに

APIリファレンスのページを丸ごと日本語に翻訳したりすると、関数名まで翻訳対象に入ってしまい使いづらかった経験をもとに、選択した範囲のテキストを日本語に翻訳しHPを書き換えるChrome拡張機能の作成方法を解説します。最近話題になっているChatGPTを利用して翻訳が可能な拡張機能を作り、実際に色々試してみた内容をまとめました。
初投稿なので、お手柔らかによろしくお願いいたします。また、アドバイスがあればいただけると幸いです。

対象読者としては、コーディングの基礎文法は理解しているが、実際に何を作ればいいかわからない人を想定しています。この記事を通して、Chrome拡張機能の作成方法や、APIを利用した実用的な開発に触れることができます。

今回目指す完成物は以下の画像のような状態をつくることです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1967764/e617319f-5f8f-6971-8773-ec23bf4337a8.png)


### Chromeの拡張機能のファイル構成

拡張機能のファイル構成は以下のようになります。
- ルートディレクトリ
  - manifest.json
  - background.js
  - content.js

注意: この拡張機能は完全に個人での利用を想定しています。

## 2. 開発環境の準備

このセクションでは、Chrome拡張機能の開発に必要な環境の準備方法について解説します。

### 2.1 必要なソフトウェアのインストール

Chrome拡張機能を開発するためには、以下のソフトウェア・ブラウザアプリが必要です。

- Google Chrome: 拡張機能を実行するためのブラウザ
- テキストエディタ: 拡張機能のコードを編集するためのツール（例: Visual Studio Code, Sublime Text, Atom）
- Deepl: 翻訳を行うAPIの取得

なお、拡張機能を作る際ChatGPTも使用しました。
- ChatGPT: 有料版GPT-4モデルを使用し、コードの骨組みからエラーの修正内容まで幅広く相談可能

これらのソフトウェアを用いて作成いたしました。

### 2.2 APIキーの取得（DeepL API）

この拡張機能では、DeepL APIを使用してテキストを翻訳します。DeepL APIの利用にはAPIキーが必要です。

1. [DeepL APIの公式サイト](https://www.deepl.com/pro#developer)にアクセスし、アカウントを作成またはログインします。
2. ダッシュボードに移動し、APIキーを取得します。具体的な方法を知りたい方は[こちら](https://auto-worker.com/blog/?p=5030)

取得したAPIキーは、後で拡張機能のコードに記載するため、メモしておいてください。


## 3. 拡張機能の構成

このセクションでは、Chrome拡張機能の主要な構成要素について説明し、それぞれの役割を理解します。

拡張機能のファイル構成は以下の通りです。

- ルートディレクトリ
  - manifest.json
  - background.js
  - content.js

### 3.1 manifest.json

manifest.jsonは、拡張機能のメタデータを記述するファイルです。拡張機能の名前、バージョン、アイコン、パーミッション、使用するスクリプトなどの情報を含みます。

### 3.2 background.js

background.jsは、拡張機能のバックグラウンド処理を行うファイルです。このファイルでは、選択したテキストを翻訳するためのコンテキストメニュー項目を追加する処理を行います。

### 3.3 content.js

content.jsは、ユーザが選択したテキストを翻訳し、ページ上の該当テキストを書き換える処理を行うファイルです。DeepL APIを使って翻訳を行い、結果を受け取った後、選択されたテキストを書き換えます。


## 4. コードの作成

このセクションでは、拡張機能の各ファイルに記述するコードを説明します。

### 4.1 manifest.json

以下は、`manifest.json`のコード例です。各行には詳細なコメントが記載されていますが、JSONファイルはコメントに対応していないので削除してお試しください。

```json
{
  "manifest_version": 3, // Manifestのバージョンを指定（今回はバージョン3）
  "name": "Text Translator", // 拡張機能の名前
  "version": "1.0", // 拡張機能のバージョン
  "description": "Translates selected text to Japanese using DeepL API", // 拡張機能の説明文
  "permissions": [ // 必要な権限を指定
    "contextMenus", // コンテキストメニューを使用する権限
    "activeTab", // アクティブなタブにアクセスする権限
    "scripting" // スクリプトを注入する権限
  ],
  "background": { // バックグラウンドスクリプトの設定
    "service_worker": "background.js" // バックグラウンドスクリプトのファイル名
  },
  "content_scripts": [ // コンテンツスクリプトの設定
    {
      "matches": ["<all_urls>"], // すべてのURLに適用
      "js": ["content.js"] // コンテンツスクリプトのファイル名
    }
  ]
}

```
### 4.2 background.js

以下は、`background.js`のコード例です。

```javascript
const apiKey = 'YOUR API KEY'; // ここにDeepL APIキーを設定

// コンテキストメニューに翻訳オプションを追加
chrome.contextMenus.create({
  id: 'translate',
  title: 'Translate selected text',
  contexts: ['selection'],
});

// コンテキストメニューがクリックされたときのリスナーを設定
chrome.contextMenus.onClicked.addListener(async (info, tab) => {
  if (info.menuItemId === 'translate') {
    try {
      // content.jsをアクティブなタブに注入
      await chrome.scripting.executeScript({
        target: { tabId: tab.id },
        files: ['content.js']
      });
      // content.jsに翻訳の指示を送信
      chrome.tabs.sendMessage(tab.id, { action: 'translate' });
    } catch (error) {
      console.error('Error executing script:', error);
    }
  }
});

// メッセージリスナーを設定
chrome.runtime.onMessage.addListener((request, sendResponse) => {
  if (request.action === 'translateText') {
    const text = request.text;
    // テキストを翻訳して結果を送信
    translateText(text, (translatedText) => {
      sendResponse({ translatedText: translatedText });
    });
    return true; 
  }
});

// テキストを翻訳する関数
function translateText(text, callback) {
  const url = `https://api-free.deepl.com/v2/translate`;
  const data = {
    auth_key: apiKey,
    source_lang: 'EN',
    target_lang: 'JA',
    text: text
  };

  const searchParams = new URLSearchParams(data);

  // DeepL APIにリクエストを送信
  fetch(url, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: searchParams.toString()
  })
    .then((response) => response.json())
    .then((data) => callback(data.translations[0].text))
    .catch((error) => console.error('Error:', error));
}

```
### 4.3 content.js

以下は、`content.js`のコード例です。

```javascript
// 選択されたテキストを置き換える関数
function replaceSelectedText(replacementText) {
  const sel = window.getSelection();
  if (sel.rangeCount) {
    const range = sel.getRangeAt(0);
    range.deleteContents(); // 選択範囲の内容を削除
    range.insertNode(document.createTextNode(replacementText)); // 翻訳されたテキストを挿入
  }
}

// メッセージリスナーを設定
chrome.runtime.onMessage.addListener((request) => {
  if (request.action === 'translate') {
    const selectedText = window.getSelection().toString(); // 選択されたテキストを取得
    if (selectedText) {
      // 翻訳リクエストをbackground.jsに送信
      chrome.runtime.sendMessage(
        { action: 'translateText', text: selectedText },
        (response) => {
          replaceSelectedText(response.translatedText); // 翻訳されたテキストで置き換え
        }
      );
    }
  }
});

```
### 4.4 実行結果

このセクションでは、拡張機能が正常に動作していることを示すための実行結果を紹介します。
今回はOpenAIのAPIリファレンスに適用してみます。

1. 選択したテキストの翻訳前の状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1967764/bff861e8-5c22-5319-af2d-d830094de640.png)

2. コンテキストメニューを開いて「Translate selected text」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1967764/d73a8a92-8b2a-a6d1-16a3-8ceb5899a973.png)

3. 翻訳後のテキストが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1967764/4eebb9bd-b0a5-d3ee-8d37-1963e56a071f.png)


上記の画像で、拡張機能が選択したテキストを正常に翻訳し、ページ上のテキストを置き換えることができることを確認できます。



### 5. 拡張機能のテストとデバッグ

このセクションでは、拡張機能のテストとデバッグ方法について説明します。以下の手順で進めます。

1. まず、Chromeブラウザを開いて、右上のメニューから「その他のツール」＞「拡張機能」を選択し、拡張機能管理画面にアクセスします。

2. 画面右上の「デベロッパーモード」を有効にし、出現する「パッケージ化されていない拡張機能を読み込む」ボタンをクリックします。

3. 拡張機能のフォルダを選択して、「開く」をクリックします。これで拡張機能がChromeに追加されます。

4. テストを開始し、拡張機能が正常に動作するか確認します。翻訳が期待通りに行われるか、ページ上のテキストが正しく置き換えられるかなど、機能の動作を確認してください。

5. エラーや不具合が発生した場合、Chromeの「検証」機能を利用して、エラーメッセージや警告を確認します。必要に応じて、ChatGPTに質問を投げて修正を行いました。適切な修正を行い、拡張機能が正常に動作することを確認してください。

6. すべてのテストが完了したら、デバッグ作業は終了です。拡張機能を使用して選択した範囲のテキストの翻訳と置き換えができることを確認しました。


### 6. まとめ

本記事では、Deepl APIを用いて部分的に翻訳を行うChrome拡張機能の作成方法について説明しました。これまで拡張機能の開発経験がなかったものの、ChatGPTに質問しながら進めた結果、所要時間はわずか1〜2時間ほどで完成することができました。

この拡張機能を活用して選択した部分のテキストを翻訳することができるため、今後は選択した部分の要約や画像化などの機能も実装できる可能性があります。これをきっかけに、さらに多機能な拡張機能の開発に挑戦してみることをお勧めします。

参考文献：
[DeepL翻訳の無料版APIキーの登録発行手順！世界一のAI翻訳サービスをAPI利用](https://auto-worker.com/blog/?p=5030)
[Chrome拡張の作り方 (超概要)](https://qiita.com/RyBB/items/32b2a7b879f21b3edefc)