ChatGPT play sound when finish generating

Plays a custom chime when chatgpt finishes

  1. // ==UserScript==
  2. // @name ChatGPT play sound when finish generating
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Plays a custom chime when chatgpt finishes
  6. // @author Salvador Martinez
  7. // @match https://chatgpt.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. let isGenerating = false;
  15.  
  16. function logEvent(message, type = 'info') {
  17. const timestamp = new Date().toLocaleTimeString();
  18. const styles = {
  19. info: 'color: blue; font-weight: bold;',
  20. success: 'color: green; font-weight: bold;',
  21. warning: 'color: orange; font-weight: bold;',
  22. error: 'color: red; font-weight: bold;'
  23. };
  24. if (type === 'warning' || type === 'error' || type === 'success' || message.includes('started') || message.includes('finished')) {
  25. console.log(`%c[Task Finished - ${timestamp}] ${message}`, styles[type] || styles.info);
  26. }
  27. }
  28.  
  29. function playCustomChime() {
  30. const AudioContext = window.AudioContext || window.webkitAudioContext;
  31. const context = new AudioContext();
  32. const gainNode = context.createGain();
  33. gainNode.connect(context.destination);
  34. gainNode.gain.value = 0.2; // Adjust volume as needed
  35.  
  36. // Frequencies for the chime
  37. const frequencies = [659.26, 659.26, 659.26, 987.76]; // E5, E5, E5, B5
  38. const durations = [150, 150, 150, 300]; // Note durations
  39.  
  40. let startTime = context.currentTime;
  41.  
  42. frequencies.forEach((freq, index) => {
  43. const oscillator = context.createOscillator();
  44. oscillator.connect(gainNode);
  45. oscillator.type = 'triangle'; // Triangle wave for that custom sound
  46. oscillator.frequency.value = freq;
  47. oscillator.start(startTime);
  48. oscillator.stop(startTime + durations[index] / 1000);
  49. startTime += durations[index] / 1000;
  50. });
  51.  
  52. }
  53.  
  54. function checkGeneration() {
  55. const generatingButton = document.querySelector('button[data-testid="stop-button"]');
  56.  
  57. if (generatingButton) {
  58. if (!isGenerating) {
  59. isGenerating = true;
  60. }
  61. } else {
  62. if (isGenerating) {
  63. isGenerating = false;
  64. playCustomChime();
  65. }
  66. }
  67. }
  68.  
  69. setInterval(checkGeneration, 500);
  70. })();