0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ChatGPTとの会話をテキストファイルで出力するChrome拡張機能を作成しました

Posted at

作成した目的

 現在、社内業務での ChatGPT 利用を検討してます。利用にあたってログを取得できるようにしたいという話題が挙がったので、調査がてら Chrome の拡張機能を作成しました。

※社内用なので外部公開はしてませんが、本記事を見てもらえれば作成できると思います。

Animation.gif

作成手順

今回作成した拡張機能 ChatGPT-Prompts-Logger のフォルダ構成は以下の通りです。

ChatGPT-Prompts-Logger
│   manifest.json
│   popup.html
│   popup.js
│   
└───images
        icon128.png
        icon16.png
        icon48.png

上から順に説明します。

  • manifest.json
    • 拡張機能の設定を記述するファイルです。
manifest.json
{
  "manifest_version": 3,
  "name": "ChatGPT Prompts Logger",
  "version": "1.0",
  "description": "Log ChatGPT prompts to the txt file.",
  "permissions": ["activeTab", "scripting", "downloads"],
  "action": {
    "default_title": "ChatGPT Prompts Logger",
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/icon16.png",
      "48": "/images/icon48.png",
      "128": "/images/icon128.png"
    }
  }
}

重要な項目だけ補足説明します。

  • permissions

    • 使用する権限を宣言する項目です。今回は ChatGPTでの会話内容を取得するための activeTab scripting と、ファイルダウンロード用に downloads を宣言してます。
  • action.default_popup

    • ブラウザのツールバーにある拡張機能のアクションボタンをクリックすると表示されるHTMLファイルを指定します。
  • popup.html

    • 拡張機能の簡単なレイアウトです。
popup.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>ChatGPT Prompts Logger</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 10px;
    }
    button {
      background-color: #4CAF50;
      color: white;
      padding: 10px 20px;
      border: none;
      cursor: pointer;
    }
    button:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <h1>ChatGPT Prompts Logger</h1>
  <button id="log">Log to Download</button>
  <script src="popup.js"></script>
</body>
</html>

実際には↓のように表示されます。

image.png

head部で <meta charset="UTF-8"> を宣言しないと、日本語が文字化けするので注意してください。

  • popup.js
    • ChatGPTとの会話内容の取得、ダウンロード処理を行います。
popup.js
document.getElementById("log").addEventListener("click", async () => {
  try {
    // アクティブなタブを取得
    let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    // URLをチェックしてChatGPTのページか確認
    const chatGPTUrlPattern = /https:\/\/chatgpt\.com\/.*/;
    if (!chatGPTUrlPattern.test(tab.url)) {
      alert("この拡張機能は https://chatgpt.com でのみ利用可能です。");
      return;
    }

    // ChatGPTのページからプロンプトを取得
    chrome.scripting.executeScript(
      {
        target: { tabId: tab.id },
        func: () => {
          const messages = Array.from(
            document.querySelectorAll(".text-message")
          );
          return messages
            .map((msg) => msg.innerText)
            .join("\n\n////////////////////////////////////////////////////////////\n\n");
        },
      },
      (results) => {
        if (results && results[0] && results[0].result) {
          // 現在の日付と時間をファイル名とヘッダー文字として使用
          const date = new Date();
          const fileName = `chatgpt_prompts_${date.getFullYear()}${(
            date.getMonth() + 1
          )
            .toString()
            .padStart(2, "0")}${date
            .getDate()
            .toString()
            .padStart(2, "0")}_${date
            .getHours()
            .toString()
            .padStart(2, "0")}${date
            .getMinutes()
            .toString()
            .padStart(2, "0")}${date
            .getSeconds()
            .toString()
            .padStart(2, "0")}.txt`;

          const header = fileName + "\n\n////////////////////////////////////////////////////////////\n\n";

          //プロンプトの内容にヘッダー追加
          const chatContent = header + results[0].result;

          // ダウンロード処理を追加
          const blob = new Blob([chatContent], { type: "text/plain" });
          const url = URL.createObjectURL(blob);

          chrome.downloads.download({
            url: url,
            filename: fileName,
          });
        } else {
          console.error("No results or empty results returned.");
        }
      }
    );
  } catch (error) {
    console.error("Error logging prompts:", error);
  }
});

拡張機能特有のメソッドとしては、以下2つになります。

  • chrome.tabs.query()
    • タブの情報を取得する非同期メソッドです。今回はユーザーが現在使用しているタブを取得したいので、引数に{ active: true, currentWindow: true } を渡してます。
  • chrome.scripting.executeScript()
    • 拡張機能から特定のタブに JavaScript を動的に注入し実行するためのメソッドです。今回はこのメソッドを使って、 .text-message クラスに記述された会話内容をすべて収集してます。

他にもいろいろなことができるので、気になる方はAPIドキュメントを参照してください。

  • images フォルダ
    • アイコン用に 16×16、48×48、128×128サイズの PNG ファイルが必要です。

以上になります!

想像より簡単に作成できたので驚きました。また何かアイディアを思いついたら作成しようと思います。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?