SaveChatGPT

    
      
  • /*
     * @title SaveChatGPT
     * @description ChatGPTのチャットをテキストファイルに
     * @include http://*
     * @license MIT License
     * @require 
     */
    
    (() => {
      function getUserName(element) {
        const imgElements = element.querySelectorAll("img[alt]");
        for (const imgElement of imgElements) {
          const altText = imgElement.alt;
          if (altText) {
            return altText;
          }
        }
        return "?";
      }
    
      function getAssistantName(assistantElement) {
        let assistantName = assistantElement.textContent;
        if (assistantName.length > 32) {
          assistantName = assistantName.substring(0, 32) + '...';
        }
        return assistantName;
      }
    
      function processCodeBlocks(element) {
        const codeBlocks = element.querySelectorAll("pre > div");
        for (const codeBlock of codeBlocks) {
          const language = codeBlock.querySelector(":first-child > span").textContent;
          const code = codeBlock.querySelector("code").textContent;
          const formattedCode = `\n\`\`\`${language}\n${code}\n\`\`\`\n`;
    
          codeBlock.parentElement.innerHTML = formattedCode;
        }
      }
    
      function generateMarkdown(elements) {
        let markdownText = "";
        const lastIndex = elements.length - 2;
        const assistantName = getAssistantName(elements[0].cloneNode(true));
    
        for (let i = 1; i <= lastIndex; i++) {
          const clonedElement = elements[i].cloneNode(true);
          processCodeBlocks(clonedElement);
    
          const userName = getUserName(clonedElement);
          const speaker = userName !== "?" ? userName : assistantName;
          markdownText += `### ${speaker}\n\n`;
    
          markdownText += clonedElement.textContent;
    
          if (i !== lastIndex) {
            markdownText += "\n---\n";
          }
        }
    
        return markdownText;
      }
    
      const elements = document.querySelector("main > div.flex-1 > div.h-full > div > div").children;
      const markdownText = generateMarkdown(elements);
      const pageTitle = document.title || "chatgpt-conversation";
      const filename = `${pageTitle}.md`;
    
      const file = new Blob([markdownText], {
        type: "text/plain"
      });
    
      const a = document.createElement("a");
      a.href = URL.createObjectURL(file);
      a.download = filename;
      a.click();
      a.remove();
    })();
    
    
    
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2023/03/23 16:43:36 - 2023-03-23
  2. 2023/03/23 16:39:44 - 2023-03-23
  3. 2023/03/23 16:39:21 - 2023-03-23
  4. 2023/03/21 20:07:51 - 2023-03-21
  5. 2023/03/21 12:06:21 - 2023-03-21