ChatGPT Export to Markdown (Enhanced with Data)

Export ChatGPT conversation to a Markdown file across multiple sites with correct content extraction.

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey to install this script.

Bu komut dosyasını yüklemek için bir kullanıcı komut dosyası yöneticisi uzantısı yüklemeniz gerekecek.

(Zaten bir kullanıcı komut dosyası yöneticim var, kurmama izin verin!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         ChatGPT Export to Markdown (Enhanced with Data)
// @namespace    https://chatgpt.com
// @version      1.3
// @description  Export ChatGPT conversation to a Markdown file across multiple sites with correct content extraction.
// @match        https://chat.openai.com/*
// @match        https://chatgpt.com/*
// @match        https://*.chatgpt.com/*
// @require      https://cdn.jsdelivr.net/npm/@kudoai/[email protected]/dist/chatgpt.min.js
// @grant        none
// ==/UserScript==

(async () => {
    'use strict';

    // Ensure chatgpt.js is loaded
    await chatgpt.isLoaded();

    // Function to create and insert the export button
    const createExportButton = () => {
        // Check if the button already exists
        if (document.getElementById('export-to-markdown-btn')) {
            return;
        }

        // Create and style the export button
        const button = document.createElement('button');
        button.id = 'export-to-markdown-btn';
        button.innerHTML = 'Export to Markdown';
        button.style.position = 'fixed';
        button.style.bottom = '20px';
        button.style.right = '20px';
        button.style.padding = '10px';
        button.style.zIndex = '10000'; // High zIndex to ensure visibility
        button.style.backgroundColor = '#4CAF50';
        button.style.color = '#fff';
        button.style.border = 'none';
        button.style.borderRadius = '5px';
        button.style.cursor = 'pointer';
        document.body.appendChild(button);

        console.log('Export button added.');

        // Button click handler to export conversation
        button.addEventListener('click', async () => {
            try {
                // Fetch the current conversation data
                const chatData = await chatgpt.getChatData("active", ["msg"], "both");
                const chatTitleData = await chatgpt.getChatData("active", "title");

                // Use the chat's title or a fallback
                const chatTitle = chatTitleData.title || 'ChatGPT_Conversation';
                const sanitizedTitle = chatTitle.replace(/[<>:"/\\|?*]+/g, ''); // Remove invalid filename characters

                // Convert the conversation data to a markdown format
                let markdownContent = `# ${chatTitle}\n\n`;
                chatData.forEach((msg, index) => {
                    markdownContent += `### Message ${index + 1}\n\n`;
                    markdownContent += `**User:**\n\n${msg.user}\n\n`;
                    markdownContent += `**ChatGPT:**\n\n${msg.chatgpt}\n\n---\n`;
                });

                // Create a Blob object from the markdown content
                const blob = new Blob([markdownContent], { type: 'text/markdown' });

                // Create a link element to download the markdown file
                const link = document.createElement('a');
                link.href = URL.createObjectURL(blob);
                link.download = `${sanitizedTitle}.md`;
                link.click();

                // Notify the user
                chatgpt.notify('✅ Exported to Markdown successfully!', 'topRight', 2);
            } catch (error) {
                chatgpt.notify('❌ Failed to export conversation!', 'topRight', 2);
                console.error('Export to Markdown failed:', error);
            }
        });
    };

    // MutationObserver to ensure button is always present
    const observer = new MutationObserver(() => {
        createExportButton(); // Ensure the button is recreated if it's removed
    });

    // Start observing changes in the body
    observer.observe(document.body, { childList: true, subtree: true });

    // Initial delay before inserting the button to ensure the page is fully loaded
    setTimeout(createExportButton, 3000); // Delay by 3 seconds to ensure all dynamic content is loaded
})();