ChatGPT Question Automation

Read a file and input its contents into an input field

目前为 2023-06-09 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name ChatGPT Question Automation
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.12
  5. // @description Read a file and input its contents into an input field
  6. // @author You
  7. // @match https://chat.openai.com/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. "use strict";
  14. const panel = document.createElement("div");
  15. panel.style.position = "fixed";
  16. panel.style.top = "0";
  17. panel.style.right = "0";
  18. panel.style.backgroundColor = "white";
  19. panel.style.padding = "10px";
  20. panel.style.border = "1px solid black";
  21. panel.style.width = "100px"; // 控制面板的宽度
  22. panel.style.fontFamily = "'Arial', sans-serif"; // 设定字体
  23. document.body.appendChild(panel);
  24.  
  25. // 在面板上添加文件输入元素
  26. const fileInput = document.createElement("input");
  27. fileInput.type = "file";
  28. fileInput.style.marginTop = "10px"; // 增加间距
  29. fileInput.style.width = "100%"; // 控制输入框的宽度
  30. panel.appendChild(fileInput);
  31.  
  32. // 显示文件名的标签
  33. const fileNameLabel = document.createElement("span");
  34. fileNameLabel.style.display = "block"; // 使得每个元素占用一行
  35. fileNameLabel.style.marginTop = "10px"; // 增加间距
  36. panel.appendChild(fileNameLabel);
  37.  
  38. // 在面板上添加输入元素以获取通用提示
  39. const promptLabel = document.createElement("span");
  40. promptLabel.textContent = "Prompt: ";
  41. promptLabel.style.display = "block"; // 使得每个元素占用一行
  42. panel.appendChild(promptLabel);
  43. const promptInput = document.createElement("input");
  44. promptInput.type = "text";
  45. promptInput.style.marginTop = "10px"; // 增加间距
  46. promptInput.style.width = "100%"; // 控制输入框的宽度
  47. panel.appendChild(promptInput);
  48. // 在面板上添加是否每25次发送后休息的复选框
  49. const restLabel = document.createElement("label");
  50. restLabel.textContent = "sleep after every 25 sends";
  51. restLabel.style.display = "block"; // 使得每个元素占用一行
  52. panel.appendChild(restLabel);
  53.  
  54. const restCheckbox = document.createElement("input");
  55. restCheckbox.type = "checkbox";
  56. restCheckbox.style.marginTop = "10px"; // 增加间距
  57. panel.appendChild(restCheckbox);
  58. // 每次信息发送后,暂停时间输入
  59. const delayInput = document.createElement("input");
  60. delayInput.type = "number";
  61. delayInput.style.marginTop = "10px"; // 增加间距
  62. delayInput.style.width = "100%"; // 控制输入框的宽度
  63. delayInput.placeholder = "sleeptime(s)";
  64. panel.appendChild(delayInput);
  65.  
  66. // 在面板上添加确认按钮
  67. const confirmButton = document.createElement("button");
  68. confirmButton.textContent = "确认";
  69. confirmButton.style.marginTop = "10px"; // 增加间距
  70. confirmButton.style.width = "100%"; // 控制按钮的宽度
  71. panel.appendChild(confirmButton);
  72.  
  73. // 在面板上添加任务完成进度的标签
  74. const progressBar = document.createElement("progress");
  75. progressBar.style.width = "100%"; // 控制进度条的宽度
  76. progressBar.style.marginTop = "10px"; // 增加间距
  77. progressBar.max = 1; // 最大值设为1(代表100%)
  78. panel.appendChild(progressBar);
  79.  
  80. // 在面板上添加一个用于显示提示的 div 元素
  81. const alertDiv = document.createElement("div");
  82. alertDiv.style.position = "fixed";
  83. alertDiv.style.top = "10px";
  84. alertDiv.style.right = "10px";
  85. alertDiv.style.padding = "10px";
  86. alertDiv.style.backgroundColor = "red";
  87. alertDiv.style.color = "white";
  88. alertDiv.style.display = "none"; // 默认隐藏
  89. document.body.appendChild(alertDiv);
  90.  
  91. // 创建一个函数用于显示提示
  92. function showAlert(message) {
  93. alertDiv.textContent = message;
  94. alertDiv.style.display = "block"; // 显示提示
  95. setTimeout(function () {
  96. alertDiv.style.display = "none"; // 3 秒后隐藏提示
  97. }, 3000);
  98. }
  99.  
  100. // 当用户点击确认按钮时,开始执行操作
  101. confirmButton.addEventListener("click", function () {
  102. let fileContent;
  103.  
  104. // 如果 localStorage 中存在文件
  105. if (localStorage.getItem("savedFile")) {
  106. // 从 localStorage 获取文件内容
  107. fileContent = localStorage.getItem("savedFile");
  108. } else {
  109. // 从文件输入框获取文件
  110. const file = fileInput.files[0];
  111. if (!file) {
  112. showAlert("请先选择文件");
  113. return;
  114. }
  115. const reader = new FileReader();
  116. reader.onload = function (e) {
  117. fileContent = e.target.result;
  118. handleFileContent(fileContent);
  119. };
  120. reader.readAsText(file);
  121. return;
  122. }
  123.  
  124. handleFileContent(fileContent);
  125. });
  126.  
  127. function handleFileContent(fileContent) {
  128. // 用 fileContent 进行后续操作...
  129. const jsonData = JSON.parse(fileContent);
  130.  
  131. if (Array.isArray(jsonData)) {
  132. let messagesSent = 0;
  133. let messageCount = 0;
  134.  
  135. // 在 handleFileContent 中,获取通用提示
  136. const prompt = promptInput.value || localStorage.getItem("prompt");
  137. localStorage.setItem("prompt", prompt);
  138. progressBar.max = jsonData.length; // 设置进度条的最大值
  139.  
  140. function sendMessage() {
  141. if (messageCount >= jsonData.length) {
  142. // taskProgressLabel.textContent = "Finish!"; // 更新任务进度标签的内容
  143. progressBar.value = jsonData.length; // 将进度条设为满值
  144. return;
  145. }
  146.  
  147. const inputField = document.querySelector("#prompt-textarea");
  148. if (!inputField) {
  149. return;
  150. }
  151. const item = jsonData[messageCount++];
  152. //添加通用提示到消息的开头
  153. inputField.value = prompt + item.title;
  154. // inputField.value = item.title;
  155.  
  156. var inputEvent = new Event("input", { bubbles: true });
  157. inputField.dispatchEvent(inputEvent);
  158.  
  159. setTimeout(function () {
  160. var submit_button = document.querySelector(
  161. "#__next > div.overflow-hidden.w-full.h-full.relative.flex.z-0 > div > div > main > div.absolute.bottom-0.left-0.w-full.border-t.md\\:border-t-0.dark\\:border-white\\/20.md\\:border-transparent.md\\:dark\\:border-transparent.md\\:bg-vert-light-gradient.bg-white.dark\\:bg-gray-800.md\\:\\!bg-transparent.dark\\:md\\:bg-vert-dark-gradient.pt-2 > form > div > div.flex.flex-col.w-full.py-\\[10px\\].flex-grow.md\\:py-4.md\\:pl-4.relative.border.border-black\\/10.bg-white.dark\\:border-gray-900\\/50.dark\\:text-white.dark\\:bg-gray-700.rounded-xl.shadow-xs.dark\\:shadow-xs > button"
  162. );
  163. submit_button.click();
  164. }, 1000);
  165.  
  166. var sleep_time = 100000 || delayInput.value * 1000;
  167. messagesSent++;
  168.  
  169. // taskProgressLabel.textContent = `progress rate : ${messagesSent} / ${jsonData.length} `; // 更新任务进度标签的内容
  170. progressBar.value = messagesSent; // 更新进度条的值
  171.  
  172. if (restCheckbox.checked && messagesSent >= 25) {
  173. // 如果用户选中了复选框,并且已经发送了25个消息,等待三小时再发送下一个
  174. setTimeout(sendMessage, 3 * 60 * 60 * 1000 - 25 * sleep_time);
  175. messagesSent = 0;
  176. } else {
  177. setTimeout(sendMessage, sleep_time);
  178. }
  179. }
  180.  
  181. sendMessage();
  182. }
  183. }
  184. // 当文件改变时,更新标签中的文件名
  185. fileInput.addEventListener("change", function () {
  186. if (this.files && this.files.length) {
  187. fileNameLabel.textContent = this.files[0].name;
  188. // 将文件内容存储到 localStorage
  189. var reader = new FileReader();
  190. reader.onload = function (event) {
  191. localStorage.setItem("savedFile", event.target.result);
  192. localStorage.setItem("savedFileName", fileInput.files[0].name); // 存储文件名
  193. };
  194. reader.readAsText(this.files[0]);
  195. }
  196. });
  197.  
  198. // 当页面加载时,尝试从 localStorage 恢复文件名
  199. window.addEventListener("load", function () {
  200. var savedFileName = localStorage.getItem("savedFileName");
  201. if (savedFileName) {
  202. fileNameLabel.textContent = savedFileName; // 更新标签中的文件名
  203. }
  204. var prompt = localStorage.getItem("prompt");
  205. if (prompt) {
  206. promptInput.value = prompt;
  207. }
  208. });
  209. })();