您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Zotero GPT Pro, support ChatGPT Gemini Poe Kimi
当前为
// ==UserScript== // @name Zotero GPT Connector // @namespace http://tampermonkey.net/ // @version 2.0 // @description Zotero GPT Pro, support ChatGPT Gemini Poe Kimi // @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/* // @icon https://cdn.oaistatic.com/_next/static/media/favicon-32x32.be48395e.png // @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') { GM_cookie.list({ url: 'https://www.coze.com/' }, function (cookies, error) { if (!error) { const cookie = `sessionid_ss=${cookies.find(i => i.name == "sessionid_ss").value};` console.log(cookie) } }); AI = "Coze" } // 在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 = (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.tasks[window.Meet.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 } } catch { } execInZotero(` let task = window.Meet.tasks[window.Meet.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 setText(text) }) }) } else if (AI == "Coze") { GM_cookie.list({ url: 'https://www.coze.com/' }, function (cookies, error) { if (!error) { const cookie = `sessionid_ss=${cookies.find(i => i.name == "sessionid_ss").value};` console.log(cookie) } }); } } // 阻塞 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.tasks = undefined `) await sleep(1000) continue; } try { const result = await execInZotero(` if (!window.Meet.tasks){ window.Meet.tasks = [] } else { window.Meet.tasks } `) const tasks = result; 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() setText(task.requestText) while (getUserQuestionNum() == questionNum) { await sleep(100) } } else if (AI == "Gemini") { let getUserQuestionNum = () => document.querySelectorAll("user-query").length const questionNum = getUserQuestionNum() 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() setText(task.requestText) while (getUserQuestionNum() == questionNum) { await sleep(100) } while (document.querySelectorAll('[class*=Message_botMessageBubble]').length != getUserQuestionNum()) { await sleep(100) } } else if (AI == "Kimi") { setText(task.requestText) } await execInZotero(` let task = window.Meet.tasks[window.Meet.tasks.length-1] task.requestText = ""; task.responseText = "<p>Answering (本过程不消耗Api Key额度)...</p>"; `) } else { let isDone = false, text = "", type = "html" const setZoteroText = async () => { await execInZotero(` let task = window.Meet.tasks[window.Meet.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.tasks[window.Meet.tasks.length-1] task.responseText = ${JSON.stringify(text)}; `) } } if (AI == "ChatGPT") { const outputEle = [...document.querySelectorAll('[data-testid^=conversation-turn]')].slice(-1)[0]; // const contentEle = outputEle.querySelector("div>div>div:nth-child(2)>div:nth-child(2)>div") isDone = Boolean(outputEle.querySelector("span[data-state=closed]")) text = outputEle.querySelector(".markdown").innerHTML 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") { // } } } } catch (e) { console.log(e) } await sleep(100) } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址