// ==UserScript==
// @name 大模型多站点
// @namespace http://tampermonkey.net/
// @version 1.0.4
// @description 提高效率
// @author wz
// @match https://www.kimi.com/*
// @match https://chat.deepseek.com/*
// @match https://www.tongyi.com/*
// @match https://chatgpt.com/*
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @license GPL-3.0-only
// ==/UserScript==
(function () {
'use strict';
console.log("ai script, start");
const CACHE_PREFIX = "tool-";
const LAST_QUESTION = "lastQuestion-";
const SPLIT_CHAR = ",,,";
const url = window.location.href;
let MAIN_SITE = 0;
// let activeSites = [1, 2];
let activeSites = [0, 1, 2];
let site = 0;
let lock = false;
const keywords = {
"kimi": 0,
"deepseek": 1,
"tongyi": 2,
"chatgpt": 3
};
for (const keyword in keywords) {
if (url.indexOf(keyword) > -1) {
site = keywords[keyword];
break;
}
}
const historySites = {
0: "https://www.kimi.com/chat/",
1: "https://chat.deepseek.com/a/chat/s/",
2: "https://www.tongyi.com/?sessionId=",
3: "https://chatgpt.com/c/"
}
const newSites = {
0: "https://www.kimi.com/",
1: "https://chat.deepseek.com/",
2: "https://www.tongyi.com/",
3: "https://chatgpt.com/"
}
function getChatId(){
let url = getUrl();
let subStr = url.substring(url.lastIndexOf('/') + 1);
// console.log("subStr: "+subStr);
if(isEmpty(subStr)){
return "";
}
if(site === 2){
let mark = 'sessionId=';
let tmp = url.lastIndexOf(mark) + mark.length;
return url.substring(tmp);
}else{
return subStr;
}
}
function getUrl(){
return window.location.href;
}
function getS(key){
return localStorage.getItem(key);
}
function setS(key, val){
return localStorage.setItem(key, val);
}
function setGV(key, value){
GM_setValue(key, value);
}
function getGV(key){
return GM_getValue(key);
}
let len = 0;
let hasChatId = false;
// setInterval(function(){
// masterCheckNew();
// receiveNew();
// }, 3000);
setTimeout(function(){
setInterval(function(){
masterCheckNew();
receiveNew();
}, 2000);
}, 1000);
// 发送端
let masterId = "";
function masterCheckNew(){
let questions = [];
if(site == 0){
questions = document.getElementsByClassName("user-content");
}else if(site == 1){
}else if(site == 2){
questions = document.querySelectorAll('[class^="bubble-"]');
}
let lenNext = questions.length;
if(lenNext > 0){
masterId = getChatId();
len = getS(CACHE_PREFIX + masterId);
if(lenNext > len){
let lastestQ = questions[lenNext - 1].textContent;
let lastQuestion = getS(LAST_QUESTION + masterId);
if(!isEmpty(lastQuestion) && lastestQ === lastQuestion){
return;
}
masterReq(masterId, lastestQ);
hasChatId = true;
setS(CACHE_PREFIX + masterId, lenNext);
}
}
};
function masterReq(masterId, lastestQ){
let uid = getS(masterId);
if(isEmpty(uid)){
uid = guid();
setS(masterId, uid);
}
let message = {
uid: uid,
question: lastestQ
};
console.log(message);
setGV("msg", message);
setS(LAST_QUESTION + masterId, lastestQ);
// 其实只有首次发问题才需要如下处理
let uidJson = getGV(uid);
if(isEmpty(uidJson)){
uidJson = {};
uidJson[site] = masterId;
console.log("master print uidJson: "+JSON.stringify(uidJson));
setGV(uid, uidJson);
}
}
function receiveNew(){
let curSlaveId = getChatId();
if(curSlaveId.length < 12){
curSlaveId = "";
}
let msg = getGV("msg");
if(isEmpty(msg)){
return;
}
let question = msg.question;
let lastQuestion = getS(LAST_QUESTION + curSlaveId);
let sameQuestion = !isEmpty(lastQuestion) && question === lastQuestion;
if(sameQuestion){
return;
}
let questionBeforeJump = getS("questionBeforeJump");
// 如果是经跳转而来,无需处理主节点信息,直接从缓存取对话内容
if(!isEmpty(questionBeforeJump)){
console.log("questionBeforeJump: " + questionBeforeJump);
let splits = questionBeforeJump.split(SPLIT_CHAR);
let cachedQuestion = splits[0];
let cachedUid = splits[1];
// 清空跳转用的缓存
setS("questionBeforeJump", "");
abstractSend(site, cachedQuestion);
if(isEmpty(curSlaveId)){
let uidJson = getGV(cachedUid);
setUid(cachedUid, cachedQuestion, uidJson);
}else{
setS(LAST_QUESTION + curSlaveId, cachedQuestion);
}
return;
}
let uid = msg.uid;
// 当前空,且之前chatId有值,则认为是手动打开的页面,
if(isEmpty(curSlaveId)){
if(hasChatId){
return;
}
}else{
hasChatId = true;
}
let targetUrl = "";
let slaveIdFlag = false;
let slaveId = "";
let uidJson = getGV(uid);
let lastQuestionOfComingSlaveId = "";
if(!isEmpty(uidJson)){
slaveId = uidJson[site];
lastQuestionOfComingSlaveId = getS(LAST_QUESTION + slaveId);
if(question === lastQuestionOfComingSlaveId){
return;
}
if(!isEmpty(slaveId)){
slaveIdFlag = true;
}
}
let curIdFlag = !isEmpty(curSlaveId);
if(slaveIdFlag){
if(curIdFlag){
if(curSlaveId === slaveId){
if(!sameQuestion){
abstractSend(site, question);
setS(LAST_QUESTION + curSlaveId, question);
}
}else{
targetUrl = historySites[site] + slaveId;
}
}else{
targetUrl = historySites[site] + slaveId;
}
}else{
if(curIdFlag){
targetUrl = newSites[site];
}else{
abstractSend(site, question);
setUid(uid, question, uidJson);
}
}
if(!isEmpty(targetUrl)){
setS("questionBeforeJump", question + SPLIT_CHAR + uid);
window.location.href = targetUrl;
}
}
function setUid(uid, question, uidJson){
let intervalId;
let lastUrl = getUrl();
let count = 0;
let gap = 100;
intervalId = setInterval(function() {
count ++;
if(count > 10000 / gap){
clearInterval(intervalId);
}
let currentUrl = getUrl();
if (currentUrl !== lastUrl) {
let chatId = getChatId();
hasChatId = true;
if(!isEmpty(uidJson)){
if(isEmpty(uidJson[site])){
uidJson[site] = chatId;
}
}else{
uidJson = {};
uidJson[site] = chatId;
}
setS(LAST_QUESTION + chatId, question);
console.log("slave print uidJson: "+JSON.stringify(uidJson));
setGV(uid, uidJson);
setS(chatId, uid);
clearInterval(intervalId);
}
}, gap);
}
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function abstractSend(site, content){
let intervalId;
let count = 0;
let gap = 100;
intervalId = setInterval(function() {
count ++;
if(count > 5000 / gap){
clearInterval(intervalId);
}
let textarea = getTextArea(site);
if (!isEmpty(textarea)) {
textarea.focus();
document.execCommand('insertText', false, content);
setTimeout(function(){
let sendBtn = getBtn(site);
sendBtn.click();
}, 100);
clearInterval(intervalId);
}
}, gap);
}
function getTextArea(site){
if(site == 0){
return document.getElementsByClassName('chat-input-editor')[0];
}else if(site === 1){
return document.getElementById('chat-input');
}else if(site === 2){
return document.getElementsByTagName('textarea')[0];
}else if(site === 3){
return document.getElementById('prompt-textarea');
}
}
function getBtn(site){
if(site == 0){
return document.getElementsByClassName('send-button-container')[0];
}else if(site === 1){
var btns = document.querySelectorAll('[role="button"]');
return btns[btns.length - 1];
}else if(site === 2){
return document.querySelectorAll('[class^="operateBtn-"], [class*=" operateBtn-"]')[0];
}else if(site === 3){
return document.getElementById('composer-submit-button');
}
}
function isEmpty(item){
if(item===null || item===undefined || item.length===0 || item === "null"){
return true;
}else{
return false;
}
}
})();