🏠 返回首頁 

Greasy Fork is available in English.

ChatGPT Message Queue

Queue messages when ChatGPT is still composing responses

// ==UserScript==
// @name        ChatGPT Message Queue
// @match       https://chat.openai.com/*
// @match       https://chatgpt.com/*
// @description Queue messages when ChatGPT is still composing responses
// @version 0.0.1.20250319105457
// @namespace https://greasyfork.org/users/1435046
// ==/UserScript==
(function() {
'use strict';
let queueCount = 0;
let queueObserver;
let processingMessage = false;
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(() => {
// Only proceed if we have messages in queue and we're not currently processing
if (queueCount > 0 && !processingMessage) {
const sendButton = document.querySelector('[data-testid="send-button"]');
const textArea = document.getElementById('prompt-textarea');
// Only click if the send button is enabled and textarea is accessible
if (sendButton && !sendButton.disabled && textArea) {
processingMessage = true;
// Wait for the current response to complete
const checkCompletion = setInterval(() => {
// Look for indicators that the AI has finished responding
const isResponding = document.querySelector('.r###lt-streaming') ||
document.querySelector('[data-testid="stop-generating"]');
if (!isResponding) {
clearInterval(checkCompletion);
// Wait a bit for the UI to fully update
setTimeout(() => {
// Now we can send the next message
sendButton.click();
queueCount--;
queueDisplay.children[0].textContent = `Queue: ${queueCount}`;
processingMessage = false;
// Stop observing when queue is empty
if (queueCount === 0) {
queueObserver.disconnect();
queueObserver = null;
}
}, 500);
}
}, 1000);
}
}
});
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) {
// Allow DOM update
setTimeout(() => {
if (textarea.textContent.trim()) {
queueCount++;
queueDisplay.children[0].textContent = `Queue: ${queueCount}`;
startQueueObserver(); // Start processing queue
}
}, 100);
}
});
}
}).observe(document.body, {childList: true, subtree: true});
})();