Auto Regenerate on Server Busy (DeepSeek)

Automatically regenerates messages on DeepSeek when the server is busy.

  1. // ==UserScript==
  2. // @name Auto Regenerate on Server Busy (DeepSeek)
  3. // @name:ar مُجَدِّد ديب سيك (DeepSeek Regenerator)
  4. // @namespace Violentmonkey Scripts
  5. // @version 1.5
  6. // @description Automatically regenerates messages on DeepSeek when the server is busy.
  7. // @description:ar سكربت مدعوم بالذكاء الاصطناعي لتحسين تجربة المستخدم على ديب سيك من خلال التجديد التلقائي، واكتشاف الأخطاء، والمحاولات الذكية.
  8. // @author Ezio Auditore
  9. // @license MIT
  10. // @icon https://i.imgur.com/3RqMFdM.png
  11. // @match https://chat.deepseek.com/*
  12. // @grant none
  13. // ==/UserScript==
  14.  
  15. (function () {
  16. "use strict";
  17.  
  18. // -----------------------
  19. // Configuration Settings
  20. // -----------------------
  21. // This XPath query checks for a <p> element that contains either the English or Chinese busy message.
  22. const BUSY_MESSAGE_XPATH = `//p[contains(text(), "The server is busy. Please try again later.") or contains(text(), "服务器繁忙")]`;
  23. const REGENERATE_SVG_ID = "重新生成"; // The id of the <rect> element within the regenerate button
  24. const DEBOUNCE_DELAY = 500; // Debounce delay in milliseconds
  25. const CLICK_COOLDOWN = 3000; // Minimum interval between clicks (in ms)
  26. const POLLING_INTERVAL = 3000; // Fallback polling interval (in ms)
  27. const DEBUG = true; // Set to false to disable debug logging
  28.  
  29. // -----------------------
  30. // Internal State Variables
  31. // -----------------------
  32. let lastClickTime = 0;
  33. let debounceTimer = null;
  34.  
  35. // -----------------------
  36. // Utility: Debug Logging
  37. // -----------------------
  38. function log(...args) {
  39. if (DEBUG) {
  40. console.log("[AutoRegenerate]", ...args);
  41. }
  42. }
  43.  
  44. // -----------------------
  45. // Core: Check for Busy Message & Click Regenerate
  46. // -----------------------
  47. function checkForServerBusy() {
  48. log("Checking for busy message...");
  49.  
  50. // Use XPath to locate a <p> element that contains either the English or Chinese busy message.
  51. const busyMessage = document.evaluate(
  52. BUSY_MESSAGE_XPATH,
  53. document,
  54. null,
  55. XPathResult.FIRST_ORDERED_NODE_TYPE,
  56. null
  57. ).singleNodeValue;
  58.  
  59. if (busyMessage) {
  60. log("Busy message detected:", busyMessage.textContent);
  61.  
  62. // Enforce click cooldown to prevent rapid, repeated clicks.
  63. const now = Date.now();
  64. if (now - lastClickTime < CLICK_COOLDOWN) {
  65. log("Click cooldown active; skipping click.");
  66. return;
  67. }
  68.  
  69. // Locate the regenerate button by finding the <rect> element with the specified id.
  70. const regenerateSvg = document.querySelector(
  71. `rect[id="${REGENERATE_SVG_ID}"]`
  72. );
  73. if (regenerateSvg) {
  74. const buttonElement = regenerateSvg.closest("div.ds-icon-button");
  75. if (buttonElement) {
  76. log("Regenerate button found. Clicking...");
  77. buttonElement.click();
  78. lastClickTime = now;
  79. log("Clicked regenerate button.");
  80. } else {
  81. console.error(
  82. "Regenerate button container (div.ds-icon-button) not found."
  83. );
  84. }
  85. } else {
  86. console.error(
  87. "Regenerate SVG element not found with id:",
  88. REGENERATE_SVG_ID
  89. );
  90. }
  91. } else {
  92. log("No busy message detected.");
  93. }
  94. }
  95.  
  96. // -----------------------
  97. // Debounce Wrapper
  98. // -----------------------
  99. function debouncedCheck() {
  100. if (debounceTimer) clearTimeout(debounceTimer);
  101. debounceTimer = setTimeout(checkForServerBusy, DEBOUNCE_DELAY);
  102. }
  103.  
  104. // -----------------------
  105. // MutationObserver Setup
  106. // -----------------------
  107. const observer = new MutationObserver((mutations) => {
  108. debouncedCheck();
  109. });
  110.  
  111. function startObserver() {
  112. if (document.body) {
  113. observer.observe(document.body, { childList: true, subtree: true });
  114. log("MutationObserver started on document.body.");
  115. } else {
  116. document.addEventListener("DOMContentLoaded", () => {
  117. observer.observe(document.body, { childList: true, subtree: true });
  118. log("MutationObserver started after DOMContentLoaded.");
  119. });
  120. }
  121. }
  122.  
  123. // -----------------------
  124. // Fallback Polling
  125. // -----------------------
  126. function startPolling() {
  127. setInterval(checkForServerBusy, POLLING_INTERVAL);
  128. log("Fallback polling started (every", POLLING_INTERVAL, "ms).");
  129. }
  130.  
  131. // -----------------------
  132. // Initialization
  133. // -----------------------
  134. function init() {
  135. startObserver();
  136. startPolling();
  137. // Also perform an initial check once the window loads.
  138. window.addEventListener("load", checkForServerBusy);
  139. }
  140.  
  141. init();
  142. })();