求助:如何实现通过URL参数自动提交ChatGPT问题?
问题:ChatGPT用户脚本自动提交问题失败
官方仅支持通过API向ChatGPT传递问题,我写了个用户脚本,想读取URL里的question参数,把问题填入ChatGPT输入框并自动提交。目前已经能从URL提取参数并填入id为prompt-textarea的文本框,但自动提交搞不定,模拟键盘交互时还存在焦点问题,求技术指导。
现有实现代码
// 1. 从URL提取问题 window.addEventListener('load', function () { console.log('DOMContentLoaded event fired.'); const url = window.location.href; console.log('URL:', url); const match = url.match(/\?question:(.*)/); if (match) { const questionParam = match[1]; const question = decodeURIComponent(questionParam.replace(/\+/g, ' ')); console.log('Matched Question:', question); // 2. 将问题填入id为"prompt-textarea"的文本框 const textarea = document.querySelector('#prompt-textarea'); if (textarea) { setTimeout(function() {textarea.value = question;}, 2000); // 延迟2秒 setTimeout(function() {textarea.innerHTML = question;}, 2000); // 延迟2秒 console.log(textarea.value); } else { console.error('未找到id为prompt-textarea的文本框'); } } else { console.error('URL格式不匹配'); } });
尝试过的模拟键盘提交代码
setTimeout(function() { alert(1); let myElement = document.querySelector('#prompt-textarea'); myElement.focus(); myElement.dispatchEvent(new KeyboardEvent('keydown', { key: '' })); myElement.dispatchEvent(new KeyboardEvent('keyup', { key: '' })); myElement.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); myElement.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' })); });
解决方案
问题根源分析
- URL参数匹配错误:你的正则用了
\?question:(.*),但标准URL参数是key=value格式,应该用\?question=(.*)。 - 未触发React组件更新:ChatGPT的输入框是React组件,直接修改
value或innerHTML不会触发组件的状态变更,必须触发input事件让组件感知内容变化。 - 模拟键盘事件不可靠:依赖焦点和键盘事件容易受页面状态影响,直接点击提交按钮更稳定。
- 固定延迟不可靠:用
setTimeout硬等2秒,页面加载慢时还是会找不到元素,应该用MutationObserver等待元素动态加载。
修正后的完整代码
// 等待目标元素加载的工具函数,替代固定延迟 function waitForElement(selector, timeout = 10000) { return new Promise((resolve, reject) => { // 先检查元素是否已存在 const element = document.querySelector(selector); if (element) { return resolve(element); } // 用MutationObserver监听元素加载 const observer = new MutationObserver(() => { const element = document.querySelector(selector); if (element) { observer.disconnect(); resolve(element); } }); observer.observe(document.body, { childList: true, subtree: true }); // 超时处理 setTimeout(() => { observer.disconnect(); reject(new Error(`元素 ${selector} 超时未加载`)); }, timeout); }); } window.addEventListener('load', async function () { console.log('页面加载完成'); const url = window.location.href; console.log('当前URL:', url); // 修正参数匹配正则:使用标准的key=value格式 const match = url.match(/\?question=(.*)/); if (match) { const questionParam = match[1]; const question = decodeURIComponent(questionParam.replace(/\+/g, ' ')); console.log('提取到的问题:', question); try { // 等待输入框加载完成 const textarea = await waitForElement('#prompt-textarea'); // 设置内容并触发input事件,让React组件感知变化 textarea.value = question; textarea.dispatchEvent(new Event('input', { bubbles: true })); // 等待提交按钮加载并可用 const sendButton = await waitForElement('[data-testid="send-button"]'); // 直接点击提交按钮,避免焦点问题 sendButton.click(); console.log('问题已自动提交'); } catch (error) { console.error('自动提交失败:', error.message); } } else { console.error('URL中未找到question参数'); } });
关键修改点说明
- 用
MutationObserver等待元素:动态监听页面元素加载,比固定延迟更可靠,适配ChatGPT的异步加载逻辑。 - 触发
input事件:修改输入框内容后必须触发这个事件,否则React组件不会更新状态,提交按钮可能仍处于禁用状态。 - 直接点击提交按钮:ChatGPT的提交按钮有固定的
data-testid="send-button"属性,直接点击比模拟键盘事件更稳定,不需要处理焦点问题。 - 修正URL参数匹配:把正则里的冒号改成等号,符合标准的URL查询参数格式。
内容的提问来源于stack exchange,提问作者brooklynsweb
相关产品推荐
相关产品推荐

