ChatGPT Smart Message Queue

Queue messages based on input field state

As of 18/03/2025. See the latest version.

// ==UserScript==
// @name        ChatGPT Smart Message Queue
// @match       https://chat.openai.com/*
// @match       https://chatgpt.com/*
// @description Queue messages based on input field state
// @version 0.0.1.20250318145059
// @namespace https://gf.zukizuki.org/users/1435046
// ==/UserScript==

(function() {
    'use strict';
    
    let queueCount = 0;
    let queueObserver;
    const queueDisplay = document.createElement('div');

    // Minimal UI setup
    queueDisplay.innerHTML = `
        <span>Queue: ${queueCount}</span>
        <button id="queue-reset">×</button>
    `;
    queueDisplay.style.cssText = `
        position:fixed; bottom:100px; right:20px;
        background:rgba(0,0,0,0.7); color:white;
        padding:5px 10px; border-radius:4px; display:flex; gap:8px;
    `;
    document.body.appendChild(queueDisplay);

    // Reset queue count when button is clicked
    document.getElementById('queue-reset').addEventListener('click', () => {
        queueCount = 0;
        queueDisplay.children[0].textContent = `Queue: ${queueCount}`;
    });

    // Function to start queue processing
    function startQueueObserver() {
        if (queueObserver) return;  // Prevent duplicate observers

        queueObserver = new MutationObserver(() => {
            if (queueCount > 0) {
                document.querySelector('[data-testid="send-button"]')?.click();
                queueCount--;
                queueDisplay.children[0].textContent = `Queue: ${queueCount}`;
            }
            if (queueCount === 0) {
                queueObserver.disconnect();
                queueObserver = null; // Stop observing when queue is empty
            }
        });

        queueObserver.observe(document.body, {childList: true, subtree: true});
    }

    // Core logic: Monitor input field
    new MutationObserver((_, observer) => {
        const textarea = document.getElementById('prompt-textarea');
        if (textarea && !textarea.dataset.queuer) {
            textarea.dataset.queuer = true;
            textarea.addEventListener('keydown', e => {
                if (e.key === 'Enter' && !e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
                    setTimeout(() => { // Allow DOM update
                        if (textarea.textContent.trim()) {
                            queueDisplay.children[0].textContent = `Queue: ${++queueCount}`;
                            startQueueObserver(); // Start processing queue
                        }
                    }, 100);
                }
            });
        }
    }).observe(document.body, {childList: true, subtree: true});
})();