您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Zotero GPT Pro, support ChatGPT Gemini Poe Kimi Coze Chatglm Yiyan Tongyi Claude
当前为
// ==UserScript== // @name Zotero GPT Connector // @description Zotero GPT Pro, support ChatGPT Gemini Poe Kimi Coze Chatglm Yiyan Tongyi Claude // @namespace http://tampermonkey.net/ // @icon https://github.com/MuiseDestiny/zotero-gpt/blob/bootstrap/addon/chrome/content/icons/favicon.png?raw=true // @version 2.7.0 // @author Polygon // @match https://chatgpt.com/* // @match https://gemini.google.com/app* // @match https://poe.com/* // @match https://www.coze.com/* // @match https://kimi.moonshot.cn/* // @match https://chatglm.cn/* // @match https://chatglm.cn/* // @match https://yiyan.baidu.com* // @match https://tongyi.aliyun.com/qianwen/* // @match https://claude.ai/* // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_cookie // @grant unsafeWindow // @run-at document-start // ==/UserScript== (async function () { 'use strict'; let isRunning = true let AI = "" if (location.host == 'chatgpt.com') { AI = "ChatGPT" } else if (location.host == 'gemini.google.com') { AI = "Gemini" } else if (location.host == 'poe.com') { AI = "Poe" } else if (location.host == 'kimi.moonshot.cn') { AI = "Kimi" } else if (location.host == 'www.coze.com') { AI = "Coze" } else if (location.host == "chatglm.cn") { AI = "Chatglm" GM_cookie.list({ url: 'https://chatglm.cn/chatglm/feed-api/assistant_top/v4/recent_list' }, function (cookies, error) { if (!error) { localStorage.setItem("token", cookies.find(i => i.name == "chatglm_token").value); localStorage.conversation_id = "" } }); } else if (location.host == 'yiyan.baidu.com') { AI = "Yiyan" } else if (location.host == 'tongyi.aliyun.com') { AI = "Tongyi" } else if (location.host == "claude.ai") { AI = "Claude" } // 在Zotero中执行代码 async function execInZotero(code) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "POST", url: "http://127.0.0.1:23119/zoterogpt", headers: { "Content-Type": "application/json", }, responseType: "json", data: JSON.stringify({ code }), onload: function (response) { if (response.status >= 200 && response.status < 300) { resolve(response.response.result); } else { reject(new Error(`Request failed with status: ${response.status}`)); } }, onerror: function (error) { reject(new Error('Network error')); } }); }); } // 设定ChatGPT输入框文本并发送 const setText = async (text) => { const originalText = text if (AI == "ChatGPT") { // 获取 input 输入框的dom对象 var element_input = window.document.querySelector('#prompt-textarea'); // 修改input的值 element_input.value = text; // 设置输入框的 input 事件 var event = new InputEvent('input', { 'bubbles': true, 'cancelable': true, }); element_input.dispatchEvent(event); const buttons = document.querySelector("#prompt-textarea").parentElement.parentElement.querySelectorAll("button"); const button = buttons[buttons.length - 1] button.click() setTimeout(() => { button.click() }, 100) } else if (AI == "Gemini") { // 获取 input 输入框的dom对象 var element_input = window.document.querySelector('rich-textarea .textarea'); // 修改input的值 element_input.textContent = text; document.querySelector(".send-button").click(); setTimeout(() => { document.querySelector(".send-button").click() }, 100) } else if (AI == "Poe") { var element_input = window.document.querySelector('textarea[class*=GrowingTextArea_textArea]'); element_input.value = text; // 设置输入框的 input 事件 var event = new InputEvent('input', { 'bubbles': true, 'cancelable': true, }); element_input.dispatchEvent(event); document.querySelector("button[class*=ChatMessageSendButton_sendButton]").click(); setTimeout(() => { document.querySelector("button[class*=ChatMessageSendButton_sendButton]").click() }, 100) } else if (AI == "Kimi") { fetch(`https://kimi.moonshot.cn/api/chat/${location.href.match(/chat\/([0-9a-z]+)/)[1]}/completion/stream`, { method: 'POST', headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${localStorage.access_token}` }, body: JSON.stringify({ "messages": [{ "role": "user", "content": text }], "refs": [], "use_search": false }) }) .then(response => { if (response.status == 200) { return response.body.getReader() } else { throw Error("授权失败") } }) .then(reader => { let text = "" const decoder = new TextDecoder(); window.setTimeout(async () => { while (true) { const { done, value } = await reader.read(); if (done) { await execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.responseText = ${JSON.stringify(text)}; task.type = "done"; task.responseType = "markdown" `) break } try { const newLines = decoder.decode(value, { stream: true }) for (let line of newLines.match(/data: .+/g)) { try { const data = JSON.parse(line.split("data: ")[1]) if (data.event && data.event == "cmpl") { text += data.text } else if (data.error) { text += data.error.message; console.log(data); document.querySelector("[data-testid=msh-sidebar-new]").click(); window.setTimeout(() => { setText(originalText) }, 1000) return } } catch { } execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.responseText = ${JSON.stringify(text)}; task.type = "pending"; task.responseType = "markdown" `) } } catch (e) { console.log(e) } } }, 0) }) .catch(e => { console.log(e) window.setTimeout(async () => { const res = await fetch("https://kimi.moonshot.cn/api/auth/token/refresh", { headers: { "Authorization": `Bearer ${localStorage.refresh_token}` } }) const data = await res.json() localStorage.access_token = data.access_token localStorage.refresh_token = data.refresh_token await setText(text) }) }) } else if (AI == "Coze") { const node = document.querySelector(".b5gKALp6yXERRDn8TV4r") node[Object.keys(node)[0]].pendingProps.children[0].props.onSendMessage({ text, mentionList: [] }) } else if (AI == "Chatglm") { fetch(`https://chatglm.cn/chatglm/backend-api/assistant/stream`, { method: 'POST', headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${localStorage.token}` }, body: JSON.stringify({ "assistant_id": "65940acff94777010aa6b796", "conversation_id": localStorage.conversation_id || "", "meta_data": { "mention_conversation_id": "", "is_test": false, "input_question_type": "xxxx", "channel": "", "draft_id": "" }, "messages": [ { "role": "user", "content": [{ "type": "text", "text": text }] }] }) }) .then(response => { if (response.status == 200) { return response.body.getReader() } else { throw Error("授权失败") } }) .then(reader => { let text = "" const decoder = new TextDecoder(); window.setTimeout(async () => { while (true) { const { done, value } = await reader.read(); if (done) { await execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.responseText = ${JSON.stringify(text)}; task.type = "done"; task.responseType = "markdown" `) break } try { const newLines = decoder.decode(value, { stream: true }) for (let line of newLines.match(/event:message\ndata: .+/g)) { try { const data = JSON.parse(line.split("data: ")[1]) if (localStorage.conversation_id.length == 0) { localStorage.conversation_id = data.conversation_id } text = data.parts[0].content[0].text } catch { } execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.responseText = ${JSON.stringify(text)}; task.type = "pending"; task.responseType = "markdown" `) } } catch (e) { console.log(e) } } }, 0) }) .catch(e => { console.log(e) localStorage.conversation_id = "" }) } else if (AI == "Yiyan") { const node = document.querySelector("#eb_model_footer") node[Object.keys(node)[1]].children[2].props.children[2].props.children[0].props.setText(text); document.querySelector(".VAtmtpqL").click() } else if (AI == "Tongyi") { const node = document.querySelector(".inputField--PE5FhWzd").children[0] node[Object.keys(node)[1]].children[3].props.children[0].props.setText(text); window.setTimeout(async () => { const node2 = document.querySelector(".operateBtn--zFx6rSR0"); node2[Object.keys(node2)[1]].onClick() }) } else if (AI == "Claude") { const node = document.querySelector("fieldset") const props = node[Object.keys(node)[1]].children[0].props.children[0].props.children[0].props; props.setInput(text); document.querySelector("button[aria-label='Send Message']").click(); } } // 阻塞 function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } GM_registerMenuCommand('🔗 运行', () => { isRunning = true window.alert("🔗 已运行") }); GM_registerMenuCommand('🎊 断开', () => { isRunning = false window.alert("🎊 断开") }); // 通信 await sleep(3000) while (true) { if (!isRunning) { await execInZotero(` window.Meet.Connector.time = 0; `) await sleep(1000) continue; } try { const tasks = (await execInZotero(` if (!window.Meet.Connector){ window.Meet.Connector = ${JSON.stringify({ AI, time: Date.now() / 1e3, tasks: [] })}; } else { window.Meet.Connector window.Meet.Connector.time = ${Date.now() / 1e3}; window.Meet.Connector.AI = "${AI}"; } window.Meet.Connector `)).tasks if (!tasks || tasks.length == 0) { await sleep(500) continue } const task = tasks.slice(-1)[0] if (task.type == "pending") { if (task.requestText) { // 操作浏览器提问 if (AI == "ChatGPT") { let getUserQuestionNum = () => document.querySelectorAll("[data-message-author-role=user]").length const questionNum = getUserQuestionNum() await setText(task.requestText) while (getUserQuestionNum() == questionNum) { await sleep(100) } } else if (AI == "Gemini") { let getUserQuestionNum = () => document.querySelectorAll("user-query").length const questionNum = getUserQuestionNum() await setText(task.requestText) while (getUserQuestionNum() == questionNum) { await sleep(100) } while (document.querySelectorAll('model-response').length != getUserQuestionNum()) { await sleep(100) } } else if (AI == "Poe") { let getUserQuestionNum = () => document.querySelectorAll("[class*=ChatMessage_humanMessageWrapper]").length const questionNum = getUserQuestionNum() await setText(task.requestText) while (getUserQuestionNum() == questionNum) { await sleep(100) } while (document.querySelectorAll('[class*=Message_botMessageBubble]').length != getUserQuestionNum()) { await sleep(100) } } else { await setText(task.requestText) } await execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.requestText = ""; task.responseText = "<p>Waiting ${AI}...</p>"; `) } else { let isDone = false, text = "", type = "html" const setZoteroText = async () => { await execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.responseText = ${JSON.stringify(text)}; task.type = ${isDone} ? "done" : "pending"; task.responseType = "${type}" `) if (isDone) { await sleep(1000) await execInZotero(` let task = window.Meet.Connector.tasks[window.Meet.Connector.tasks.length-1] task.responseText = ${JSON.stringify(text)}; `) } } if (AI == "ChatGPT") { type = "markdown" const outputEle = [...document.querySelectorAll('[data-testid^=conversation-turn]')].slice(-1)[0]; const node = outputEle.querySelector("[data-message-author-role=assistant]") // const contentEle = outputEle.querySelector("div>div>div:nth-child(2)>div:nth-child(2)>div") isDone = Boolean(outputEle.querySelector("span[data-state=closed]")) text = node[Object.keys(node)[0]].alternate.alternate.pendingProps.children[1].props.messages[0].message.content.parts[0] await setZoteroText() } else if (AI == "Gemini") { const outputEle = [...document.querySelectorAll('model-response')].slice(-1)[0]; const contentEle = outputEle.querySelector(".response-content message-content") isDone = Boolean(outputEle.querySelector(".complete")) text = contentEle.querySelector(".markdown").innerHTML await setZoteroText() } else if (AI == "Poe") { const outputEle = [...document.querySelectorAll('[class*=Message_botMessageBubble]')].slice(-1)[0]; const contentEle = outputEle.querySelector("[class*=Markdown_markdownContainer]") isDone = Boolean(document.querySelector("[class*=ChatMessageActionBar_actionBar]")) text = contentEle.innerHTML await setZoteroText() } else if (AI == "Kimi") { // 无需这一步 } else if (AI == "Coze") { const outputEle = document.querySelector(".message-group-wrapper"); const contentEle = outputEle.querySelector("[data-testid='bot.ide.chat_area.message_box'] .flow-markdown-body") isDone = Boolean(outputEle.querySelector(".chat-uikit-message-box-container__message__message-box__footer").childNodes.length != 0) text = contentEle.innerHTML.replace(/<br .+?>/g, "").replace(/<hr .+?>/g, "<hr/>") await setZoteroText() } else if (AI == "Kimi") { // 无需这一步 } else if (AI == "Yiyan") { const outputEle = document.querySelector(".ErXhAgf5 .RmHagX8t"); const contentEle = outputEle.querySelector(".custom-html.md-stream-desktop") isDone = Boolean(outputEle.querySelector(".fXxD0Rtx")) text = contentEle.innerHTML.replace(/<br .+?>/g, "").replace(/<hr .+?>/g, "<hr/>") await setZoteroText() } else if (AI == "Tongyi") { const lastQuestion = [...document.querySelectorAll(".questionItem--dS3Alcnv")].slice(-1)[0] const outputEle = lastQuestion.nextElementSibling; const contentEle = outputEle.querySelector(".tongyi-ui-markdown") isDone = Boolean(outputEle.querySelector(".tools--IJfoLgka")) type = "markdown" text = contentEle[Object.keys(contentEle)[1]].children._owner.pendingProps.children .replace(/\[ty-private-cursor\]\(ty-private-cursor\)$/, "") await setZoteroText() } else if (AI == "Claude") { const node = [...document.querySelectorAll("div[data-test-render-count]")].slice(-1)[0].querySelector("[data-is-streaming]"); type = "markdown" text = node[Object.keys(node)[1]].children[0].props.children.props.text; isDone = node.getAttribute("data-is-streaming") == "false"; await setZoteroText() } } } } catch (e) { console.log(e) await sleep(1000) } await sleep(100) } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址