// ==UserScript== // @name Auto click Continue generating // @namespace Violentmonkey Scripts // @match https://chatgpt.com/* // @match https://chat.openai.com/* // @grant none // @version 1.0 // @description 6/4/2024, 6:45:45 PM // ==/UserScript== let stopTime = null; let notifyTimeout = null; let originalTitle = document.title; let titleFlashInterval; function generationStarted() { console.log(`Generation started at: ${new Date(stopTime).toLocaleTimeString()}`); if (notifyTimeout) { clearTimeout(notifyTimeout); notifyTimeout = null; } } function generationStopped() { const elapsedTime = (Date.now() - stopTime) / 1000; console.log(`Generation stopped at: ${new Date().toLocaleTimeString()}, elapsed time: ${elapsedTime} seconds`); // Check for continue generating button const continueBtn = Array.from(document.querySelectorAll('button')).filter(btn => /Continue generating/i.test(btn.innerText)); if (continueBtn.length) { console.log('Auto clicking Continue generating...'); continueBtn[0].click(); } else { console.log(`Generation stopped at: ${new Date().toLocaleTimeString()}, elapsed time: ${elapsedTime} seconds`); // Send notification after it stopped generating notifyTimeout = setTimeout(notify, 1000); } } function notify() { if (document.hidden) { playBeep(); triggerNotification(); } else { playBeep(0.2); // Quieter beep if visible } } // Function to play a beep sound using the Web Audio API function playBeep(volume = 1.0) { const AudioContext = window.AudioContext || window.webkitAudioContext; const audioCtx = new AudioContext(); const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); gainNode.gain.value = volume; oscillator.type = 'square'; oscillator.frequency.setValueAtTime(440, audioCtx.currentTime); // Frequency in hertz (A4) oscillator.start(); gainNode.gain.exponentialRampToValueAtTime(0.00001, audioCtx.currentTime + 1); // 1 second beep oscillator.stop(audioCtx.currentTime + 1); } // Function to trigger a notification function triggerNotification() { if (Notification.permission === 'granted') { console.log('Notification permission granted, triggering notification.'); new Notification('Generation Stopped', { body: 'The generation process has stopped.', }); } else { console.log('Notification permission not granted.'); } } // Function to check the button state let previousState = ''; function checkButtonState() { const targetNode = document.querySelector('button[data-testid="fruitjuice-send-button"], button[data-testid="fruitjuice-stop-button"]'); if (targetNode) { const newValue = targetNode.getAttribute('data-testid'); if (newValue !== previousState) { if (newValue === 'fruitjuice-stop-button') { if (!stopTime) { stopTime = Date.now(); generationStarted(); } } else if (newValue === 'fruitjuice-send-button' && stopTime) { generationStopped(); stopTime = null; // Reset stopTime } previousState = newValue; // Update previous state } } } // Throttling function with leading call function throttle(func, delay) { let lastCall = 0; let timeoutId; return function(...args) { const now = new Date().getTime(); if (now - lastCall < delay) { clearTimeout(timeoutId); timeoutId = setTimeout(() => { lastCall = new Date().getTime(); func(...args); }, delay); return; } lastCall = now; func(...args); }; } // Throttled version of checkButtonState const throttledCheckButtonState = throttle(checkButtonState, 500); const onReady = fn => document.readyState !== 'loading' ? fn() : document.addEventListener('DOMContentLoaded', fn); onReady(() => { // Set an observer on the body element to detect changes const bodyObserver = new MutationObserver(throttledCheckButtonState); bodyObserver.observe(document.body, { childList: true, subtree: true }); // Initial check in case the button is already in the DOM checkButtonState(); // Request notification permission if not already granted if (Notification.permission !== 'granted') { Notification.requestPermission().then(permission => { if (permission === 'granted') { console.log('Notification permission granted.'); } else { console.log('Notification permission denied.'); } }).catch(error => { console.error('Notification permission request error:', error); }); } else { console.log('Notification permission already granted.'); } });